Forráskód Böngészése

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVisaServiceImpl.java
liuyc 1 éve
szülő
commit
c85ea82d29
46 módosított fájl, 1649 hozzáadás és 143 törlés
  1. 2 0
      blade-common/src/main/java/org/springblade/common/constant/LauncherConstant.java
  2. 22 0
      blade-service-api/blade-land-api/pom.xml
  3. 24 0
      blade-service-api/blade-land-api/src/main/java/org/springblade/land/dto/PolicyInfoDTO.java
  4. 37 0
      blade-service-api/blade-land-api/src/main/java/org/springblade/land/dto/PolicyInfoSearchDTO.java
  5. 36 0
      blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/AttachmentInfo.java
  6. 45 0
      blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/PolicyInfo.java
  7. 1 0
      blade-service-api/pom.xml
  8. 1 1
      blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java
  9. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/EVisaTaskCheckController.java
  10. 3 2
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  11. 18 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml
  12. 2 2
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml
  13. 13 0
      blade-service/blade-e-visa/pom.xml
  14. 122 43
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVisaServiceImpl.java
  15. 117 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/PDFUtils.java
  16. 67 0
      blade-service/blade-land/pom.xml
  17. 19 0
      blade-service/blade-land/src/main/java/org/springblade/land/LandApplication.java
  18. 75 0
      blade-service/blade-land/src/main/java/org/springblade/land/controller/AttachmentInfoController.java
  19. 92 0
      blade-service/blade-land/src/main/java/org/springblade/land/controller/PolicyInfoController.java
  20. 40 0
      blade-service/blade-land/src/main/java/org/springblade/land/mapper/AttachmentInfoMapper.java
  21. 21 0
      blade-service/blade-land/src/main/java/org/springblade/land/mapper/AttachmentInfoMapper.xml
  22. 35 0
      blade-service/blade-land/src/main/java/org/springblade/land/mapper/PolicyInfoMapper.java
  23. 19 0
      blade-service/blade-land/src/main/java/org/springblade/land/mapper/PolicyInfoMapper.xml
  24. 44 0
      blade-service/blade-land/src/main/java/org/springblade/land/service/IAttachmentInfoService.java
  25. 49 0
      blade-service/blade-land/src/main/java/org/springblade/land/service/IPolicyInfoService.java
  26. 98 0
      blade-service/blade-land/src/main/java/org/springblade/land/service/impl/AttachmentInfoServiceImpl.java
  27. 134 0
      blade-service/blade-land/src/main/java/org/springblade/land/service/impl/PolicyInfoServiceImpl.java
  28. 74 0
      blade-service/blade-land/src/main/java/org/springblade/land/utils/FileUtils.java
  29. 19 0
      blade-service/blade-land/src/main/resources/application-dev.yml
  30. 11 0
      blade-service/blade-land/src/main/resources/application-prod.yml
  31. 10 0
      blade-service/blade-land/src/main/resources/application-test.yml
  32. 3 2
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java
  33. 6 1
      blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java
  34. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/AppVersionDetailController.java
  35. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  36. 6 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormulaController.java
  37. 1 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java
  38. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/ITurnPointCalculator.java
  39. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/FormulaMileage.java
  40. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ContractInfoMapper.xml
  41. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeContractSyncImpl.java
  42. 61 6
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  43. 40 6
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  44. 0 71
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/ExcelInfoUtils.java
  45. 271 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/ExcelInfoUtils2.java
  46. 1 0
      blade-service/pom.xml

+ 2 - 0
blade-common/src/main/java/org/springblade/common/constant/LauncherConstant.java

@@ -35,6 +35,8 @@ public interface LauncherConstant {
 
     String APPLICATION_VISUAL_NAME = APPLICATION_NAME_PREFIX + "visual";
 
+    String APPLICATION_LAND_NAME = APPLICATION_NAME_PREFIX + "land";
+
     /**
      * xxljob
      */

+ 22 - 0
blade-service-api/blade-land-api/pom.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>blade-service-api</artifactId>
+        <groupId>org.springblade</groupId>
+        <version>2.9.1.RELEASE</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>blade-land-api</artifactId>
+    <name>${project.artifactId}</name>
+    <version>${bladex.project.version}</version>
+    <packaging>jar</packaging>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+    </properties>
+
+</project>

+ 24 - 0
blade-service-api/blade-land-api/src/main/java/org/springblade/land/dto/PolicyInfoDTO.java

@@ -0,0 +1,24 @@
+package org.springblade.land.dto;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+import org.springblade.land.entity.AttachmentInfo;
+import org.springblade.land.entity.PolicyInfo;
+
+import java.util.List;
+
+/**
+ * @Param  政策法规-附件表
+ * @Author wangwl
+ * @Date 2023/9/12 11:47
+ **/
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class PolicyInfoDTO extends PolicyInfo {
+
+    @ApiModelProperty(value = "附件集合")
+    private List<AttachmentInfo> list;
+}

+ 37 - 0
blade-service-api/blade-land-api/src/main/java/org/springblade/land/dto/PolicyInfoSearchDTO.java

@@ -0,0 +1,37 @@
+package org.springblade.land.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.land.entity.AttachmentInfo;
+import org.springblade.land.entity.PolicyInfo;
+
+import java.time.LocalDate;
+import java.util.List;
+
+/**
+ * @Param  政策法规-附件表
+ * @Author wangwl
+ * @Date 2023/9/12 11:47
+ **/
+@Data
+public class PolicyInfoSearchDTO {
+
+    @ApiModelProperty(value = "项目id")
+    private Long projectId;
+
+    @ApiModelProperty(value = "名称")
+    private String name;
+
+    @ApiModelProperty(value = "区域id")
+    private Long areaId;
+
+    @ApiModelProperty(value = "1政策法规2双方协议")
+    private Integer type;
+
+    @ApiModelProperty(value = "开始时间")
+    private LocalDate startDate;
+
+    @ApiModelProperty(value = "结束时间")
+    private LocalDate endDate;
+}

+ 36 - 0
blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/AttachmentInfo.java

@@ -0,0 +1,36 @@
+package org.springblade.land.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+
+/**
+ * @Param  政策法规-附件表
+ * @Author wangwl
+ * @Date 2023/9/12 11:47
+ **/
+@Data
+@TableName("l_attachment_info")
+@EqualsAndHashCode(callSuper = true)
+public class AttachmentInfo extends BaseEntity {
+
+    @ApiModelProperty(value = "项目id")
+    private Long projectId;
+
+    @ApiModelProperty(value = "主键id")
+    private Long masterId;
+
+    @ApiModelProperty(value = "附件名称")
+    private String name;
+
+    @ApiModelProperty(value = "附件路径")
+    private String domainUrl;
+
+    @ApiModelProperty(value = "附件后缀")
+    private String extension;
+
+    @ApiModelProperty(value = "附件PDF路径")
+    private String domainPdfUrl;
+}

+ 45 - 0
blade-service-api/blade-land-api/src/main/java/org/springblade/land/entity/PolicyInfo.java

@@ -0,0 +1,45 @@
+package org.springblade.land.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springblade.core.mp.base.BaseEntity;
+
+import java.time.LocalDate;
+
+/**
+ * @Param  政策法规,双方协议表
+ * @Author wangwl
+ * @Date 2023/9/12 11:03
+ **/
+@Data
+@TableName("l_policy_info")
+@EqualsAndHashCode(callSuper = true)
+public class PolicyInfo extends BaseEntity {
+
+    @ApiModelProperty(value = "项目id")
+    private Long projectId;
+
+    @ApiModelProperty(value = "业务编号")
+    private String number;
+
+    @ApiModelProperty(value = "名称")
+    private String name;
+
+    @ApiModelProperty(value = "区域id")
+    private Long areaId;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @ApiModelProperty(value = "附件pdf路径")
+    private String pdfUrl;
+
+    @ApiModelProperty(value = "类型1政策法规2双方协议")
+    private Integer type;
+
+    @ApiModelProperty(value = "类型1政策法规2双方协议")
+    private LocalDate uploadDate;
+
+}

+ 1 - 0
blade-service-api/pom.xml

@@ -26,6 +26,7 @@
         <module>blade-e-visa-api</module>
         <module>blade-archive-api</module>
         <module>blade-control-api</module>
+        <module>blade-land-api</module>
     </modules>
 
     <dependencies>

+ 1 - 1
blade-service/blade-archive/src/main/java/org/springblade/archive/controller/ArchivesAutoController.java

@@ -326,7 +326,7 @@ public class ArchivesAutoController extends BladeController {
 	@ApiOperation(value = "获取归档树同级节点", notes = "传入节点id")
 	public R test() {
 
-		archivesAutoService.test();
+		archiveAutoPdfService.test();
 		return R.data("");
 	}
 

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

@@ -565,6 +565,8 @@ public class EVisaTaskCheckController {
             //资料填报
             //jsonList = this.eVisaConfigClient.queryEVisaConfigAllByTableIds(json.getJSONArray("privatePKeyId").toJavaList(String.class));
             List<String> ids = json.getJSONArray("privatePKeyId").toJavaList(String.class);
+            //指向项目级的ID有可能为null
+            ids = ids.stream().filter(Objects::nonNull).collect(Collectors.toList());
             String sql = "select * from m_textdict_info where tab_id in(" + StringUtils.join(ids, ",") + ")";
             List<TextdictInfo> query = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(TextdictInfo.class));
             jsonList = JSONArray.parseArray(JSONObject.toJSONString(query), JSONObject.class);

+ 3 - 2
blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java

@@ -31,6 +31,7 @@ import org.springblade.core.boot.ctrl.BladeController;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
+import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.sms.model.SmsResponse;
@@ -676,8 +677,8 @@ public class TaskController extends BladeController {
     @GetMapping("/query-task-type-status")
     @ApiOperationSupport(order = 6)
     @ApiOperation(value = "获取任务类型或任务状态")
-    public R<List<DictBiz>> queryTaskTypeOrStatus(String typeOrStatus) {
-        return R.data(jdbcTemplate.query("select dict_key, dict_value from blade_dict_biz where code = '" + typeOrStatus + "' and parent_id > 0 and is_sealed = 0 and is_deleted = 0 order by sort", new BeanPropertyRowMapper<>(DictBiz.class)));
+    public R<List<DictBiz>> queryTaskTypeOrStatus(String typeOrStatus, BladeUser bladeUser) {
+        return R.data(jdbcTemplate.query("select dict_key, dict_value from blade_dict_biz where code = '" + typeOrStatus + "' and tenant_id="+bladeUser.getTenantId()+" and parent_id > 0 and is_sealed = 0 and is_deleted = 0 order by sort", new BeanPropertyRowMapper<>(DictBiz.class)));
     }
 
     /**

+ 18 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/ArchiveFileMapper.xml

@@ -385,6 +385,23 @@
     </update>
 
     <select id="getListByContractId" resultType="org.springblade.business.entity.ArchiveFile">
+        SELECT
+            u.id,
+            u.project_id AS projectId,
+            u.node_id AS nodeId,
+            u.node_ext_id AS nodeExtId,
+            u.file_name AS fileName,
+            u.pdf_file_url AS pdfFileUrl,
+            u.sort
+        FROM
+            u_archive_file u
+                LEFT JOIN m_archive_tree_contract ar on u.node_id = ar.id
+        where 	u.contract_id = #{contractId}
+          AND u.is_deleted = 0
+          AND u.source_type = 1 and ar.is_deleted = 0;
+    </select>
+
+    <select id="getListByContractId1" resultType="org.springblade.business.entity.ArchiveFile">
         select id,
                project_id   as projectId,
                node_id      as nodeId,
@@ -395,6 +412,7 @@
         from u_archive_file
         where contract_id = #{contractId} and is_deleted = 0 and source_type = 1;
     </select>
+
     <select id="getAllArchiveAutoByContractType" resultType="org.springblade.archive.vo.ArchivesAutoVO">
         SELECT uaa.*, matc.tree_code as 'contractType'
         FROM u_archives_auto uaa

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

@@ -31,8 +31,8 @@
         <result column="source_type" property="sourceType"/>
         <result column="pdf_trial_url_position" property="pdfTrialUrlPosition"/>
        <result column="business_time" property="businessTime"/>
-        <result column="e_visa_pdf_page" property="eVisaPdfSize"/>
-        <result column="e_visa_pdf_size" property="eVisaPdfPage"/>
+        <result column="e_visa_pdf_page" property="eVisaPdfPage"/>
+        <result column="e_visa_pdf_size" property="eVisaPdfSize"/>
     </resultMap>
 
     <resultMap id="queryProcessDataMap" type="org.springblade.business.vo.QueryProcessDataVO">

+ 13 - 0
blade-service/blade-e-visa/pom.xml

@@ -12,6 +12,14 @@
 
     <artifactId>blade-e-visa</artifactId>
 
+    <repositories>
+        <repository>
+            <id>com.e-iceblue</id>
+            <name>e-iceblue</name>
+            <url>https://repo.e-iceblue.cn/repository/maven-public/</url>
+        </repository>
+    </repositories>
+
     <dependencies>
         <dependency>
             <groupId>org.springblade</groupId>
@@ -195,6 +203,11 @@
             <version>2.0.20</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>e-iceblue</groupId>
+            <artifactId>spire.office.free</artifactId>
+            <version>5.3.1</version>
+        </dependency>
         <dependency>
             <groupId>org.springblade</groupId>
             <artifactId>blade-system-api</artifactId>

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

@@ -23,34 +23,29 @@ import cfca.paperless.dto.response.responsebody.tx40.VerifyPdfSealResponseBody;
 import cfca.paperless.dto.response.tx20.MakeSealResponse;
 import cfca.paperless.dto.response.tx40.CompoundSealPdfListDetachedResponse;
 import cfca.paperless.dto.response.tx40.VerifyPdfSealResponse;
-import cfca.sadk.com.itextpdf.styledxmlparser.jsoup.helper.DataUtil;
 import cn.hutool.core.io.file.FileReader;
 import com.alibaba.fastjson.JSONObject;
 import lombok.AllArgsConstructor;
-import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springblade.business.entity.ArchiveFile;
-import org.springblade.business.entity.Task;
 import org.springblade.business.feign.TaskClient;
 import org.springblade.business.vo.TaskApprovalVO;
 import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.constant.EVisaConstant;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
-import org.springblade.common.utils.SystemUtils;
 import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.secure.utils.AuthUtil;
-import org.springblade.core.secure.utils.SecureUtil;
-import org.springblade.core.tool.utils.DateUtil;
 import org.springblade.core.tool.utils.FileUtil;
-import org.springblade.core.tool.utils.ObjectUtil;
 import org.springblade.evisa.redissionUtil.DistributedRedisLock;
 import org.springblade.evisa.service.EVisaService;
-import org.springblade.evisa.vo.*;
+import org.springblade.evisa.vo.EVisaMakeSealVO;
+import org.springblade.evisa.vo.EVisaTaskApprovalVO;
+import org.springblade.evisa.vo.SealPdfVO;
+import org.springblade.evisa.vo.SealStrategyVO;
 import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.entity.SignPfxFile;
 import org.springblade.manager.feign.ContractClient;
@@ -62,8 +57,6 @@ import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
 import org.springframework.http.converter.HttpMessageConverter;
 import org.springframework.http.converter.StringHttpMessageConverter;
-import org.springframework.jdbc.core.BeanPropertyRowMapper;
-import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.mock.web.MockMultipartFile;
 import org.springframework.stereotype.Service;
 import org.springframework.web.client.RestTemplate;
@@ -77,8 +70,10 @@ import javax.imageio.stream.ImageOutputStream;
 import java.awt.image.BufferedImage;
 import java.io.*;
 import java.nio.charset.StandardCharsets;
-import java.util.*;
-import java.util.stream.Collectors;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
 
 @Service
 @AllArgsConstructor
@@ -108,11 +103,12 @@ public class EVisaServiceImpl implements EVisaService {
 
     private final ContractClient contractClient;
 
-    private final JdbcTemplate jdbcTemplate;
-
     @Autowired
     StringRedisTemplate RedisTemplate;
 
+    private final JdbcTemplate jdbcTemplate;
+
+
     @Override
     public String certification(String pdfUrl, String fileName, String contractId) {
         try {
@@ -220,6 +216,83 @@ public class EVisaServiceImpl implements EVisaService {
      */
     @Override
     public String eVisaContractSeal(EVisaTaskApprovalVO task, String finalPdfUrl) {
+
+        //获取任务对应表格的电签配置(合同张)
+        String sysBatch = ParamCache.getValue(CommonConstant.SYS_USER_TASK_BATCH);
+        int batch = 2;
+        if (CommonUtil.checkIsBigDecimal(sysBatch)) {
+            batch = new Integer(sysBatch);
+        }
+
+        if (DistributedRedisLock.acquire(AuthUtil.getUserId().toString(), batch)) {
+            try {
+
+                List<String> eVisaConfigList = PDFUtils.getPdfSignIds(finalPdfUrl);
+                if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
+                    return finalPdfUrl;
+                }
+                String contractId = this.taskClient.queryTaskContractId(task.getParallelProcessInstanceId());
+
+                String ids = String.join(",", eVisaConfigList);
+                String sqlinfo = "SELECT a.id,a.pyzbx,a.pyzby,b.signature_file_url,b.id as sfId,b.certificate_password,b.certificate_user_name from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + contractId + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + ids + ")";
+                List<Map<String, Object>> maps = jdbcTemplate.queryForList(sqlinfo);
+                System.out.println("合同-"+contractId+"--"+sqlinfo);
+
+                //准备签章策略
+                List<SealStrategyVO> sealStrategyVOS = new ArrayList<>();
+                for (Map<String, Object> eVisaConfig : maps) {
+                    //设置签章策略
+                    SealStrategyVO vo = new SealStrategyVO();
+                    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);
+                }
+
+                SealPdfVO pdfVO = new SealPdfVO();
+                pdfVO.setStrategyVoList(sealStrategyVOS);
+
+                //获取字节
+                byte[] fileByte = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(finalPdfUrl));
+                //执行电签
+                Object[] result = this.signPdfByAXQZ(pdfVO, fileByte);
+                if (result != null) {
+                    if (result[0] != null) {
+                        MultipartFile newFiles = new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "text/plain", IOUtils.toByteArray(new ByteArrayInputStream((byte[]) result[0])));
+                        //重新上传
+                        BladeFile bladeFile = this.newIOSSClient.uploadFileByInputStream(newFiles);
+                        if (bladeFile != null) {
+                            finalPdfUrl = bladeFile.getLink();
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        //释放锁
+        DistributedRedisLock.release(AuthUtil.getUserId().toString());
+
+        return finalPdfUrl;
+    }
+
+
+    /**
+     * 合同章 签字
+     *
+     * @param task
+     * @param finalPdfUrl
+     * @return
+     */
+
+    public String eVisaContractSeal222(EVisaTaskApprovalVO task, String finalPdfUrl) {
         //获取任务对应表格的电签配置(合同张)
         List<JSONObject> eVisaConfigList = this.taskClient.queryBusinessTableEVisaConfig(task.getParallelProcessInstanceId(), task.getUserId(), "true");
         if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
@@ -327,7 +400,7 @@ public class EVisaServiceImpl implements EVisaService {
             return NOT_PFX_OR_FILE;
         }
 
-        //获取任务对应表格的电签配置
+        /*//获取任务对应表格的电签配置
         List<JSONObject> eVisaConfigList = this.taskClient.queryBusinessTableEVisaConfig(task.getParallelProcessInstanceId(), task.getUserId(), "false");
         if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
             //没有电签配置,默认当前任务为不签字审批,返回成功
@@ -341,7 +414,7 @@ public class EVisaServiceImpl implements EVisaService {
             //没有签章,不执行电签
             RedisTemplate.delete("sign-" + task.getFormDataId());
             return NOT_PFX_OR_FILE;
-        }
+        }*/
 
         //上锁
         //if (DistributedRedisLock.acquire(task.getUserId().toString(), batch)) {
@@ -355,42 +428,51 @@ public class EVisaServiceImpl implements EVisaService {
                     //TODO ============== 试验相关的关联文件不电签 liuYC 2023-03-17 ==============
                     continue;
                 }
-
+                String pdfUrl = file.getFileUrl();
+                List<String> eVisaConfigList = PDFUtils.getPdfSignIds(pdfUrl);
+                if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
+                    //没有电签配置,默认当前任务为不签字审批,返回成功
+                    RedisTemplate.delete("sign-" + task.getFormDataId());
+                    return SUCCESS + "@@@@" + taskFile.getApprovalFileList().get(0).getFileUrl();
+                }
+                String contractId = this.taskClient.queryTaskContractId(task.getParallelProcessInstanceId());
+                String ids = String.join(",", eVisaConfigList);
+                String sqlinfo = " SELECT a.id,a.pyzbx ,a.pyzby,(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=" + contractId + " and user_id=" + task.getUserId() + " and c.is_deleted=0 )";
+                List<Map<String, Object>> maps = jdbcTemplate.queryForList(sqlinfo);
+                System.out.println("个人-user-id"+task.getUserId()+"--SQL="+sqlinfo);
+                if (maps == null || maps.size() <= 0) {
+                    //没有签章,不执行电签
+                    RedisTemplate.delete("sign-" + task.getFormDataId());
+                    return NOT_PFX_OR_FILE;
+                }
                 //准备签章策略
                 List<SealStrategyVO> sealStrategyVOS = new ArrayList<>();
-                for (JSONObject eVisaConfig : eVisaConfigList) {
+                for (Map<String, Object> eVisaConfig : maps) {
                     //设置签章策略
                     SealStrategyVO vo = new SealStrategyVO();
                     vo.setSealCode(EVisaConstant.SIGN_SEAL_CODE + task.getUserId());
                     vo.setSealPassword(task.getUserId().toString().substring(0, EVisaConstant.USER_ID_SUB));
                     vo.setSealPerson(task.getNickName());
                     //设置签字文件
-                    vo.setImageUrl(userPfxList.get(0).getSignatureFileUrl());
+                    vo.setImageUrl(eVisaConfig.get("signature_file_url") + "");
                     vo.setSealType("3");
-
-                    vo.setKeyword(eVisaConfig.getString("KEY"));
-                    vo.setOffSetX(eVisaConfig.getString("X"));
-                    vo.setOffSetY(eVisaConfig.getString("Y"));
+                    vo.setKeyword(eVisaConfig.get("id") + "");
+                    vo.setOffSetX(eVisaConfig.get("pyzbx") + "");
+                    vo.setOffSetY(eVisaConfig.get("pyzby") + "");
                     sealStrategyVOS.add(vo);
                 }
                 SealPdfVO pdfVO = new SealPdfVO();
                 pdfVO.setStrategyVoList(sealStrategyVOS);
 
                 //获取字节
-                byte[] fileByte = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(file.getFileUrl()));
+                byte[] fileByte = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(pdfUrl));
                 //执行电签
                 Object[] result = this.signPdfByAXQZ(pdfVO, fileByte);
                 if (result != null) {
                     if (result[0] != null) {
-
-                        //MultipartFile newFiles = new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "text/plain", IOUtils.toByteArray(new ByteArrayInputStream((byte[]) result[0])));
-
-                        byte[] byteArray = IOUtils.toByteArray(new ByteArrayInputStream((byte[]) result[0]));
-                        String dataUrl = "/www/wwwroot/Users/hongchuangyanfa/Desktop/pdf/" + SnowFlakeUtil.getId() + ".pdf";
-                        File file1 = new File(dataUrl);
-                        FileUtil.copy(byteArray, file1);
+                        MultipartFile newFiles = new MockMultipartFile("file", SnowFlakeUtil.getId() + ".pdf", "text/plain", IOUtils.toByteArray(new ByteArrayInputStream((byte[]) result[0])));
                         //重新上传
-                        BladeFile bladeFile = this.newIOSSClient.uploadFile(SnowFlakeUtil.getId() + ".pdf", dataUrl);
+                        BladeFile bladeFile = this.newIOSSClient.uploadFileByInputStream(newFiles);
                         if (bladeFile != null) {
                             resultMessage = SUCCESS + "@@@@" + bladeFile.getLink();
                         } else {
@@ -762,15 +844,12 @@ public class EVisaServiceImpl implements EVisaService {
                     //对图片进行扣白底
                     imageData = ImageUtil.transferAlpha(imageData);
 
-                    //设置大小(首先排查档案水印章,因为水印章要保持原样)
-                    if (!vo.getImageUrl().equals("https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20230911/5b42583d931664b785ebf481c37d17bc.png")) {
-                        if (vo.isCompanySeal()) {
-                            //合同章
-                            imageData = ImageUtil.resizeImage(imageData, 540, 540);
-                        } else {
-                            //非合同章
-                            imageData = ImageUtil.resizeImage(imageData, 480, 132);
-                        }
+                    //设置大小
+                    if (vo.isCompanySeal()) {
+                        imageData = ImageUtil.resizeImage(imageData, 540, 540);
+                    } else {
+                        imageData = ImageUtil.resizeImage(imageData, 480, 132);
+//                        imageData = ImageUtil.resizeImage(imageData,540,540);
                     }
 
                     //图片dpi设置
@@ -795,7 +874,7 @@ public class EVisaServiceImpl implements EVisaService {
                     sealStrategy.setOffsetX(vo.getOffSetX());
                     sealStrategy.setOffsetY(vo.getOffSetY());
                 } else if (vo.getSealType().equals("2")) {
-                    //设置PDF坐标原点,签章图片定位点默认为PDF左下角,签章图片定位为左下角
+                    //设置PDF坐标原点,签章图片定位点   默认为PDF左下角,签章图片定位为左下角
                     if (StringUtils.isNotEmpty(vo.getIsCenterCoordinate())) {
                         sealStrategy.setIsCenterCoordinate(vo.getIsCenterCoordinate());
                     }

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

@@ -0,0 +1,117 @@
+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.springblade.common.utils.CommonUtil;
+import org.springblade.core.tool.utils.Func;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class PDFUtils {
+/*
+    public static List<String> getPdfSignIds(String pdfUrl) {
+        PdfDocument pdf = new PdfDocument();
+        List<String> eVisaConfigList = new ArrayList<>();
+
+        try {
+            InputStream ossInputStream = CommonUtil.getOSSInputStream(pdfUrl);
+            //加载PDF文档
+            pdf.loadFromStream(ossInputStream);
+            //创建PdfTableExtractor类的对象
+            PdfTableExtractor extractor = new PdfTableExtractor(pdf);
+            for (int page = 0; page < pdf.getPages().getCount(); page++) {
+                //提取页面中的表格存入PdfTable[]数组
+                PdfTable[] tableLists = extractor.extractTable(page);
+                if (tableLists != null && tableLists.length > 0) {
+                    //遍历表格
+                    for (PdfTable table : tableLists) {
+                        int row = table.getRowCount();//获取表格行
+                        int column = table.getColumnCount();//获取表格列
+                        for (int i = 0; i < row; i++) {
+                            for (int j = 0; j < column; j++) {
+                                //获取表格中的文本内容
+                                String text = table.getText(i, j);
+                                System.out.println(text);
+                                String textVal[] = text.split(" ");
+                                for (String textStr : textVal) {
+                                    if (textStr.length() >= 15 && Func.isNumeric(textStr)) {
+                                        eVisaConfigList.add(textStr);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            ossInputStream.close();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        return eVisaConfigList;
+    }
+*/
+
+
+    public static List<String> getPdfSignIds(String pdfUrl) {
+        PdfDocument pdf = new PdfDocument();
+        List<String> eVisaConfigList = new ArrayList<>();
+        try {
+            InputStream ossInputStream = CommonUtil.getOSSInputStream(pdfUrl);
+            //加载PDF文档
+            pdf.loadFromStream(ossInputStream);
+
+            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.length() >= 15 && Func.isNumeric(textStr)) {
+                        System.out.println(textStr);
+                        eVisaConfigList.add(textStr);
+                    }
+                }
+            }
+            ossInputStream.close();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return eVisaConfigList;
+    }
+
+    public static void main123(String[] args) {
+        String pdfUrl= "https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20230913/0193a0611867a1828164bb0abc65584c.pdf";
+        List<String> eVisaConfigList = new ArrayList<>();
+        try {
+            PdfDocument pdf = new PdfDocument();
+            InputStream ossInputStream = CommonUtil.getOSSInputStream(pdfUrl);
+            //加载PDF文档
+            pdf.loadFromStream(ossInputStream);
+
+            for(int i= 0;i<pdf.getPages().getCount();i++){
+                PdfPageBase page = pdf.getPages().get(i);
+               // System.out.println( page.extractText(true));
+                String text= page.extractText(false);
+                PdfTextFindCollection allText = page.findAllText();
+                PdfTextFind[] finds = allText.getFinds();
+                for(int k=0;k<finds.length;k++){
+                    String textStr = finds[k].getMatchText();
+                    if (textStr.length() >= 15 && Func.isNumeric(textStr)) {
+                        System.out.println(textStr);
+                        eVisaConfigList.add(textStr);
+                    }
+                }
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+}

+ 67 - 0
blade-service/blade-land/pom.xml

@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>blade-service</artifactId>
+        <groupId>org.springblade</groupId>
+        <version>2.9.1.RELEASE</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>blade-land</artifactId>
+    <name>${project.artifactId}</name>
+    <version>${bladex.project.version}</version>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-core-boot</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-starter-swagger</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-land-api</artifactId>
+            <version>${bladex.project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-starter-oss</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-resource-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itextpdf</artifactId>
+            <version>5.5.13</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itextpdf</artifactId>
+            <version>5.5.13</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-system-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
+
+    </dependencies>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+    </properties>
+
+</project>

+ 19 - 0
blade-service/blade-land/src/main/java/org/springblade/land/LandApplication.java

@@ -0,0 +1,19 @@
+package org.springblade.land;
+
+import org.springblade.common.constant.LauncherConstant;
+import org.springblade.core.cloud.feign.EnableBladeFeign;
+import org.springblade.core.launch.BladeApplication;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cloud.client.SpringCloudApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
+
+@EnableBladeFeign
+@SpringCloudApplication
+@EnableAsync
+@EnableCaching //缓存
+public class LandApplication {
+
+    public static void main(String[] args) {
+        BladeApplication.run(LauncherConstant.APPLICATION_LAND_NAME, LandApplication.class, args);
+    }
+}

+ 75 - 0
blade-service/blade-land/src/main/java/org/springblade/land/controller/AttachmentInfoController.java

@@ -0,0 +1,75 @@
+package org.springblade.land.controller;
+
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.AllArgsConstructor;
+import lombok.SneakyThrows;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.core.boot.ctrl.BladeController;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.FileUtil;
+import org.springblade.land.entity.AttachmentInfo;
+import org.springblade.land.entity.PolicyInfo;
+import org.springblade.land.service.IAttachmentInfoService;
+import org.springblade.land.service.IPolicyInfoService;
+import org.springblade.resource.feign.IOSSClient;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.Valid;
+
+/**
+ * @author yangyj
+ * @Date 2023/2/17 10:40
+ * @description TODO
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/attachmentInfo")
+@Api(value = "政策法规-附件", tags = "政策法规-附件")
+public class AttachmentInfoController extends BladeController {
+
+
+    private final IAttachmentInfoService attachmentInfoService;
+    /**
+     * 上传文件
+     *
+     * @param file 文件
+     * @return ObjectStat
+     */
+    @SneakyThrows
+    @PostMapping("/add-file")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "附件上传", notes = "附件上传")
+    @ApiImplicitParams(value = {
+            @ApiImplicitParam(name = "file", value = "文件", required = true),
+            @ApiImplicitParam(name = "projectId", value = "projectId", required = true)
+    })
+    public R<AttachmentInfo> addFile(@RequestParam("file") MultipartFile file, Long projectId) {
+       return attachmentInfoService.addFile(file,projectId);
+
+    }
+
+    /**
+     * 删除文件
+     */
+    @GetMapping("delete")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "删除文件", notes = "传入文件id")
+    @ApiImplicitParams(value = {
+            @ApiImplicitParam(name = "id", value = "文件id", required = true)
+    })
+    public R delete(Long id){
+        attachmentInfoService.delete(id);
+        return R.success("删除成功");
+    }
+
+
+
+
+}

+ 92 - 0
blade-service/blade-land/src/main/java/org/springblade/land/controller/PolicyInfoController.java

@@ -0,0 +1,92 @@
+package org.springblade.land.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.swagger.annotations.*;
+import lombok.AllArgsConstructor;
+import org.springblade.core.boot.ctrl.BladeController;
+
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.land.dto.PolicyInfoDTO;
+import org.springblade.land.dto.PolicyInfoSearchDTO;
+import org.springblade.land.entity.PolicyInfo;
+import org.springblade.land.service.IPolicyInfoService;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.io.FileNotFoundException;
+import java.util.List;
+
+/**
+ * @author yangyj
+ * @Date 2023/2/17 10:40
+ * @description TODO
+ */
+@RestController
+@AllArgsConstructor
+@RequestMapping("/policyInfo")
+@Api(value = "政策法规-双方协议", tags = "政策法规-双方协议")
+public class PolicyInfoController extends BladeController {
+
+    private final IPolicyInfoService policyInfoService;
+
+    /**
+     * 新增或修改
+     */
+    @PostMapping("/addOrUpdate")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "新增或修改", notes = "传入对象")
+    public R add(@Valid @RequestBody PolicyInfoDTO dto) throws FileNotFoundException {
+        policyInfoService.add(dto);
+        return R.success("操作成功");
+    }
+
+    /**
+     * 分页
+     */
+    @GetMapping("page")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "分页", notes = "传入搜索值")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "projectId", value = "项目id", required = true),
+            @ApiImplicitParam(name = "type", value = "1政策法规2双方协议", required = true),
+            @ApiImplicitParam(name = "current", value = "当前页", required = true),
+            @ApiImplicitParam(name = "size", value = "每页的数量", required = true),
+            @ApiImplicitParam(name = "name", value = "名称", required = false),
+            @ApiImplicitParam(name = "areaId", value = "区域id", required = false),
+            @ApiImplicitParam(name = "startDate", value = "开始时间", required = false),
+            @ApiImplicitParam(name = "endDate", value = "结束时间", required = false)
+    })
+    public R<IPage<PolicyInfo>> page(Query query, PolicyInfoSearchDTO dto){
+        IPage<PolicyInfo> iPage = policyInfoService.page(query, dto);
+        return R.data(iPage);
+    }
+
+    /**
+     * 查询
+     */
+    @GetMapping("detail")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "查询", notes = "传入单个id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", required = true)
+    })
+    public R<PolicyInfoDTO> detail(Long id){
+        return R.data(policyInfoService.detail(id));
+    }
+
+
+    /**
+     * 批量删除
+     */
+    @PostMapping("/remove")
+    @ApiOperationSupport(order = 4)
+    @ApiOperation(value = "批量逻辑删除", notes = "传入ids")
+    public R remove(@ApiParam(value = "主键集合", required = true) @RequestBody List<Long> ids) {
+        policyInfoService.remove(ids);
+        return R.success("删除成功");
+    }
+
+}

+ 40 - 0
blade-service/blade-land/src/main/java/org/springblade/land/mapper/AttachmentInfoMapper.java

@@ -0,0 +1,40 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.land.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.springblade.land.entity.AttachmentInfo;
+import org.springblade.land.entity.PolicyInfo;
+
+import java.util.List;
+
+
+/**
+ *  Mapper 接口
+ *
+ * @author BladeX
+ * @since 2023-02-17
+ */
+public interface AttachmentInfoMapper extends BaseMapper<AttachmentInfo> {
+
+    void deleteByMasterId(@Param("masterId") Long masterId);
+
+    void deleteByMasterIds(@Param("masterIds") List<Long> masterIds);
+
+    void delete(@Param("id") Long id);
+}

+ 21 - 0
blade-service/blade-land/src/main/java/org/springblade/land/mapper/AttachmentInfoMapper.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.land.mapper.AttachmentInfoMapper">
+
+
+    <delete id="deleteByMasterId">
+        delete from l_attachment_info
+        where master_id = #{masterId}
+    </delete>
+    <delete id="deleteByMasterIds">
+        delete from l_attachment_info
+        where master_id in
+        <foreach collection="masterIds" item="masterId" open="(" separator="," close=")">
+            #{masterId}
+        </foreach>
+    </delete>
+    <delete id="delete">
+        delete from l_attachment_info
+        where id = #{id}
+    </delete>
+</mapper>

+ 35 - 0
blade-service/blade-land/src/main/java/org/springblade/land/mapper/PolicyInfoMapper.java

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

+ 19 - 0
blade-service/blade-land/src/main/java/org/springblade/land/mapper/PolicyInfoMapper.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.land.mapper.PolicyInfoMapper">
+
+
+    <select id="page" resultType="org.springblade.land.entity.PolicyInfo">
+        select * from l_policy_info
+        where is_deleted = 0
+        <if test="dto.areaId != null and dto.areaId != ''">
+            and area_id = #{dto.areaId}
+        </if>
+        <if test="dto.name != null and dto.name != ''">
+            and name like concat('%',#{dto.name},'%')
+        </if>
+        <if test="dto.startDate != null and dto.startDate != '' and dto.endDate != null and dto.endDate != '' ">
+            and upload_date between #{dto.startDate} and #{dto.endDate}
+        </if>
+    </select>
+</mapper>

+ 44 - 0
blade-service/blade-land/src/main/java/org/springblade/land/service/IAttachmentInfoService.java

@@ -0,0 +1,44 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.land.service;
+
+
+import org.springblade.core.mp.base.BaseService;
+import org.springblade.core.tool.api.R;
+import org.springblade.land.entity.AttachmentInfo;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+
+public interface IAttachmentInfoService extends BaseService<AttachmentInfo> {
+
+    //新增附件
+    R<AttachmentInfo> addFile(MultipartFile file, Long projectId);
+
+    //根据主件id查询所有附件
+    List<AttachmentInfo> getAllFile(Long masterId);
+
+    //根据主件id删除附件
+    void deleteByMasterId(Long id);
+
+    //根据主件id批量删除附件
+    void deleteByMasterIds(List<Long> ids);
+
+    //根据附件id删除附件
+    void delete(Long id);
+}

+ 49 - 0
blade-service/blade-land/src/main/java/org/springblade/land/service/IPolicyInfoService.java

@@ -0,0 +1,49 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.land.service;
+
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springblade.core.mp.base.BaseService;
+import org.springblade.core.mp.support.Query;
+import org.springblade.land.dto.PolicyInfoDTO;
+import org.springblade.land.dto.PolicyInfoSearchDTO;
+import org.springblade.land.entity.PolicyInfo;
+
+import java.io.FileNotFoundException;
+import java.util.List;
+
+
+/**
+ *  服务类
+ *
+ * @author BladeX
+ * @since 2023-02-17
+ */
+public interface IPolicyInfoService extends BaseService<PolicyInfo> {
+
+    //新增或修改
+    void add(PolicyInfoDTO dto) throws FileNotFoundException;
+
+    //分页查询
+    IPage<PolicyInfo> page(Query page, PolicyInfoSearchDTO dto);
+
+    //批量删除
+    void remove(List<Long> ids);
+
+    PolicyInfoDTO detail(Long id);
+}

+ 98 - 0
blade-service/blade-land/src/main/java/org/springblade/land/service/impl/AttachmentInfoServiceImpl.java

@@ -0,0 +1,98 @@
+package org.springblade.land.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import lombok.AllArgsConstructor;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.FileUtil;
+import org.springblade.land.entity.AttachmentInfo;
+import org.springblade.land.entity.PolicyInfo;
+import org.springblade.land.mapper.AttachmentInfoMapper;
+import org.springblade.land.mapper.PolicyInfoMapper;
+import org.springblade.land.service.IAttachmentInfoService;
+import org.springblade.land.service.IPolicyInfoService;
+import org.springblade.resource.feign.CommonFileClient;
+import org.springblade.resource.feign.IOSSClient;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springblade.resource.vo.NewBladeFile;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+@Service
+@AllArgsConstructor
+public class AttachmentInfoServiceImpl extends BaseServiceImpl<AttachmentInfoMapper, AttachmentInfo> implements IAttachmentInfoService {
+
+    //上传文件
+    private final IOSSClient iossClient;
+
+
+    // pdf转换
+    private final CommonFileClient commonFileClient;
+
+    @Override
+    public R<AttachmentInfo> addFile(MultipartFile file, Long projectId) {
+        if (file.getSize() > 52428800L){
+            throw new ServiceException("上传失败,文件大小超过50MB");
+        }
+        String fileExtension = FileUtil.getFileExtension(file.getOriginalFilename()).toLowerCase();
+        if (fileExtension.contains("doc") || fileExtension.contains("pdf")) {
+            R<BladeFile> bladeFile = iossClient.addFileInfo(file);
+            BladeFile bladeFile1 = bladeFile.getData();
+            AttachmentInfo info = new AttachmentInfo();
+            info.setId(SnowFlakeUtil.getId());
+            info.setName(file.getOriginalFilename());
+            info.setDomainUrl(bladeFile1.getLink());
+            info.setMasterId(-1L);
+            info.setProjectId(projectId);
+            if (fileExtension.contains("doc")){
+                NewBladeFile newBladeFile = this.commonFileClient.wordToPdf(file);
+                info.setDomainPdfUrl(newBladeFile.getPdfUrl());
+            }else {
+                info.setDomainPdfUrl(bladeFile1.getLink());
+            }
+            this.save(info);
+            return R.data(info);
+        }else {
+            throw new ServiceException("上传失败,只能上传doc或pdf文件");
+        }
+    }
+
+    /**
+     * 根据主件id获取所有附件
+     * @param masterId
+     * @return
+     */
+    @Override
+    public List<AttachmentInfo> getAllFile(Long masterId) {
+        return this.list(new LambdaQueryWrapper<AttachmentInfo>().eq(AttachmentInfo::getMasterId,masterId));
+    }
+
+    /**
+     * 根据主件删除附件
+     * @param masterId
+     */
+    @Override
+    public void deleteByMasterId(Long masterId) {
+        baseMapper.deleteByMasterId(masterId);
+    }
+
+    /**
+     * 根据主件删除附件
+     * @param masterIds
+     */
+    @Override
+    public void deleteByMasterIds(List<Long> masterIds) {
+        baseMapper.deleteByMasterIds(masterIds);
+    }
+
+    @Override
+    public void delete(Long id) {
+        baseMapper.delete(id);
+    }
+}

+ 134 - 0
blade-service/blade-land/src/main/java/org/springblade/land/service/impl/PolicyInfoServiceImpl.java

@@ -0,0 +1,134 @@
+package org.springblade.land.service.impl;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.AllArgsConstructor;
+import net.bytebuddy.asm.Advice;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.log.exception.ServiceException;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.mp.support.Query;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.ResourceUtil;
+import org.springblade.land.dto.PolicyInfoDTO;
+import org.springblade.land.dto.PolicyInfoSearchDTO;
+import org.springblade.land.entity.AttachmentInfo;
+import org.springblade.land.entity.PolicyInfo;
+import org.springblade.land.mapper.PolicyInfoMapper;
+import org.springblade.land.service.IAttachmentInfoService;
+import org.springblade.land.service.IPolicyInfoService;
+import org.springblade.land.utils.FileUtils;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+@AllArgsConstructor
+public class PolicyInfoServiceImpl extends BaseServiceImpl<PolicyInfoMapper, PolicyInfo> implements IPolicyInfoService {
+
+    private final IAttachmentInfoService attachmentInfoService;
+
+    private final NewIOSSClient newIOSSClient;
+
+    /**
+     * 新增法律法规
+     * @param dto
+     */
+    @Override
+    @Transactional
+    public void add(PolicyInfoDTO dto) throws FileNotFoundException {
+        String file_path = FileUtils.getSysLocalFileUrl();
+        PolicyInfo policyInfo = new PolicyInfo();
+        BeanUtils.copyProperties(dto,policyInfo);
+        Boolean isExist = true;
+        if (policyInfo.getId() == null){
+            isExist = false;
+            policyInfo.setId(SnowFlakeUtil.getId());
+            policyInfo.setUploadDate(LocalDate.now());
+            //删除之前的附件
+            attachmentInfoService.deleteByMasterId(-1L);
+        }else {
+            //删除之前的附件
+            attachmentInfoService.deleteByMasterId(policyInfo.getId());
+        }
+        List<AttachmentInfo> list = dto.getList();
+        if (list == null || list.size() == 0){
+            throw new ServiceException("请上传附件");
+        }
+        List<String> data = new ArrayList<>();
+        for (AttachmentInfo info : list) {
+            info.setMasterId(policyInfo.getId());
+            data.add(info.getDomainPdfUrl());
+        }
+        if (data.size() < 1){
+            throw new ServiceException("附件信息错误");
+        }
+        String listPdf = file_path + "/pdf/" + policyInfo.getId() + ".pdf";
+        File pdf2 = ResourceUtil.getFile(listPdf);
+        if (pdf2.exists()) {
+            pdf2.delete();
+        }
+        //pdf合并
+        FileUtils.mergePdfPublicMethods(data, listPdf);
+        BladeFile bladeFile = this.newIOSSClient.uploadFile( policyInfo.getId() + ".pdf", listPdf);
+        policyInfo.setPdfUrl(bladeFile.getLink());
+        if (isExist){
+            this.updateById(policyInfo);
+        }else {
+            this.save(policyInfo);
+        }
+        //修改附件的主件id
+        attachmentInfoService.saveBatch(list);
+    }
+
+    /**
+     * 分页查询
+     * @param page
+     * @param dto
+     * @return
+     */
+    @Override
+    public IPage<PolicyInfo> page(Query page, PolicyInfoSearchDTO dto) {
+        IPage<PolicyInfo> iPage = new Page<>(page.getCurrent(),page.getSize());
+        return baseMapper.page(iPage,dto);
+    }
+
+    /**
+     * 批量删除
+     * @param ids
+     */
+    @Override
+    public void remove(List<Long> ids) {
+        //删除附件
+        attachmentInfoService.deleteByMasterIds(ids);
+        //删除主件
+        baseMapper.deleteBatchIds(ids);
+    }
+
+    /**
+     * 根据id查询
+     * @param id
+     * @return
+     */
+    @Override
+    public PolicyInfoDTO detail(Long id) {
+        PolicyInfoDTO dto = new PolicyInfoDTO();
+        PolicyInfo info = this.getById(id);
+        BeanUtils.copyProperties(info,dto);
+        List<AttachmentInfo> list = attachmentInfoService.getAllFile(id);
+        dto.setList(list);
+        return dto;
+    }
+
+}

+ 74 - 0
blade-service/blade-land/src/main/java/org/springblade/land/utils/FileUtils.java

@@ -0,0 +1,74 @@
+package org.springblade.land.utils;
+
+
+import com.itextpdf.text.Document;
+import com.itextpdf.text.pdf.PdfCopy;
+import com.itextpdf.text.pdf.PdfReader;
+import lombok.extern.slf4j.Slf4j;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SystemUtils;
+import org.springblade.system.cache.ParamCache;
+
+import java.io.FileOutputStream;
+import java.util.List;
+
+@Slf4j
+public class FileUtils {
+
+    /**
+     * 合并方法
+     */
+    public static void mergePdfPublicMethods(List<String> urlList, String localImgUrl) {
+        PdfReader reader = null;
+
+        Document doc = new Document();
+        PdfCopy pdfCopy = null;
+        try {
+            pdfCopy = new PdfCopy(doc, new FileOutputStream(localImgUrl));
+            int pageCount;
+            doc.open();
+
+            for (String urlStr : urlList) {
+                try {
+                    //获取OSS文件输入流
+                    reader = new PdfReader(CommonUtil.getOSSInputStream(urlStr));
+
+                    pageCount = reader.getNumberOfPages();
+
+                    for (int i = 0; i < pageCount; ++i) {
+                        int is = i + 1;
+                        pdfCopy.addPage(pdfCopy.getImportedPage(reader, is));
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                } finally {
+                    if (reader != null) {
+                        reader.close();
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (pdfCopy != null) {
+                pdfCopy.flush();
+                pdfCopy.close();
+            }
+            doc.close();
+        }
+    }
+
+    public static String getSysLocalFileUrl() {
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        if (SystemUtils.isMacOs()) {
+            file_path = "/Users/hongchuangyanfa/Desktop/";
+        } else if (SystemUtils.isWindows()) {
+            file_path = "C://upload";
+        }
+        return file_path;
+    }
+
+
+}

+ 19 - 0
blade-service/blade-land/src/main/resources/application-dev.yml

@@ -0,0 +1,19 @@
+#服务器端口
+server:
+  port: 9102
+
+#数据源配置
+spring:
+  datasource:
+    url: ${blade.datasource.dev.url}
+    username: ${blade.datasource.dev.username}
+    password: ${blade.datasource.dev.password}
+
+oss:
+  enabled: true
+  name: alioss
+  tenant-mode: true
+  endpoint: https://oss-cn-chengdu.aliyuncs.com/
+  access-key: LTAI4FmSV1pWZAJ9xSvHg5rP
+  secret-key: 5D3XQj4pBe8VbOAVFNqdioJA8riH4S
+  bucket-name: bladex-test-info

+ 11 - 0
blade-service/blade-land/src/main/resources/application-prod.yml

@@ -0,0 +1,11 @@
+#服务器端口
+server:
+  port: 8102
+
+#数据源配置
+spring:
+  datasource:
+    url: ${blade.datasource.prod.url}
+    username: ${blade.datasource.prod.username}
+    password: ${blade.datasource.prod.password}
+

+ 10 - 0
blade-service/blade-land/src/main/resources/application-test.yml

@@ -0,0 +1,10 @@
+#服务器端口
+server:
+  port: 8102
+
+#数据源配置
+spring:
+  datasource:
+    url: ${blade.datasource.test.url}
+    username: ${blade.datasource.test.username}
+    password: ${blade.datasource.test.password}

+ 3 - 2
blade-service/blade-manager/src/main/java/com/mixsmart/utils/CustomFunction.java

@@ -2177,7 +2177,7 @@ public class CustomFunction {
 
     /**扩散*/
     public static List<Object> diffusion(List<Object> data) {
-        List<Object> result = new ArrayList<>();
+      /*  List<Object> result = new ArrayList<>();
         if (data != null) {
             Optional<Object> op = data.stream().filter(StringUtils::isNotEmpty).findFirst();
             if (op.isPresent()) {
@@ -2186,7 +2186,8 @@ public class CustomFunction {
                         .collect(Collectors.toList());
             }
         }
-        return result;
+        return result;*/
+        return follow(data);
     }
 
     /**元素内容永远跟随第一页*/

+ 6 - 1
blade-service/blade-manager/src/main/java/com/mixsmart/utils/FormulaUtils.java

@@ -174,7 +174,12 @@ public class FormulaUtils {
                         if(values.stream().filter(CustomFunction::containsZH).anyMatch(e->e.toString().contains("\n"))){
                             fd.getValues().get(0).setValue(values.stream().filter(Objects::nonNull).map(Object::toString).collect(Collectors.joining()));
                         }else{
-                            fd.getValues().get(0).setValue(values.stream().map(StringUtils::handleNull).collect(Collectors.joining("、")));
+                            /*日期类型的元素只获取最后一个非空*/
+                            if(StringUtils.isEquals(4,fd.getEType())){
+                                fd.getValues().get(0).setValue(values.stream().filter(StringUtils::isNotEmpty).reduce((first, second) -> second).orElse(null));
+                            }else{
+                                fd.getValues().get(0).setValue(values.stream().map(StringUtils::handleNull).collect(Collectors.joining("、")));
+                            }
                         }
                     }else{
                         // copy(fd,values);

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

@@ -36,11 +36,12 @@ public class AppVersionDetailController extends BladeController {
     @GetMapping("/getNewVersion")
     @ApiOperationSupport(order = 2)
     @ApiOperation(value = "获取最新版本", notes = "传入版本id与软件类型1安卓2IOS")
-    public R<AppVersionDetail> getNewVersion(String platform,Integer softwareType){
+    public R<AppVersionDetail> getNewVersion(String platform,Integer softwareType,Integer fileType){
         AppVersion one = versionService.getOne(new LambdaQueryWrapper<AppVersion>().eq(AppVersion::getPlatform, platform));
         return R.data(versionDetailService.getOne(new LambdaQueryWrapper<AppVersionDetail>()
                             .eq(AppVersionDetail::getVersionId,one.getId())
                             .eq(AppVersionDetail::getSoftwareType,softwareType)
+                            .eq(AppVersionDetail::getFileType,fileType)
                             .orderByDesc(AppVersionDetail::getUpdateDate)
                             .last("limit 1")));
     }

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

@@ -2163,7 +2163,7 @@ public class ExcelTabController extends BladeController {
         //保存数据到数据库
         R<Object> result = this.excelTabService.saveOrUpdateInfo(tableInfoList);
         if (!result.isSuccess()) {
-            return R.fail("以下的表在保存数据时发生了异常【" + result.getMsg() + "】");
+            return R.fail(result.getMsg());
         }
 
 

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

@@ -125,7 +125,6 @@ public class FormulaController {
                         WbsTree wbsTree = this.wbsTreeService.getById(f.getNodeId());
                         efm.setWbsId(Long.parseLong(wbsTree.getWbsId()));
                     }
-
                 }
                 this.elementFormulaMappingService.save(efm);
                 /*假如不存在projectId则认为是系统级模版公式,必须同步给所有项目TODO*/
@@ -468,7 +467,12 @@ public class FormulaController {
         result.put("serve",   System.getProperty("os.name"));
         if (Func.isNotEmpty(pkeyId)) {
             String sql="select * from m_formula_log where id=?";
-            result.put("执行情况", this.jdbcTemplate.queryForList(sql,pkeyId));
+            List<Map<String,Object>> data = this.jdbcTemplate.queryForList(sql,pkeyId);
+            if(data.size()>0){
+                Map<String,Object> map =data.get(0);
+                result.put("执行情况", JSON.parse(map.get("content").toString()));
+            }
+
         }
         return R.data(result);
     }

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

@@ -528,7 +528,7 @@ public class TextdictInfoController extends BladeController {
             throw new ServiceException("请勿重复提交,请3秒后再尝试");
         }
         JSONArray jsonArray = dataInfo.getJSONArray("dataInfo");
-        Long tableId = dataInfo.getLong("tabId");
+        Long tableId = dataInfo.getLong("tabId"); //节点pkid
 
         //当前清表信息
         WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(tableId);
@@ -547,7 +547,6 @@ public class TextdictInfoController extends BladeController {
         }
 
         // 读取html页面信息
-        // File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
 
         InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(wbsTreePrivate.getHtmlUrl());
         String htmlString = IoUtil.readToString(inputStreamByUrl);

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/ITurnPointCalculator.java

@@ -17,7 +17,7 @@ import static org.springblade.manager.formula.TurnPoint.*;
  * @author yangyj
  */
 public interface ITurnPointCalculator {
-    Long VERSION=2309081800L;
+    Long VERSION=2309121330L;
      String ZD_REG="(?i)zd\\d+";
     static List<TurnPoint> create(List<Map<String, Object>> data, LinkedHashMap<String, String> configMap,LevelInfo levelInfo) {
         /*1.验证数据的合理性,如果已经合理则不需要计算

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

@@ -117,7 +117,7 @@ public class FormulaMileage implements FormulaStrategy {
             }
 
         }
-
+        cur.setFinished(Boolean.TRUE);
     }
 
     public static final Pattern MILE_P = Pattern.compile("(?<=T\\(com.mixsmart.utils.CustomFunction\\).MILE\\()([^,]+),([^,]+)(?=,)");

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

@@ -73,6 +73,7 @@
         <result column="key" property="key"/>
         <result column="has_children" property="hasChildren"/>
         <result column="node_type" property="nodeType"/>
+        <result column="major_data_type" property="majorDataType"/>
         <result column="old_id" property="oldId"/>
         <result column="sort" property="sort"/>
     </resultMap>
@@ -463,6 +464,7 @@
         d.id AS "value",
         d.id AS "key",
         old_id,
+        major_data_type,
         sort
         FROM m_wbs_tree_contract d
         WHERE

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

@@ -615,7 +615,7 @@ public class ArchiveTreeContractSyncImpl {
             if (current == null) {
                 return null; // 如果没有找到对应的节点,则返回 null
             }
-            if (current.getNodeType().equals(nodeType)) {
+            if (current.getNodeType() <= nodeType && !current.getNodeName().contains("中间交工")) {
                 return current.getPKeyId(); // 如果找到了符合要求的节点,则返回其 pKeyId 属性值
             }
             id = current.getParentId(); // 取出当前节点的父节点 ID,准备进行下一轮循环操作

+ 61 - 6
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -1,5 +1,6 @@
 package org.springblade.manager.service.impl;
 
+import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.StopWatch;
 import cn.hutool.log.StaticLog;
 import com.alibaba.fastjson.JSON;
@@ -14,17 +15,19 @@ import com.mixsmart.utils.FormulaUtils;
 import com.mixsmart.utils.ListUtils;
 import com.mixsmart.utils.RegexUtils;
 import com.spire.xls.FileFormat;
-import com.spire.xls.Worksheet;
 import lombok.AllArgsConstructor;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang3.ObjectUtils;
+import org.apache.poi.hssf.usermodel.HSSFRichTextString;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.apache.poi.ss.usermodel.CellStyle;
 import org.apache.poi.ss.usermodel.Font;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.util.IOUtils;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
@@ -426,9 +429,9 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             };
             this.jdbcTemplate.batchUpdate(sql);*/
             String deleteSql = "DELETE FROM m_formula_log WHERE id = ?";
-            String insertSql = "INSERT INTO m_formula_log (id, content) VALUES (?, ?)";
+            String insertSql = "INSERT INTO m_formula_log (id, content,update_time) VALUES (?, ?,?)";
             jdbcTemplate.update(deleteSql, pKeyId);
-            jdbcTemplate.update(insertSql, pKeyId, log);
+            jdbcTemplate.update(insertSql, pKeyId, log, DateTime.now());
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -1402,7 +1405,16 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
         //获取excel流 和 html流
         InputStream exceInp = CommonUtil.getOSSInputStream(excelTab.getFileUrl());
-        Workbook workbook = WorkbookFactory.create(exceInp);
+
+        Workbook workbook=null;
+        int index = excelTab.getFileUrl().lastIndexOf(".");
+        String suffix = excelTab.getFileUrl().substring(index);
+
+        if (".xls".equals(suffix)) {
+            workbook = new HSSFWorkbook(exceInp);
+        } else if (".xlsx".equals(suffix)) {
+            workbook = new XSSFWorkbook(exceInp);
+        }
 
         //获取工作表
         Sheet sheet = workbook.getSheetAt(0);
@@ -1610,7 +1622,50 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             }
 
             // 组装电签设置
-            QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
+
+            Elements dqids = table.getElementsByAttribute("dqid");
+
+            for (Element element : dqids){
+                String dqid = element.attr("dqid");
+               // if(element.hasAttr("x1") && element.hasAttr("y1")){
+                    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"));
+
+                        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();
+
+                                if(CellValue!=null && StringUtils.isNotEmpty(CellValue)){
+                                    RichTextString ts= new HSSFRichTextString(CellValue + "--"+dqid);
+                                   // ts.applyFont(0,CellValue.length(),oldfontAt);
+                                 //   ts.applyFont(10,ts.length(),redFont);
+                                    cell.setCellValue(ts);
+                                }else{
+                                    CellStyle newStyle = workbook.createCellStyle(); //创建单元格样式
+                                    newStyle.cloneStyleFrom(cell.getCellStyle());
+                                    newStyle.setFont(redFont);
+                                    newStyle.setShrinkToFit(true);
+                                    cell.setCellStyle(newStyle);
+                                    cell.setCellValue(dqid);
+                                }
+                            }
+                        }
+                    }
+               // }
+            }
+
+          /*  QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
             queryWrapper.in("type", 2, 6);
             queryWrapper.eq("tab_id", wbsTreeContract.getIsTypePrivatePid());
             List<TextdictInfo> textdictInfos = textdictInfoService.getBaseMapper().selectList(queryWrapper);
@@ -1663,7 +1718,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         }
                     }
                 }
-            }
+            }*/
         }
 
         //输出流

+ 40 - 6
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -276,8 +276,8 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                                 if (op.isPresent()) {
                                     g = op.get();
                                 }
-                            }
-                            if (g == null) {
+                            }else{
+                                /*只有不存在配置的前提下才能尝试自动匹配*/
                                 Optional<ElementBlock> op = elementBlockList.stream().filter(w -> FormulaUtils.similarity(w.getEName(), t.getPoint()) > 0.3).max(Comparator.comparingDouble((ElementBlock b) -> FormulaUtils.similarity(b.getEName(), t.getPoint())));
                                 /*相似匹配*/
                                 if (op.isPresent()) {
@@ -287,7 +287,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             if (g != null) {
                                 List<ItemBlock> itemBlockList = g.getList();
                                 int originSize = itemBlockList.size();
-                                List<Long> ids =getNodeType46().stream().map(CurrentNode::getId).collect(Collectors.toList());
+                                List<Long> ids =getNodeType46().stream().map(CurrentNode::getPkId).collect(Collectors.toList());
                                 /*清除那些已经不存在的工序*/
                                 itemBlockList.removeIf(ik -> !ids.contains(ik.getPkeyId()));
                                 if (itemBlockList.size() > 0) {
@@ -338,9 +338,25 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
     }
 
 
+    public void  descendantType46(Object id, List<Map<String,Object>> listMaps){
+        String sql="select p_Key_id pkId,id,node_type nodeType,table_type tableType  from m_wbs_tree_contract where parent_id =? and is_deleted=0";
+        List<Map<String,Object>> tmp=this.jdbcTemplate.queryForList(sql,id);
+        if(tmp.size()>0){
+            for(Map<String,Object>map:tmp){
+                if(StringUtils.isEquals(map.get("nodeType"),6)){
+                    listMaps.add(map);
+                }else{
+                    descendantType46(map.get("id"),listMaps);
+                }
+            }
+        }
+    }
+
    public List<CurrentNode> getNodeType46(){
         if(tec.getCurrentNode().getDivisional().size()==0){
-            List<Map<String,Object>> listMaps=this.jdbcTemplate.queryForList("select b.p_Key_id pkId,b.id from m_wbs_tree_contract a join m_wbs_tree_contract b on (a.contract_id=b.contract_id and b.ancestors like CONCAT(a.ancestors,'%')) where a.p_key_id="+tec.getCurrentNode().getPkId()+" and b.is_deleted=0 and b.node_type=6 ORDER BY b.sort");
+           // List<Map<String,Object>> listMaps=this.jdbcTemplate.queryForList("select b.p_Key_id pkId,b.id from m_wbs_tree_contract a join m_wbs_tree_contract b on (a.contract_id=b.contract_id and b.ancestors like CONCAT(a.ancestors,'%')) where a.p_key_id="+tec.getCurrentNode().getPkId()+" and b.is_deleted=0 and b.node_type=6 ORDER BY b.sort");
+            List<Map<String,Object>> listMaps =new ArrayList<>();
+            descendantType46(tec.getCurrentNode().getParentId(),listMaps);
             if(listMaps.size()>0){
                 tec.getCurrentNode().getDivisional().addAll(listMaps.stream().map(m->BeanUtil.toBean(m,CurrentNode.class)).collect(Collectors.toList()));
             }
@@ -1043,7 +1059,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     });
                 }
                 List<ElementBlock> finalElementBlockList = elementBlockList;
-                tec.checkItems.stream().filter(e -> !e.empty()).forEach(c -> {
+                tec.checkItems.forEach(c -> {
                     ElementBlock eb = elementBlockMap.get(c.getCode());
                     ItemBlock targetItem = itemBlockMap.get(c.getCode() + ":" + tec.getCurrentNode().getPkId());
                     List<Object> list = c.getValues().stream().map(ElementData::getValue).filter(StringUtils::isNotEmpty).collect(Collectors.toList());
@@ -1601,7 +1617,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                          /*表名+合同段+父节点*/
                          String findStr="OP['"+fd.getTableName()+"']['"+fd.getKey()+"']['RG']";
                           String rangeStr=StringUtils.handleNull(Expression.parse(findStr).calculate(tec.constantMap));
-                         System.out.println("随机值参数:"+rangeStr);
+                         //System.out.println("随机值参数:"+rangeStr);
                          if(false){
                           /*   Optional<RangeInfo> op=tableColKeyVal.stream().map(map-> BeanUtil.toBean(JSON.parseObject(map.get("val").toString()),RangeInfo.class)).findFirst();
                              if(op.isPresent()){
@@ -1665,6 +1681,24 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                              if(CustomFunction.containsZH(devStr)||StringUtils.isEmpty(devStr)||StringUtils.handleNull(devStr).contains("/")){
                                  devStr="±100000";
                              }
+                             if(devStr.contains("E[")){
+                                List<String> codes= getCodeByEl(devStr);
+                                Map<String,Object> map = new HashMap<>();
+                                boolean isNull=false;
+                                for (String c:codes){
+                                    FormData ffd= tec.getFormDataMap().get(c);
+                                    if(ffd.empty()){
+                                        isNull=true;
+                                        break;
+                                    } else{
+                                        map.put("E["+c+"]",ffd.getRawValue().stream().filter(StringUtils::isNotEmpty).findFirst().orElse(null)) ;
+                                    }
+                                }
+                               if(isNull){
+                                   devStr="±100000";
+                               }
+                               devStr= Arrays.stream(devStr.replaceAll("^\\[|\\]$","").split(",")).map(s->map.getOrDefault(s,s)).map(StringUtils::handleNull).collect(Collectors.joining(","));
+                             }
                              /*设计值可以是数值类型,或空(等效0)*/
                              if(dataFd!=null){
                                     List<Object> values= dataFd.getRawValue();

+ 0 - 71
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/ExcelInfoUtils.java

@@ -9,13 +9,11 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.usermodel.WorkbookFactory;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
 
-import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.tool.utils.FileUtil;
 import org.springblade.core.tool.utils.Func;
@@ -33,75 +31,6 @@ import java.util.Map;
 
 public class ExcelInfoUtils {
 
-    public static void main1234(String[] args) throws Exception {
-        String fileUrl = "/Users/hongchuangyanfa/Downloads/29ed5438d62d301bf290b908acf3bdbb.xlsx";
-        InputStream exceInp = new FileInputStream(new File(fileUrl));
-
-        org.apache.poi.ss.usermodel.Workbook workbook = WorkbookFactory.create(exceInp);
-
-        //获取工作表
-        Sheet sheet = workbook.getSheetAt(0);
-        sheet.setForceFormulaRecalculation(true);
-
-        Row row = sheet.getRow(34);
-
-        Cell cell = sheet.getRow(34).getCell(1);
-
-        System.out.println(cell.getStringCellValue());
-        // 解析原始excel
-        Workbook wb = new Workbook();
-        wb.loadFromMHtml(fileUrl);
-        Worksheet sheet2 = wb.getWorksheets().get(0);
-
-        CellRange cellRange = sheet2.getCellRange(35, 2);
-        System.out.println(cellRange.getText());
-
-        //sheet.saveToHtml("/Users/hongchuangyanfa/Desktop/pdf/test.html");
-    }
-
-    public static void main123(String[] args) throws FileNotFoundException {
-        String excelUrl = "/Users/hongchuangyanfa/Downloads/C10.28隧道注浆施工记录表(1).xlsx";
-        String old_html = "/Users/hongchuangyanfa/Desktop/pdf/old_html.html";
-        String old_xlsx = "/Users/hongchuangyanfa/Desktop/pdf/old_html.xlsx";
-        File file = new File(excelUrl);
-        InputStream fileInputStream = new FileInputStream(file);
-      //  excelInfo(fileInputStream,old_xlsx,old_html,"1");
-
-
-        // 解析原始excel
-        Workbook wb = new Workbook();
-        wb.loadFromMHtml(excelUrl);
-        Worksheet sheet = wb.getWorksheets().get(0);
-
-        CellRange[] mergedCells = sheet.getCells();
-        for(int i=0;i<mergedCells.length;i++){
-            CellRange oldcell =mergedCells[i];
-           // sheet.get(oldcell.getRow(),oldcell.getColumn()).getDataValidation().setErrorMessage("");
-          //  sheet.get(oldcell.getRow(),oldcell.getColumn(),oldcell.getLastRow(),oldcell.getLastColumn()).getDataValidation().setErrorMessage("");
-            oldcell.getDataValidation().setErrorMessage("");
-        }
-
-
-        CellRange[] mergedCells1 = sheet.getMergedCells();
-        for(int i=0;i<mergedCells1.length;i++) {
-            CellRange oldcell = mergedCells1[i];
-            oldcell.getDataValidation().setErrorMessage(i+"");
-        }
-
-
-
-        CellRange[] cells = sheet.getCells();
-        for(int i=0;i< cells.length;i++){
-            CellRange oldcell = cells[i];
-            System.out.println(oldcell.getRow()+"---"+oldcell.getColumn()+"---="+oldcell.getText()+"---x="+oldcell.getDataValidation().getErrorMessage());
-        }
-
-
-
-        String new_html = "/Users/hongchuangyanfa/Desktop/pdf/new_html.html";
-        String new_xlsx = "/Users/hongchuangyanfa/Desktop/pdf/new_html.xlsx";
-       // excelInfo(old_xlsx,new_xlsx,new_html);
-    }
 
     public static void excelInfo(InputStream inputStream, String excelURL, String htmlUrl,String type) {
         try {

+ 271 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/ExcelInfoUtils2.java

@@ -0,0 +1,271 @@
+package org.springblade.manager.utils;
+
+import com.spire.pdf.PdfDocument;
+import com.spire.pdf.utilities.PdfTable;
+import com.spire.pdf.utilities.PdfTableExtractor;
+import com.spire.xls.CellRange;
+import com.spire.xls.FileFormat;
+import com.spire.xls.Workbook;
+import com.spire.xls.Worksheet;
+import com.spire.xls.core.spreadsheet.HTMLOptions;
+import org.apache.commons.lang.StringUtils;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.tool.utils.FileUtil;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.IoUtil;
+import org.springblade.manager.vo.DateFormat;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ExcelInfoUtils2 {
+
+
+    public static void excelInfo(InputStream inputStream, String excelURL, String htmlUrl,String type) {
+        try {
+            String file_path = "/Users/hongchuangyanfa/Desktop//pdf/";
+            String filecode = SnowFlakeUtil.getId() + "";
+            String thmlUrl2 = file_path + filecode + "123.html";
+
+            // 解析原始excel
+            Workbook wb = new Workbook();
+            wb.loadFromMHtml(inputStream);
+            Worksheet sheet = wb.getWorksheets().get(0);
+
+            HTMLOptions options = new HTMLOptions();
+            options.setImageEmbedded(true);
+
+            //复制一份
+            wb.saveToFile(excelURL,FileFormat.Version2013);
+            // 操作
+            Workbook wb2 = new Workbook();
+            wb2.loadFromMHtml(excelURL);
+            Worksheet sheet2 = wb2.getWorksheets().get(0);
+
+            // 坐标map
+            Map<String, Map<String, Integer>> xyList = new HashMap<>();
+            int j = 0;
+            int maxVal = 0;
+            if(type.equals("2")){
+                CellRange[] sheet2Cells = sheet2.getCells();
+                for (int i = 0; i < sheet2Cells.length; i++) {
+                    CellRange oldcell = sheet2Cells[i];
+                    String data = oldcell.getDataValidation().getErrorMessage();
+                    int k = 0;
+                    if(Func.isNumeric(data)){
+                        k = Func.toInt(data);
+                    }
+                    if (maxVal < k) {
+                        maxVal = k;
+                    }
+                }
+            }else if(type.equals("1")){
+                CellRange[] sheet2Cells = sheet.getCells();
+                for (int i = 0; i < sheet2Cells.length; i++) {
+                    CellRange oldcell = sheet2Cells[i];
+                    oldcell.getDataValidation().setErrorMessage("");
+                    sheet.get(oldcell.getRow(),oldcell.getColumn()).getDataValidation().setErrorMessage("");
+                }
+            }
+
+            //合并单元格操作
+            CellRange[] mergedCells = sheet.getMergedCells();
+            for (int i = 0; i < mergedCells.length; i++) {
+                Map<String, Integer> dataMap = new HashMap<>();
+                CellRange oldcell = mergedCells[i];
+                CellRange mergedCell = sheet.getCellRange(oldcell.getRow(), oldcell.getColumn());
+                if(type.equals("2")){
+                    String data = mergedCell.getDataValidation().getErrorMessage();
+                    if (StringUtils.isEmpty(data)) {
+                        if(maxVal<=0){
+                            j = j + 1;
+                        }else{
+                            maxVal = maxVal+1;
+                            j=maxVal;
+                        }
+                    } else {
+                        j = Func.toInt(data);
+                    }
+                }else{
+                    j = j + 1;
+                }
+                // 目标表添加备注信息
+                mergedCell.getDataValidation().setErrorMessage(j+"");
+                oldcell.getDataValidation().setErrorMessage(j+"");
+                sheet2.getMergedCells()[i].setText(j+"");
+                dataMap.put("y1", oldcell.getRow());
+                dataMap.put("y2", oldcell.getLastRow());
+                dataMap.put("x1", oldcell.getColumn());
+                dataMap.put("x2", oldcell.getLastColumn());
+                xyList.put(j + "", dataMap);
+            }
+
+            //变更最大值
+            if(maxVal<=0){
+                maxVal = j;
+            }
+
+            // 单个
+            CellRange[] onCell = sheet.getCells();
+            // 单个cell
+            for (int i = 0; i < onCell.length; i++) {
+                CellRange oldcell = onCell[i];
+                String data = oldcell.getDataValidation().getErrorMessage();
+                System.out.println(oldcell.getRow()+"---"+oldcell.getColumn()+"---="+oldcell.getText()+"---x="+data);
+                if (StringUtils.isEmpty(data)) {
+                    if(maxVal<=0){
+                        j = j + 1;
+                    }else{
+                        maxVal = maxVal+1;
+                        j=maxVal;
+                    }
+                } else {
+                    j = Func.toInt(data);
+                }
+
+              /*  if(StringUtils.isEmpty(data)){
+                    oldcell.getDataValidation().setErrorMessage(j+"");
+                    sheet2.getCells()[i].setText(j+"");
+                }*/
+
+                if(!xyList.containsKey(j+"")){
+                    Map<String, Integer> dataMap = new HashMap<>();
+                    dataMap.put("y1", oldcell.getRow());
+                    dataMap.put("y2", oldcell.getLastRow());
+                    dataMap.put("x1", oldcell.getColumn());
+                    dataMap.put("x2", oldcell.getLastColumn());
+                    xyList.put(j + "", dataMap);
+                }
+            }
+
+            // 保存上传的excel
+            wb.saveToFile(excelURL,FileFormat.Version2013);
+           // sheet.saveToHtml(htmlUrl, options);
+            sheet2.saveToHtml(thmlUrl2);
+
+            // html 转换值
+
+            // 组装坐标
+            File html1 = new File(htmlUrl);  // 原始html
+            File html2 = new File(thmlUrl2); // 坐标html
+            InputStream inputStream1 = new FileInputStream(html1);
+            InputStream inputStream2 = new FileInputStream(html2);
+            String htmlString1 = IoUtil.readToString(inputStream1);
+            String htmlString2 = IoUtil.readToString(inputStream2);
+
+            Document doc1 = Jsoup.parse(htmlString1);
+            Element table1 = doc1.select("table").first();
+            Elements trs1 = table1.select("tr");
+            Document doc2 = Jsoup.parse(htmlString2);
+            Element table2 = doc2.select("table").first();
+            Elements trs2 = table2.select("tr");
+
+            for (int i = 0; i < trs1.size(); i++) {
+                Elements td1 = trs1.get(i).select("td");
+                Elements td2 = trs2.get(i).select("td");
+                for (int x = 0; x < td1.size(); x++) {
+                    Element cell1 = td1.get(x);
+                    Element cell2 = td2.get(x);
+                    String html = cell2.text();
+                    Map<String, Integer> xyMap = xyList.get(html);
+                    if (xyMap != null) {
+                        // td 添加坐标
+                        cell1.attr("x1", xyMap.get("x1") + "");
+                        cell1.attr("x2", xyMap.get("x2") + "");
+                        cell1.attr("y1", xyMap.get("y1") + "");
+                        cell1.attr("y2", xyMap.get("y2") + "");
+                        cell1.attr("exceVal",html);
+
+
+                        // 为下面对象添加坐标
+                        if(cell1.children().size()>=1){
+                            Element element = cell1.children().get(0);
+                            if(element.hasAttr("x1") && element.hasAttr("y1")){
+                                element.removeAttr("x1");
+                                element.removeAttr("x2");
+                                element.removeAttr("y1");
+                                element.removeAttr("y2");
+                                element.attr("x1", xyMap.get("x1") + "");
+                                element.attr("x2", xyMap.get("x2") + "");
+                                element.attr("y1", xyMap.get("y1") + "");
+                                element.attr("y2", xyMap.get("y2") + "");
+                            }else{
+                                if(element.children().size()>=1){
+                                    Element element2 = element.children().get(0);
+                                    if(element2.hasAttr("x1") && element2.hasAttr("y1")){
+                                        element2.removeAttr("x1");
+                                        element2.removeAttr("x2");
+                                        element2.removeAttr("y1");
+                                        element2.removeAttr("y2");
+                                        element2.attr("x1", xyMap.get("x1") + "");
+                                        element2.attr("x2", xyMap.get("x2") + "");
+                                        element2.attr("y1", xyMap.get("y1") + "");
+                                        element2.attr("y2", xyMap.get("y2") + "");
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            FileUtil.writeToFile(html1, doc1.html(), Boolean.parseBoolean("UTF-8"));
+
+            if (html2.exists()) {
+                html2.delete();
+            }
+            wb2.dispose();
+            wb.dispose();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    public static void main123(String[] args) throws Exception {
+
+       /* String html="/Users/hongchuangyanfa/Desktop/privateUrl/1701131518073634816.html";
+        File html1 = new File(html);  // 原始html
+        InputStream inputStream1 = new FileInputStream(html1);
+
+        String htmlString1 = IoUtil.readToString(inputStream1);
+        Document doc1 = Jsoup.parse(htmlString1);
+        Element table1 = doc1.select("table").first();
+        Elements dqids = table1.getElementsByAttribute("dqid");
+        int x1=0;
+        int y1=0;
+        for (Element element : dqids){
+            if(element.hasAttr("x1") && element.hasAttr("y1")){
+                Elements x11 = element.getElementsByAttribute("x1");
+                Element element1 = x11.get(x11.size()-1);
+                x1 = Func.toInt(element1.attr("x1"));
+                y1 = Func.toInt(element1.attr("y1"));
+            }
+        }*/
+        String excelPath="/Users/hongchuangyanfa/Desktop/pdf/1234567.xlsx";
+        String data="https://bladex-chongqing-info.oss-cn-hangzhou.aliyuncs.com//upload/20230911/b63658909c268efeb753dcf673ce34ab.xlsx";
+        InputStream exceInp = CommonUtil.getOSSInputStream(data);
+        org.apache.poi.ss.usermodel.Workbook workbook = WorkbookFactory.create(exceInp);
+
+        //获取工作表
+        Sheet sheet = workbook.getSheetAt(0);
+        Row row = sheet.getRow(7-1);
+        Cell cell = row.getCell(5-1);
+        cell.setCellValue("123444");
+
+        FileOutputStream outputStream = new FileOutputStream(excelPath);
+        workbook.write(outputStream);
+    }
+
+}

+ 1 - 0
blade-service/pom.xml

@@ -26,6 +26,7 @@
         <module>blade-e-visa</module>
         <module>blade-archive</module>
         <module>blade-control</module>
+        <module>blade-land</module>
     </modules>
 
     <dependencies>