Ver Fonte

Merge branch 'feature-lihb-bug' of http://219.151.181.73:3000/zhuwei/bladex into dev-test-merge

# Conflicts:
#	blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
lvy há 3 semanas atrás
pai
commit
199b039fb1
22 ficheiros alterados com 524 adições e 24 exclusões
  1. 56 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreeContractOldHtml.java
  2. 6 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreeContractClient.java
  3. 25 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreeContractOldHtmlClient.java
  4. 42 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  5. 19 2
      blade-service/blade-business/src/main/java/org/springblade/business/controller/RecycleBinController.java
  6. 45 0
      blade-service/blade-business/src/main/java/org/springblade/business/utils/FileUtils.java
  7. 11 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  8. 8 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java
  9. 33 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractOldHtmlClientImpl.java
  10. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.java
  11. 9 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.xml
  12. 18 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractOldHtmlMapper.java
  13. 22 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractOldHtmlMapper.xml
  14. 4 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreeContractService.java
  15. 13 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/WbsTreeContractOldHtmlService.java
  16. 57 7
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  17. 10 8
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  18. 51 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsSynchronousEViSaServiceImpl.java
  19. 17 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsSynchronousServiceImpl.java
  20. 22 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractOldHtmlServiceImpl.java
  21. 13 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java
  22. 41 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/FileUtils.java

+ 56 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/WbsTreeContractOldHtml.java

@@ -0,0 +1,56 @@
+package org.springblade.manager.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * 合同段表单上报之前的html记录
+ * @author LHB
+ * @TableName m_wbs_tree_contract_old_html
+ */
+@TableName(value ="m_wbs_tree_contract_old_html")
+@Data
+public class WbsTreeContractOldHtml {
+    /**
+     * 
+     */
+    @TableId
+    private Long id;
+
+    /**
+     * 合同WBS的p_key_id
+     */
+    private Long contractFormId;
+
+    /**
+     * 上报之前的html表单
+     */
+    private String oldHtmlUrl;
+
+    /**
+     *  是否删除(0-正常,1-已删除)
+     */
+    private Integer isDeleted;
+
+    /**
+     *  创建时间
+     */
+    private Date createTime;
+
+    /**
+     *  创建人
+     */
+    private Long createUser;
+
+    /**
+     *  修改时间
+     */
+    private Date updateTime;
+
+    /**
+     *  修改人
+     */
+    private Long updateUser;
+}

+ 6 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreeContractClient.java

@@ -202,4 +202,10 @@ public interface WbsTreeContractClient {
 
     @GetMapping(API_PREFIX + "/get-ekey")
     EKeyDto getEKey(@RequestParam String contractId, @RequestParam Long pKeyId, @RequestParam String wbsId);
+
+    @GetMapping(API_PREFIX + "/findIsExistTreeNode")
+    Integer findIsExistTreeNode(List<String> processNodeList);
+
+    @PostMapping(API_PREFIX + "/queryListByPIds")
+    List<WbsTreeContract> queryListByPIds(@RequestBody List<Long> pIds);
 }

+ 25 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/WbsTreeContractOldHtmlClient.java

@@ -0,0 +1,25 @@
+package org.springblade.manager.feign;
+
+import org.springblade.manager.entity.WbsTreeContract;
+import org.springblade.manager.entity.WbsTreeContractOldHtml;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+import static org.springblade.core.launch.constant.AppConstant.APPLICATION_NAME_PREFIX;
+
+@FeignClient(value = APPLICATION_NAME_PREFIX + "manager")
+public interface WbsTreeContractOldHtmlClient {
+    /**
+     * 接口前缀
+     */
+    String API_PREFIX = "/api/manager/WbsTreeContractOldHtml";
+
+    @PostMapping(API_PREFIX + "/save")
+    Boolean save(@RequestBody List<WbsTreeContractOldHtml> data);
+
+    @PostMapping(API_PREFIX + "/deleteByContractFormIds")
+    void deleteByContractFormIds(@RequestBody List<Long> collect);
+}

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

@@ -7,6 +7,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
@@ -79,6 +80,9 @@ import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
 import java.io.*;
 import java.net.URLEncoder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
@@ -105,6 +109,7 @@ public class InformationWriteQueryController extends BladeController {
     private final ContractClient contractClient;
 
     private final WbsTreeContractClient wbsTreeContractClient;
+    private final WbsTreeContractOldHtmlClient wbsTreeContractOldHtmlClient;
 
     private final WbsTreePrivateClient wbsTreePrivateClient;
 
@@ -1034,8 +1039,45 @@ public class InformationWriteQueryController extends BladeController {
                 return R.data(300, false, "未查询到填报信息,上报失败");
             }
         } else { //质检
+            //记录选中节点的所有表单旧html
+            List<Long> list = Arrays.stream(startTaskVO.getIds().split(",")).map(Long::parseLong).collect(Collectors.toList());
+            List<WbsTreeContract> wbsTreeContracts =  wbsTreeContractClient.queryListByPIds(list);
+
+
             businessData = this.informationQueryService.getOne(Wrappers.<InformationQuery>lambdaQuery().eq(InformationQuery::getWbsId, startTaskVO.getIds().replaceAll(",", "")).eq(InformationQuery::getClassify, startTaskVO.getClassify().toString()).eq(InformationQuery::getType, 1).last("order by id desc limit 1"));
             if (businessData != null) {
+
+                //处理html 复制之后记录在新表中w
+                if (CollectionUtils.isNotEmpty(wbsTreeContracts)) {
+                    List<WbsTreeContractOldHtml> data = new ArrayList<>();
+                    try {
+                        for (WbsTreeContract wbsTreeContract : wbsTreeContracts) {
+                            WbsTreeContractOldHtml oldHtml = new WbsTreeContractOldHtml();
+                            oldHtml.setId(SnowFlakeUtil.getId());
+                            oldHtml.setCreateUser(getUser().getUserId());
+                            String htmlUrl = wbsTreeContract.getHtmlUrl();
+                            // 获取或下载文件
+                            Path sourcePath = FileUtils.getOrDownloadFile(htmlUrl);
+                            // 生成副本路径
+                            Path copyPath = FileUtils.generateCopyPath(sourcePath);
+                            // 执行复制操作(覆盖已存在的文件)
+                            Files.copy(sourcePath, copyPath, StandardCopyOption.REPLACE_EXISTING);
+
+                            oldHtml.setContractFormId(wbsTreeContract.getPKeyId());
+                            oldHtml.setOldHtmlUrl(copyPath.toFile().getAbsolutePath());
+                            data.add(oldHtml);
+                        }
+                        List<Long> collect = data.stream().map(WbsTreeContractOldHtml::getContractFormId).collect(Collectors.toList());
+                        //删除旧记录
+                        wbsTreeContractOldHtmlClient.deleteByContractFormIds(collect);
+
+                        wbsTreeContractOldHtmlClient.save(data);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                        throw new ServiceException(e.getMessage());
+                    }
+                }
+
                 //设置业务数据ID
                 startTaskVO.setIds(businessData.getId().toString());
                 return this.batchTask(startTaskVO);

+ 19 - 2
blade-service/blade-business/src/main/java/org/springblade/business/controller/RecycleBinController.java

@@ -3,6 +3,7 @@ package org.springblade.business.controller;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -63,7 +64,7 @@ public class RecycleBinController extends BladeController {
         if (vo.getRegainIds() != null && vo.getRegainIds().size() > 0) {
             //获取数据
             List<Long> longs = vo.getRegainIds().stream().map(i -> i.getId()).collect(Collectors.toList());
-            List<RecycleBin> recycleBinList = this.recycleBinService.list(Wrappers.<RecycleBin>lambdaQuery().in(RecycleBin::getId, longs));
+            List<RecycleBin> recycleBinList = this.recycleBinService.list(Wrappers.<RecycleBin>lambdaQuery().eq(RecycleBin::getStatus,1).in(RecycleBin::getId, longs));
             //恢复数据成功后删除回收站对应记录
             List<String> recycleBinIds = new ArrayList<>();
             //划分数据类型
@@ -71,10 +72,26 @@ public class RecycleBinController extends BladeController {
             List<RecycleBin> nodeTypeList = recycleBinList.stream().filter(recycleBin -> new Integer("2").equals(recycleBin.getDelType())).distinct().collect(Collectors.toList());
             boolean regainNode = false, regainFile = false;
             if (nodeTypeList.size() > 0) {
+                List<RecycleBin> errorList = new ArrayList<>();
+                //筛选出项目级存在的节点
+                for (RecycleBin recycleBin : nodeTypeList) {
+                    //当前是否有节点在项目级被删除了  如果是标记当前节点不可用
+                    Integer count = this.wbsTreeContractClient.findIsExistTreeNode(Arrays.asList(recycleBin.getBusinessId().split(",")));
+                    if (count > 0){
+                        recycleBin.setStatus(2);
+                        errorList.add(recycleBin);
+                    }
+                }
+                if(CollectionUtils.isNotEmpty(errorList)){
+                    recycleBinService.updateBatchById(errorList);
+                    nodeTypeList.removeAll(errorList);
+                }
+
                 //恢复集合
                 List<String> processNodeList = new ArrayList<>();
                 this.foreachQueryData(nodeTypeList, recycleBinIds, processNodeList);
                 try {
+
                     //恢复数据
                     if (processNodeList.size() > 0) {
                         regainNode = this.wbsTreeContractClient.regainRemoveTreeByPrimaryKeyIds(processNodeList);
@@ -123,7 +140,7 @@ public class RecycleBinController extends BladeController {
 
     private void foreachQueryData(List<RecycleBin> recycleList, List<String> recycleBinIds, List<String> result) {
         for (RecycleBin recycleBin : recycleList) {
-            if (StringUtils.isNotEmpty(recycleBin.getBusinessId())) {
+            if (StringUtils.isNotEmpty(recycleBin.getBusinessId()) && recycleBin.getStatus() == 1) {
                 if (recycleBin.getBusinessId().contains(",")) {
                     result.addAll(new ArrayList<>(Arrays.asList(recycleBin.getBusinessId().split(","))));
                 } else {

+ 45 - 0
blade-service/blade-business/src/main/java/org/springblade/business/utils/FileUtils.java

@@ -17,6 +17,7 @@ import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SystemUtils;
 import org.springblade.common.vo.DataVO;
+import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.tool.utils.IoUtil;
 import org.springblade.system.cache.ParamCache;
 
@@ -30,7 +31,9 @@ import java.awt.geom.AffineTransform;
 import java.awt.image.AffineTransformOp;
 import java.awt.image.BufferedImage;
 import java.io.*;
+import java.net.URL;
 import java.net.URLEncoder;
+import java.nio.file.*;
 import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
@@ -366,4 +369,46 @@ public class FileUtils {
         String path = sys_file_net_url + fileUrl.replaceAll("//", "/").replaceAll(file_path2, "");
         return path;
     }
+
+    /**
+     * 获取本地文件,若不存在则从URL下载
+     */
+    public static Path getOrDownloadFile(String localPath) throws IOException {
+        Path path = Paths.get(localPath);
+
+        // 如果本地文件不存在,则从URL下载
+        if (!Files.exists(path)) {
+            System.out.println("本地文件不存在,开始下载...");
+            // 确保父目录存在
+            Path parentDir = path.getParent();
+            if (parentDir != null && !Files.exists(parentDir)) {
+                Files.createDirectories(parentDir);
+            }
+
+            // 从URL下载文件
+            try (InputStream in = CommonUtil.getOSSInputStream(getNetUrl(localPath))) {
+                Files.copy(in, path);
+                System.out.println("文件下载成功: " + path);
+            } catch (IOException e) {
+                throw new IOException("下载文件失败: " + e.getMessage(), e);
+            }
+        }
+        return path;
+    }
+
+    /**
+     * 生成带后缀的副本路径
+     */
+    public static Path generateCopyPath(Path originalPath) {
+        String suffix = "_copy";
+        String fileName = originalPath.getFileName().toString();
+        int dotIndex = fileName.lastIndexOf('.');
+
+        // 处理带扩展名和不带扩展名的文件
+        String newName = (dotIndex > 0)
+                ? fileName.substring(0, dotIndex) + suffix + fileName.substring(dotIndex)
+                : fileName + suffix;
+
+        return originalPath.resolveSibling(newName);
+    }
 }

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

@@ -163,6 +163,7 @@ public class ExcelTabController extends BladeController {
 
     private final  SignFtpUtil signFtpUtil;
 
+    private final WbsTreeContractOldHtmlService wbsTreeContractOldHtmlService;
 
     @Autowired
     StringRedisTemplate RedisTemplate;
@@ -603,7 +604,9 @@ public class ExcelTabController extends BladeController {
                          if (titleName.equals(ysName)) {
                             lastName = elementInfo.getEName();
                             attrInfo = elementInfo.getEKey() + "__" + i + "_" + j;
+
                             filedType = WbsElementUtil.getInitTableFiledType(elementInfo.getEType());
+
                             filedLength = elementInfo.getELength().toString();
 
                             maxScore = 100;
@@ -2035,7 +2038,13 @@ public class ExcelTabController extends BladeController {
         }
         executionTime.info("----公式填充执行完毕----");
 
-        //把CL08 和CL10 的监理表添加进去
+        //删除旧html数据 重刷电签不允许删除旧html
+        if(dataInfo.get("isNotDelOldHtml") == null){
+            List<String> collect = tableInfoList.stream().map(TableInfo::getPkeyId).collect(Collectors.toList());
+            boolean update = wbsTreeContractOldHtmlService.update(Wrappers.<WbsTreeContractOldHtml>update().lambda()
+                    .set(WbsTreeContractOldHtml::getIsDeleted, 1)
+                    .in(WbsTreeContractOldHtml::getContractFormId, collect));
+        }
 
         //保存数据到数据库
         R<Object> result = this.excelTabService.saveOrUpdateInfo(tableInfoList,singnType);
@@ -4661,6 +4670,7 @@ public class ExcelTabController extends BladeController {
                 js2.put("orderList", array);
                 js.put("dataInfo", js2);
                 js.put("signType", "1");
+                js.put("isNotDelOldHtml", 1);
                 this.saveBussData2(js);
             }
         } catch (Exception e) {

+ 8 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractClientImpl.java

@@ -491,5 +491,13 @@ public class WbsTreeContractClientImpl implements WbsTreeContractClient {
         return wbsTreeContractService.getEKey(contractId,pKeyId,wbsId);
     }
 
+    @Override
+    public Integer findIsExistTreeNode(List<String> ids) {
+        return wbsTreeContractService.findIsExistTreeNode(ids);
+    }
 
+    @Override
+    public List<WbsTreeContract> queryListByPIds(List<Long> pIds) {
+        return wbsTreeContractService.queryListByPIds(pIds);
+    }
 }

+ 33 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreeContractOldHtmlClientImpl.java

@@ -0,0 +1,33 @@
+package org.springblade.manager.feign;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.AllArgsConstructor;
+import org.springblade.manager.entity.WbsTreeContractOldHtml;
+import org.springblade.manager.service.WbsTreeContractOldHtmlService;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * @author LHB
+ */
+@RestController
+@AllArgsConstructor
+public class WbsTreeContractOldHtmlClientImpl implements WbsTreeContractOldHtmlClient {
+    @Resource
+    private WbsTreeContractOldHtmlService wbsTreeContractOldHtmlService;
+
+    @Override
+    public Boolean save(List<WbsTreeContractOldHtml> data) {
+        return wbsTreeContractOldHtmlService.saveBatch(data);
+    }
+
+    @Override
+    public void deleteByContractFormIds(List<Long> collect) {
+        wbsTreeContractOldHtmlService.update(Wrappers.<WbsTreeContractOldHtml>update().lambda()
+                .set(WbsTreeContractOldHtml::getIsDeleted, 1)
+                .eq(WbsTreeContractOldHtml::getIsDeleted, 0)
+                .in(WbsTreeContractOldHtml::getContractFormId, collect));
+    }
+}

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

@@ -157,4 +157,6 @@ public interface WbsTreeContractMapper extends EasyBaseMapper<WbsTreeContract> {
     void updateSortBatchByPKeyId(List<WbsTreeContract> resourceData);
 
     List<WbsTreeContract> selectListForcheckAllNodeDate(@Param("projectId") Long projectId, @Param("contractId") Long contractId);
+
+    Integer findIsExistTreeNode(List<String> ids);
 }

+ 9 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.xml

@@ -973,6 +973,15 @@
           AND wtc.wbs_id = #{wbsId}
           AND wtc.is_deleted = 0;
     </select>
+    <select id="findIsExistTreeNode" resultType="java.lang.Integer">
+        SELECT count(0) FROM `m_wbs_tree_contract` a
+        left join m_wbs_tree_private b on a.is_type_private_pid = b.p_key_id
+        where a.p_key_id in
+          <foreach collection="list" item="item" open="(" close=")" separator=",">
+              #{item}
+          </foreach>
+        and (b.p_key_id is null or b.is_deleted = 1)
+    </select>
     <select id="selectListForcheckAllNodeDate" resultType="org.springblade.manager.entity.WbsTreeContract">
         select * from m_wbs_tree_contract where
        <if test="projectId!=null and projectId!=''">

+ 18 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractOldHtmlMapper.java

@@ -0,0 +1,18 @@
+package org.springblade.manager.mapper;
+
+import org.springblade.manager.entity.WbsTreeContractOldHtml;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+* @author LHB
+* @description 针对表【m_wbs_tree_contract_old_html(合同段表单上报之前的html记录)】的数据库操作Mapper
+* @createDate 2025-07-01 17:37:36
+* @Entity generator.domain.MWbsTreeContractOldHtml
+*/
+public interface WbsTreeContractOldHtmlMapper extends BaseMapper<WbsTreeContractOldHtml> {
+
+}
+
+
+
+

+ 22 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractOldHtmlMapper.xml

@@ -0,0 +1,22 @@
+<?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.manager.mapper.WbsTreeContractOldHtmlMapper">
+
+    <resultMap id="BaseResultMap" type="org.springblade.manager.entity.WbsTreeContractOldHtml">
+            <id property="id" column="id" />
+            <result property="contractFormId" column="contract_form_id" />
+            <result property="oldHtmlUrl" column="old_html_url" />
+            <result property="isDeleted" column="is_deleted" />
+            <result property="createTime" column="create_time" />
+            <result property="createUser" column="create_user" />
+            <result property="updateTime" column="update_time" />
+            <result property="updateUser" column="update_user" />
+    </resultMap>
+
+    <sql id="Base_Column_List">
+        id,contract_form_id,old_html_url,is_deleted,create_time,create_user,
+        update_time,update_user
+    </sql>
+</mapper>

+ 4 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreeContractService.java

@@ -92,4 +92,8 @@ public interface IWbsTreeContractService extends BaseService<WbsTreeContract> {
     boolean checkNodeAllDate(WbsTreeContract contract);
 
     boolean checkAllNodeDate(Long projectId, Long contractId);
+
+    Integer findIsExistTreeNode(List<String> ids);
+
+    List<WbsTreeContract> queryListByPIds(List<Long> pIds);
 }

+ 13 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/WbsTreeContractOldHtmlService.java

@@ -0,0 +1,13 @@
+package org.springblade.manager.service;
+
+import org.springblade.manager.entity.WbsTreeContractOldHtml;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+* @author LHB
+* @description 针对表【m_wbs_tree_contract_old_html(合同段表单上报之前的html记录)】的数据库操作Service
+* @createDate 2025-07-01 17:37:36
+*/
+public interface WbsTreeContractOldHtmlService extends IService<WbsTreeContractOldHtml> {
+
+}

+ 57 - 7
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -65,10 +65,7 @@ import org.springblade.manager.formula.NodeTable;
 import org.springblade.manager.formula.impl.TableElementConverter;
 import org.springblade.manager.mapper.ExcelTabMapper;
 import org.springblade.manager.service.*;
-import org.springblade.manager.utils.FileUtils;
-import org.springblade.manager.utils.PdfAddContextUtils;
-import org.springblade.manager.utils.PdfAddimgUtil;
-import org.springblade.manager.utils.RandomNumberHolder;
+import org.springblade.manager.utils.*;
 import org.springblade.manager.vo.*;
 import org.springblade.resource.feign.NewIOSSClient;
 import org.springblade.system.cache.ParamCache;
@@ -88,6 +85,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.support.DefaultTransactionDefinition;
 
 import java.io.*;
+import java.net.URL;
 import java.nio.file.Files;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
@@ -130,6 +128,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
     private final TableInfoServiceImpl tableInfoService;
     private final INodeBaseInfoService nodeBaseInfoService;
     private final TrialSelfInspectionRecordClient trialSelfInspectionRecordClient;
+    private final WbsTreeContractOldHtmlService wbsTreeContractOldHtmlService;
 
 
     @Autowired
@@ -852,7 +851,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         int status = callback.getStatus();
         int saved = 0;
         //status=6,表示点击保存按钮 2 关闭保存
-        /*if (status == 3 || status == 6) //MustSave, Corrupted
+        if (status == 3 || status == 6) //MustSave, Corrupted
         {
             //获取url
             String downloadUri = callback.getUrl();
@@ -901,7 +900,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 editCallback.setError(1);
                 e.printStackTrace();
             }
-        }*/
+        }
         return editCallback;
     }
 
@@ -1329,7 +1328,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 //保存操作记录
                 this.operationLogClient.saveUserOperationLog(1, "资料填报", "工序填报页面", json);
                 // 更新redis
-                informationQueryClient.AsyncWbsTree(wbsTreeContractByP.getParentId() + "", wbsTreeContractByP.getParentId() + "", wbsTreeContractByP.getContractId(), "", "1");
+//                informationQueryClient.AsyncWbsTree(wbsTreeContractByP.getParentId() + "", wbsTreeContractByP.getParentId() + "", wbsTreeContractByP.getContractId(), "", "1");
             } catch (Exception e) {
                 e.printStackTrace();
                 return R.fail("操作失败");
@@ -1445,6 +1444,15 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         String keyNameList="";
         // 匹配关联
         try {
+            // 这里先从旧html表中获取  如果有用旧的html m_wbs_tree_contract_old_html
+            WbsTreeContractOldHtml oldHtml = wbsTreeContractOldHtmlService.getOne(Wrappers.<WbsTreeContractOldHtml>lambdaQuery()
+                    .eq(WbsTreeContractOldHtml::getContractFormId, pkeyId)
+                    .eq(WbsTreeContractOldHtml::getIsDeleted, 0)
+                    .last("limit 1"));
+            if(oldHtml != null){
+                wbsTreeContract.setHtmlUrl(oldHtml.getOldHtmlUrl());
+            }
+
             InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(wbsTreeContract.getHtmlUrl());
             String htmlString = IoUtil.readToString(inputStreamByUrl);
             Document doc = Jsoup.parse(htmlString);
@@ -5532,6 +5540,48 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         jdbcTemplate.update(sql);
     }
 
+    @Override
+    @Async("taskExecutor1")
+    public void synchronizedPdf(List<TableInfo> tableInfoList, String nodeId, String classify, String contractId, String projectId) {
+        try {
+            List<String> errorPKeyIds = new ArrayList<>();
+            //单个pdf加载
+            if (tableInfoList != null) {
+                tableInfoList.parallelStream().forEach(tableInfo -> {
+                    R bussPdfInfo = null;
+                    try {
+                        bussPdfInfo = this.getBussPdfInfo(Long.parseLong(tableInfo.getPkeyId()));
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                    if (ObjectUtil.isEmpty(bussPdfInfo) || bussPdfInfo.getCode() != 200) {
+                        //如果返回的单张pdfUrl为空,那么表示发生异常,返回异常信息
+                        errorPKeyIds.add(tableInfo.getPkeyId());
+                    }
+                });
+            }
+
+            //发生异常后直接返回,不进行合并
+//        if (errorPKeyIds.size() > 0) {
+//            List<AppWbsTreeContractVO> errorTabs = new LinkedList<>();
+//            for (AppWbsTreeContractVO appWbsTreeContractVO : tableAll) {
+//                if (errorPKeyIds.contains(appWbsTreeContractVO.getPKeyId().toString())) {
+//                    errorTabs.add(appWbsTreeContractVO);
+//                }
+//            }
+//            if (errorTabs.size() > 0) {
+//                List<String> names = errorTabs.stream().map(WbsTreeContract::getNodeName).collect(Collectors.toList());
+//                return R.fail("以下的表在生成pdf文件时发生了异常【" + StringUtils.join(names, "、") + "】");
+//            }
+//        }
+
+            //合并pdf加载
+            this.getBussPdfs(nodeId, classify, contractId, projectId);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new ServiceException("问题");
+        }
+    }
     @Override
     public void synPdfKeyInfo(String nodeId, String classify, String contractId, String projectId) throws Exception {
         // 获取有权限的节点信息

+ 10 - 8
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -607,6 +607,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             });
                         });
                         AtomicBoolean update = new AtomicBoolean(false);
+                        List<Long> ids = getNodeType46(tec).stream().map(CurrentNode::getPkId).collect(Collectors.toList());
                         itemsMap.values().stream().filter(Measurement::isMatching).forEach(t -> {
                             ElementBlock g = null;
                             FormData vfd = t.getValue();
@@ -628,7 +629,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                             if (g != null) {
                                 List<ItemBlock> itemBlockList = g.getList();
                                 int originSize = itemBlockList.size();
-                                List<Long> ids = getNodeType46(tec).stream().map(CurrentNode::getPkId).collect(Collectors.toList());
+
                                 /*清除那些已经不存在的工序*/
                                 itemBlockList.removeIf(ik -> !ids.contains(ik.getPkeyId()));
                                 if (itemBlockList.size() > 0) {
@@ -663,7 +664,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         }
     }
 
-    public void descendantType46(Object id, List<Map<String, Object>> listMaps) {
+    public void descendantType46(Long id, Long contractId, List<Map<String, Object>> listMaps) {
         String sql = "select " +
                         "p_Key_id pkId," +
                         "id," +
@@ -672,15 +673,16 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                         "sort," +
                         "IFNULL(if(length(trim(full_name))>0,full_name,node_name),node_name) AS title," +
                         "create_time createTime " +
-                        "from m_wbs_tree_contract where parent_id =? and is_deleted=0";
-        List<Map<String, Object>> tmp = this.jdbcTemplate.queryForList(sql, id);
+                        "from m_wbs_tree_contract where  contract_id =  " + contractId + " and find_in_set( " + id + ",ancestors_p_id) and is_deleted=0";
+        List<Map<String, Object>> tmp = this.jdbcTemplate.queryForList(sql);
         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);
                 }
+//                else {
+//                    descendantType46(map.get("id"), listMaps);
+//                }
             }
         }
     }
@@ -689,7 +691,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         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 = new ArrayList<>();
-            descendantType46(tec.getCurrentNode().getParentId(), listMaps);
+            descendantType46(tec.getCurrentNode().getParentPkeyId(),tec.getCurrentNode().getContractId(), listMaps);
             if (listMaps.size() > 0) {
                 tec.getCurrentNode().getDivisional().addAll(listMaps.stream().map(m -> BeanUtil.toBean(m, CurrentNode.class)).collect(Collectors.toList()));
             }
@@ -6933,5 +6935,5 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
         }
         return wbsTreeContract;
     }
-    
+
 }

+ 51 - 5
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsSynchronousEViSaServiceImpl.java

@@ -1,25 +1,32 @@
 package org.springblade.manager.service.impl;
 
 import cn.hutool.core.date.DateTime;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.tool.utils.CollectionUtil;
 import org.springblade.manager.entity.*;
+import org.springblade.manager.feign.WbsTreeContractOldHtmlClient;
 import org.springblade.manager.mapper.TextdictInfoMapper;
 import org.springblade.manager.mapper.WbsTreeContractMapper;
 import org.springblade.manager.mapper.WbsTreePrivateMapper;
 import org.springblade.manager.mapper.WbsTreeSynchronousRecordMapper;
+import org.springblade.manager.service.WbsTreeContractOldHtmlService;
+import org.springblade.manager.utils.FileUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.*;
 import java.util.stream.Collectors;
 
+import static org.springblade.core.secure.utils.AuthUtil.getUser;
+
 /**
  * @author LHB
  */
@@ -40,6 +47,9 @@ public class WbsSynchronousEViSaServiceImpl {
     @Autowired
     private ElementFormulaMappingServiceImpl elementFormulaMappingService;
 
+    @Autowired
+    private WbsTreeContractOldHtmlService wbsTreeContractOldHtmlService;
+
     @Transactional(rollbackFor = Exception.class)
     public void updateTextDictInfo(Long projectId, List<Long> editPrivateIds, List<TextdictInfo> addData) {
         //删除 需要新增的节点的电签和默认值
@@ -154,7 +164,7 @@ public class WbsSynchronousEViSaServiceImpl {
     }
 
     @Transactional(rollbackFor = Exception.class)
-    public void updateContract(String type, Long pId, Long createUserId, List<WbsTreeContract> list) {
+    public void updateContract(String type, Long pId, Long createUserId, List<WbsTreeContract> list, List<WbsTreeContract> wbsTreeContracts) {
         //排序调整
         if (type.contains("7")) {
             list.sort(Comparator.comparingInt(WbsTreeContract::getSort));
@@ -202,6 +212,42 @@ public class WbsSynchronousEViSaServiceImpl {
                 wbsTreeContractMapper.updateSortBatchByPKeyId(resourceData);
             }
         }
+
+        //处理html 复制之后记录在新表中w
+        if (CollectionUtils.isNotEmpty(wbsTreeContracts)) {
+            List<WbsTreeContractOldHtml> data = new ArrayList<>();
+            try {
+                for (WbsTreeContract wbsTreeContract : wbsTreeContracts) {
+                    //如果有历史记录 并且状态为0 则不记录当前历史记录
+                    long count = wbsTreeContractOldHtmlService.count(Wrappers.<WbsTreeContractOldHtml>lambdaQuery()
+                            .eq(WbsTreeContractOldHtml::getContractFormId, wbsTreeContract.getPKeyId())
+                            .eq(WbsTreeContractOldHtml::getIsDeleted, 0));
+                    if(count > 0){
+                        continue;
+                    }
+
+
+                    WbsTreeContractOldHtml oldHtml = new WbsTreeContractOldHtml();
+                    oldHtml.setId(SnowFlakeUtil.getId());
+                    oldHtml.setCreateUser(getUser().getUserId());
+                    String htmlUrl = wbsTreeContract.getHtmlUrl();
+                    // 获取或下载文件
+                    Path sourcePath = FileUtils.getOrDownloadFile(htmlUrl);
+                    // 生成副本路径
+                    Path copyPath = FileUtils.generateCopyPath(sourcePath);
+                    // 执行复制操作(覆盖已存在的文件)
+                    Files.copy(sourcePath, copyPath, StandardCopyOption.REPLACE_EXISTING);
+
+                    oldHtml.setContractFormId(wbsTreeContract.getPKeyId());
+                    oldHtml.setOldHtmlUrl(copyPath.toFile().getAbsolutePath());
+                    data.add(oldHtml);
+                }
+                wbsTreeContractOldHtmlService.saveBatch(data);
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new ServiceException(e.getMessage());
+            }
+        }
     }
 
     @Transactional(rollbackFor = Exception.class)

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

@@ -598,6 +598,7 @@ public class WbsSynchronousServiceImpl {
         List<ContractInfo> contractInfos = contractInfoMapper.selectContractIdByProjectId(String.valueOf(wbsTreeSynchronousRecord.getProjectId()));
 
         List<WbsTreeContract> editData = new ArrayList<>();
+        List<WbsTreeContract> oldHtml = new ArrayList<>();
         for (String primaryKeyId : nodeIds) {
 
             //获取当前节点对应节点信息
@@ -687,6 +688,10 @@ public class WbsSynchronousServiceImpl {
                                 if (templateNode.getType() == 2) {
                                     //同步范围 当前节点是否允许修改
                                     Boolean isSync = false;
+
+                                    //是否记录历史html
+                                    Boolean isOldHtml = false;
+
                                     if (CollectionUtil.isNotEmpty(contractRanges)) {
                                         switch (Integer.valueOf(wbsTreePrivate.getWbsType())) {
                                             //质检
@@ -706,9 +711,11 @@ public class WbsSynchronousServiceImpl {
                                                     } else if (submit == 1 && contractRanges.contains(WbsSyncTypeEnum.PENDING_APPROVAL.code)) {
                                                         //待审批 104
                                                         isSync = true;
+                                                        isOldHtml = true;
                                                     } else if (submit == 2 && contractRanges.contains(WbsSyncTypeEnum.APPROVED.code)) {
                                                         //已审批 105
                                                         isSync = true;
+                                                        isOldHtml = true;
                                                     }
                                                 }
                                                 break;
@@ -761,6 +768,11 @@ public class WbsSynchronousServiceImpl {
                                             if (isSync) {
                                                 editContractNodes.add(editContractNode);
                                             }
+                                            //记录历史html
+                                            if (isOldHtml) {
+                                                oldHtml.add(editContractNode);
+                                            }
+
                                         }
                                     }
                                     //找到了某个选中节点下与项目节点想同的节点了  提前结束循环,节省资源
@@ -818,17 +830,21 @@ public class WbsSynchronousServiceImpl {
         Set<Long> pIds = collect1.keySet();
         Integer nodeNumEnd = 0;
 
+        Map<Long, List<WbsTreeContract>> collect2 = oldHtml.stream().collect(Collectors.groupingBy(WbsTreeContract::getPId));
+
         for (Long pId : pIds) {
             nodeNumEnd++;
             List<WbsTreeContract> list = collect1.get(pId);
+            List<WbsTreeContract> oldHtmlPId = collect2.get(pId);
 
-            wbsSynchronousEViSaService.updateContract(wbsTreeSynchronousRecord.getType(), pId, wbsTreeSynchronousRecord.getCreateUserId(), list);
+            wbsSynchronousEViSaService.updateContract(wbsTreeSynchronousRecord.getType(), pId, wbsTreeSynchronousRecord.getCreateUserId(), list, oldHtmlPId);
             synchronousRecordMapper.update(null, Wrappers.<WbsTreeSynchronousRecord>lambdaUpdate()
                     .set(WbsTreeSynchronousRecord::getNodeNumEnd, nodeNumEnd)
                     .set(WbsTreeSynchronousRecord::getUpdateTime, DateTime.now())
                     .eq(WbsTreeSynchronousRecord::getId, wbsTreeSynchronousRecord.getId()));
         }
 
+
         synchronousRecordMapper.update(null, Wrappers.<WbsTreeSynchronousRecord>lambdaUpdate()
                 .set(WbsTreeSynchronousRecord::getStatus, 2)
                 .set(WbsTreeSynchronousRecord::getErrorMsg, null)

+ 22 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractOldHtmlServiceImpl.java

@@ -0,0 +1,22 @@
+package org.springblade.manager.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springblade.manager.entity.WbsTreeContractOldHtml;
+import org.springblade.manager.service.WbsTreeContractOldHtmlService;
+import org.springblade.manager.mapper.WbsTreeContractOldHtmlMapper;
+import org.springframework.stereotype.Service;
+
+/**
+* @author LHB
+* @description 针对表【m_wbs_tree_contract_old_html(合同段表单上报之前的html记录)】的数据库操作Service实现
+* @createDate 2025-07-01 17:37:36
+*/
+@Service
+public class WbsTreeContractOldHtmlServiceImpl extends ServiceImpl<WbsTreeContractOldHtmlMapper, WbsTreeContractOldHtml>
+    implements WbsTreeContractOldHtmlService {
+
+}
+
+
+
+

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

@@ -3099,6 +3099,12 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         return baseMapper.getEKey(contractId,pKeyId,wbsId);
     }
 
+
+    @Override
+    public Integer findIsExistTreeNode(List<String> ids) {
+        return baseMapper.findIsExistTreeNode(ids);
+    }
+
     @Override
     public boolean checkNodeAllDate(WbsTreeContract contract) {
         List<Integer>tableOwners=new ArrayList<>();
@@ -4256,6 +4262,13 @@ public static boolean hasConflictingCodes(List<ImportTreeDto> list) {
         return false;
     }
 
+    @Override
+    public List<WbsTreeContract> queryListByPIds(List<Long> pIds) {
+        return baseMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery()
+                .in(WbsTreeContract::getPId, pIds)
+                .eq(WbsTreeContract::getIsDeleted, 0));
+    }
+
 
     @Override
     public boolean checkAllNodeDate(Long projectId, Long contractId) {

+ 41 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/FileUtils.java

@@ -29,6 +29,7 @@ import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.common.utils.SystemUtils;
 import org.springblade.common.vo.DataVO;
+import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.tool.utils.FileUtil;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.IoUtil;
@@ -42,6 +43,7 @@ import java.awt.*;
 import java.awt.image.BufferedImage;
 import java.io.*;
 import java.net.URLEncoder;
+import java.nio.file.*;
 import java.util.List;
 import java.util.*;
 import java.util.regex.Matcher;
@@ -1052,6 +1054,45 @@ public class FileUtils {
     }
 
 
+    /**
+     * 获取本地文件,若不存在则从URL下载
+     */
+    public static Path getOrDownloadFile(String localPath) throws IOException {
+        Path path = Paths.get(localPath);
+
+        // 如果本地文件不存在,则从URL下载
+        if (!Files.exists(path)) {
+            System.out.println("本地文件不存在,开始下载...");
+            // 确保父目录存在
+            Path parentDir = path.getParent();
+            if (parentDir != null && !Files.exists(parentDir)) {
+                Files.createDirectories(parentDir);
+            }
+
+            // 从URL下载文件
+            try (InputStream in = CommonUtil.getOSSInputStream(getNetUrl(localPath))) {
+                Files.copy(in, path);
+                System.out.println("文件下载成功: " + path);
+            } catch (IOException e) {
+                throw new IOException("下载文件失败: " + e.getMessage(), e);
+            }
+        }
+        return path;
+    }
+
+    /**
+     * 生成带后缀的副本路径
+     */
+    public static Path generateCopyPath(Path originalPath) {
+        String suffix = "_copy";
+        String fileName = originalPath.getFileName().toString();
+        int dotIndex = fileName.lastIndexOf('.');
 
+        // 处理带扩展名和不带扩展名的文件
+        String newName = (dotIndex > 0)
+                ? fileName.substring(0, dotIndex) + suffix + fileName.substring(dotIndex)
+                : fileName + suffix;
 
+        return originalPath.resolveSibling(newName);
+    }
 }