Преглед изворни кода

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

# Conflicts:
#	blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
#	blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
#	blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
yangyj пре 1 година
родитељ
комит
576eecc71b
20 измењених фајлова са 445 додато и 170 уклоњено
  1. 2 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/OperationLogVO.java
  2. 7 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/SaveUserInfoByProjectClient.java
  3. 1 1
      blade-service-api/blade-user-api/src/main/java/org/springblade/system/user/feign/IUserClient.java
  4. 7 2
      blade-service/blade-business/src/main/java/org/springblade/business/controller/OperationLogController.java
  5. 4 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/OperationLogMapper.java
  6. 6 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/OperationLogMapper.xml
  7. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/UserOpinionFlowMapper.java
  8. 26 1
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/UserOpinionFlowMapper.xml
  9. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/IUserOpinionFlowService.java
  10. 20 7
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  11. 11 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/UserOpinionFlowServiceImpl.java
  12. 53 6
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/UserOpinionServiceImpl.java
  13. 134 117
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  14. 8 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/SaveUserInfoByProjectClientImpl.java
  15. 20 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProjectInfoMapper.xml
  16. 2 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IExcelTabService.java
  17. 91 17
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  18. 3 5
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java
  19. 34 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ProjectInfoServiceImpl.java
  20. 12 6
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

+ 2 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/OperationLogVO.java

@@ -47,4 +47,6 @@ public class OperationLogVO extends OperationLog {
     @ApiModelProperty("结束时间")
     private String endTime;
 
+    private Long contractId;
+
 }

+ 7 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/SaveUserInfoByProjectClient.java

@@ -20,6 +20,7 @@ public interface SaveUserInfoByProjectClient {
      */
     String SEARCH_USER_INFO_AND_PROJECT = "/api/manager/searchUserInfoAndProject";
     String SEARCH_USER_INFO_AND_PROJECT2 = "/api/manager/searchUserInfoAndProject2";
+    String SEARCH_USER_INFO_AND_PROJECT_BY_USER_IDS = "/api/manager/searchUserInfoAndProjectByUserIds";
     String QUERY_USER_CONTRACT_ROLE = "/api/manager/queryUserContractRole";
     String SAVE_INFO_RELATION = "/api/manager/saveInfoRelation";
 
@@ -38,6 +39,12 @@ public interface SaveUserInfoByProjectClient {
     @GetMapping(SEARCH_USER_INFO_AND_PROJECT2)
     List<SaveUserInfoByProjectDTO> searchUserInfoAndProject2(@RequestParam("userId") String userId);
 
+    /**
+     * 获取用户引用项目合同角色信息
+     */
+    @PostMapping(SEARCH_USER_INFO_AND_PROJECT_BY_USER_IDS)
+    List<SaveUserInfoByProjectDTO> searchUserInfoAndProjectByUserIds(@RequestBody List<Long> userIds);
+
     /**
      * 保存用户项目角色关联信息
      */

+ 1 - 1
blade-service-api/blade-user-api/src/main/java/org/springblade/system/user/feign/IUserClient.java

@@ -171,7 +171,7 @@ public interface IUserClient {
     @GetMapping(USER_INFO_ALL)
     List<User> selectUserAll();
 
-    @GetMapping(USER_LIST_INFO_BY_IDS)
+    @PostMapping(USER_LIST_INFO_BY_IDS)
     List<User> userInfoByIds(@RequestBody List<Long> userIds);
 
     @PostMapping(SAVE_USER_DTO)

+ 7 - 2
blade-service/blade-business/src/main/java/org/springblade/business/controller/OperationLogController.java

@@ -17,6 +17,7 @@
 package org.springblade.business.controller;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
@@ -25,6 +26,7 @@ import lombok.AllArgsConstructor;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.time.DateUtils;
 import org.jetbrains.annotations.NotNull;
+import org.springblade.business.mapper.OperationLogMapper;
 import org.springblade.business.wrapper.OperationLogWrapper;
 import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
@@ -60,6 +62,8 @@ public class OperationLogController extends BladeController {
 
     private final IDictBizClient dictBizClient;
 
+    private final OperationLogMapper logMapper;
+
 
 
     /**
@@ -156,8 +160,9 @@ public class OperationLogController extends BladeController {
         }
 
 
-
-        IPage<OperationLog> pages = operationLogService.page(Condition.getPage(query), wrapper.lambda().orderBy(true, false, OperationLog::getCreateTime));
+        IPage<OperationLog> pages = new Page<>(query.getCurrent(),query.getSize());
+//        IPage<OperationLog> pages = operationLogService.page(Condition.getPage(query), wrapper.lambda().orderBy(true, false, OperationLog::getCreateTime));
+        pages = logMapper.getPage(pages,operationLog);
 
         //获取业务字典
         List<DictBiz> dictBizList = this.dictBizClient.getList("operation_type", "notRoot").getData();

+ 4 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/OperationLogMapper.java

@@ -16,9 +16,11 @@
  */
 package org.springblade.business.mapper;
 
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.apache.ibatis.annotations.Param;
 import org.springblade.business.entity.OperationLog;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springblade.business.vo.OperationLogVO;
 
 import java.util.List;
 
@@ -37,4 +39,6 @@ public interface OperationLogMapper extends BaseMapper<OperationLog> {
     List<String> queryBusinessModule(@Param("userId") Long userId);
 
     Long getAdminId();
+
+    IPage<OperationLog> getPage(IPage<OperationLog> pages,@Param("vo") OperationLogVO operationLog);
 }

+ 6 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/OperationLogMapper.xml

@@ -52,5 +52,11 @@
     <select id="getAdminId" resultType="java.lang.Long">
         select id from blade_role WHERE role_name = '超级管理员'
     </select>
+    <select id="getPage" resultType="org.springblade.business.entity.OperationLog">
+        select *
+        from u_operation_log uol where is_deleted = 0
+        and (SELECT contract_id from m_wbs_tree_contract WHERE p_key_id = SUBSTRING_INDEX(uol.business_id,",",1)) = #{vo.contractId}
+        order by uol.create_time desc
+    </select>
 
 </mapper>

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

@@ -48,4 +48,6 @@ public interface UserOpinionFlowMapper extends BaseMapper<UserOpinionFlow> {
      */
     List<UserOpinionFlowVO> selectUserOpinionFlowPage(IPage page, UserOpinionFlowVO userOpinionFlow);
 
+    List<UserOpinionFlow> queryUserOpinionFlowsByConcatenatedIds(List<String> list);
+
 }

+ 26 - 1
blade-service/blade-business/src/main/java/org/springblade/business/mapper/UserOpinionFlowMapper.xml

@@ -123,7 +123,8 @@
                manage_time,
                reply_name,
                reply_content,
-               is_current
+               is_current,
+               number
         from u_user_opinion_flow
         where is_deleted = 0
           and user_opinion_id = #{key}
@@ -145,4 +146,28 @@
         select * from u_user_opinion_flow where is_deleted = 0
     </select>
 
+    <select id="queryUserOpinionFlowsByConcatenatedIds" resultMap="userOpinionFlowResultMap">
+        SELECT  id,
+                user_opinion_id,
+                evaluation,
+                manage_user,
+                manage_user_name,
+                manage_user_phone,
+                sort,
+                manage_time,
+                reply_name,
+                reply_content,
+                is_current,
+                number
+        FROM u_user_opinion_flow
+        WHERE is_deleted = 0
+        AND (
+                <foreach collection="list" item="item" separator=" OR " open="" close="">
+                    CONCAT(user_opinion_id, '___', number) = #{item}
+                </foreach>
+             )
+        ORDER BY sort ASC
+    </select>
+
+
 </mapper>

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

@@ -53,4 +53,6 @@ public interface IUserOpinionFlowService extends BaseService<UserOpinionFlow> {
 
     Integer selectIsSolveByUserOpinionKey(Long userOpinionKey);
 
+    List<UserOpinionFlowVO> queryUserOpinionFlowsByConcatenatedIds(List<String> concatenatedList);
+
 }

+ 20 - 7
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java

@@ -23,6 +23,7 @@ import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.*;
 import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.entity.ContractRelationJlyz;
@@ -359,7 +360,20 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
                                                    Integer classify, Integer sourceType,
                                                    String isFirst, String sourceUrl,
                                                    String pdfUrl, String firstFileName, List<JSONObject> linkDataList) {
-        BladeUser user = AuthUtil.getUser();
+        Long userId = 0L ;
+        String userNmae ="";
+
+        if(primaryKeyId.indexOf(":")>=0){
+           String prdata[] = primaryKeyId.split(":");
+            primaryKeyId = prdata[0];
+            userId = Long.parseLong(prdata[1]);
+            R<User> userR = userClient.userInfoById(userId);
+            userNmae = userR.getData().getName();
+        }else{
+            BladeUser user = AuthUtil.getUser();
+            userId = user.getUserId();
+            userNmae = user.getNickName();
+        }
 
         if (StringUtils.isNotEmpty(isFirst) && "true".equals(isFirst)) {
             return this.saveOrUpdateFirstInformationQueryData(primaryKeyId, tableId, businessId, fileName, classify, sourceType, sourceUrl, pdfUrl, firstFileName, linkDataList);
@@ -377,9 +391,9 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
                 }
 
                 //拼接填报人信息
-                String fileUser = user.getUserId() + "-" + user.getNickName();
+                String fileUser = userId + "-" + userNmae;
                 if (StringUtils.isNotEmpty(oldData.getFileUserIdAndName())) {
-                    if (!oldData.getFileUserIdAndName().contains(user.getUserId().toString())) {
+                    if (!oldData.getFileUserIdAndName().contains(userId.toString())) {
                         //不包含,拼接
                         oldData.setFileUserIdAndName(oldData.getFileUserIdAndName() + "," + fileUser);
                     }
@@ -388,7 +402,7 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
                 }
 
                 oldData.setUpdateTime(new Date());
-                oldData.setUpdateUser(user.getUserId());
+                oldData.setUpdateUser(userId);
 
                 List<String> linkIds = linkDataList.stream().map(json -> json.getString("id")).distinct().collect(Collectors.toList());
                 if (linkIds.size() > 0) {
@@ -419,17 +433,16 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
                 //流程状态,默认未上报
                 newData.setStatus(0);
                 //填报人ID及姓名
-                newData.setFileUserIdAndName(user.getUserId() + "-" + user.getNickName());
+                newData.setFileUserIdAndName(userId + "-" + userNmae);
                 //数据源类型
                 newData.setSourceType(sourceType);
-                newData.setCreateUser(user.getUserId());
+                newData.setCreateUser(userId);
                 newData.setCreateTime(new Date());
 
                 List<String> linkIds = linkDataList.stream().map(json -> json.getString("id")).distinct().collect(Collectors.toList());
                 if (linkIds.size() > 0) {
                     newData.setSjRecordIds(StringUtils.join(linkIds, ","));
                 }
-
                 //保存数据
                 this.baseMapper.insert(newData);
             }

+ 11 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/UserOpinionFlowServiceImpl.java

@@ -69,4 +69,15 @@ public class UserOpinionFlowServiceImpl extends BaseServiceImpl<UserOpinionFlowM
         return this.baseMapper.selectIsSolveByUserOpinionKey(userOpinionKey);
     }
 
+    @Override
+    public List<UserOpinionFlowVO> queryUserOpinionFlowsByConcatenatedIds(List<String> concatenatedList) {
+        List<UserOpinionFlow> result = this.baseMapper.queryUserOpinionFlowsByConcatenatedIds(concatenatedList);
+        List<UserOpinionFlowVO> resultVo = JSONArray.parseArray(JSONObject.toJSONString(result), UserOpinionFlowVO.class);
+        resultVo.forEach(vo -> {
+            vo.setCurrent(new Integer("1").equals(vo.getIsCurrent()));
+            vo.setCurrentBol(new Integer("2").equals(vo.getIsCurrent()));
+        });
+        return resultVo;
+    }
+
 }

+ 53 - 6
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/UserOpinionServiceImpl.java

@@ -1,6 +1,7 @@
 package org.springblade.business.service.impl;
 
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -23,13 +24,17 @@ import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.manager.dto.SaveUserInfoByProjectDTO;
 import org.springblade.manager.feign.SaveUserInfoByProjectClient;
+import org.springblade.system.entity.Role;
 import org.springblade.system.feign.ISysClient;
 import org.springblade.system.user.entity.User;
 import org.springblade.system.user.feign.IUserClient;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 
 import java.util.*;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 /**
@@ -56,6 +61,8 @@ public class UserOpinionServiceImpl extends BaseServiceImpl<UserOpinionMapper, U
 
     private final SaveUserInfoByProjectClient saveUserInfoByProjectClient;
 
+    private final JdbcTemplate jdbcTemplate;
+
     @Override
     public Integer getOpinionNumber(String userId) {
         return this.baseMapper.getOpinionNumber(userId);
@@ -85,6 +92,34 @@ public class UserOpinionServiceImpl extends BaseServiceImpl<UserOpinionMapper, U
             List<Long> userOpinionKeys = finalResult.stream().map(BusinessUserOpinionVO::getUserOpinionId).distinct().collect(Collectors.toList());
             List<UserOpinionFile> allFile = this.userOpinionFileService.selectUserOpinionFileByUserOpinionKeys(userOpinionKeys);
 
+            /*所有工单最新状态userOpinionFlowGroupMap*/
+            List<String> concatenatedList = finalResult.stream()
+                    .filter(obj -> ObjectUtil.isNotEmpty(obj.getUserOpinionId()) && ObjectUtil.isNotEmpty(obj.getNewNumber()))
+                    .map(obj -> obj.getUserOpinionId() + "___" + obj.getNewNumber())
+                    .map(String::valueOf)
+                    .collect(Collectors.toList());
+            List<UserOpinionFlowVO> UserOpinionFlowVOList = this.userOpinionFlowService.queryUserOpinionFlowsByConcatenatedIds(concatenatedList);
+            Map<String, List<UserOpinionFlowVO>> userOpinionFlowGroupMap = UserOpinionFlowVOList.stream()
+                    .filter(vo -> Objects.nonNull(vo.getUserOpinionId()) && Objects.nonNull(vo.getNumber()))
+                    .collect(Collectors.groupingBy(
+                            vo -> vo.getUserOpinionId() + vo.getNumber() + ""
+                    ));
+
+            /*获取所有提交人userOpinionMap*/
+            List<UserOpinion> userOpinionList = this.getBaseMapper().selectBatchIds(userOpinionKeys);
+            Map<Long, UserOpinion> userOpinionMap = userOpinionList.stream().collect(Collectors.toMap(UserOpinion::getId, Function.identity()));
+
+            /*获取创建人信息userMap*/
+            List<Long> createUserIds = userOpinionList.stream().map(UserOpinion::getCreateUser).collect(Collectors.toList());
+            List<User> userList = this.userClient.userInfoByIds(createUserIds);
+            Map<Long, User> userMap = userList.stream().distinct().collect(Collectors.toMap(User::getId, Function.identity()));
+
+            /*获取用户与项目关系信息saveUserInfoByProjectGroupMap*/
+            Map<String, List<SaveUserInfoByProjectDTO>> saveUserInfoByProjectGroupMap = this.saveUserInfoByProjectClient.searchUserInfoAndProjectByUserIds(createUserIds).stream().collect(Collectors.groupingBy(SaveUserInfoByProjectDTO::getUserId));
+
+            /*获取角色信息roleMap*/
+            Map<Long, Role> roleMap = jdbcTemplate.query("SELECT id,role_name FROM blade_role WHERE is_deleted = 0", new BeanPropertyRowMapper<>(Role.class)).stream().collect(Collectors.toMap(Role::getId, Function.identity()));
+
             //设置附件信息
             finalResult.forEach(vo -> {
                 List<String> imageUrls = new ArrayList<>();
@@ -103,7 +138,8 @@ public class UserOpinionServiceImpl extends BaseServiceImpl<UserOpinionMapper, U
                 vo.setImageUrl(imageUrls);
 
                 //获取当前工单最新状态
-                List<UserOpinionFlowVO> newFlow = this.userOpinionFlowService.queryCurrentUserOpinionFlowByUserOpinionId(String.valueOf(vo.getUserOpinionId()), vo.getNewNumber());
+                /*List<UserOpinionFlowVO> newFlow = this.userOpinionFlowService.queryCurrentUserOpinionFlowByUserOpinionId(String.valueOf(vo.getUserOpinionId()), vo.getNewNumber());*/
+                List<UserOpinionFlowVO> newFlow = userOpinionFlowGroupMap.getOrDefault(vo.getUserOpinionId() + vo.getNewNumber() + "", null);
                 if (newFlow != null && newFlow.size() > 0) {
                     //获取退后阶段
                     UserOpinionFlowVO flow = newFlow.get(3);
@@ -156,13 +192,16 @@ public class UserOpinionServiceImpl extends BaseServiceImpl<UserOpinionMapper, U
                 }
 
                 //获取提交人
-                UserOpinion opinion = this.getById(vo.getUserOpinionId());
+                //UserOpinion opinion = this.getById(vo.getUserOpinionId());
+                UserOpinion opinion = userOpinionMap.getOrDefault(vo.getUserOpinionId(), null);
                 if (opinion != null) {
                     vo.setSubmitUserName(opinion.getCreateUserName());
-                    User user = this.userClient.userInfoById(opinion.getCreateUser()).getData();
+                    //User user = this.userClient.userInfoById(opinion.getCreateUser()).getData();
+                    User user = userMap.getOrDefault(opinion.getCreateUser(), null);
                     if (user != null) {
                         vo.setSubmitPhone(user.getPhone());
-                        List<SaveUserInfoByProjectDTO> userRoleList = this.saveUserInfoByProjectClient.searchUserInfoAndProject2(opinion.getCreateUser().toString());
+                        //List<SaveUserInfoByProjectDTO> userRoleList = this.saveUserInfoByProjectClient.searchUserInfoAndProject2(opinion.getCreateUser().toString());
+                        List<SaveUserInfoByProjectDTO> userRoleList = saveUserInfoByProjectGroupMap.getOrDefault(opinion.getCreateUser().toString(), null);
                         //用户角色
                         String roleIds = user.getRoleId();
                         if (userRoleList != null && userRoleList.size() > 0) {
@@ -172,8 +211,16 @@ public class UserOpinionServiceImpl extends BaseServiceImpl<UserOpinionMapper, U
                                 roleIds = userRoleList.stream().map(SaveUserInfoByProjectDTO::getRoleId).distinct().collect(Collectors.joining(","));
                             }
                         }
-                        List<String> roleNames = this.sysClient.getRoleNames(roleIds).getData();
-                        if (roleNames != null && roleNames.size() > 0) {
+
+                        List<String> roleNames = new ArrayList<>();
+                        for (String roleId : roleIds.split(",")) {
+                            Role role = roleMap.getOrDefault(Long.parseLong(roleId), null);
+                            if (role != null) {
+                                roleNames.add(role.getRoleName());
+                            }
+                        }
+                        //List<String> roleNames = this.sysClient.getRoleNames(roleIds).getData();
+                        if (/*roleNames != null &&*/ roleNames.size() > 0) {
                             vo.setSubmitUserRole(String.join(",", roleNames));
                         }
                     }

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

@@ -64,6 +64,8 @@ import org.springblade.resource.feign.IOSSClient;
 import org.springblade.resource.feign.NewIOSSClient;
 import org.springblade.resource.vo.NewBladeFile;
 import org.springblade.system.cache.ParamCache;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.transaction.annotation.Transactional;
@@ -117,15 +119,12 @@ public class ExcelTabController extends BladeController {
     // 元素信息表-
     private final IWbsTreeContractService wbsTreeContractService;
 
-    private final WbsTreeContractServiceImpl wbsTreeContractServiceImpl;
-
     private final WbsTreePrivateMapper wbsTreePrivateMapper;
 
     private final JdbcTemplate jdbcTemplate;
 
     private final ExcelTabMapper excelTabMapper;
 
-
     // 表单附件信息
     private final ITableFileService tableFileService;
 
@@ -148,6 +147,8 @@ public class ExcelTabController extends BladeController {
 
     private final IWbsParamService wbsParamService;
 
+    @Autowired
+    StringRedisTemplate RedisTemplate;
 
     /**
      * 详情
@@ -624,7 +625,7 @@ public class ExcelTabController extends BladeController {
     @ApiImplicitParams(value = {
             @ApiImplicitParam(name = "pkeyId", value = "pkeyId", required = true)
     })
-    public R getExcelHtmlByBuss(Long pkeyId) throws Exception {
+    public R getExcelHtmlByBuss(Long pkeyId){
 
         WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
                 .eq(WbsTreeContract::getPKeyId, pkeyId));
@@ -635,74 +636,75 @@ public class ExcelTabController extends BladeController {
             return R.fail("暂无表单!");
         }
 
-        String fileUrl = wbsTreeContract.getHtmlUrl();
-        InputStream fileInputStream = FileUtils.getInputStreamByUrl(fileUrl);
-
-        String htmlString = IoUtil.readToString(fileInputStream);
-        htmlString = htmlString.replaceAll("placeholder", "placeholderxx");
-        htmlString = htmlString.replaceAll("title", "titlexx");
-
-        // 远程搜索配置
-        Document doc = Jsoup.parse(htmlString);
-        int maxCol = doc.select("Col").size();
-        Element table = doc.select("table").first();
-        Elements hc = doc.select("hc-form-select-search");
-        if (hc.size() >= 1) {
-            for (int i = 0; i < hc.size(); i++) {
-                Element datax = hc.get(i);
-                datax.removeAttr("pkeyId");
-                datax.removeAttr("contractId");
-                datax.attr("pkeyId", pkeyId + "");
-                datax.attr("contractId", wbsTreeContract.getContractId());
+        try {
+            String fileUrl = wbsTreeContract.getHtmlUrl();
+            InputStream fileInputStream = FileUtils.getInputStreamByUrl(fileUrl);
+
+            String htmlString = IoUtil.readToString(fileInputStream);
+            htmlString = htmlString.replaceAll("placeholder", "placeholderxx");
+            htmlString = htmlString.replaceAll("title", "titlexx");
+
+            // 远程搜索配置
+            Document doc = Jsoup.parse(htmlString);
+            int maxCol = doc.select("Col").size();
+            Element table = doc.select("table").first();
+            Elements hc = doc.select("hc-form-select-search");
+            if (hc.size() >= 1) {
+                for (int i = 0; i < hc.size(); i++) {
+                    Element datax = hc.get(i);
+                    datax.removeAttr("pkeyId");
+                    datax.removeAttr("contractId");
+                    datax.attr("pkeyId", pkeyId + "");
+                    datax.attr("contractId", wbsTreeContract.getContractId());
+                }
             }
-        }
 
-        // 远程搜索配置2-设计强度搜索
-        Elements hc2 = doc.select("hc-form-select-search2");
-        if (hc2.size() >= 1) {
-            for (int i = 0; i < hc2.size(); i++) {
-                Element datax = hc2.get(i);
-                datax.removeAttr("contractId");
-                datax.attr("contractId", wbsTreeContract.getContractId());
+            // 远程搜索配置2-设计强度搜索
+            Elements hc2 = doc.select("hc-form-select-search2");
+            if (hc2.size() >= 1) {
+                for (int i = 0; i < hc2.size(); i++) {
+                    Element datax = hc2.get(i);
+                    datax.removeAttr("contractId");
+                    datax.attr("contractId", wbsTreeContract.getContractId());
+                }
             }
-        }
 
-        // 标题解决
-        ProjectInfo projectInfo = projectInfoService.getById(wbsTreeContract.getProjectId());
-        //判断是否是水利水电表,水利水电项目名14,表名12 。   其他表都是18
-        Boolean isWater = false;
-        ExcelTab tab = excelTabMapper.getWaterByTableId(wbsTreeContract.getExcelId());
-        if (tab != null) {
-            isWater = true;
-        }
+            // 标题解决
+            ProjectInfo projectInfo = projectInfoService.getById(wbsTreeContract.getProjectId());
+            //判断是否是水利水电表,水利水电项目名14,表名12 。   其他表都是18
+            Boolean isWater = false;
+            ExcelTab tab = excelTabMapper.getWaterByTableId(wbsTreeContract.getExcelId());
+            if (tab != null) {
+                isWater = true;
+            }
 
-        // 添加标题显示
-        Elements trs = table.select("tr");
-        for (int i = 1; i < 6; i++) {
-            Element tr = trs.get(i);
-            Elements tds = tr.select("td");
-            for (int j = 0; j < tds.size(); j++) {
-                Element data = tds.get(j);
-                int colspan = data.attr("COLSPAN").equals("") ? 0 : Integer.parseInt(data.attr("COLSPAN"));
-                String style = data.attr("style");
-                if (style.indexOf("font-size") >= 0) {
-                    int fontsize = Integer.parseInt(style.substring(style.indexOf("font-size:") + 10, style.indexOf(".0pt")));
-                    if (isWater) {
-                        if (StringUtils.isNotEmpty(data.text()) && fontsize >= 12) {
-                            trs.get(i - 1).select("td").get(0).text(projectInfo.getProjectName());
-                        }
-                    } else {
-                        if (StringUtils.isNotEmpty(data.text()) && fontsize >= 14) {
-                            trs.get(i - 1).select("td").get(0).text(projectInfo.getProjectName());
+            // 添加标题显示
+            Elements trs = table.select("tr");
+            for (int i = 1; i < 6; i++) {
+                Element tr = trs.get(i);
+                Elements tds = tr.select("td");
+                for (int j = 0; j < tds.size(); j++) {
+                    Element data = tds.get(j);
+                    int colspan = data.attr("COLSPAN").equals("") ? 0 : Integer.parseInt(data.attr("COLSPAN"));
+                    String style = data.attr("style");
+                    if (style.indexOf("font-size") >= 0) {
+                        int fontsize = Integer.parseInt(style.substring(style.indexOf("font-size:") + 10, style.indexOf(".0pt")));
+                        if (isWater) {
+                            if (StringUtils.isNotEmpty(data.text()) && fontsize >= 12) {
+                                trs.get(i - 1).select("td").get(0).text(projectInfo.getProjectName());
+                            }
+                        } else {
+                            if (StringUtils.isNotEmpty(data.text()) && fontsize >= 14) {
+                                trs.get(i - 1).select("td").get(0).text(projectInfo.getProjectName());
+                            }
                         }
                     }
                 }
             }
-        }
 
-        // 获取公式颜色
-        String tabName = wbsTreeContract.getInitTableName();
-        // 字段查询 获取公式字段
+            // 获取公式颜色
+            String tabName = wbsTreeContract.getInitTableName();
+            // 字段查询 获取公式字段
 //        String colkeys = "SELECT e_key from m_table_info a ,m_wbs_form_element b WHERE a.tab_en_name = '" + tabName + "' and a.id=b.f_id and b.id  in(SELECT element_id from m_element_formula_mapping c where c.is_deleted=0) ";
 //
 //        List<Map<String, Object>> maps = jdbcTemplate.queryForList(colkeys);
@@ -723,16 +725,19 @@ public class ExcelTabController extends BladeController {
 //                }
 //            }
 //        }
-        WbsTreeContract process = this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery()
-                .eq(WbsTreeContract::getId, wbsTreeContract.getParentId())
-                .eq(WbsTreeContract::getContractId, wbsTreeContract.getContractId())
-                .eq(WbsTreeContract::getWbsId, wbsTreeContract.getWbsId()).last("limit 1"));
-        if (process != null) {
-            this.excelTabService.gsColor(pkeyId, process.getPKeyId().toString(), wbsTreeContract.getProjectId(), doc);
+            WbsTreeContract process = this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery()
+                    .eq(WbsTreeContract::getId, wbsTreeContract.getParentId())
+                    .eq(WbsTreeContract::getContractId, wbsTreeContract.getContractId())
+                    .eq(WbsTreeContract::getWbsId, wbsTreeContract.getWbsId()).last("limit 1"));
+            if (process != null) {
+                this.excelTabService.gsColor(pkeyId, process.getPKeyId().toString(), wbsTreeContract.getProjectId(), doc);
+            }
+            doc.select("Col").remove();
+            fileInputStream.close();
+            return R.data(table + "");
+        }catch (Exception e){
+            return R.fail("暂无表单!");
         }
-        doc.select("Col").remove();
-        fileInputStream.close();
-        return R.data(table + "");
     }
 
 
@@ -1815,7 +1820,7 @@ public class ExcelTabController extends BladeController {
             @ApiImplicitParam(name = "pkeyId", value = "pkeyId", required = true)
     })
     public R getBussDataInfo(Long pkeyId) throws FileNotFoundException {
-        return excelTabService.getBussDataInfo(pkeyId, 0);
+        return R.data(excelTabService.getBussDataInfo(pkeyId, 0));
     }
 
 
@@ -2011,6 +2016,12 @@ public class ExcelTabController extends BladeController {
     })
     public R getPdfS(String nodeId, String classify, String contractId) throws FileNotFoundException {
         String file_path = FileUtils.getSysLocalFileUrl();
+        Boolean aBoolean = RedisTemplate.hasKey("pdf-" + nodeId+"-"+classify);
+        if(aBoolean){
+            Long expire = RedisTemplate.getExpire("pdf-" + nodeId + "-" + classify);
+            return R.fail("pdf正在生成,还有"+expire+"秒");
+        }
+
         //获取节点下的所有表单,和附件,如果表单全是隐藏的,并且没有附件,则提示暂无数据
         String sql = "select pdf_url,e_visa_pdf_url,pdf_trial_url,pdf_trial_url_position,status from u_information_query where classify='" + classify + "' and wbs_id='" + nodeId + "' and contract_id='" + contractId + "'";
         List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
@@ -2106,7 +2117,7 @@ public class ExcelTabController extends BladeController {
     }
 
 
-    @PostMapping("/save_buss_data")
+    @PostMapping("/save_buss_data111")
     @ApiOperationSupport(order = 13)
     @ApiOperation(value = "填报页面数据保存", notes = "填报页面数据保存")
     public R saveBussData2(@Valid @RequestBody JSONObject dataInfo) throws Exception {
@@ -2175,6 +2186,7 @@ public class ExcelTabController extends BladeController {
         if (tableInfoList != null) {
             for (TableInfo tableInfo : tableInfoList) {
                 R bussPdfInfo = excelTabService.getBussPdfInfo(Long.parseLong(tableInfo.getPkeyId()));
+
                 if (ObjectUtil.isEmpty(bussPdfInfo) || bussPdfInfo.getCode() != 200) {
                     //如果返回的单张pdfUrl为空,那么表示发生异常,返回异常信息
                     errorPKeyIds.add(tableInfo.getPkeyId());
@@ -3541,7 +3553,7 @@ public class ExcelTabController extends BladeController {
     @ApiImplicitParams(value = {
             @ApiImplicitParam(name = "pkeyId", value = "pkeyId", required = true)
     })
-    public R getHtmlBussCols(Long pkeyId) throws Exception {
+    public R getHtmlBussCols(Long pkeyId)  {
         String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
         String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
         WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
@@ -3552,51 +3564,54 @@ public class ExcelTabController extends BladeController {
         if (wbsTreeContract.getHtmlUrl() == null) {
             return R.fail("暂无表单!");
         }
+        try {
+            String fileUrl = wbsTreeContract.getHtmlUrl();
+            File file1 = ResourceUtil.getFile(fileUrl);
+            InputStream fileInputStream = null;
+            if (file1.exists()) {
+                fileInputStream = new FileInputStream(file1);
+            } else {
+                String path = sys_file_net_url + fileUrl.replaceAll("//", "/").replaceAll(file_path, "");
+                fileInputStream = CommonUtil.getOSSInputStream(path);
+            }
 
-        String fileUrl = wbsTreeContract.getHtmlUrl();
-        File file1 = ResourceUtil.getFile(fileUrl);
-        InputStream fileInputStream = null;
-        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);
-        // 解析 style
-        Document doc = Jsoup.parse(htmlString);
-        Element table = doc.select("table").first();
-        Elements trs = table.select("tr");
 
-        List<List<String>> redata = new ArrayList<>();
-        for (int i = 0; i < trs.size(); i++) {
-            Element tr = trs.get(i);
-            Elements tds = tr.select("td");
-            List<String> tdList = new ArrayList<>();
-            for (int j = 0; j < tds.size(); j++) {
-                Element element = tds.get(j);
-                if (element.html().indexOf("el-tooltip") >= 0) {
-                    element = element.children().get(0);
-                }
-                if (element.children().size() >= 1) {
-                    String keyname = element.children().get(0).attr("keyname");
-                    if (StringUtils.isNotEmpty(keyname)) {
-                        tdList.add(keyname);
+            String htmlString = IoUtil.readToString(fileInputStream);
+            // 解析 style
+            Document doc = Jsoup.parse(htmlString);
+            Element table = doc.select("table").first();
+            Elements trs = table.select("tr");
+
+            List<List<String>> redata = new ArrayList<>();
+            for (int i = 0; i < trs.size(); i++) {
+                Element tr = trs.get(i);
+                Elements tds = tr.select("td");
+                List<String> tdList = new ArrayList<>();
+                for (int j = 0; j < tds.size(); j++) {
+                    Element element = tds.get(j);
+                    if (element.html().indexOf("el-tooltip") >= 0) {
+                        element = element.children().get(0);
+                    }
+                    if (element.children().size() >= 1) {
+                        String keyname = element.children().get(0).attr("keyname");
+                        if (StringUtils.isNotEmpty(keyname)) {
+                            tdList.add(keyname);
+                        }
                     }
                 }
+                if (tdList != null && tdList.size() >= 1) {
+                    redata.add(tdList);
+                }
             }
-            if (tdList != null && tdList.size() >= 1) {
-                redata.add(tdList);
-            }
-        }
 
-        String[][] res = new String[redata.size()][]; // 存放转换结果的 二维数组
-        for (int i = 0; i < res.length; i++) { // 转换方法
-            res[i] = redata.get(i).toArray(new String[redata.get(i).size()]);
+            String[][] res = new String[redata.size()][]; // 存放转换结果的 二维数组
+            for (int i = 0; i < res.length; i++) { // 转换方法
+                res[i] = redata.get(i).toArray(new String[redata.get(i).size()]);
+            }
+            return R.data(res);
+        }catch (Exception e){
+            return R.fail("暂无表单!");
         }
-        return R.data(res);
     }
 
 
@@ -3843,7 +3858,7 @@ public class ExcelTabController extends BladeController {
      * @return
      * @throws Exception
      */
-    @PostMapping("/save_buss_data2")
+    @PostMapping("/save_buss_data")
     @ApiOperationSupport(order = 13)
     @ApiOperation(value = "填报页面数据保存", notes = "填报页面数据保存")
     public R saveBussData(@Valid @RequestBody JSONObject dataInfo) throws Exception {
@@ -3855,7 +3870,11 @@ public class ExcelTabController extends BladeController {
             dataArray.add(dataInfo);
         }
         this.excelTabService.formulaFillData2(dataArray, ExecuteType.INSPECTION);
-        return excelTabService.saveBussData(dataArray);
+        if(dataArray!=null && dataArray.size()>=1){
+            return excelTabService.saveBussData(dataArray);
+        }else{
+            return R.fail("公式报错,导致保存接口无入参数");
+        }
     }
 
 
@@ -3896,7 +3915,6 @@ public class ExcelTabController extends BladeController {
         } else {
             return R.data("请上传pdf");
         }
-
     }
 
 
@@ -3937,8 +3955,7 @@ public class ExcelTabController extends BladeController {
                 if (tableAll != null && tableAll.size() >= 1) {
                     for (AppWbsTreeContractVO tab : tableAll) {
                         try {
-                            R bussDataInfo = excelTabService.getBussDataInfo(tab.getPKeyId(), 0);
-                            Map<String, Object> jo = (Map<String, Object>) bussDataInfo.getData();
+                            Map<String, Object> jo = excelTabService.getBussDataInfo(tab.getPKeyId(), 0);
                             String s = new Gson().toJson(jo);
                             //字符串转jsonobject
                             JSONObject obj = JSON.parseObject(s);

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

@@ -45,6 +45,14 @@ public class SaveUserInfoByProjectClientImpl implements SaveUserInfoByProjectCli
         );
     }
 
+    @Override
+    public List<SaveUserInfoByProjectDTO> searchUserInfoAndProjectByUserIds(List<Long> userIds) {
+        return saveUserInfoByProjectService.list(
+                Wrappers.<SaveUserInfoByProjectDTO>query().lambda()
+                        .in(SaveUserInfoByProjectDTO::getUserId, userIds)
+        );
+    }
+
     @Override
     public void saveInfoRelation(Long userId, Long projectId, Long contractId, Long roleId) {
         SaveUserInfoByProjectDTO obj = new SaveUserInfoByProjectDTO();

+ 20 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/ProjectInfoMapper.xml

@@ -56,7 +56,7 @@
     </resultMap>
 
     <select id="queryProjectUserAmount" resultMap="projectUserAmount">
-        select mpi.project_alias,
+        /*select mpi.project_alias,
                (select COUNT(DISTINCT user_id) end
         from m_project_assignment_user
         where is_deleted = 0
@@ -87,7 +87,25 @@
            or parent_id =
             '1537246243393589249'))) as owner
         from
-            m_project_info as mpi
+            m_project_info as mpi*/
+
+        SELECT
+            mpi.project_alias,
+            mpi.create_time,
+            COUNT(DISTINCT CASE WHEN m.role_id = '1537247986361782274' OR r1.parent_id = '1537247986361782274' THEN m.user_id END) AS contractor,
+            COUNT(DISTINCT CASE WHEN m.role_id = '1537246384519335938' OR r2.parent_id = '1537246384519335938' THEN m.user_id END) AS supervision,
+            COUNT(DISTINCT CASE WHEN m.role_id = '1537246243393589249' OR r3.parent_id = '1537246243393589249' THEN m.user_id END) AS owner
+        FROM
+            m_project_info AS mpi
+                LEFT JOIN m_project_assignment_user AS m ON mpi.id = m.project_id AND m.is_deleted = 0
+                LEFT JOIN blade_role AS r1 ON m.role_id = r1.id AND r1.is_deleted = 0
+                LEFT JOIN blade_role AS r2 ON m.role_id = r2.id AND r2.is_deleted = 0
+                LEFT JOIN blade_role AS r3 ON m.role_id = r3.id AND r3.is_deleted = 0
+        GROUP BY
+            mpi.project_alias
+        ORDER BY
+            mpi.create_time;
+
     </select>
 
     <select id="singPfxManagementPage" resultMap="singPfxManagementResultMap">

+ 2 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IExcelTabService.java

@@ -113,9 +113,9 @@ public interface IExcelTabService extends BaseService<ExcelTab> {
     Map<String, String> getTablbCols(String pkeyid, String colkey) throws FileNotFoundException;
 
     // 获取用户端 单个表单接口数据
-    R getBussDataInfo(Long pkeyId, int type);
+    Map<String,Object> getBussDataInfo(Long pkeyId, int type);
     // 获取用户端 单个表单接口数据
-    R getBussDataInfo(Long pkeyId, int type,Boolean isFormLoading);
+    Map<String,Object> getBussDataInfo(Long pkeyId, int type,Boolean isFormLoading);
     // 单个pdf 生成
     R getBussPdfInfo(Long pkeyId) throws Exception;
 

+ 91 - 17
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -87,6 +87,7 @@ import java.text.SimpleDateFormat;
 import java.util.List;
 import java.util.*;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.function.Function;
 import java.util.regex.Matcher;
 import java.util.stream.Collectors;
@@ -326,7 +327,10 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                         }
                     }
                 }
-                dataMap2.put("p_key_id", tableInfo.getPkeyId());
+                dataInfo2.put("p_key_id", tableInfo.getPkeyId());
+                dataInfo2.put("classify",tableInfo.getClassify());
+                dataInfo2.put("contractId",tableInfo.getContractId());
+                dataInfo2.put("projectId",tableInfo.getProjectId());
                 tableInfo.setDataMap(dataMap2);
                 result.add(tableInfo);
             }
@@ -1241,29 +1245,32 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         return this.getBussDataInfo(pkeyId,type,false);
     }
     @Override
-    public R getBussDataInfo(Long pkeyId, int type,Boolean isFormLoading) {
+    public Map<String,Object> getBussDataInfo(Long pkeyId, int type,Boolean isFormLoading) {
         Document document=null;
         Map<String, Object> reData = new HashMap<>();
 
         WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
                 .eq(WbsTreeContract::getPKeyId, pkeyId));
         if (wbsTreeContract == null) {
-            return R.data(reData);
+            return reData;
         }
 
         if (wbsTreeContract.getHtmlUrl() == null) {
-            return R.data(reData);
+            return reData;
         }
 
         //表单是否存储在
-        String tabName = wbsTreeContract.getInitTableName();
+    /*    String tabName = wbsTreeContract.getInitTableName();
         String isExitSql = " select * from information_schema.TABLES where TABLE_NAME='" + tabName + "'";
         List<Map<String, Object>> tabList = jdbcTemplate.queryForList(isExitSql);
         if (tabList == null || tabList.size() <= 0) {
-            return R.fail("无实体表对应");
+            return reData;
         }
 
-        String querySql = "select * from " + wbsTreeContract.getInitTableName() + " where p_key_id=" + pkeyId;
+        String querySql = "select * from " + wbsTreeContract.getInitTableName() + " where p_key_id=" + pkeyId;*/
+
+
+        String querySql = "select * from table_data_info where p_key_id=" + pkeyId;
         List<Map<String, Object>> dataIn = jdbcTemplate.queryForList(querySql);
 
         // 匹配关联
@@ -1396,6 +1403,12 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         }
 
         if (dataIn != null && dataIn.size() >= 1) {
+            for (Map<String, Object>  data : dataIn) {
+                reData.put(data.get("tab_key")+"",data.get("key_val"));
+            }
+        }
+
+        /*if (dataIn != null && dataIn.size() >= 1) {
             Map<String, Object> mysqlData = dataIn.get(0);
             for (String key : mysqlData.keySet()) {
                 String tabVal = mysqlData.get(key) + "";
@@ -1460,7 +1473,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     }
                 }
             }
-        }
+        }*/
 
         // 获取默认值
         QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
@@ -1494,7 +1507,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         if(isFormLoading) {
             this.formulaService.paramFormula(wbsTreeContract, reData, document);
         }
-        return R.data(reData);
+        return reData;
     }
 
     @Override
@@ -1525,7 +1538,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             return R.fail("未获取到清表信息");
         }
 
-        Map<String, Object> DataInfo = (Map<String, Object>) getBussDataInfo(pkeyId, 0).getData();
+        Map<String, Object> DataInfo = getBussDataInfo(pkeyId, 0);
         //真实填报率
         Integer realFillRate = 0;
 
@@ -1631,6 +1644,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                     realFillRate = v.intValue();
                 }
             }
+
             Elements trs = table.select("tr");
             if (ObjectUtil.isNotEmpty(DataInfo)) {
                 for (String val : DataInfo.keySet()) {
@@ -1886,6 +1900,9 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         // 获取有权限的节点信息
         List<AppWbsTreeContractVO> wbsTreeContractList = wbsTreeContractService.searchNodeAllTable(nodeId, classify, contractId, projectId,null);
         List<String> data = new ArrayList<>();
+        if(nodeId.indexOf(":")>=0){
+            nodeId = nodeId.split(":")[0];
+        }
         if (wbsTreeContractList != null && wbsTreeContractList.size() >= 1) {
             for (WbsTreeContract wbsInfo : wbsTreeContractList) {
                 // 隐藏的不生成pdf
@@ -2938,11 +2955,14 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         String contractId = tableInfo1.getString("contractId");
         String projectId = tableInfo1.getString("projectId");
         String classify = tableInfo1.getString("classify");
+        String UserId = AuthUtil.getUserId()+"";
+        RedisTemplate.opsForValue().set("pdf-" + nodeId+"-"+classify, "1", 300, TimeUnit.SECONDS);
         //构造阻塞器
         CountDownLatch cdl = new CountDownLatch(dataArray.size());
         // 构造多线程保存用户数据到表中 并生成excel
         for (int i = 0; i < dataArray.size(); i++) {
             JSONObject jsonObject = dataArray.getJSONObject(i);
+            jsonObject.put("UserId",UserId);
             Thread countUserThread = new Thread(() -> {
                 try {
                     SaveOneTabInfo(jsonObject);
@@ -2953,18 +2973,34 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 }
             });
             countUserThread.start();
+
+            new Thread(() -> {
+                try {
+                    cdl.await();
+                    //合并pdf加载
+                    this.getBussPdfs(nodeId+":"+UserId, classify, contractId, projectId);
+                    //更新缓存
+                    informationQueryClient.delAsyncWbsTree(contractId);
+                    RedisTemplate.delete("pdf-" + nodeId+"-"+classify);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                } finally {
+                    cdl.countDown();//标记已经完成一个任务
+                }
+            }).start();
         }
-        //合并pdf加载
-        this.getBussPdfs(nodeId, classify, contractId, projectId);
-        //更新缓存
-        informationQueryClient.delAsyncWbsTree(contractId);
         return R.data("操作成功");
     }
 
     // 保存单表
     public void SaveOneTabInfo(JSONObject tableInfo) throws Exception {
         System.out.println("---------=" + new Date().toLocaleString());
-        String pKeyId = tableInfo.getString("pkeyId");
+        String pKeyId = tableInfo.getString("p_key_id");
+        String nodeId = tableInfo.getString("nodeId");
+        String classify = tableInfo.getString("classify");
+        String UserId = tableInfo.getString("UserId");
+        //真实填报率
+        Integer realFillRate = 0;
 
         tableInfo.fluentRemove("contractId")
                 .fluentRemove("pkeyId")
@@ -3018,6 +3054,31 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             String htmlString = IoUtil.readToString(inputStreamByUrl);
             Document doc = Jsoup.parse(htmlString);
             Element table = doc.select("table").first();
+
+            //计算填报率
+            List<String> keyList = table.getElementsByAttribute("v-model").stream()
+                    .map(l -> {
+                        String attr = l.attr("v-model");
+                        System.out.println(attr);
+                        String[] split = attr.split("\\.");
+                        return split[1];
+                    })
+                    .collect(Collectors.toList());
+            Long sigSize = table.getElementsByAttribute(":readonly").stream().count();
+            int keySize = keyList.size();
+            List<String> fills = tableInfo.keySet().stream().filter(e -> StringUtils.isNotEmpty(tableInfo.getString(e)) && e.contains("__") && e.contains("key")).collect(Collectors.toList());
+            if (fills.size() != 0 && keyList != null && keyList.size() != 0){
+                if (keySize == sigSize){
+                    realFillRate = 100;
+                }else if (keySize > sigSize) {
+                    keySize = keySize - sigSize.intValue();
+                    keyList.retainAll(fills);
+                    Double v = new Double(keyList.size()) / new Double(keySize) * 100;
+                    realFillRate = v.intValue();
+                }
+            }
+
+
             if (ObjectUtil.isNotEmpty(tableInfo)) {
                 for (String key : tableInfo.keySet()) {
                     if (key.contains("key") && key.contains("__")) {
@@ -3220,8 +3281,20 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
             throw new RuntimeException("字段过长,新增失败");
         }
 
-        String file_path = FileUtils.getSysLocalFileUrl();
+        String fileName ="暂无文件提名1";
+        // 处理文件提名
+        try {
+            WbsTreeContract wbsTreeContractByP = this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, nodeId));
+            //处理文件提名
+            fileName = this.wbsParamService.createFileTitle(wbsTreeContractByP);
+        }catch (Exception exception){
+
+        }finally {
+            //huangjn 保存成功后调用生成资料查询列表数据
+            this.informationQueryClient.saveOrUpdateInformationQueryData(nodeId+":"+UserId, "首件使用字段", "业务ID(主要将来给首件使用)", fileName, Integer.parseInt(classify), 2, "false", "源文件(首件字段)", "pdf文件(首件字段)", "首件上传总结报告名称", new ArrayList<>());
+        }
 
+        String file_path = FileUtils.getSysLocalFileUrl();
         String pdfPath = file_path + "/pdf//" + pKeyId + ".pdf";
         String excelPath = file_path + "/pdf//" + pKeyId + ".xlsx";
 
@@ -3286,10 +3359,11 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         UpdateWrapper<WbsTreeContract> updateWrapper = new UpdateWrapper<>();
         updateWrapper.in("p_key_id", pKeyId + "");
         updateWrapper.set("pdf_url", fileUrl);
+        updateWrapper.set("real_fill_rate", realFillRate);
+        updateWrapper.set("is_tab_pdf", 2);
         wbsTreeContractService.update(updateWrapper);
         tabPdf2.delete();
         tabPdf.delete();
-        ResourceUtil.getFile(excelPath);
         //关闭流
         IoUtil.closeQuietly(outputStream);
         IoUtil.closeQuietly(exceInp);

+ 3 - 5
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaServiceImpl.java

@@ -1760,7 +1760,6 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 total.addAll(wpsPrivate);
             }
             if(Func.isNotEmpty(total)){
-                total= new ArrayList<>(total.stream().collect(Collectors.toMap(WbsParam::getK, w -> w, (v1, v2) -> v2)).values());
                 List<ElementFormulaMapping> mappingList =  this.elementFormulaMappingService.list(Wrappers.<ElementFormulaMapping>lambdaQuery().in(ElementFormulaMapping::getParamId,total.stream().map(WbsParam::getId).collect(Collectors.toList())));
                 if(Func.isNotEmpty(mappingList)){
                     list.forEach(e->{
@@ -2351,7 +2350,7 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
             }
 
             Map<String,Formula> formulaIdMap = this.wpService.formulaKeyMap(total.stream().map(WbsParam::getK).collect(Collectors.toList()));
-             /*元素动态绑定  获取已配置节点公式   未查明的bug暂时关闭
+             //元素动态绑定  获取已配置节点公式   未查明的bug暂时关闭
             Map<Long,String> paramIdKeyMap=  total.stream().collect(Collectors.toMap(WbsParam::getId,WbsParam::getK));
             List<ElementFormulaMapping> mappingList =  this.elementFormulaMappingService.list(Wrappers.<ElementFormulaMapping>lambdaQuery().in(ElementFormulaMapping::getParamId,total.stream().map(WbsParam::getId).collect(Collectors.toList())));
             if(Func.isNotEmpty(mappingList)){
@@ -2367,11 +2366,11 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                 });
             }
 
-            检查是否可以自动绑定参数公式
+           // 检查是否可以自动绑定参数公式
             List<FormData> notFormulaFds=fds.stream().filter(f->f.getFormulaId()==null).collect(Collectors.toList());
             if(notFormulaFds.size()>0){
                 notFormulaFds.forEach(e->{
-                    暂时用参数名称是否包含元素名称作为匹配规则
+                    //暂时用参数名称是否包含元素名称作为匹配规则
                     total.stream().filter(p->e.getEName().contains(p.getName().replaceAll("【[\\u4E00-\\u9FFF]+】|\\s+",""))).findAny().ifPresent(d->{
                         Formula tf= formulaIdMap.get(d.getK());
                         if(tf!=null&&e.getId()!=null) {
@@ -2386,7 +2385,6 @@ public class FormulaServiceImpl extends BaseServiceImpl<FormulaMapper, Formula>
                     });
                 });
             }
-            */
             fds.removeIf(f->f.getFormula()==null);
             if(fds.size()>0) {
                 /*执行结果放回数据集合*/

+ 34 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ProjectInfoServiceImpl.java

@@ -1,6 +1,9 @@
 package org.springblade.manager.service.impl;
 
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.Data;
+import org.apache.commons.lang.StringUtils;
 import org.springblade.manager.entity.ContractInfo;
 import org.springblade.manager.vo.*;
 import org.springblade.manager.entity.ProjectInfo;
@@ -9,11 +12,16 @@ import org.springblade.manager.entity.WbsTreePrivate;
 import org.springblade.manager.mapper.*;
 import org.springblade.manager.service.IProjectInfoService;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 
 import javax.annotation.Resource;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 @Service
 public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, ProjectInfo> implements IProjectInfoService {
@@ -28,6 +36,9 @@ public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, P
     @Resource
     private SignPfxFileMapper signPfxFileMapper;
 
+    @Resource
+    private JdbcTemplate jdbcTemplate;
+
     public List<ProjectUserAmountVO> queryProjectUserAmount() {
         return this.baseMapper.queryProjectUserAmount();
     }
@@ -37,16 +48,35 @@ public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, P
         long current = (vo.getCurrent() - 1L) * vo.getSize();
         List<SingPfxManagementVO> result = this.baseMapper.singPfxManagementPage(current, vo.getSize(), vo, alias);
 
+        Set<Long> projectIds = result.stream().map(SingPfxManagementVO::getProjectId).collect(Collectors.toSet());
+
+        /*获取个人签章Map*/
+        String sql_1 = "select pau.project_id from m_sign_pfx_file AS spf left join m_project_assignment_user AS pau on spf.certificate_user_id = pau.user_id where spf.is_deleted = 0 and pau.is_deleted = 0 and pau.project_id in(" + StringUtils.join(projectIds, ",") + ") and spf.certificate_type = 1";
+        List<QueryPersonalOrEnterpriseCountResultVO> projectSelfCountList = jdbcTemplate.query(sql_1, new BeanPropertyRowMapper<>(QueryPersonalOrEnterpriseCountResultVO.class));
+        Map<Long, Long> projectSelfCountMap = projectSelfCountList.stream().collect(Collectors.groupingBy(QueryPersonalOrEnterpriseCountResultVO::getProjectId, Collectors.counting()));
+
+        /*获取企业签章Map*/
+        String sql_2 = "select spd.project_id from m_sign_pfx_file AS spf LEFT JOIN m_sign_pfx_deputy AS spd ON spf.id = spd.sign_pfx_file_id where spf.is_deleted = 0 and spd.is_deleted = 0 and spd.project_id in(" + StringUtils.join(projectIds, ",") + ") and spf.certificate_type = 2";
+        List<QueryPersonalOrEnterpriseCountResultVO> projectFirmCountList = jdbcTemplate.query(sql_2, new BeanPropertyRowMapper<>(QueryPersonalOrEnterpriseCountResultVO.class));
+        Map<Long, Long> projectFirmCountMap = projectFirmCountList.stream().collect(Collectors.groupingBy(QueryPersonalOrEnterpriseCountResultVO::getProjectId, Collectors.counting()));
+
         result.forEach(vos -> {
             //查询个人签章
-            vos.setPersonalCount(this.signPfxFileMapper.queryPersonalOrEnterpriseCount(vos.getProjectId(), 1).toString());
+            //vos.setPersonalCount(this.signPfxFileMapper.queryPersonalOrEnterpriseCount(vos.getProjectId(), 1).toString());
+            vos.setPersonalCount(ObjectUtil.isNotEmpty(projectSelfCountMap.get(vos.getProjectId())) ? projectSelfCountMap.get(vos.getProjectId()).toString() : null);
             //查询企业章
-            vos.setEnterpriseCount(this.signPfxFileMapper.queryPersonalOrEnterpriseCount(vos.getProjectId(), 2).toString());
+            //vos.setEnterpriseCount(this.signPfxFileMapper.queryPersonalOrEnterpriseCount(vos.getProjectId(), 2).toString());
+            vos.setEnterpriseCount(ObjectUtil.isNotEmpty(projectFirmCountMap.get(vos.getProjectId())) ? projectFirmCountMap.get(vos.getProjectId()).toString() : null);
         });
 
         return result;
     }
 
+    @Data
+    private static class QueryPersonalOrEnterpriseCountResultVO {
+        private Long projectId;
+    }
+
     @Override
     public List<ProjectInfo> selectProjectList(List<String> projectIds) {
         return this.baseMapper.selectProjectList(projectIds);
@@ -90,7 +120,7 @@ public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, P
     }
 
     @Override
-    public Long getContractIdbyName(String projectName,String contractName) {
+    public Long getContractIdbyName(String projectName, String contractName) {
         Long contractId = null;
         List<ProjectInfo> projectInfos = baseMapper.selectList(Wrappers.<ProjectInfo>query().lambda()
                 .eq(ProjectInfo::getIsDeleted, 0)
@@ -110,7 +140,7 @@ public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, P
             return contractId;
         }
 
-        return  contractInfos.get(0).getId();
+        return contractInfos.get(0).getId();
 
     }
 

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

@@ -458,6 +458,8 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
 
         //接口请求表单类型(施工质检 或 监理抽检)
         Set<String> tabTableOwnerSets = new HashSet<>();
+
+        /*tableOwner!=null,表示从资料填报查询,查权限数据,roleTableOwnerSets=取交集后*/
         if (StringUtils.isNotEmpty(tableOwner)) {
             String tableOwners;
             if (tableOwner.equals("1")) {
@@ -468,9 +470,12 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                 tableOwners = "7,8,9";
             }
             tabTableOwnerSets.addAll(Func.toStrList(tableOwners));
+
+            //取交集
+            roleTableOwnerSets.retainAll(tabTableOwnerSets);
         }
-        //取交集
-        roleTableOwnerSets.retainAll(tabTableOwnerSets);
+
+        /*tableOwner=null,表示从工程划分处查询,默认查询所有类型数据,roleTableOwnerSets=原始*/
 
         //判断是客户端还是APP
         List<AppWbsTreeContractVO> resultTabs;
@@ -729,7 +734,8 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                     List<WbsTreeContractLazyVO> nodesAll = this.getNodeAll(contractId);
 
                     //获取当前层懒加载节点
-                    List<WbsTreeContractLazyVO> lazyNodes = jdbcTemplate.query("select p_key_id,contract_id,(SELECT id FROM u_contract_tree_drawings where process_id = p_key_id) AS drawingsId,id,parent_id,node_type,type,wbs_type,is_concrete,major_data_type,partition_code,old_id,contract_id_relation,is_concealed_works_node,CASE (SELECT count(1) FROM u_tree_contract_first AS tcf WHERE tcf.is_deleted = 0 AND tcf.wbs_node_id = a.p_key_id) WHEN 0 THEN 'false' ELSE 'true' END AS isFirst,IFNULL(if(length(trim(full_name))>0,full_name,node_name),node_name) AS title,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND b.type = 1 and b.status = 1 AND b.contract_id = " + contractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where a.node_type != 111 and a.type = 1 and a.status = 1 and a.is_deleted = 0 and parent_id = " + (StringUtils.isNotEmpty(id) ? id : 0) + " and contract_id = " + contractId + " ORDER BY a.sort,title,a.create_time", new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+                    String sql = "select p_key_id,contract_id,(SELECT id FROM u_contract_tree_drawings where process_id = p_key_id and is_deleted = 0 limit 1) AS drawingsId,id,parent_id,node_type,type,wbs_type,is_concrete,major_data_type,partition_code,old_id,contract_id_relation,is_concealed_works_node,CASE (SELECT count(1) FROM u_tree_contract_first AS tcf WHERE tcf.is_deleted = 0 AND tcf.wbs_node_id = a.p_key_id) WHEN 0 THEN 'false' ELSE 'true' END AS isFirst,IFNULL(if(length(trim(full_name))>0,full_name,node_name),node_name) AS title,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND b.type = 1 and b.status = 1 AND b.contract_id = " + contractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where a.node_type != 111 and a.type = 1 and a.status = 1 and a.is_deleted = 0 and parent_id = " + (StringUtils.isNotEmpty(id) ? id : 0) + " and contract_id = " + contractId + " ORDER BY a.sort,title,a.create_time";
+                    List<WbsTreeContractLazyVO> lazyNodes = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
                     if (lazyNodes.size() > 0 && nodesAll.size() > 0) {
                         List<WbsTreeContractLazyVO> distinctNodesAll = nodesAll.stream()
                                 .collect(Collectors.collectingAndThen(
@@ -864,7 +870,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                         if (sgContractInfo != null) {
                             List<WbsTreeContractLazyVO> nodesAll = this.getNodeAll(sgContractId);
 
-                            List<WbsTreeContractLazyVO> lazyNodes = jdbcTemplate.query("select p_key_id,contract_id,(SELECT id FROM u_contract_tree_drawings where process_id = p_key_id) AS drawingsId,id,parent_id,node_type,type,wbs_type,major_data_type,partition_code,old_id,contract_id_relation,is_concealed_works_node,CASE (SELECT count(1) FROM u_tree_contract_first AS tcf WHERE tcf.is_deleted = 0 AND tcf.wbs_node_id = a.p_key_id) WHEN 0 THEN 'false' ELSE 'true' END AS isFirst,IFNULL(if(length(trim(full_name))>0,full_name,node_name),node_name) AS title,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND  b.type = 1 and b.status = 1 AND b.contract_id = " + sgContractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where a.node_type != 111 and a.type = 1 and a.status = 1 and a.is_deleted = 0 and parent_id = " + (StringUtils.isNotEmpty(id) ? id : 0) + " and contract_id = " + sgContractId + " ORDER BY a.sort,title,a.create_time", new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+                            List<WbsTreeContractLazyVO> lazyNodes = jdbcTemplate.query("select p_key_id,contract_id,(SELECT id FROM u_contract_tree_drawings where process_id = p_key_id and is_deleted = 0 limit 1) AS drawingsId,id,parent_id,node_type,type,wbs_type,major_data_type,partition_code,old_id,contract_id_relation,is_concealed_works_node,CASE (SELECT count(1) FROM u_tree_contract_first AS tcf WHERE tcf.is_deleted = 0 AND tcf.wbs_node_id = a.p_key_id) WHEN 0 THEN 'false' ELSE 'true' END AS isFirst,IFNULL(if(length(trim(full_name))>0,full_name,node_name),node_name) AS title,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND  b.type = 1 and b.status = 1 AND b.contract_id = " + sgContractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where a.node_type != 111 and a.type = 1 and a.status = 1 and a.is_deleted = 0 and parent_id = " + (StringUtils.isNotEmpty(id) ? id : 0) + " and contract_id = " + sgContractId + " ORDER BY a.sort,title,a.create_time", new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
                             if (lazyNodes.size() > 0 && nodesAll.size() > 0) {
                                 List<WbsTreeContractLazyVO> distinctNodesAll = nodesAll.stream()
                                         .collect(Collectors.collectingAndThen(
@@ -1076,7 +1082,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                             redisTemplate.opsForValue().set("blade-manager::contract:wbstree:" + contractId, JSON.toJSON(array).toString());
                         }
                     }
-                    List<WbsTreeContractLazyVO> lazyNodes = jdbcTemplate.query("select p_key_id,(SELECT id FROM u_contract_tree_drawings where process_id = p_key_id) AS drawingsId,id,parent_id,node_type,type,wbs_type,is_concrete,major_data_type,partition_code,old_id,contract_id_relation,is_concealed_works_node,CASE (SELECT count(1) FROM u_tree_contract_first AS tcf WHERE tcf.is_deleted = 0 AND tcf.wbs_node_id = a.p_key_id) WHEN 0 THEN 'false' ELSE 'true' END AS isFirst,IFNULL(if(length(trim(full_name))>0,full_name,node_name),node_name) AS title,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND b.type = 1 and b.status = 1 AND b.contract_id = " + contractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where a.node_type != 111 and a.type = 1 and a.status = 1 and a.is_deleted = 0 and parent_id = " + (StringUtils.isNotEmpty(id) ? id : 0) + " and contract_id = " + contractId + " ORDER BY a.sort,title,a.create_time", new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+                    List<WbsTreeContractLazyVO> lazyNodes = jdbcTemplate.query("select p_key_id,(SELECT id FROM u_contract_tree_drawings where process_id = p_key_id and is_deleted = 0 limit 1) AS drawingsId,id,parent_id,node_type,type,wbs_type,is_concrete,major_data_type,partition_code,old_id,contract_id_relation,is_concealed_works_node,CASE (SELECT count(1) FROM u_tree_contract_first AS tcf WHERE tcf.is_deleted = 0 AND tcf.wbs_node_id = a.p_key_id) WHEN 0 THEN 'false' ELSE 'true' END AS isFirst,IFNULL(if(length(trim(full_name))>0,full_name,node_name),node_name) AS title,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND b.type = 1 and b.status = 1 AND b.contract_id = " + contractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where a.node_type != 111 and a.type = 1 and a.status = 1 and a.is_deleted = 0 and parent_id = " + (StringUtils.isNotEmpty(id) ? id : 0) + " and contract_id = " + contractId + " ORDER BY a.sort,title,a.create_time", new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
                     if (lazyNodes.size() > 0 && nodesAll.size() > 0) {
                         List<WbsTreeContractLazyVO> distinctNodesAll = nodesAll.stream()
                                 .collect(Collectors.collectingAndThen(
@@ -1184,7 +1190,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
                                 }
                             }
 
-                            List<WbsTreeContractLazyVO> lazyNodes = jdbcTemplate.query("select p_key_id,(SELECT id FROM u_contract_tree_drawings where process_id = p_key_id) AS drawingsId,id,parent_id,node_type,type,wbs_type,major_data_type,partition_code,old_id,contract_id_relation,is_concealed_works_node,CASE (SELECT count(1) FROM u_tree_contract_first AS tcf WHERE tcf.is_deleted = 0 AND tcf.wbs_node_id = a.p_key_id) WHEN 0 THEN 'false' ELSE 'true' END AS isFirst,IFNULL(if(length(trim(full_name))>0,full_name,node_name),node_name) AS title,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND  b.type = 1 and b.status = 1 AND b.contract_id = " + sgContractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where a.node_type != 111 and a.type = 1 and a.status = 1 and a.is_deleted = 0 and parent_id = " + (StringUtils.isNotEmpty(id) ? id : 0) + " and contract_id = " + sgContractId + " ORDER BY a.sort,title,a.create_time", new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
+                            List<WbsTreeContractLazyVO> lazyNodes = jdbcTemplate.query("select p_key_id,(SELECT id FROM u_contract_tree_drawings where process_id = p_key_id and is_deleted = 0 limit 1) AS drawingsId,id,parent_id,node_type,type,wbs_type,major_data_type,partition_code,old_id,contract_id_relation,is_concealed_works_node,CASE (SELECT count(1) FROM u_tree_contract_first AS tcf WHERE tcf.is_deleted = 0 AND tcf.wbs_node_id = a.p_key_id) WHEN 0 THEN 'false' ELSE 'true' END AS isFirst,IFNULL(if(length(trim(full_name))>0,full_name,node_name),node_name) AS title,(SELECT CASE WHEN count(1) > 0 THEN 1 ELSE 0 END FROM m_wbs_tree_contract b WHERE b.parent_id = a.id AND  b.type = 1 and b.status = 1 AND b.contract_id = " + sgContractId + " AND b.is_deleted = 0 ) AS hasChildren from m_wbs_tree_contract a where a.node_type != 111 and a.type = 1 and a.status = 1 and a.is_deleted = 0 and parent_id = " + (StringUtils.isNotEmpty(id) ? id : 0) + " and contract_id = " + sgContractId + " ORDER BY a.sort,title,a.create_time", new BeanPropertyRowMapper<>(WbsTreeContractLazyVO.class));
                             if (lazyNodes.size() > 0 && nodesAll.size() > 0) {
                                 List<WbsTreeContractLazyVO> distinctNodesAll = nodesAll.stream()
                                         .collect(Collectors.collectingAndThen(