Ver Fonte

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

yangyj há 1 ano atrás
pai
commit
cbce56e5b5

+ 7 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/TaskClient.java

@@ -35,6 +35,7 @@ public interface TaskClient {
     String QUERY_TASK_CONTRACT_ID = API_PREFIX + "/query-task-contract-id";
     String QUERY_TASK_ALL_BATCH = API_PREFIX + "/query-contract-all-batch";
     String SAVE_TASK = API_PREFIX + "/save_task";
+    String UPDATE_TASK = API_PREFIX + "/update_task";
     String SAVE_TASK_PARALLEL = API_PREFIX + "/save_task_parallel";
     String UDATE_DATA_FORMID = API_PREFIX + "/updateBusinessDataByFormDataId";
     String TRIAL_TASK_PELATED = API_PREFIX + "/trialSelfTaskRelated";
@@ -55,6 +56,12 @@ public interface TaskClient {
     @PostMapping(SAVE_TASK)
     boolean saveTask(@RequestBody Task task);
 
+    /**
+     * 修改任务
+     */
+    @PostMapping(UPDATE_TASK)
+    R updateTask(@RequestBody Task task);
+
     /**
      * 保存副任务
      */

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

@@ -1,11 +1,13 @@
 package org.springblade.manager.feign;
 
+import org.springblade.core.tool.api.R;
 import org.springblade.manager.entity.TextdictInfo;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
 import org.springblade.manager.vo.WbsTreePrivateVO;
 import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
@@ -74,4 +76,8 @@ public interface WbsTreePrivateClient {
     @PostMapping(API_PREFIX + "/selectListNode")
     List<WbsTreeContract> selectListNode(@RequestParam List<Long> fuIds, @RequestParam String projectId, @RequestParam String wbsId, @RequestParam String wbsType, @RequestParam String contractId);
 
+    //根据项目id,获取计量咨询意见配置节点信息
+    @GetMapping(API_PREFIX + "/getProjectOpinionNode")
+    R<WbsTreePrivate> getProjectOpinionNode(@RequestParam Long projectId);
+
 }

+ 5 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/dto/TaskApproveDTO.java

@@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.io.Serializable;
+import java.util.Map;
 
 @Data
 public class TaskApproveDTO implements Serializable {
@@ -17,4 +18,8 @@ public class TaskApproveDTO implements Serializable {
     @ApiModelProperty(value = "合同段id")
     private String contractId;
 
+    @ApiModelProperty(value = "表单数据")
+    private Map<String,Object> tableData;
+
+
 }

+ 2 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/TaskDetailVO.java

@@ -37,4 +37,6 @@ public class TaskDetailVO implements Serializable {
     @ApiModelProperty(value = "表单数据")
     private Map<String,Object> tableData;
 
+    @ApiModelProperty(value = "表单字符串")
+    private String tableHtml;
 }

+ 6 - 0
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/TaskClientImpl.java

@@ -64,6 +64,12 @@ public class TaskClientImpl implements TaskClient {
         return taskService.save(task);
     }
 
+    @Override
+    public R updateTask(Task task) {
+        taskService.updateById(task);
+        return R.success("修改成功");
+    }
+
     @Override
     public void saveTaskParallel(TaskParallel taskParallel) {
         taskParallelService.save(taskParallel);

+ 23 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/WbsTreePrivateClientImpl.java

@@ -9,6 +9,7 @@ import com.mixsmart.utils.StringUtils;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.node.ForestNodeMerger;
 import org.springblade.core.tool.utils.BeanUtil;
 import org.springblade.core.tool.utils.Func;
@@ -238,6 +239,28 @@ public class WbsTreePrivateClientImpl implements WbsTreePrivateClient {
                 .eq(WbsTreeContract::getStatus, 1));
     }
 
+    @Override
+    public R<WbsTreePrivate> getProjectOpinionNode(Long projectId) {
+        List<WbsTreePrivate> list = wbsTreePrivateService.list(new LambdaQueryWrapper<WbsTreePrivate>()
+                .eq(WbsTreePrivate::getProjectId, projectId)
+                .eq(WbsTreePrivate::getWbsType, 3)
+                .eq(WbsTreePrivate::getNodeType, 6));
+        if (list.size() == 0){
+            return R.fail("未获取到项目配置的咨询意见单节点");
+        }
+        if (list.size() != 1){
+            return R.fail("项目配置的咨询意见单节点存在多个,请重新配置");
+        }
+        WbsTreePrivate node = privateMapper.getProjectOpinionNode(projectId,list.get(0).getId());
+        if (node == null){
+            return R.fail("项目配置的咨询意见单节点下未配置表单");
+        }
+        if (org.apache.commons.lang3.StringUtils.isBlank(node.getHtmlUrl())){
+            return R.fail("项目配置的咨询意见单未关联清表");
+        }
+        return R.data(node);
+    }
+
     private void foreachSetChildList(List<WbsTreeContractTreeVOS> vosResult, List<WbsTreePrivateVO> voList) {
         voList.forEach(wbsTreePrivateVO -> {
             WbsTreeContractTreeVOS vos = new WbsTreeContractTreeVOS();

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

@@ -118,5 +118,7 @@ public interface WbsTreePrivateMapper extends EasyBaseMapper<WbsTreePrivate> {
     //根据项目id,获取所有type为1的节点
     List<WbsTreePrivate> getAllNodeByProjectId(@Param("projectId") Long projectId);
 
+    WbsTreePrivate getProjectOpinionNode(@Param("projectId") Long projectId,@Param("id") Long id);
+
     List<Long> linkNodeTreeBynodeId(@Param("pkeyid") String pkeyid);
 }

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

@@ -855,6 +855,9 @@
     <select id="getAllNodeByProjectId" resultType="org.springblade.manager.entity.WbsTreePrivate">
         select p_key_id,id,wbs_id,project_id from m_wbs_tree_private where project_id = #{projectId} and type = 1 and is_deleted = 0
     </select>
+    <select id="getProjectOpinionNode" resultType="org.springblade.manager.entity.WbsTreePrivate">
+        select * from m_wbs_tree_private where type = 2 and project_id = #{projectId} and parent_id = #{id} limit 1;
+    </select>
 
 
     <delete id="delTabProjectById">

+ 7 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ContractInfoServiceImpl.java

@@ -226,9 +226,14 @@ public class ContractInfoServiceImpl extends BaseServiceImpl<ContractInfoMapper,
                 //如果是复制节点,id也变了,oldId有没有改变暂不清楚(另一个接口),后面再排查
                 wbsTreePrivateRoot = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getId, oldId)
                         .eq(WbsTreePrivate::getProjectId, parentNodeRoot.getProjectId()).eq(WbsTreePrivate::getWbsId, parentNodeRoot.getWbsId()).eq(WbsTreePrivate::getStatus, 1));
-                if (ObjectUtil.isEmpty(wbsTreePrivateRoot)) {
-                    throw new ServiceException("暂无数据");
+                if (ObjectUtil.isEmpty(wbsTreePrivateRoot)){
+                    wbsTreePrivateRoot = wbsTreePrivateMapper.selectOne(Wrappers.<WbsTreePrivate>lambdaQuery()
+                            .eq(WbsTreePrivate::getPKeyId, parentNodeRoot.getIsTypePrivatePid()));
+                    if (ObjectUtil.isEmpty(wbsTreePrivateRoot)) {
+                        throw new ServiceException("未找到对应项目级节点");
+                    }
                 }
+
             }
 
             //获取项目树所有子节点

+ 6 - 0
blade-service/blade-meter/pom.xml

@@ -79,6 +79,12 @@
             <groupId>org.jsoup</groupId>
             <artifactId>jsoup</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springblade</groupId>
+            <artifactId>blade-e-visa-api</artifactId>
+            <version>2.9.1.RELEASE</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 
 </project>

+ 652 - 46
blade-service/blade-meter/src/main/java/org/springblade/meter/controller/TaskController.java

@@ -3,9 +3,11 @@ package org.springblade.meter.controller;
 
 import cn.hutool.log.StaticLog;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.aspose.cells.PageSetup;
 import com.aspose.cells.SaveFormat;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -22,15 +24,20 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import lombok.Data;
+import net.logstash.logback.encoder.org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.time.DateUtils;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellRangeAddress;
 import org.apache.poi.util.IOUtils;
 import org.apache.poi.xssf.usermodel.XSSFRichTextString;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
 import org.springblade.business.entity.*;
 import org.springblade.business.feign.TaskClient;
 import org.springblade.common.constant.ClientIdConstant;
+import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.BaseUtils;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
@@ -45,11 +52,11 @@ import org.springblade.core.secure.utils.SecureUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.*;
 import org.springblade.core.tool.utils.DateUtil;
+import org.springblade.evisa.feign.EVisaClient;
+import org.springblade.evisa.vo.SigInfoVO;
 import org.springblade.feign.ArchiveFileTaskClient;
-import org.springblade.manager.entity.ContractInfo;
-import org.springblade.manager.entity.ContractRelationJlyz;
-import org.springblade.manager.feign.FormulaClient;
-import org.springblade.manager.feign.ProjectClient;
+import org.springblade.manager.entity.*;
+import org.springblade.manager.feign.*;
 import org.springblade.manager.vo.ReportMergeCellsConfig;
 import org.springblade.manager.vo.ReportResult;
 import org.springblade.meter.config.MyJdbcTemplate;
@@ -63,9 +70,11 @@ import org.springblade.meter.service.IInterimPayCertificateService;
 import org.springblade.meter.service.IMaterialStartStatementService;
 import org.springblade.meter.service.impl.*;
 import org.springblade.meter.utils.CollectionUtils;
+import org.springblade.meter.utils.FileUtils;
 import org.springblade.meter.vo.*;
 import org.springblade.producer.bean.PushMessage;
 import org.springblade.resource.feign.NewIOSSClient;
+import org.springblade.system.cache.ParamCache;
 import org.springblade.system.user.entity.User;
 import org.springblade.system.user.feign.IUserClient;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
@@ -88,6 +97,8 @@ import java.util.concurrent.ExecutionException;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
+import static org.bouncycastle.asn1.x500.style.RFC4519Style.o;
+
 @RestController
 @AllArgsConstructor
 @RequestMapping("/task")
@@ -96,6 +107,7 @@ public class TaskController extends BladeController {
 
 
     private final ProjectClient projectClient;
+    private final ContractClient contractClient;
     private final JdbcTemplate jdbcTemplate;
     private final MyJdbcTemplate myJdbcTemplate;
     private final BladeRedis bladeRedis;
@@ -118,6 +130,10 @@ public class TaskController extends BladeController {
     private final AttachmentFormServiceTaskImpl attachmentFormServiceTask;
     private final MiddleMeterApplyMapper middleMeterApplyMapper;
 
+    private final WbsTreePrivateClient wbsTreePrivateClient;
+    private final ExcelTabClient excelTabClient;
+    private final EVisaClient eVisaClient;
+    private final SaveUserInfoByProjectClient saveUserInfoByProjectClient;
 
     private final ChangeTokenFormServiceImpl changeTokenFormService;
     private final ChangeTokenFormServiceTaskImpl changeTokenFormServiceTask;
@@ -1182,47 +1198,6 @@ public class TaskController extends BladeController {
             if (taskParallels.size() == 0){
                 throw new ServiceException("未获取到任务流程信息");
             }
-            String firstUser = taskParallels.get(0).getTaskUser();
-            /*中间计量申请,返回值增加:上报总金额,本期进度款,审计意见*/
-            if (task.getMeterTaskType() != null && task.getMeterTaskType() == 1){
-                //实时查询上报总金额
-                BigDecimal reportAllMoney = middleMeterApplyTaskMapper.selectAllMoney(task.getId());
-                if (reportAllMoney == null){
-                    throw new ServiceException("上报金额不能为0");
-                }
-                ContractMeterPeriod period = contractMeterPeriodService.getById(task.getFormDataId());
-                if (period == null){
-                    throw new ServiceException("未获取到计量期信息");
-                }
-                vo.setReportAllMoney(reportAllMoney);
-                vo.setProgressMoney(task.getTaskCommonMoney() == null ? BigDecimal.ZERO : task.getTaskCommonMoney());
-                vo.setPdfUrl(task.getAttachmentPdfUrl());
-                //查看当前用户是否是第一人
-                String currentUser = AuthUtil.getUserId()+"";
-                if (currentUser.equals(firstUser)){
-                    //是第一人,设置意见为1,并返回默认值字段
-                    vo.setOpinionType(1);
-                    //todo 目前直接把key写死在代码里面,后面有空再去动态获取key
-                    Map<String,Object> tableData = new HashMap<>();
-                    tableData.put("key_18__3_1",projectClient.getById(task.getProjectId()).getProjectName());
-                    tableData.put("key_7__4_3",reportAllMoney);
-                    tableData.put("key_1__5_3",LocalDate.now());
-                    tableData.put("key_5__10_1",reportAllMoney);
-                    //获取本期之前所有计量期金额
-                    BigDecimal beforeMoney = contractMeterPeriodMapper.getBeforeMoney(period);
-                    tableData.put("key_14__11_1",beforeMoney == null ? "" : beforeMoney);
-                    tableData.put("key_10__11_3",beforeMoney == null ? reportAllMoney : beforeMoney.add(reportAllMoney));
-                    vo.setTableData(tableData);
-                }else {
-                    //不是第一人,判断PDF是否生成,生成了类型为2,没有生成类型为3
-                    if (StringUtils.isNotBlank(task.getAttachmentPdfUrl())){
-                        vo.setOpinionType(2);
-                    }else {
-                        vo.setOpinionType(3);
-                    }
-                }
-
-            }
 
             /*上报人*/
             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@@ -1233,9 +1208,18 @@ public class TaskController extends BladeController {
             taskUserOne.put("flowValue", "上报");
             taskProcessInfo.add(0, taskUserOne);
 
+            //判断当前用户所属流程,如果为第一流程则类型1显示Excel,如果是后面流程则类型2显示PDF,没有PDF则类型3
+            int currentUserFlow = 1;
             /*预设流程(平行、顺序审批)*/
             if (ObjectUtil.isNotEmpty(task.getFixedFlowId()) && !task.getFixedFlowId().equals(0L)) {
                 List<FixedFlowLink> query = jdbcTemplate.query("SELECT * FROM u_fixed_flow_link WHERE fixed_flow_id = ?", new Object[]{task.getFixedFlowId()}, new BeanPropertyRowMapper<>(FixedFlowLink.class));
+                //校验当前用户在第几流程
+                Integer sort = query.stream().collect(Collectors.toMap(l -> l.getFixedFlowLinkUser(), l -> l.getFixedFlowBranchSort())).get(AuthUtil.getUserId());
+                if (sort == null){
+                    throw new ServiceException("未获取到当前用户在流程中的信息");
+                }
+                currentUserFlow = sort;
+
                 Map<String, List<FixedFlowLink>> group = query.stream()
                         .collect(Collectors.groupingBy(obj -> obj.getFixedFlowLink() + "@@@" + obj.getFixedFlowLinkType(),
                                 LinkedHashMap::new,
@@ -1305,6 +1289,68 @@ public class TaskController extends BladeController {
                 }
                 vo.setTaskProcessInfo(taskProcessInfo);
             }
+            /*中间计量申请,返回值增加:上报总金额,本期进度款,审计意见*/
+            if (task.getMeterTaskType() != null && task.getMeterTaskType() == 1){
+                //实时查询上报总金额
+                BigDecimal reportAllMoney = middleMeterApplyTaskMapper.selectAllMoney(task.getId());
+                if (reportAllMoney == null){
+                    throw new ServiceException("上报金额不能为0");
+                }
+                ContractMeterPeriod period = contractMeterPeriodService.getById(task.getFormDataId());
+                if (period == null){
+                    throw new ServiceException("未获取到计量期信息");
+                }
+                vo.setReportAllMoney(reportAllMoney);
+                vo.setProgressMoney(task.getTaskCommonMoney() == null ? BigDecimal.ZERO : task.getTaskCommonMoney());
+                vo.setPdfUrl(task.getAttachmentPdfUrl());
+                String html = this.getExcelHtmlByBuss(Long.valueOf(task.getProjectId()));
+                if (html != null) {
+                    vo.setTableHtml(html);
+                    //查看当前用户是否在第一流程
+                    if (currentUserFlow == 1) {
+                        //是第一人,设置意见为1,查询已经填写的值,如果没有则返回默认值
+                        vo.setOpinionType(1);
+                        R<WbsTreePrivate> r = wbsTreePrivateClient.getProjectOpinionNode(Long.valueOf(task.getProjectId()));
+                        if (r.getCode() != 200) {
+                            throw new ServiceException(r.getMsg());
+                        }
+                        WbsTreePrivate aPrivate = r.getData();
+                        //实体数据
+//                    String querySql = "select * from " + aPrivate.getInitTableName() + " where p_key_id=" + task.getId();
+//                    List<Map<String, Object>> dataIn = jdbcTemplate.queryForList(querySql);
+                        Map<String, Object> dataInfo = getBussDataInfo(aPrivate, task.getId());
+                        //todo 目前直接把key写死在代码里面,后面有空再去动态获取key
+                        Map<String, Object> tableData = new HashMap<>();
+                        if (dataInfo.size() == 0) {
+                            tableData.put("key_18__3_1", projectClient.getById(task.getProjectId()).getProjectName() + contractClient.getContractById(Long.valueOf(task.getContractId())).getContractName());
+                            tableData.put("key_7__4_3", reportAllMoney);
+                            tableData.put("key_1__5_3", DateTimeFormatter.ofPattern("yyyy年MM月dd日").format(LocalDate.now()));
+                            tableData.put("key_5__10_1", reportAllMoney);
+                            //获取本期之前所有计量期金额
+                            BigDecimal beforeMoney = contractMeterPeriodMapper.getBeforeMoney(period);
+                            if (beforeMoney != null){
+                                tableData.put("key_14__11_1",beforeMoney);
+                            }
+                            tableData.put("key_10__11_3", beforeMoney == null ? reportAllMoney : beforeMoney.add(reportAllMoney));
+                        } else {
+                            tableData = dataInfo;
+                            tableData.put("key_18__3_1", projectClient.getById(task.getProjectId()).getProjectName() + contractClient.getContractById(Long.valueOf(task.getContractId())).getContractName());
+                        }
+                        vo.setTableData(tableData);
+                    } else {
+                        if (StringUtils.isNotBlank(task.getAttachmentPdfUrl())) {
+                            vo.setOpinionType(2);
+                        } else {
+                            //不是第一人,判断PDF是否生成,生成了类型为2,没有生成类型为3
+                            vo.setOpinionType(3);
+                        }
+                    }
+                }else {
+                    vo.setOpinionType(3);
+                }
+            }
+
+
 
             /*中间业务taskVO复制数据(只有待审批、已审批任务才能查看到具体的taskVO复制数据,因为废除任务时taskVO被删除,但是单条驳回时有记录单条数据的历史信息,所以通过的任务还是能查看到)*/
 //            if (ObjectUtil.isNotEmpty(task.getFormDataId()) && Arrays.asList(1, 2).contains(task.getStatus())) {
@@ -2269,6 +2315,7 @@ public class TaskController extends BladeController {
     @ApiOperationSupport(order = 19)
     @ApiOperation(value = "同意审批(批量审批)", notes = "传入TaskApproveDTO")
     @PushMessage(clientId = ClientIdConstant.METER_CLIENT_ID)
+    @Transactional
     public R<Object> approve(@RequestBody TaskApproveDTO dto) {
         if (ObjectUtil.isEmpty(dto.getTaskId()) || ObjectUtil.isEmpty(dto.getProjectId()) || ObjectUtil.isEmpty(dto.getContractId()) || ObjectUtil.isEmpty(SecureUtil.getUserId())) {
             throw new ServiceException("入参数据异常");
@@ -2296,8 +2343,11 @@ public class TaskController extends BladeController {
             /*当前审批轮次*/
             String sql_2 = "SELECT * FROM u_task_parallel WHERE process_instance_id = ? ORDER BY sort";
             List<TaskParallel> taskParallels = jdbcTemplate.query(sql_2, new Object[]{task.getProcessInstanceId()}, new BeanPropertyRowMapper<>(TaskParallel.class));
-            boolean isCurrentUserLastApprove = checkTheTaskPersonSort(taskParallels);
 
+            //如果当前是中间计量申请,并且是第一流程,则保存表单但数据,若第一流程所有人都已审批则生成PDF,并且设置task对应值
+            checkMiddleApp(dto,task,taskParallels);
+
+            boolean isCurrentUserLastApprove = checkTheTaskPersonSort(taskParallels);
             /*单条业务数据状态*/
             updateCopyDataStatus(task, dto);
             String reportId = null;
@@ -2381,6 +2431,157 @@ public class TaskController extends BladeController {
         return R.fail("操作失败");
     }
 
+    private void checkMiddleApp(TaskApproveDTO dto, Task task, List<TaskParallel> taskParallels) {
+        String html = this.getExcelHtmlByBuss(Long.valueOf(task.getProjectId()));
+        if (html != null) {
+            if (task.getMeterTaskType() != null && task.getMeterTaskType() == 1) {
+                //判断当前用户所属流程,只处理第一流程
+                int currentUserFlow = 1;
+                Boolean isDefiniteFlow = false;
+                Boolean isAllApp = false;
+                List<FixedFlowLink> query = new ArrayList<>();
+                if (task.getFixedFlowId() != null && !task.getFixedFlowId().equals(0L)) {
+                    isDefiniteFlow = true;
+                    query = jdbcTemplate.query("SELECT * FROM u_fixed_flow_link WHERE fixed_flow_id = ?", new Object[]{task.getFixedFlowId()}, new BeanPropertyRowMapper<>(FixedFlowLink.class));
+                    //校验当前用户在第几流程
+                    Integer sort = query.stream().collect(Collectors.toMap(l -> l.getFixedFlowLinkUser(), l -> l.getFixedFlowBranchSort())).get(AuthUtil.getUserId());
+                    if (sort == null) {
+                        throw new ServiceException("未获取到当前用户在流程中的信息");
+                    }
+                    currentUserFlow = sort;
+                }
+                if (currentUserFlow == 1) {
+                    //当前流程所有用户id,后面PDF权限校验
+                    Map<Long, String> flowIds = new HashMap<>();
+                    //查询出项目审计意见节点的基本信息
+                    R r = wbsTreePrivateClient.getProjectOpinionNode(Long.valueOf(dto.getProjectId()));
+                    if (r.getCode() != 200) {
+                        throw new ServiceException(r.getMsg());
+                    }
+                    WbsTreePrivate aPrivate = (WbsTreePrivate) r.getData();
+                    if (isDefiniteFlow) {
+                        flowIds = query.stream().filter(l -> l.getFixedFlowBranchSort() == 1)
+                                .collect(Collectors.toMap(l -> l.getFixedFlowLinkUser(), l -> l.getFixedFlowLinkUserName()));
+                        //获取出当前流程中所有用户
+                        List<String> ids = query.stream()
+                                .filter(l -> l.getFixedFlowBranchSort() == 1 && !l.getFixedFlowLinkUser().equals(AuthUtil.getUserId()))
+                                .map(l -> l.getFixedFlowLinkUser() + "")
+                                .collect(Collectors.toList());
+                        //根据用户获取这些用户在当前任务中的进度,来判断是否全部审批完成
+                        long count = taskParallels.stream()
+                                .filter(l -> ids.contains(l.getTaskUser()))
+                                .filter(l -> l.getStatus() != 2).count();
+                        if (count == 0) {
+                            isAllApp = true;
+                        }
+                    } else {
+                        flowIds = taskParallels.stream().collect(Collectors.toMap(l -> Long.valueOf(l.getTaskUser()), l -> l.getTaskUserName()));
+                        long count = taskParallels.stream()
+                                .filter(l -> !l.getTaskUser().equals(AuthUtil.getUserId() + ""))
+                                .filter(l -> l.getStatus() != 2).count();
+                        if (count == 0) {
+                            isAllApp = true;
+                        }
+                    }
+                    //保存数据到m表
+                    String delSql = "delete from " + aPrivate.getInitTableName() + " where p_key_id=" + task.getId();
+                    jdbcTemplate.execute(delSql);
+                    String sqlInfo = "";
+                    Map<String, Object> dataMap2 = dto.getTableData();
+                    Map<String, Object> dataMap = new HashMap<>();
+                    for (String e : dataMap2.keySet()) {
+                        if (e.contains("__")) {
+                            String[] split = e.split("__");
+                            dataMap.put(split[0], dataMap2.get(e) + "_^_" + split[1]);
+                        }
+                    }
+                    /*检查发现有p_key_id缺失的情况,导致表单数据丢失,所以强制覆盖*/
+                    dataMap.put("p_key_id", task.getId());
+                    sqlInfo = "INSERT INTO " + aPrivate.getInitTableName() + " ( ";
+                    String keyStr = "id,";
+                    String valStr = SnowFlakeUtil.getId() + ",";
+                    for (String keys : dataMap.keySet()) {
+                        keyStr += keys + ",";
+                        valStr += "'" + dataMap.get(keys) + "',";
+                    }
+                    keyStr = keyStr.substring(0, keyStr.lastIndexOf(","));
+                    valStr = valStr.substring(0, valStr.lastIndexOf(","));
+                    sqlInfo = sqlInfo + keyStr + ") VALUES (" + valStr + ")";
+                    jdbcTemplate.execute(sqlInfo);
+
+                    //任务
+                    Task updateTask = new Task();
+                    updateTask.setId(task.getId());
+                    Map<String, Object> tableData = dto.getTableData();
+                    Object object = tableData.get("key_5__10_1");
+                    if (object != null) {
+                        try {
+                            BigDecimal decimal = new BigDecimal(object.toString());
+                            updateTask.setTaskCommonMoney(decimal);
+                            Object object2 = tableData.get("key_14__11_1");
+                            if (object2 != null) {
+                                BigDecimal decimal2 = new BigDecimal(object2.toString());
+                                tableData.put("key_10__11_3", decimal.add(decimal2));
+                            } else {
+                                tableData.put("key_10__11_3", decimal);
+                            }
+                        } catch (Exception e) {
+                            throw new ServiceException("本期审核进度款格式不对");
+                        }
+                    }
+                    //如果为第一流程则判断是否当前流程已全部审批,已经全部审批则生成电签PDF,没有全部审批则只保存数据
+                    if (isAllApp) {
+                        //要求付款额度
+                        this.addYuan("key_7__4_3", tableData);
+                        //本期审核进度款
+                        this.addYuan("key_5__10_1", tableData);
+                        //截至上期累计进度款
+                        this.addYuan("key_14__11_1", tableData);
+                        //截至本期累计进度款
+                        this.addYuan("key_10__11_3", tableData);
+                        if (flowIds.size() == 0) {
+                            throw new ServiceException("未找到流程人信息");
+                        }
+                        tableData.put("key_18__3_1", projectClient.getById(task.getProjectId()).getProjectName() + contractClient.getContractById(Long.valueOf(task.getContractId())).getContractName());
+                        //申请进度时间
+                        tableData.put("key_17__7_3", DateTimeFormatter.ofPattern("yyyy年MM月dd日").format(LocalDate.now()));
+                        //电签单位日期
+                        tableData.put("key_4__13_4", DateTimeFormatter.ofPattern("yyyy年MM月dd日").format(LocalDate.now()));
+                        String pdfUrl = "";
+                        try {
+                            pdfUrl = getEntrustPDFTrial(Long.valueOf(dto.getProjectId()), dto.getContractId(), aPrivate.getPKeyId(), tableData, flowIds);
+                        } catch (Exception e) {
+                            throw new ServiceException("生成咨询意见时失败:" + e.getMessage());
+                        }
+
+                        updateTask.setAttachmentPdfUrl(pdfUrl);
+                    }
+
+                    R r1 = taskClient.updateTask(updateTask);
+                    if (r1.getCode() != 200) {
+                        throw new ServiceException("修改任务信息时出现错误");
+                    }
+                }
+//            if (1==1){
+//                throw new ServiceException("回滚测试");
+//            }
+            }
+        }
+    }
+
+    public void addYuan(String key,Map<String, Object> tableData){
+        Object object2 = tableData.get(key);
+        if (object2 != null) {
+            try {
+                BigDecimal decimal = new BigDecimal(object2.toString());
+                tableData.put(key,decimal.toString()+"元");
+            }catch (Exception e){
+                throw new ServiceException("金额格式不对");
+            }
+        }
+
+    }
+
     private void check(Task task) {
         String sql_2 = "SELECT * FROM u_task_parallel WHERE process_instance_id = ? ORDER BY sort";
         List<TaskParallel> taskParallels = jdbcTemplate.query(sql_2, new Object[]{task.getProcessInstanceId()}, new BeanPropertyRowMapper<>(TaskParallel.class));
@@ -3309,4 +3510,409 @@ public class TaskController extends BladeController {
         return R.success("操作成功");
     }
 
+    public String getExcelHtmlByBuss(Long projectId) {
+
+        R<WbsTreePrivate> r = wbsTreePrivateClient.getProjectOpinionNode(projectId);
+        if (r.getCode() != 200){
+//            throw new ServiceException(r.getMsg());
+            //如果没有节点或者清单,直接判断不需要
+            return null;
+        }
+        WbsTreePrivate aPrivate = r.getData();
+        try {
+            InputStream fileInputStream = new FileInputStream(aPrivate.getHtmlUrl());
+//            InputStream fileInputStream = new FileInputStream("C:\\Users\\泓创研发01\\Desktop\\fsdownload\\1789967486389583872.html");
+            String htmlString = IoUtil.readToString(fileInputStream);
+            htmlString = htmlString.replaceAll("placeholder", "placeholderxx");
+            htmlString = htmlString.replaceAll("title", "titlexx");
+            // 远程搜索配置
+            org.jsoup.nodes.Document doc = Jsoup.parse(htmlString);
+            Element table = doc.select("table").first();
+            fileInputStream.close();
+            return table+"";
+        } catch (Exception e) {
+           throw new ServiceException("解析咨询意见表单时发生异常");
+        }
+    }
+
+    public String getEntrustPDFTrial(Long projectId,String contractId,Long pkeyId,Map<String, Object> DataInfo, Map<Long,String> flowIds) throws Exception {
+        String file_path = FileUtils.getSysLocalFileUrl();//ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
+        R r = wbsTreePrivateClient.getProjectOpinionNode(projectId);
+        if (r.getCode() != 200){
+            throw new ServiceException(r.getMsg());
+        }
+        WbsTreePrivate aPrivate = (WbsTreePrivate) r.getData();
+
+        String pdfPath = file_path + "/pdf//" + pkeyId + ".pdf";
+        String excelPath = file_path + "/pdf//" + pkeyId + ".xlsx";
+
+        File tabPdf = ResourceUtil.getFile(pdfPath);
+        if (tabPdf.exists()) {
+            tabPdf.delete();
+        }
+
+        //获取清表信息
+        ExcelTab excelTab = excelTabClient.getById(aPrivate.getExcelId()+"");
+
+        if (excelTab == null) {
+            throw new ServiceException("操作失败!");
+        }
+
+        //获取清表excel文件
+        org.apache.poi.ss.usermodel.Workbook workbook = WorkbookFactory.create(Objects.requireNonNull(CommonUtil.getOSSInputStreamTow(excelTab.getFileUrl())));
+        Sheet sheet = workbook.getSheetAt(0);
+        sheet.setForceFormulaRecalculation(true);
+
+
+        //数据不为空,构造数据
+        String fileUrl = aPrivate.getHtmlUrl();
+        File file1 = ResourceUtil.getFile(fileUrl);
+//        File file1 = ResourceUtil.getFile("C:\\Users\\泓创研发01\\Desktop\\fsdownload\\1789967486389583872.html");
+        InputStream fileInputStream;
+        if (file1.exists()) {
+            fileInputStream = new FileInputStream(file1);
+        } else {
+            String path = sys_file_net_url + fileUrl.replaceAll("//", "/").replaceAll(file_path, "");
+            fileInputStream = CommonUtil.getOSSInputStream(path);
+        }
+
+        String htmlString = IoUtil.readToString(fileInputStream);
+        htmlString = htmlString.replaceAll("placeholder", "placeholderxx");
+        htmlString = htmlString.replaceAll("title", "titlexx");
+
+        org.jsoup.nodes.Document doc = Jsoup.parse(htmlString);
+        Element table = doc.select("table").first();
+        Elements trs = table.select("tr");
+
+        //实际电签人
+        Set<User> sigUser = new HashSet<>();
+
+        if (ObjectUtil.isNotEmpty(DataInfo)) {
+            for (String val : Objects.requireNonNull(DataInfo).keySet()) {
+                if (val.contains("__")) {
+                    String[] DataVal = val.split("__");
+                    String[] xy = DataVal[1].split("_");
+                    if (Integer.parseInt(xy[0]) < trs.size()) {
+                        Element ytzData = trs.get(Integer.parseInt(xy[0]));
+                        if (ytzData != null) {
+                            Elements tdsx = ytzData.select("td");
+                            if (Integer.parseInt(xy[1]) < tdsx.size()) {
+                                Element data = ytzData.select("td").get(Integer.parseInt(xy[1]));
+                                if (data != null) {
+                                    if (data.html().contains("x1") && data.html().contains("y1")) {
+                                        int x1 = 0;
+                                        int x2 = 0;
+                                        int y1 = 0;
+                                        int y2 = 0;
+                                        if (data.html().contains("el-tooltip")) {
+                                            x1 = Integer.parseInt(data.children().get(0).children().get(0).attr("x1"));
+                                            x2 = Integer.parseInt(data.children().get(0).children().get(0).attr("x2"));
+                                            y1 = Integer.parseInt(data.children().get(0).children().get(0).attr("y1"));
+                                        } else {
+                                            x1 = Integer.parseInt(data.children().get(0).attr("x1"));
+                                            y1 = Integer.parseInt(data.children().get(0).attr("y1"));
+                                        }
+                                        if (x1 == 0) {
+                                            x1 = 1;
+                                        }
+                                        String myData = DataInfo.get(val) + "";
+                                        if (myData.contains("T") && myData.contains("-") && myData.contains(":")) {
+                                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+                                            sdf.setTimeZone(TimeZone.getTimeZone("GTM+8"));
+                                            SimpleDateFormat formatStr = new SimpleDateFormat("yyyy年MM月dd日");
+                                            if (myData.contains(",") && myData.contains("]")) {
+
+                                                myData = myData.replace("[", "").replace("]", "").replaceAll("'", "");
+                                                String[] dataVal = myData.split(",");
+
+                                                Date Start_dataStr = sdf.parse(dataVal[0]);
+                                                Date end_dataStr = sdf.parse(dataVal[1]);
+                                                String StartDate = formatStr.format(Start_dataStr);
+                                                String endDate = formatStr.format(end_dataStr);
+                                                if (StartDate.equals(endDate)) {
+                                                    myData = StartDate;
+                                                } else {
+                                                    myData = StartDate + "-" + endDate;
+                                                }
+                                            } else {
+                                                String[] dataStr = myData.split("T")[0].split("-");
+                                                myData = StringUtil.format("{}年{}月{}日", dataStr[0], dataStr[1], Integer.parseInt(dataStr[2]));
+                                            }
+                                        }
+
+                                        if (myData.contains("lang.String")) {
+                                            Object obj = DataInfo.get(val);
+                                            if (obj instanceof String[]) {
+                                                String[] dataDate = (String[]) obj;
+                                                myData = dataDate[0].trim() + "-" + dataDate[1].trim();
+                                                if (dataDate[0].trim().equals(dataDate[1].trim())) {
+                                                    myData = dataDate[0];
+                                                }
+                                            }
+                                        }
+
+                                       if (myData.equals("1") && data.html().contains("hc-form-checkbox-group")) {
+                                            Row row = sheet.getRow(y1 - 1);
+                                            if (row != null) {
+                                                Cell cell = row.getCell(x1 - 1);
+                                                if (cell != null) {
+                                                    String exceVal = cell.getStringCellValue().replaceAll(" ", "");
+                                                    short fontIndex = cell.getCellStyle().getFontIndex();
+                                                    Font fontAt = workbook.getFontAt(fontIndex);
+                                                    fontAt.setFontName("EUDC");
+                                                    cell.setCellValue(exceVal.replace("□", "\u2611"));
+                                                } else {
+                                                    ObjectUtils.isNotEmpty(cell);
+                                                }
+                                            }
+                                        } else {
+                                            Row row = sheet.getRow(y1 - 1);
+                                            if (row != null) {
+                                                Cell cell = row.getCell(x1 - 1);
+                                                if (cell != null) {
+                                                    cell.setCellValue(myData);
+                                                } else {
+                                                    ObjectUtils.isNotEmpty(cell);
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                // 组装电签设置
+                List<TextdictInfo> textdictInfos = jdbcTemplate.query("select * from m_textdict_info where type in (2,6) and tab_id = " + aPrivate.getPKeyId(), new BeanPropertyRowMapper<>(TextdictInfo.class));
+                if (textdictInfos != null && !textdictInfos.isEmpty()) {
+                    //校验是否每个位置都能找到对应的人
+                    List<String> roleIds = textdictInfos.stream().map(l -> l.getSigRoleId()).collect(Collectors.toList());
+                    Map<String, TextdictInfo> roleMap = new HashMap<>();
+                    try {
+                        roleMap = textdictInfos.stream().collect(Collectors.toMap(l -> l.getSigRoleId(), l -> l));
+                    }catch (Exception e){
+                        throw new ServiceException("在审计咨询意见表单中,电签位置不能配置相同角色");
+                    }
+
+                    //获取这些人资料合同段下的权限
+                    List<JSONObject> userRoleList = this.saveUserInfoByProjectClient.queryUserContractRole(new ArrayList<>(flowIds.keySet()), contractId);
+                    if (userRoleList == null || userRoleList.size() == 0) {
+                        throw new ServiceException("电签时未找到审批人在合同段下的权限");
+                    }
+                    Map<Long,String> htmlDeptIdMap = new HashMap<>();
+                    //确保每一个配置了电签的位置都能签名,并且设置好DQID和实际电签信息之间的映射关系,以便在HTML中写入
+                    for (String roleId : roleIds) {
+                        boolean isRole = true;
+                        for (JSONObject userRole : userRoleList) {
+                            if (roleId.contains(userRole.getString("roleId"))) {
+                                List<User> userInfo = jdbcTemplate.query("select * from blade_user WHERE id =" + userRole.getString("userId"),new BeanPropertyRowMapper<>(User.class));
+                                if (userInfo.size() != 1){
+                                    throw new ServiceException("未找到"+flowIds.get(Long.valueOf(userRole.getString("roleId")))+"的用户信息");
+                                }
+                                User user = userInfo.get(0);
+                                sigUser.add(user);
+                                htmlDeptIdMap.put(roleMap.get(roleId).getId(),user.getName()+user.getPhone().substring(0,3));
+                                isRole = false;
+                                break;
+                            }
+                        }
+                        if (isRole){
+                            throw new ServiceException("当前审批人中,不存在:"+roleMap.get(roleId).getSigRoleName()+",无法电签,请查看后台配置");
+                        }
+                    }
+
+                    //修改输入框里面的值为电签标识
+                    for (TextdictInfo e : textdictInfos) {
+                        String key = e.getColKey();
+                        String[] keys = key.split("__");
+                        String[] trtd = keys[1].split("_");
+                        if (Integer.parseInt(trtd[0]) < trs.size()) {
+                            Element ytzData = trs.get(Integer.parseInt(trtd[0]));
+                            if (ytzData != null) {
+                                Elements tdsx = ytzData.select("td");
+                                if (Integer.parseInt(trtd[1]) < tdsx.size()) {
+                                    Element data = ytzData.select("td").get(Integer.parseInt(trtd[1]));
+                                    if (data.html().contains("el-tooltip")) {
+                                        data = data.children().get(0);
+                                    }
+                                    Elements children = data.children();
+                                    Element element = children.get(0);
+                                    int x1 = Integer.parseInt(data.children().get(0).attr("x1"));
+                                    if (x1 == 0) {
+                                        x1 = 1;
+                                    }
+                                    int y1 = Integer.parseInt(data.children().get(0).attr("y1"));
+
+                                    Row row = sheet.getRow(y1 - 1);
+                                    if (row != null) {
+                                        Cell cell = sheet.getRow(y1 - 1).getCell(x1 - 1);
+                                        if (cell != null) {
+                                            short fontIndex = cell.getCellStyle().getFontIndex();
+                                            Font oldfontAt = workbook.getFontAt(fontIndex);
+
+                                            Font redFont = workbook.createFont();
+                                            redFont.setColor(IndexedColors.WHITE.getIndex()); //设置字体颜色
+                                            redFont.setFontHeightInPoints(oldfontAt.getFontHeightInPoints());//设置字体大小
+                                            redFont.setFontName(oldfontAt.getFontName());//设置字体
+
+                                            CellStyle newStyle = workbook.createCellStyle(); //创建单元格样式
+                                            newStyle.cloneStyleFrom(cell.getCellStyle());
+                                            newStyle.setFont(redFont);
+                                            cell.setCellStyle(newStyle);
+                                            String sig = htmlDeptIdMap.get(e.getId());
+                                            cell.setCellValue(sig);
+                                        } else {
+                                            ObjectUtils.isNotEmpty(cell);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }else {
+                    throw new ServiceException("未找到审计意见的电签配置");
+                }
+            }
+        }
+
+        //输出流
+        FileOutputStream outputStream = new FileOutputStream(excelPath);
+
+
+
+        workbook.write(outputStream);
+
+        FileUtils.setExcelScaleToPdf(excelPath, pdfPath);
+        BladeFile bladeFile = newIOSSClient.uploadFile(pkeyId + ".pdf", pdfPath);
+
+        if (bladeFile != null) {
+            //获取所有专家个人证书
+            List<SignPfxFile> list = jdbcTemplate.query(" select * from m_sign_pfx_file where is_deleted = 0 and certificate_user_id in ("+sigUser.stream().map(User::getId).distinct().map(Objects::toString).collect(Collectors.joining(",")) +")", new BeanPropertyRowMapper<>(SignPfxFile.class));
+            if (list.size() == 0 || list.size() != sigUser.size()){
+                throw new ServiceException("有签字人没有配置电签,请联系管理员");
+            }
+            Map<Long, SignPfxFile> map = list.stream().collect(Collectors.toMap(l -> l.getCertificateUserId(), l -> l));
+            SigInfoVO vo = new SigInfoVO();
+            List<SigInfoVO.SigInfo> infos = new ArrayList<>();
+            for (User user : sigUser) {
+                SignPfxFile file = map.get(user.getId());
+                if (file == null){
+                    throw new ServiceException("未获取到专家:"+user.getName()+"的电签信息");
+                }
+                SigInfoVO.SigInfo info = new SigInfoVO.SigInfo();
+                info.setUserName(user.getName());
+                info.setUserSig(user.getName()+user.getPhone().substring(0,3));
+                info.setSealCode("S_NEW_"+file.getCertificatePassword());
+                info.setSealPassword(file.getCertificatePassword());
+                if (StringUtils.isBlank(file.getSignatureFileUrl())){
+                    throw new ServiceException("未获取到专家:"+user.getName()+"的签字图片");
+                }
+                info.setSigPic(file.getSignatureFileUrl());
+                infos.add(info);
+            }
+            vo.setList(infos);
+            vo.setPdfUrl(bladeFile.getLink());
+            R<String> r1 = eVisaClient.batchEVisa(vo);
+            if (r1.getCode() != 200 || StringUtils.isBlank(r1.getData())){
+                throw new ServiceException("咨询意见PDF电签时失败");
+            }
+            return r1.getData();
+        }else {
+            throw new ServiceException("生成咨询意见PDF时失败");
+        }
+
+    }
+
+    public Map<String,Object> getBussDataInfo(WbsTreePrivate aPrivate,Long taskId) {
+
+        Map<String, Object> reData = new HashMap<>();
+
+        //表单是否存储在
+        String tabName = aPrivate.getInitTableName();
+        String isExitSql = " select * from information_schema.TABLES where TABLE_NAME='" + tabName + "'";
+        List<Map<String, Object>> tabList = jdbcTemplate.queryForList(isExitSql);
+        if (tabList == null || tabList.size() <= 0) {
+            return reData;
+        }
+
+        String querySql = "select * from " + aPrivate.getInitTableName() + " where p_key_id=" + taskId;
+
+
+        //String querySql = "select * from table_data_info where p_key_id=" + pkeyId;
+        List<Map<String, Object>> dataIn = jdbcTemplate.queryForList(querySql);
+
+        if (dataIn != null && dataIn.size() >= 1) {
+            Map<String, Object> mysqlData = dataIn.get(0);
+            for (String key : mysqlData.keySet()) {
+                String tabVal = mysqlData.get(key) + "";
+                // 时间段处理
+                if (StringUtils.isNotEmpty(tabVal) && tabVal.indexOf("null") < 0) {
+                    if (tabVal.indexOf("T") >= 0 && tabVal.indexOf(".000Z]") >= 0) {
+                        String[] tabData = tabVal.split("_\\^_");
+
+                        if (reData.containsKey("pickerKey")) {
+                            String pickerKey = reData.get("pickerKey") + "," + key + "__" + tabData[1];
+                            reData.put("pickerKey", pickerKey);
+                        } else {
+                            reData.put("pickerKey", key + "__" + tabData[1]);
+                        }
+
+                        String sql = tabData[0];
+                        sql = sql.replaceAll("\\[", "['");
+                        sql = sql.replaceAll("]", "']");
+                        sql = sql.replaceAll("000Z,", "000Z',");
+                        sql = sql.replaceAll(", 20", ", '20");
+                        //   sql = sql.replaceAll("'", "");
+                        if (StringUtils.isNotEmpty(tabData[0])) {
+                            reData.put(key + "__" + tabData[1], sql);
+                        }
+                    } else if (tabVal.indexOf("T") >= 0 && tabVal.indexOf(".000Z") >= 0) { //时间
+                        // 时间和字符串合作
+                        if (tabVal.indexOf("☆") >= 0) {
+                            String[] mysql = tabVal.split("☆");
+                            for (String data : mysql) {
+                                String[] tabData = data.split("_\\^_");
+                                if (StringUtils.isNotEmpty(tabData[0])) {
+                                    reData.put(key + "__" + tabData[1], tabData[0]);
+                                }
+                            }
+                        } else {
+                            String[] tabData = tabVal.split("_\\^_");
+                            if (StringUtils.isNotEmpty(tabData[0])) {
+                                reData.put(key + "__" + tabData[1], tabData[0]);
+                            }
+                        }
+                    } else if (tabVal.indexOf("☆") >= 0) {
+                        String[] mysql = tabVal.split("☆");
+                        for (String data : mysql) {
+                            String[] tabData = data.split("_\\^_");
+                            if (StringUtils.isNotEmpty(tabData[0])) {
+                                reData.put(key + "__" + tabData[1], tabData[0]);
+                            }
+                        }
+                    } else if (tabVal.indexOf("_^_") >= 0) { //数组处理方式
+                        String[] tabData = tabVal.split("_\\^_");
+                        if (StringUtils.isNotEmpty(tabData[0])) {
+                            if (tabVal.contains("[") && tabVal.contains("年")) {
+                                String[] strings = StringUtils.strip(tabData[0], "[]").split(",");
+                                reData.put(key + "__" + tabData[1], strings);
+                            }if (tabVal.contains("[") && tabVal.contains("]") && tabVal.indexOf(",")>=0) {
+                                String[] strings = StringUtils.strip(tabData[0], "[]").split(",");
+                                reData.put(key + "__" + tabData[1], strings);
+                            } else {
+                                reData.put(key + "__" + tabData[1], tabData[0]);
+                            }
+                        }
+                    } else {
+                        reData.put(key, tabVal);
+                    }
+                }
+            }
+        }
+
+        return reData;
+    }
+
 }

+ 10 - 10
blade-service/blade-meter/src/main/java/org/springblade/meter/service/impl/MeterTreeContractServiceImpl.java

@@ -2189,16 +2189,16 @@ public class MeterTreeContractServiceImpl extends BaseServiceImpl<MeterTreeContr
                 throw new ServiceException("当前工程编号已经存在");
             }
         }
-        //校验如果为混泥土节点
-        if (dto.getIsConcreteNode() == 1){
-            if ( (dto.getSevenRatio() == null || dto.getTwentyEightRatio() == null)) {
-                throw new ServiceException("混泥土节点必须填写强度比例");
-            }
-            if ((dto.getSevenRatio().compareTo(BigDecimal.ZERO) < 0 || dto.getSevenRatio().compareTo(new BigDecimal("100")) > 0)
-                    || (dto.getTwentyEightRatio().compareTo(BigDecimal.ZERO) < 0 || dto.getTwentyEightRatio().compareTo(new BigDecimal("100")) > 0)){
-                throw new ServiceException("强度比例必须在0-100范围内");
-            }
-        }
+        //校验如果为混泥土节点,强度比例需求已经转移到合同信息了
+//        if (dto.getIsConcreteNode() == 1){
+//            if ( (dto.getSevenRatio() == null || dto.getTwentyEightRatio() == null)) {
+//                throw new ServiceException("混泥土节点必须填写强度比例");
+//            }
+//            if ((dto.getSevenRatio().compareTo(BigDecimal.ZERO) < 0 || dto.getSevenRatio().compareTo(new BigDecimal("100")) > 0)
+//                    || (dto.getTwentyEightRatio().compareTo(BigDecimal.ZERO) < 0 || dto.getTwentyEightRatio().compareTo(new BigDecimal("100")) > 0)){
+//                throw new ServiceException("强度比例必须在0-100范围内");
+//            }
+//        }
         //校验比例是否在范围之内
         if (dto.getUpPayRatio() == null){
         }else if (dto.getUpPayRatio().compareTo(BigDecimal.ZERO) < 0 || dto.getUpPayRatio().compareTo(new BigDecimal("100")) > 0){

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

@@ -0,0 +1,101 @@
+package org.springblade.meter.utils;
+
+import com.aspose.cells.SaveFormat;
+import org.apache.poi.hssf.usermodel.HSSFPrintSetup;
+import org.apache.poi.xssf.usermodel.XSSFPrintSetup;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.SystemUtils;
+import org.springblade.system.cache.ParamCache;
+
+import java.io.*;
+
+/**
+ * @Param
+ * @Author wangwl
+ * @Date 2024/5/14 16:44
+ **/
+public class FileUtils {
+    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;
+    }
+
+    public static void setExcelScaleToPdf(String inputPath, String outPath) {
+        //读取excel文件
+        XSSFWorkbook workbook = null;
+        ByteArrayOutputStream outReport = null, bos = null;
+        ByteArrayInputStream byteArrayInputStream = null;
+        try {
+            workbook = new XSSFWorkbook(new FileInputStream(inputPath));
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        OutputStream fos = null;
+        try {
+            for (int i = 0; i < workbook.getNumberOfSheets(); i++) {//获取每个Sheet表
+                XSSFSheet sheet = workbook.getSheetAt(i);
+                //打印设置
+                XSSFPrintSetup printSetup = sheet.getPrintSetup();
+                /*print.setLandscape(false); // 打印方向,true:横向,false:纵向(默认)
+                print.setFitHeight((short)0);//设置高度为自动分页
+                print.setFitWidth((short) 1);//设置宽度为一页
+                print.setPaperSize(HSSFPrintSetup.A4_EXTRA_PAPERSIZE); //纸张类型
+                print.setScale((short)100);//自定义缩放①,此处100为无缩放
+                //启用“适合页面”打印选项的标志
+                sheet.setFitToPage(true);*/
+
+                sheet.setHorizontallyCenter(true);//设置打印页面为水平居中
+                sheet.setVerticallyCenter(true);
+                sheet.setAutobreaks(true);
+                // printSetup.setLandscape(false);
+                sheet.setMargin(XSSFSheet.BottomMargin, (double) 0.1);// 页边距(下)
+                sheet.setMargin(XSSFSheet.LeftMargin, (double) 0.7);// 页边距(左)
+                sheet.setMargin(XSSFSheet.RightMargin, (double) 0.7);// 页边距(右)
+                sheet.setMargin(XSSFSheet.TopMargin, (double) 0.1);// 页边距(上)
+                printSetup.setScale((short) 100);//自定义缩放①,此处100为无缩放
+                System.out.print(sheet.getAutobreaks());
+                printSetup.setPaperSize(HSSFPrintSetup.A4_PAPERSIZE);
+                //  printSetup.setFitHeight((short) 1);//设置高度为自动分页
+                // printSetup.setFitWidth((short) 1);//设置宽度为一页
+                // sheet.setFitToPage(true);
+            }
+            // Excel文件生成后存储的位置。
+            outReport = new ByteArrayOutputStream();
+            workbook.write(outReport);
+            byteArrayInputStream = new ByteArrayInputStream(outReport.toByteArray());
+            com.aspose.cells.Workbook wb = new com.aspose.cells.Workbook(byteArrayInputStream);
+            File pdfFile = new File(outPath);
+            if (!pdfFile.exists()) {
+                pdfFile.mkdir();
+            }
+            wb.save(outPath, SaveFormat.PDF);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if (fos != null) {
+                try {
+                    fos.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+            if (workbook != null) {
+                try {
+                    workbook.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+}