浏览代码

重庆高速-计量接口
1、接口调整

LHB 13 小时之前
父节点
当前提交
9bebf4338a
共有 16 个文件被更改,包括 705 次插入121 次删除
  1. 1 0
      blade-gateway/src/main/java/org/springblade/gateway/provider/AuthProvider.java
  2. 3 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/InformationQueryClient.java
  3. 19 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/cq/Attachment.java
  4. 21 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/cq/QualityData.java
  5. 24 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/cq/QualityDataFile.java
  6. 30 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/cq/ResultApi.java
  7. 51 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/APIWbsContractSubdivisionExpandVo.java
  8. 0 28
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/APIWbsContractSubdivisionVo.java
  9. 5 1
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/InformationQueryClientImpl.java
  10. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.java
  11. 13 1
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml
  12. 121 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/APIController.java
  13. 3 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.java
  14. 10 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.xml
  15. 5 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IWbsTreeContractService.java
  16. 397 84
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

+ 1 - 0
blade-gateway/src/main/java/org/springblade/gateway/provider/AuthProvider.java

@@ -68,6 +68,7 @@ public class AuthProvider {
         DEFAULT_SKIP_URL.add("/getQualityTestingToken"); //成渝第三方登录获取质检系统tokne
         DEFAULT_SKIP_URL.add("/getArchiveToken"); //成渝第三方登录获取档案系统tokne
         DEFAULT_SKIP_URL.add("/meeting/**");//DingDing会议接口
+        DEFAULT_SKIP_URL.add("/hczc/api/meter/**");//重庆高速计量获取分部分项划分
 
     }
 

+ 3 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/InformationQueryClient.java

@@ -104,4 +104,7 @@ public interface InformationQueryClient {
 
     @PostMapping(API_PREFIX+"/delInformation")
     void delInformation(@RequestBody InformationQuery infoByWbsId);
+
+    @PostMapping(API_PREFIX+"/getInformationByContractIdAll")
+    List<InformationQuery> getInformationByContractIdAll(@RequestParam Long contractId);
 }

+ 19 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/cq/Attachment.java

@@ -0,0 +1,19 @@
+package org.springblade.manager.entity.cq;
+
+import lombok.Data;
+
+/**
+ * @author LHB
+ */
+@Data
+public class Attachment {
+
+    //文件名称
+    private String name;
+    //文件类型排序
+    private String order;
+    //pdf文件url
+    private String url;
+    //文件备注
+    private String comment;
+}

+ 21 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/cq/QualityData.java

@@ -0,0 +1,21 @@
+package org.springblade.manager.entity.cq;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author LHB
+ * 质量资料对象
+ */
+@Data
+public class QualityData {
+    //文件类型(支持多个文件类型)
+    private String type;
+    //文件类型名称
+    private String typename;
+    //文件类型排序
+    private Integer typeOrder;
+    //文件(支持多个文件)
+    private List<QualityDataFile> files;
+}

+ 24 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/cq/QualityDataFile.java

@@ -0,0 +1,24 @@
+package org.springblade.manager.entity.cq;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author LHB
+ */
+@Data
+public class QualityDataFile {
+    //文件名称
+    private String name;
+    //文件类型名称
+    private String typeName;
+    //文件类型排序
+    private String order;
+    //pdf文件url
+    private String url;
+    //文件备注
+    private String comment;
+    //附件(支持多个附件)
+    private List<Attachment> attachments;
+}

+ 30 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/entity/cq/ResultApi.java

@@ -0,0 +1,30 @@
+package org.springblade.manager.entity.cq;
+
+
+import lombok.Data;
+
+/**
+ * @author LHB
+ * 重庆高速计量接口响应类
+ */
+@Data
+public class ResultApi<T> {
+    private Integer state;
+    private String message;
+    private T data;
+
+    public static ResultApi success(Object data) {
+        ResultApi resultApi = new ResultApi();
+        resultApi.setState(1);
+        resultApi.setMessage("");
+        resultApi.setData(data);
+        return resultApi;
+    }
+
+    public static ResultApi fail(String message) {
+        ResultApi resultApi = new ResultApi();
+        resultApi.setState(2);
+        resultApi.setMessage(message);
+        return resultApi;
+    }
+}

+ 51 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/APIWbsContractSubdivisionExpandVo.java

@@ -0,0 +1,51 @@
+package org.springblade.manager.vo;
+
+import lombok.Data;
+
+/**
+ * 合同段分部分项划分节点试图
+ * 包含各个状态
+ * | 01   | 交工证书     | 所有子节点存在一个的major_data_type = 3   值为 true     |
+ * | 02   | 7天强度报告  | 所有最小节点中在m_table_file 中type = 11  存在一个true  |
+ * | 03   | 28天强度报告 | 所有最小节点中在m_table_file 中type = 12   存在一个true |
+ * | 04   | 监理收验资料 | 监理 major_data_type = 4  全部已审批                    |
+ * | 05   | 桩检报告     | 所有最小节点中在m_table_file  中type = 13   存在一个true |
+ * | 06   | 质检资料     | 质检 major_data_type = 4  全部已审批                    |
+ * | 07   | 评定资料     | major_data_type = 2  全部已审批                         |
+ * @author LHB
+ */
+@Data
+public class APIWbsContractSubdivisionExpandVo {
+    /**
+     * 主键
+     */
+    private Long id;
+    /**
+     * 交工证书
+     */
+    private Boolean completionCertificate = false;
+    /**
+     * 7天强度报告
+     */
+    private Boolean strengthReportSeven = false;
+    /**
+     * 28天强度报告
+     */
+    private Boolean strengthReportTwentyEight = false;
+    /**
+     * 监理资料
+     */
+    private Boolean supervisionData = false;
+    /**
+     * 桩检报告
+     */
+    private Boolean pileInspectionReport = false;
+    /**
+     * 质检资料
+     */
+    private Boolean qualityInspectionData = false;
+    /**
+     * 评定资料
+     */
+    private Boolean evaluationData = false;
+}

+ 0 - 28
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/vo/APIWbsContractSubdivisionVo.java

@@ -53,34 +53,6 @@ public class APIWbsContractSubdivisionVo {
      * 专业工程名称
      */
     private String partitionCatagName;
-    /**
-     * 交工证书
-     */
-    private Boolean completionCertificate = false;
-    /**
-     * 7天强度报告
-     */
-    private Boolean strengthReportSeven = false;
-    /**
-     * 28天强度报告
-     */
-    private Boolean strengthReportTwentyEight = false;
-    /**
-     * 监理资料
-     */
-    private Boolean supervisionData = false;
-    /**
-     * 桩检报告
-     */
-    private Boolean pileInspectionReport = false;
-    /**
-     * 质检资料
-     */
-    private Boolean qualityInspectionData = false;
-    /**
-     * 评定资料
-     */
-    private Boolean evaluationData = false;
     /**
      * 排序
      */

+ 5 - 1
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/InformationQueryClientImpl.java

@@ -15,6 +15,7 @@ import org.springblade.business.vo.QueryProcessDataVO;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 
@@ -142,5 +143,8 @@ public class InformationQueryClientImpl implements InformationQueryClient {
         informationQueryMapper.deleteById(infoByWbsId);
     }
 
-
+    @Override
+    public List<InformationQuery> getInformationByContractIdAll(Long contractId) {
+        return informationQueryMapper.getInformationByContractIdAll(contractId);
+    }
 }

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

@@ -152,4 +152,6 @@ public interface InformationQueryMapper extends BaseMapper<InformationQuery> {
     int addCheckPdfInfoByIds(@Param("ids") List<String> ids,@Param("classify") String classify);
 
     ChekPdfPaceVo getCheckPdfPaceInfo(@Param("contractId") String contractId, @Param("classify") String classify);
+
+    List<InformationQuery> getInformationByContractIdAll(@Param("contractId") Long contractId);
 }

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

@@ -988,7 +988,7 @@
         node_pdf_url
         from u_information_query
         where is_deleted = 0
-          and contract_id = #{contractId} and classify = #{classify} and status = 2 and is_deleted = 0;
+          and contract_id = #{contractId} and classify = #{classify} and status in(0,1,2) and is_deleted = 0;
     </select>
 
     <select id="getTabussTimeInfo" resultMap="tabBusstimeInfoResultMap">
@@ -1043,5 +1043,17 @@
           AND classify = #{classify,jdbcType=VARCHAR}
           AND chek_status IN (0,1,2,3)
     </select>
+    <select id="getInformationByContractIdAll" resultType="org.springblade.business.entity.InformationQuery">
+        select id,
+               wbs_id,
+               name,
+               IFNULL(IFNULL(e_visa_pdf_url,node_pdf_url),pdf_url) pdf_url,
+               classify,
+               sort
+        from u_information_query
+        where is_deleted = 0
+          and (pdf_url is not null or e_visa_pdf_url is not null or node_pdf_url is not null)
+          and contract_id = #{contractId} and classify in(1,2) and status in(0,1,2) and is_deleted = 0;
+    </select>
 
 </mapper>

+ 121 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/APIController.java

@@ -1,15 +1,23 @@
 package org.springblade.manager.controller;
 
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import io.jsonwebtoken.Claims;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
+import me.zhyd.oauth.model.AuthToken;
 import org.springblade.core.boot.ctrl.BladeController;
+import org.springblade.core.jwt.JwtUtil;
+import org.springblade.core.jwt.props.JwtProperties;
+import org.springblade.core.launch.constant.TokenConstant;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.manager.entity.cq.QualityData;
+import org.springblade.manager.entity.cq.ResultApi;
 import org.springblade.manager.service.IWbsTreeContractService;
 import org.springblade.manager.vo.APIWbsContractNodeHzrcVo;
 import org.springblade.manager.vo.APIWbsContractNodeVo;
@@ -17,6 +25,7 @@ import org.springblade.manager.vo.APIWbsContractSubdivisionVo;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletRequest;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -27,7 +36,7 @@ import java.util.Map;
 @RequestMapping("/hczc/api")
 @Api(value = "接口信息", tags = "接口信息类")
 public class APIController extends BladeController {
-
+    private final JwtProperties jwtProperties;
     private final JdbcTemplate jdbcTemplate;
     private final IWbsTreeContractService iWbsTreeContractService;
 
@@ -95,15 +104,123 @@ public class APIController extends BladeController {
         return R.fail(200, "未查询到信息");
     }
 
+
+
+    @GetMapping("/meter/getContractInfo")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "获取合同段信息", notes = "传入项目Id")
+    public ResultApi getContractInfoMeter(@RequestParam String projectId, HttpServletRequest handler) {
+        //解析token
+        String token = handler.getHeader("sx_token");
+        token = JwtUtil.getToken(token);
+        Claims claims = JwtUtil.parseJWT(token);
+        if (token == null || claims == null) {
+            return ResultApi.fail("请求未授权");
+        }
+        String userId = String.valueOf(claims.get(TokenConstant.USER_ID));
+        if(StringUtil.isBlank(userId)){
+            return ResultApi.fail("用户不存在");
+        }
+
+        List<Map<String, Object>> maps = jdbcTemplate.queryForList("SELECT distinct c.id,c.contract_number code,c.contract_name as name from m_contract_info c,m_project_info a  where  c.is_deleted=0 and c.p_id='"+projectId+"'");
+        return ResultApi.success(maps);
+    }
     /**
      * 获取某一合同段的分部分项划分
      */
-    @GetMapping("/getWbsContractSubdivision")
+    @GetMapping("/meter/getWbsContractSubdivision")
     @ApiOperationSupport(order = 5)
     @ApiOperation(value = "获取某一合同段的分部分项划分", notes = "合同")
     @ApiImplicitParam(name = "sectionId", value = "合同段Id", required = true)
-    public R<List<APIWbsContractSubdivisionVo>> getWbsContractSubdivision(String sectionId){
+    public ResultApi getWbsContractSubdivision(@RequestParam String sectionId, HttpServletRequest handler){
+        String token = handler.getHeader("sx_token");
+        token = JwtUtil.getToken(token);
+        Claims claims = JwtUtil.parseJWT(token);
+        if (token == null || claims == null) {
+            return ResultApi.fail("请求未授权");
+        }
+        String userId = String.valueOf(claims.get(TokenConstant.USER_ID));
+        if(StringUtil.isBlank(userId)){
+            return ResultApi.fail("用户不存在");
+        }
+
         List<APIWbsContractSubdivisionVo> list = iWbsTreeContractService.getWbsContractSubdivision(sectionId);
-        return R.data(list);
+        return ResultApi.success(list);
+    }
+
+    /**
+     * 可计量的分部分项编码获取接口
+     */
+    @GetMapping("/meter/getWbsContractSubdivisionMeasurable")
+    @ApiOperationSupport(order = 5)
+    @ApiOperation(value = "可计量的分部分项编码获取接口", notes = "合同")
+    @ApiImplicitParam(name = "sectionId", value = "合同段Id", required = true)
+    public ResultApi getWbsContractSubdivisionMeasurable(@RequestParam String projectId,
+                                                         @RequestParam String sectionId,
+                                                         String pid, HttpServletRequest handler){
+        String token = handler.getHeader("sx_token");
+        token = JwtUtil.getToken(token);
+        Claims claims = JwtUtil.parseJWT(token);
+        if (token == null || claims == null) {
+            return ResultApi.fail("请求未授权");
+        }
+        String userId = String.valueOf(claims.get(TokenConstant.USER_ID));
+        if(StringUtil.isBlank(userId)){
+            return ResultApi.fail("用户不存在");
+        }
+
+        Object list = iWbsTreeContractService.getWbsContractSubdivisionMeasurable(projectId, sectionId, pid, true);
+        return ResultApi.success(list);
+    }
+
+    /**
+     * 不可计量的分部分项编码获取接口
+     */
+    @GetMapping("/meter/getWbsContractSubdivisionUnmeasurable")
+    @ApiOperationSupport(order = 5)
+    @ApiOperation(value = "不可计量的分部分项编码获取接口", notes = "合同")
+    @ApiImplicitParam(name = "sectionId", value = "合同段Id", required = true)
+    public ResultApi getWbsContractSubdivisionUnmeasurable(@RequestParam String projectId,
+                                                           @RequestParam String sectionId,
+                                                           HttpServletRequest handler){
+        String token = handler.getHeader("sx_token");
+        token = JwtUtil.getToken(token);
+        Claims claims = JwtUtil.parseJWT(token);
+        if (token == null || claims == null) {
+            return ResultApi.fail("请求未授权");
+        }
+        String userId = String.valueOf(claims.get(TokenConstant.USER_ID));
+        if(StringUtil.isBlank(userId)){
+            return ResultApi.fail("用户不存在");
+        }
+
+        Object list = iWbsTreeContractService.getWbsContractSubdivisionMeasurable(projectId, sectionId, null, false);
+        return ResultApi.success(list);
+    }
+
+    /**
+     * 质量资料获取接口
+     */
+    @GetMapping("/meter/qualityDataAcquisition")
+    @ApiOperationSupport(order = 5)
+    @ApiOperation(value = "质量资料获取接口", notes = "合同")
+    @ApiImplicitParam(name = "sectionId", value = "合同段Id", required = true)
+    public ResultApi qualityDataAcquisition(@RequestParam String projectId,
+                                            @RequestParam String sectionId,
+                                            @RequestParam String codesId,
+                                            HttpServletRequest handler){
+        String token = handler.getHeader("sx_token");
+        token = JwtUtil.getToken(token);
+        Claims claims = JwtUtil.parseJWT(token);
+        if (token == null || claims == null) {
+            return ResultApi.fail("请求未授权");
+        }
+        String userId = String.valueOf(claims.get(TokenConstant.USER_ID));
+        if(StringUtil.isBlank(userId)){
+            return ResultApi.fail("用户不存在");
+        }
+
+        List<QualityData> list = iWbsTreeContractService.qualityDataAcquisition(projectId, sectionId, codesId);
+        return ResultApi.success(list);
     }
 }

+ 3 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/WbsTreeContractMapper.java

@@ -164,7 +164,9 @@ public interface WbsTreeContractMapper extends EasyBaseMapper<WbsTreeContract> {
      * @param contractId
      * @return
      */
-    List<APIWbsContractSubdivisionVo> getWbsContractSubdivision(@Param("contractId") String contractId);
+    List<APIWbsContractSubdivisionVo> getWbsContractSubdivision(@Param("contractId") String contractId,
+                                                                @Param("pid") String pid,
+                                                                @Param("type") Integer type);
 
     /**
      * 获取只当合同段下的分部分项划分节点的祖级节点

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

@@ -1018,6 +1018,7 @@
             CASE
                 WHEN node_type = 18 THEN 1
                 WHEN node_type = 2 THEN 2
+                WHEN node_type = 1 THEN 0
                 ELSE 3
                 END nodeType,
             null levelCode,
@@ -1027,10 +1028,17 @@
         FROM
             `m_wbs_tree_contract`
         WHERE
-            node_type IN ( 2, 4, 18 )
-          AND is_deleted = 0
+          is_deleted = 0
+        <if test="type != null and type == 1">
+            AND node_type IN ( 1, 2, 4, 18 )
+        </if>
           AND status = 1
+          AND type = #{type}
+          AND p_id > 0
           AND contract_id = #{contractId}
+        <if test="pid != null and pid != ''">
+            AND find_in_set(#{pid}, ancestors_p_id)
+        </if>
     </select>
     <select id="getWbsContractSubdivisionParentNode"
             resultType="org.springblade.manager.vo.APIWbsContractSubdivisionVo">

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

@@ -11,6 +11,7 @@ import org.springblade.manager.dto.WbsTreeContractDTO2;
 import org.springblade.manager.entity.ContractRelationJlyz;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.entity.WbsTreePrivate;
+import org.springblade.manager.entity.cq.QualityData;
 import org.springblade.manager.vo.*;
 import org.springframework.core.io.Resource;
 import org.springframework.http.ResponseEntity;
@@ -113,4 +114,8 @@ public interface IWbsTreeContractService extends BaseService<WbsTreeContract> {
     R<List<WbsTreeContract>> getSiblingWbsContract(Long pKeyId);
 
     R moveNode(MoveNodeDTO dto);
+
+    Object getWbsContractSubdivisionMeasurable(String projectId, String sectionId, String pid, Boolean judgment);
+
+    List<QualityData> qualityDataAcquisition(String projectId, String sectionId, String codesId);
 }

+ 397 - 84
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java

@@ -59,6 +59,9 @@ import org.springblade.core.tool.utils.*;
 import org.springblade.manager.bean.NodeVO;
 import org.springblade.manager.dto.*;
 import org.springblade.manager.entity.*;
+import org.springblade.manager.entity.cq.Attachment;
+import org.springblade.manager.entity.cq.QualityData;
+import org.springblade.manager.entity.cq.QualityDataFile;
 import org.springblade.manager.excel.WbsExcelBatchUtil;
 import org.springblade.manager.excel.WbsExcelUtil;
 import org.springblade.manager.feign.ContractClient;
@@ -4588,101 +4591,101 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         executionTime.info("----查询开始----");
 
         // 1. 查询符合条件的节点
-        List<APIWbsContractSubdivisionVo> list = baseMapper.getWbsContractSubdivision(contractId);
+        List<APIWbsContractSubdivisionVo> list = baseMapper.getWbsContractSubdivision(contractId, null, 1);
         if (CollectionUtil.isEmpty(list)) {
             return Collections.emptyList();
         }
 
         // 2. 查询所有节点并构建快速查找结构
-        List<WbsTreeContract> allContract = baseMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery()
-                .eq(WbsTreeContract::getContractId, contractId)
-                .eq(WbsTreeContract::getType, 1)
-                .isNotNull(WbsTreeContract::getAncestorsPId)
-                .eq(WbsTreeContract::getIsDeleted, 0));
+//        List<WbsTreeContract> allContract = baseMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery()
+//                .eq(WbsTreeContract::getContractId, contractId)
+//                .eq(WbsTreeContract::getType, 1)
+//                .isNotNull(WbsTreeContract::getAncestorsPId)
+//                .eq(WbsTreeContract::getIsDeleted, 0));
 
         // 构建祖先ID到节点列表的映射
-        Map<Long, List<WbsTreeContract>> ancestorMap = new HashMap<>();
-        for (WbsTreeContract node : allContract) {
-            Arrays.stream(node.getAncestorsPId().split(","))
-                    .filter(StringUtils::isNotBlank)
-                    .map(Long::parseLong)
-                    .forEach(ancestorId -> {
-                        ancestorMap.computeIfAbsent(ancestorId, k -> new ArrayList<>()).add(node);
-                    });
-        }
-        executionTime.info("----构建节点映射完成----");
+//        Map<Long, List<WbsTreeContract>> ancestorMap = new HashMap<>();
+//        for (WbsTreeContract node : allContract) {
+//            Arrays.stream(node.getAncestorsPId().split(","))
+//                    .filter(StringUtils::isNotBlank)
+//                    .map(Long::parseLong)
+//                    .forEach(ancestorId -> {
+//                        ancestorMap.computeIfAbsent(ancestorId, k -> new ArrayList<>()).add(node);
+//                    });
+//        }
+//        executionTime.info("----构建节点映射完成----");
 
         // 3. 查询节点附件
-        List<TableFile> nodeFiles = tableFileService.list(Wrappers.<TableFile>lambdaQuery()
-                .eq(TableFile::getContractId, contractId)
-                .in(TableFile::getType, FILE_TYPES)
-                .eq(TableFile::getIsDeleted, 0));
-
-        // 构建附件查找表 (tabId -> 类型集合)
-        Map<Long, Set<Integer>> fileTypeMap = new HashMap<>();
-        for (TableFile file : nodeFiles) {
-            fileTypeMap.computeIfAbsent(Long.valueOf(file.getTabId()), k -> new HashSet<>())
-                    .add(file.getType());
-        }
-        executionTime.info("----构建附件映射完成----");
+//        List<TableFile> nodeFiles = tableFileService.list(Wrappers.<TableFile>lambdaQuery()
+//                .eq(TableFile::getContractId, contractId)
+//                .in(TableFile::getType, FILE_TYPES)
+//                .eq(TableFile::getIsDeleted, 0));
+//
+//        // 构建附件查找表 (tabId -> 类型集合)
+//        Map<Long, Set<Integer>> fileTypeMap = new HashMap<>();
+//        for (TableFile file : nodeFiles) {
+//            fileTypeMap.computeIfAbsent(Long.valueOf(file.getTabId()), k -> new HashSet<>())
+//                    .add(file.getType());
+//        }
+//        executionTime.info("----构建附件映射完成----");
 
         // 4. 查询审批信息
-        List<InformationQuery> oneQuery = informationQueryClient.getInformationByContractId(Long.valueOf(contractId), 1);
-        Set<Long> oneQueryWbsIds = oneQuery.stream().map(InformationQuery::getWbsId).collect(Collectors.toSet());
-
-        List<InformationQuery> twoQuery = informationQueryClient.getInformationByContractId(Long.valueOf(contractId), 2);
-        Set<Long> twoQueryWbsIds = twoQuery.stream().map(InformationQuery::getWbsId).collect(Collectors.toSet());
-
-        Set<Long> allQueryIds = new HashSet<>();
-        allQueryIds.addAll(oneQueryWbsIds);
-        allQueryIds.addAll(twoQueryWbsIds);
-        executionTime.info("----获取审批信息完成----");
-
+//        List<InformationQuery> oneQuery = informationQueryClient.getInformationByContractId(Long.valueOf(contractId), 1);
+//        Set<Long> oneQueryWbsIds = oneQuery.stream().map(InformationQuery::getWbsId).collect(Collectors.toSet());
+//
+//        List<InformationQuery> twoQuery = informationQueryClient.getInformationByContractId(Long.valueOf(contractId), 2);
+//        Set<Long> twoQueryWbsIds = twoQuery.stream().map(InformationQuery::getWbsId).collect(Collectors.toSet());
+//
+//        Set<Long> allQueryIds = new HashSet<>();
+//        allQueryIds.addAll(oneQueryWbsIds);
+//        allQueryIds.addAll(twoQueryWbsIds);
+//        executionTime.info("----获取审批信息完成----");
+//
         // 5. 处理每个节点
-        for (APIWbsContractSubdivisionVo vo : list) {
-            // 6. 从映射中直接获取子节点
-            List<WbsTreeContract> children = ancestorMap.getOrDefault(vo.getId(), Collections.emptyList());
-            if (CollectionUtil.isEmpty(children)) {
-                continue;
-            }
-
-            // 7. 数据匹配处理
-            Set<Long> childrenIds = children.stream()
-                    .map(WbsTreeContract::getPKeyId)
-                    .collect(Collectors.toSet());
-
-            // 交工证书判断
-            List<Long> completionCertificate = children.stream()
-                    .filter(node -> node.getMajorDataType() != null && node.getMajorDataType() == 3)
-                    .map(WbsTreeContract::getPKeyId)
-                    .collect(Collectors.toList());
-            if (CollectionUtil.isNotEmpty(completionCertificate)) {
-                vo.setCompletionCertificate(allQueryIds.containsAll(completionCertificate));
-            }
-
-            // 附件报告判断
-            vo.setStrengthReportSeven(childrenIds.stream().anyMatch(id ->
-                    fileTypeMap.getOrDefault(id, Collections.emptySet()).contains(11)));
-            vo.setStrengthReportTwentyEight(childrenIds.stream().anyMatch(id ->
-                    fileTypeMap.getOrDefault(id, Collections.emptySet()).contains(12)));
-            vo.setPileInspectionReport(childrenIds.stream().anyMatch(id ->
-                    fileTypeMap.getOrDefault(id, Collections.emptySet()).contains(13)));
-
-            // 评定资料判断
-            List<Long> evaluationNodes = children.stream()
-                    .filter(node -> node.getMajorDataType() != null && node.getMajorDataType() == 2)
-                    .map(WbsTreeContract::getPKeyId)
-                    .collect(Collectors.toList());
-            if (CollectionUtil.isNotEmpty(evaluationNodes)) {
-                vo.setEvaluationData(allQueryIds.containsAll(evaluationNodes));
-            }
-
-            // 施工收监报告
-            processApprovalData(vo, children, SG_SET, oneQueryWbsIds, "qualityInspectionData");
-
-            // 监理收监报告
-            processApprovalData(vo, children, JL_SET, twoQueryWbsIds, "supervisionData");
-        }
+//        for (APIWbsContractSubdivisionVo vo : list) {
+//            // 6. 从映射中直接获取子节点
+//            List<WbsTreeContract> children = ancestorMap.getOrDefault(vo.getId(), Collections.emptyList());
+//            if (CollectionUtil.isEmpty(children)) {
+//                continue;
+//            }
+//
+//            // 7. 数据匹配处理
+//            Set<Long> childrenIds = children.stream()
+//                    .map(WbsTreeContract::getPKeyId)
+//                    .collect(Collectors.toSet());
+//
+//            // 交工证书判断
+//            List<Long> completionCertificate = children.stream()
+//                    .filter(node -> node.getMajorDataType() != null && node.getMajorDataType() == 3)
+//                    .map(WbsTreeContract::getPKeyId)
+//                    .collect(Collectors.toList());
+//            if (CollectionUtil.isNotEmpty(completionCertificate)) {
+//                vo.setCompletionCertificate(allQueryIds.containsAll(completionCertificate));
+//            }
+//
+//            // 附件报告判断
+//            vo.setStrengthReportSeven(childrenIds.stream().anyMatch(id ->
+//                    fileTypeMap.getOrDefault(id, Collections.emptySet()).contains(11)));
+//            vo.setStrengthReportTwentyEight(childrenIds.stream().anyMatch(id ->
+//                    fileTypeMap.getOrDefault(id, Collections.emptySet()).contains(12)));
+//            vo.setPileInspectionReport(childrenIds.stream().anyMatch(id ->
+//                    fileTypeMap.getOrDefault(id, Collections.emptySet()).contains(13)));
+//
+//            // 评定资料判断
+//            List<Long> evaluationNodes = children.stream()
+//                    .filter(node -> node.getMajorDataType() != null && node.getMajorDataType() == 2)
+//                    .map(WbsTreeContract::getPKeyId)
+//                    .collect(Collectors.toList());
+//            if (CollectionUtil.isNotEmpty(evaluationNodes)) {
+//                vo.setEvaluationData(allQueryIds.containsAll(evaluationNodes));
+//            }
+//
+//            // 施工收监报告
+//            processApprovalData(vo, children, SG_SET, oneQueryWbsIds, "qualityInspectionData");
+//
+//            // 监理收监报告
+//            processApprovalData(vo, children, JL_SET, twoQueryWbsIds, "supervisionData");
+//        }
 
         executionTime.info("----组装完成----");
         executionTime.brief();
@@ -5733,7 +5736,7 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
 
 
     // 抽取公共处理逻辑
-    private void processApprovalData(APIWbsContractSubdivisionVo vo,
+    private void processApprovalData(APIWbsContractSubdivisionExpandVo vo,
                                      List<WbsTreeContract> children,
                                      Set<Integer> ownerSet,
                                      Set<Long> approvalIds,
@@ -5771,4 +5774,314 @@ public class WbsTreeContractServiceImpl extends BaseServiceImpl<WbsTreeContractM
         }
         return baseMapper.selectList(eq);
     }
+
+    @Override
+    public Object getWbsContractSubdivisionMeasurable(String projectId, String contractId, String pid, Boolean judgment) {
+        // 1. 静态数组转为静态常量
+        final Set<Integer> SG_SET = Collections.unmodifiableSet(
+                new HashSet<>(Arrays.asList(1, 2, 3))
+        );
+        final Set<Integer> JL_SET = Collections.unmodifiableSet(
+                new HashSet<>(Arrays.asList(4,5,6))
+        );
+        final Set<Integer> FILE_TYPES = Collections.unmodifiableSet(
+                new HashSet<>(Arrays.asList(11, 12, 13))
+        );
+        ExecutionTime executionTime = new ExecutionTime();
+        executionTime.info("----查询开始----");
+
+        // 1. 查询符合条件的节点
+        List<APIWbsContractSubdivisionVo> list1 = baseMapper.getWbsContractSubdivision(contractId, pid, 1);
+
+        List<APIWbsContractSubdivisionExpandVo> list = BeanUtil.copyProperties(list1, APIWbsContractSubdivisionExpandVo.class);
+
+
+        if (CollectionUtil.isEmpty(list)) {
+            return Collections.emptyList();
+        }
+
+
+        // 2. 查询所有节点并构建快速查找结构
+        List<WbsTreeContract> allContract = baseMapper.selectList(Wrappers.<WbsTreeContract>lambdaQuery()
+                .eq(WbsTreeContract::getContractId, contractId)
+                .eq(WbsTreeContract::getType, 1)
+                .isNotNull(WbsTreeContract::getAncestorsPId)
+                .eq(WbsTreeContract::getIsDeleted, 0));
+
+        // 构建祖先ID到节点列表的映射
+        Map<Long, List<WbsTreeContract>> ancestorMap = new HashMap<>();
+        for (WbsTreeContract node : allContract) {
+            Arrays.stream(node.getAncestorsPId().split(","))
+                    .filter(StringUtils::isNotBlank)
+                    .map(Long::parseLong)
+                    .forEach(ancestorId -> {
+                        ancestorMap.computeIfAbsent(ancestorId, k -> new ArrayList<>()).add(node);
+                    });
+        }
+        executionTime.info("----构建节点映射完成----");
+
+        // 3. 查询节点附件
+        List<TableFile> nodeFiles = tableFileService.list(Wrappers.<TableFile>lambdaQuery()
+                .eq(TableFile::getContractId, contractId)
+                .in(TableFile::getType, FILE_TYPES)
+                .eq(TableFile::getIsDeleted, 0));
+
+        // 构建附件查找表 (tabId -> 类型集合)
+        Map<Long, Set<Integer>> fileTypeMap = new HashMap<>();
+        for (TableFile file : nodeFiles) {
+            fileTypeMap.computeIfAbsent(Long.valueOf(file.getTabId()), k -> new HashSet<>())
+                    .add(file.getType());
+        }
+        executionTime.info("----构建附件映射完成----");
+
+        // 4. 查询审批信息
+        List<InformationQuery> oneQuery = informationQueryClient.getInformationByContractId(Long.valueOf(contractId), 1);
+        Set<Long> oneQueryWbsIds = oneQuery.stream().map(InformationQuery::getWbsId).collect(Collectors.toSet());
+
+        List<InformationQuery> twoQuery = informationQueryClient.getInformationByContractId(Long.valueOf(contractId), 2);
+        Set<Long> twoQueryWbsIds = twoQuery.stream().map(InformationQuery::getWbsId).collect(Collectors.toSet());
+
+        Set<Long> allQueryIds = new HashSet<>();
+        allQueryIds.addAll(oneQueryWbsIds);
+        allQueryIds.addAll(twoQueryWbsIds);
+        executionTime.info("----获取审批信息完成----");
+        // 5. 处理每个节点
+        for (APIWbsContractSubdivisionExpandVo vo : list) {
+            // 6. 从映射中直接获取子节点
+            List<WbsTreeContract> children = ancestorMap.getOrDefault(vo.getId(), Collections.emptyList());
+            if (CollectionUtil.isEmpty(children)) {
+                continue;
+            }
+
+            // 7. 数据匹配处理
+            Set<Long> childrenIds = children.stream()
+                    .map(WbsTreeContract::getPKeyId)
+                    .collect(Collectors.toSet());
+
+            // 交工证书判断
+            List<Long> completionCertificate = children.stream()
+                    .filter(node -> node.getMajorDataType() != null && node.getMajorDataType() == 3)
+                    .map(WbsTreeContract::getPKeyId)
+                    .collect(Collectors.toList());
+            if (CollectionUtil.isNotEmpty(completionCertificate)) {
+                vo.setCompletionCertificate(allQueryIds.containsAll(completionCertificate));
+            }
+
+            // 附件报告判断
+            vo.setStrengthReportSeven(childrenIds.stream().anyMatch(id ->
+                    fileTypeMap.getOrDefault(id, Collections.emptySet()).contains(11)));
+            vo.setStrengthReportTwentyEight(childrenIds.stream().anyMatch(id ->
+                    fileTypeMap.getOrDefault(id, Collections.emptySet()).contains(12)));
+            vo.setPileInspectionReport(childrenIds.stream().anyMatch(id ->
+                    fileTypeMap.getOrDefault(id, Collections.emptySet()).contains(13)));
+            // 评定资料判断
+            List<Long> evaluationNodes = children.stream()
+                    .filter(node -> node.getMajorDataType() != null && node.getMajorDataType() == 2)
+                    .map(WbsTreeContract::getPKeyId)
+                    .collect(Collectors.toList());
+            if (CollectionUtil.isNotEmpty(evaluationNodes)) {
+                vo.setEvaluationData(allQueryIds.containsAll(evaluationNodes));
+            }
+
+            // 施工收监报告
+            processApprovalData(vo, children, SG_SET, oneQueryWbsIds, "qualityInspectionData");
+
+            // 监理收监报告
+            processApprovalData(vo, children, JL_SET, twoQueryWbsIds, "supervisionData");
+
+        }
+        executionTime.info("----组装完成----");
+        executionTime.brief();
+        if(judgment){
+            return list.stream().filter(f -> f.getCompletionCertificate() || f.getStrengthReportSeven() || f.getStrengthReportTwentyEight()).collect(Collectors.toList());
+        }else{
+            List<String> collect = list.stream().filter(f -> !f.getCompletionCertificate() && !f.getStrengthReportSeven() && !f.getStrengthReportTwentyEight()).map(APIWbsContractSubdivisionExpandVo::getId).map(String::valueOf).collect(Collectors.toList());
+            //若返回合同段ID,则表示该合同段都不允许计量
+            if(collect.size() == list.size()){
+                collect.clear();
+                collect.add(contractId);
+            }
+            return collect;
+        }
+
+    }
+
+    @Override
+    public List<QualityData> qualityDataAcquisition(String projectId, String contractId, String codesId) {
+        final Set<Integer> NODE_TYPES = Collections.unmodifiableSet(
+                new HashSet<>(Arrays.asList(2, 8, 9))
+        );
+        //所有表单父级id
+        Set<Long> ids = new HashSet<>();
+        ArrayList<QualityData> qualityDatas = new ArrayList<>();
+
+        //1、根据codesId 获取所有子级节点的表单
+        List<String> pIds = Arrays.asList(codesId.split(","));
+        // 1. 查询符合条件的节点
+        pIds.forEach(pId -> {
+            List<APIWbsContractSubdivisionVo> list = baseMapper.getWbsContractSubdivision(contractId, pId, 2);
+            if(CollectionUtil.isNotEmpty(list)){
+                ids.addAll(list.stream().map(APIWbsContractSubdivisionVo::getPid).collect(Collectors.toSet()));
+            }
+        });
+
+        //查询所有有pdf的资料
+        List<InformationQuery> oneQuery = informationQueryClient.getInformationByContractIdAll(Long.valueOf(contractId));
+        if(CollectionUtil.isEmpty(oneQuery)){
+            oneQuery = new ArrayList<>();
+        }
+        //根据wbs分组
+        Map<Long, List<InformationQuery>> collect = oneQuery.stream().filter(f -> StringUtils.isNotBlank(f.getPdfUrl())).collect(Collectors.groupingBy(InformationQuery::getWbsId));
+        //查询当前合同下所有附件资料
+        List<TableFile> list = tableFileService.list(Wrappers.<TableFile>lambdaQuery().eq(TableFile::getContractId, Long.valueOf(contractId)));
+        Map<String, List<TableFile>> collect1 = list.stream().collect(Collectors.groupingBy(TableFile::getTabId));
+
+
+        //查询所有父节点
+        List<WbsTreeContract> list1 = wbsTreeContractMapper.selectBatchIds(ids);
+        list1 = list1.stream().sorted(Comparator.comparing(WbsTreeContract::getSort)).collect(Collectors.toList());
+        //排序
+        list1.sort(this::compareAncestors);
+
+        for (int i = 0; i < list1.size(); i++) {
+            WbsTreeContract wbsTreeContract = list1.get(i);
+            Long f = wbsTreeContract.getPKeyId();
+            QualityData qualityData = new QualityData();
+
+            List<InformationQuery> informationQueries = collect.get(f);
+            if(CollectionUtil.isNotEmpty(informationQueries)){
+                String type = "99";
+                String typename;
+                if(wbsTreeContract.getMajorDataType() == 1){
+                    type = "1";
+                    typename = "开工报告";
+                }else if(NODE_TYPES.contains(wbsTreeContract.getMajorDataType())){
+                    type = "4";
+                    typename = "评定报告及表格对应的附件";
+                }else if(wbsTreeContract.getMajorDataType() == 4){
+                    if(informationQueries.size() == 2){
+                        type = "2,3";
+                        typename = "工序资料、监理抽检资料";
+                    }else{
+                        if(informationQueries.get(0).getClassify() == 1){
+                            type = "2";
+                            typename = "工序资料";
+                        }else{
+                            type = "3";
+                            typename = "监理抽检资料";
+                        }
+                    }
+                } else {
+                    typename = "其他";
+                }
+                //当前节点下的附件
+                List<TableFile> tableFiles = collect1.get(f.toString());
+                //根据类型分组
+                Map<Integer, List<TableFile>> collect2;
+                if(CollectionUtil.isNotEmpty(tableFiles)){
+                    //根据类型分组
+                    collect2 = tableFiles.stream().collect(Collectors.groupingBy(TableFile::getClassify));
+                } else {
+                    collect2 = null;
+                }
+                //封装数据
+                qualityData.setType(type);
+                qualityData.setTypename(typename);
+                qualityData.setTypeOrder(i + 1);
+
+                ArrayList<QualityDataFile> qualityDataFiles = new ArrayList<>();
+                //封装文件
+                informationQueries.forEach(f1 -> {
+                    QualityDataFile file = new QualityDataFile();
+                    file.setName(f1.getName());
+                    if(f1.getClassify() == 1) {
+                        file.setTypeName("工序资料");
+                    } else {
+                        file.setTypeName("监理抽检资料");
+                    }
+                    file.setOrder(String.valueOf(f1.getSort()));
+                    file.setUrl(f1.getPdfUrl());
+
+                    //封装附件
+                    if(collect2 != null){
+                        List<TableFile> tableFiles1 = collect2.get(f1.getClassify());
+                        if(CollectionUtil.isNotEmpty(tableFiles1)){
+                            List<Attachment> attachmentArrList = new ArrayList<Attachment>();
+                            tableFiles1.forEach(f2 -> {
+                                Attachment attachment = new Attachment();
+                                attachment.setName(f2.getName());
+                                attachment.setOrder(String.valueOf(f2.getSort()));
+                                attachment.setUrl(f2.getDomainPdfUrl());
+                                attachmentArrList.add(attachment);
+                            });
+                            file.setAttachments(attachmentArrList);
+                        }
+                    }
+
+                    qualityDataFiles.add(file);
+                });
+                qualityData.setFiles(qualityDataFiles);
+                qualityDatas.add(qualityData);
+            }
+        }
+
+        //3、根据id获取query表中资料文件
+        return qualityDatas;
+    }
+
+    /**
+     * 比较两个祖级路径
+     */
+    private int compareAncestors(WbsTreeContract obj1, WbsTreeContract obj2) {
+        String ancestors1 = obj1.getAncestorsPId();
+        String ancestors2 = obj2.getAncestorsPId();
+        if (ancestors1 == null && ancestors2 == null) return 0;
+        if (ancestors1 == null) return -1;
+        if (ancestors2 == null) return 1;
+
+        String[] arr1 = ancestors1.split(",");
+        String[] arr2 = ancestors2.split(",");
+
+        int minLength = Math.min(arr1.length, arr2.length);
+
+        // 比较相同索引的ID
+        for (int i = 0; i < minLength; i++) {
+            String id1 = arr1[i].trim();
+            String id2 = arr2[i].trim();
+
+            if (!id1.equals(id2)) {
+                // 查询数据库获取排序值
+                Integer sort1 = wbsTreeContractMapper.selectById(id1).getSort();
+                Integer sort2 = wbsTreeContractMapper.selectById(id2).getSort();
+
+                // 比较排序值
+                if (sort1 != null && sort2 != null) {
+                    return Integer.compare(sort1, sort2);
+                } else if (sort1 != null) {
+                    return -1;
+                } else if (sort2 != null) {
+                    return 1;
+                } else {
+                    return id1.compareTo(id2); // 降级方案
+                }
+            }
+        }
+        // 如果共同部分都相同,说明是同级节点
+        if (arr1.length == arr2.length) {
+            Integer sort1 = obj1.getSort();
+            Integer sort2 = obj2.getSort();
+            if (sort1 != null && sort2 != null) {
+                return Integer.compare(sort1, sort2);
+            } else if (sort1 != null) {
+                return -1;
+            } else if (sort2 != null) {
+                return 1;
+            } else {
+                return 0; // 都没有排序值,保持原顺序
+            }
+        }
+
+        // 如果共同部分都相同,长度短的排在前面(父级在子级前面)
+        return Integer.compare(arr1.length, arr2.length);
+    }
 }