瀏覽代碼

计量bug

liuyc 1 年之前
父節點
當前提交
84ce942bb0

+ 13 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/MeterTreeContractTreeVO.java

@@ -0,0 +1,13 @@
+package org.springblade.meter.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springblade.meter.entity.MeterTreeContract;
+
+@Data
+public class MeterTreeContractTreeVO extends MeterTreeContract {
+
+    @ApiModelProperty(value = "是否没有子级 true=最下级(没有子级) false=有子级")
+    private boolean notExsitChild;
+
+}

+ 13 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/MeterTreeProjectTreeVO.java

@@ -0,0 +1,13 @@
+package org.springblade.meter.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springblade.meter.entity.MeterTreeProject;
+
+@Data
+public class MeterTreeProjectTreeVO extends MeterTreeProject {
+
+    @ApiModelProperty(value = "是否没有子级 true=最下级(没有子级) false=有子级")
+    private boolean notExsitChild;
+
+}

+ 13 - 0
blade-service-api/blade-meter-api/src/main/java/org/springblade/meter/vo/MeterTreeSystemTreeVO.java

@@ -0,0 +1,13 @@
+package org.springblade.meter.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springblade.meter.entity.MeterTreeSystem;
+
+@Data
+public class MeterTreeSystemTreeVO extends MeterTreeSystem {
+
+    @ApiModelProperty(value = "是否没有子级 true=最下级(没有子级) false=有子级")
+    private boolean notExsitChild;
+
+}

+ 47 - 38
blade-service/blade-meter/src/main/java/org/springblade/meter/controller/MeterTreeController.java

@@ -29,7 +29,10 @@ import org.springblade.meter.service.MeterTreeContractService;
 import org.springblade.meter.service.MeterTreeProjectService;
 import org.springblade.meter.service.MeterTreeSystemService;
 import org.springblade.meter.service.MeterTreeTemplateInfoService;
+import org.springblade.meter.vo.MeterTreeContractTreeVO;
 import org.springblade.meter.vo.MeterTreeContractVO;
+import org.springblade.meter.vo.MeterTreeProjectTreeVO;
+import org.springblade.meter.vo.MeterTreeSystemTreeVO;
 import org.springframework.jdbc.core.BeanPropertyRowMapper;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.web.bind.annotation.*;
@@ -245,13 +248,17 @@ public class MeterTreeController extends BladeController {
     @GetMapping("/system/lazy")
     @ApiOperationSupport(order = 11)
     @ApiOperation(value = "系统树节点懒加载", notes = "传入templateId、节点id(根节点id=0)")
-    public R<List<MeterTreeSystem>> systemLazy(@RequestParam String templateId, @RequestParam String id) {
+    public R<List<MeterTreeSystemTreeVO>> systemLazy(@RequestParam String templateId, @RequestParam String id) {
         if (StringUtils.isNotEmpty(id) && StringUtils.isNotEmpty(templateId)) {
-            return R.data(meterTreeSystemService.getBaseMapper().selectList(Wrappers.<MeterTreeSystem>lambdaQuery()
-                    .eq(MeterTreeSystem::getParentId, id)
-                    .eq(MeterTreeSystem::getTemplateId, templateId)
-                    .eq(MeterTreeSystem::getStatus, 1)
-                    .orderByAsc(MeterTreeSystem::getSort)));
+            List<MeterTreeSystemTreeVO> query = jdbcTemplate.query(
+                    "SELECT *," +
+                            "(SELECT CASE WHEN count(1) > 0 THEN false ELSE true END FROM s_meter_tree_system b" +
+                            "   WHERE b.parent_id = a.id AND b.is_deleted = 0 AND b.status = 1 AND b.template_id = " + templateId + ") AS notExsitChild" +
+                            " FROM s_meter_tree_system a WHERE a.template_id = " + templateId +
+                            " AND a.is_deleted = 0 AND a.status = 1 AND a.parent_id = " + id +
+                            " ORDER BY a.sort",
+                    new BeanPropertyRowMapper<>(MeterTreeSystemTreeVO.class));
+            return R.data(query);
         }
         return R.data(null);
     }
@@ -277,7 +284,7 @@ public class MeterTreeController extends BladeController {
         if (StringUtils.isEmpty(projectId)) {
             throw new ServiceException("未获取到项目信息");
         }
-        ProjectInfo projectInfo = jdbcTemplate.query("SELECT * FROM m_project_info WHERE id = " + projectId, new BeanPropertyRowMapper<>(ProjectInfo.class)).stream().findAny().orElse(null);
+        ProjectInfo projectInfo = jdbcTemplate.query("SELECT meter_template_id FROM m_project_info WHERE id = " + projectId, new BeanPropertyRowMapper<>(ProjectInfo.class)).stream().findAny().orElse(null);
         if (projectInfo != null && ObjectUtil.isNotEmpty(projectInfo.getMeterTemplateId())) {
 
             /*加锁*/
@@ -290,14 +297,10 @@ public class MeterTreeController extends BladeController {
             bladeRedis.expire(redisKey, 60);
 
             /*初始化 或 增量同步 项目计量树*/
-            boolean result = meterTreeProjectService.projectTreeInitOrSync(projectInfo.getMeterTemplateId(), Long.parseLong(projectId));
-            if (result) {
-                return R.success("操作成功");
-            } else {
-                return R.fail("操作失败");
-            }
+            return meterTreeProjectService.projectTreeInitOrSync(projectInfo.getMeterTemplateId(), Long.parseLong(projectId));
+
         } else {
-            throw new ServiceException("未获取到项目关联的系统单元信息,操作失败");
+            throw new ServiceException("未获取到项目关联的系统级计量模板信息,操作失败!");
         }
     }
 
@@ -418,13 +421,17 @@ public class MeterTreeController extends BladeController {
     @GetMapping("/project/lazy")
     @ApiOperationSupport(order = 20)
     @ApiOperation(value = "项目树节点懒加载", notes = "传入projectId、节点id(根节点id=0)")
-    public R<List<MeterTreeProject>> projectLazy(@RequestParam String projectId, @RequestParam String id) {
+    public R<List<MeterTreeProjectTreeVO>> projectLazy(@RequestParam String projectId, @RequestParam String id) {
         if (StringUtils.isNotEmpty(id) && StringUtils.isNotEmpty(projectId)) {
-            return R.data(meterTreeProjectService.getBaseMapper().selectList(Wrappers.<MeterTreeProject>lambdaQuery()
-                    .eq(MeterTreeProject::getParentId, id)
-                    .eq(MeterTreeProject::getProjectId, projectId)
-                    .eq(MeterTreeProject::getStatus, 1)
-                    .orderByAsc(MeterTreeProject::getSort)));
+            List<MeterTreeProjectTreeVO> query = jdbcTemplate.query(
+                    "SELECT *," +
+                            "(SELECT CASE WHEN count(1) > 0 THEN false ELSE true END FROM s_meter_tree_project b" +
+                            "   WHERE b.parent_id = a.id AND b.is_deleted = 0 AND b.status = 1 AND b.project_id = " + projectId + ") AS notExsitChild" +
+                            " FROM s_meter_tree_project a WHERE a.project_id = " + projectId +
+                            " AND a.is_deleted = 0 AND a.status = 1 AND a.parent_id = " + id +
+                            " ORDER BY a.sort",
+                    new BeanPropertyRowMapper<>(MeterTreeProjectTreeVO.class));
+            return R.data(query);
         }
         return R.data(null);
     }
@@ -483,7 +490,7 @@ public class MeterTreeController extends BladeController {
                     result = meterTreeContractService.contractTreeSync(meterTreeProjects, rootNode.getTemplateId(), Long.parseLong(contractId), Long.parseLong(projectId));
                 }
             } else {
-                throw new ServiceException("未获取到项目计量单元信息!");
+                throw new ServiceException("未获取到需要同步的项目计量单元信息!");
             }
         }
         if (result) {
@@ -568,13 +575,17 @@ public class MeterTreeController extends BladeController {
     @GetMapping("/contract/lazy")
     @ApiOperationSupport(order = 26)
     @ApiOperation(value = "合同段树节点懒加载", notes = "传入contractId、节点id(根节点id=0)")
-    public R<List<MeterTreeContract>> contractLazy(@RequestParam String contractId, @RequestParam String id) {
+    public R<List<MeterTreeContractTreeVO>> contractLazy(@RequestParam String contractId, @RequestParam String id) {
         if (StringUtils.isNotEmpty(id) && StringUtils.isNotEmpty(contractId)) {
-            return R.data(meterTreeContractService.getBaseMapper().selectList(Wrappers.<MeterTreeContract>lambdaQuery()
-                    .eq(MeterTreeContract::getParentId, id)
-                    .eq(MeterTreeContract::getContractId, contractId)
-                    .eq(MeterTreeContract::getStatus, 1)
-                    .orderByAsc(MeterTreeContract::getSort)));
+            List<MeterTreeContractTreeVO> query = jdbcTemplate.query(
+                    "SELECT *," +
+                            "(SELECT CASE WHEN count(1) > 0 THEN false ELSE true END FROM s_meter_tree_contract b" +
+                            "   WHERE b.parent_id = a.id AND b.is_deleted = 0 AND b.status = 1 AND b.contract_id = " + contractId + ") AS notExsitChild" +
+                            " FROM s_meter_tree_contract a WHERE a.contract_id = " + contractId +
+                            " AND a.is_deleted = 0 AND a.status = 1 AND a.parent_id = " + id +
+                            " ORDER BY a.sort",
+                    new BeanPropertyRowMapper<>(MeterTreeContractTreeVO.class));
+            return R.data(query);
         }
         return R.data(null);
     }
@@ -657,17 +668,15 @@ public class MeterTreeController extends BladeController {
                         .eq(MeterTreeContract::getStatus, 1)
                         .like(MeterTreeContract::getAncestor, id)
                 );
-                if (meterTreeContracts.size() > 0) {
-                    /*添加选择的顶级节点*/
-                    meterTreeContracts.add(obj);
-                    /*批量修改*/
-                    List<Long> contractNodeIds = meterTreeContracts.stream().map(MeterTreeContract::getId).collect(Collectors.toList());
-                    UpdateWrapper<MeterTreeContract> updateWrapper = new UpdateWrapper<>();
-                    updateWrapper.in("id", contractNodeIds);
-                    MeterTreeContract updateEntity = new MeterTreeContract();
-                    updateEntity.setIsLock(lockStatus);
-                    return R.data(meterTreeContractService.update(updateEntity, updateWrapper));
-                }
+                /*添加选择的顶级节点*/
+                meterTreeContracts.add(obj);
+                /*批量修改*/
+                List<Long> contractNodeIds = meterTreeContracts.stream().map(MeterTreeContract::getId).collect(Collectors.toList());
+                UpdateWrapper<MeterTreeContract> updateWrapper = new UpdateWrapper<>();
+                updateWrapper.in("id", contractNodeIds);
+                MeterTreeContract updateEntity = new MeterTreeContract();
+                updateEntity.setIsLock(lockStatus);
+                return R.data(meterTreeContractService.update(updateEntity, updateWrapper));
             }
         }
         return R.fail("操作失败");

+ 2 - 1
blade-service/blade-meter/src/main/java/org/springblade/meter/service/MeterTreeProjectService.java

@@ -1,12 +1,13 @@
 package org.springblade.meter.service;
 
 import org.springblade.core.mp.base.BaseService;
+import org.springblade.core.tool.api.R;
 import org.springblade.meter.entity.MeterTreeProject;
 
 public interface MeterTreeProjectService extends BaseService<MeterTreeProject> {
 
     Integer selectMaxSort(Long parentId);
 
-    boolean projectTreeInitOrSync(Long meterTemplateId, Long projectId);
+    R<Object> projectTreeInitOrSync(Long meterTemplateId, Long projectId);
 
 }

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

@@ -33,6 +33,7 @@ public class MeterTreeContractServiceImpl extends BaseServiceImpl<MeterTreeContr
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public boolean contractTreeInit(List<MeterTreeProject> meterTreeProjects, Long contractId) {
         /*创建旧节点ID和新节点ID的映射newNodeIdMap*/
         List<Long> projectNodeIdList = meterTreeProjects.stream().map(MeterTreeProject::getId).collect(Collectors.toList());
@@ -93,6 +94,7 @@ public class MeterTreeContractServiceImpl extends BaseServiceImpl<MeterTreeContr
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public boolean contractTreeSync(List<MeterTreeProject> meterTreeProjects, Long templateId, Long contractId, Long projectId) {
         /*获取合同段树*/
         List<MeterTreeContract> meterTreeContracts = baseMapper.selectList(Wrappers.<MeterTreeContract>lambdaQuery()
@@ -110,105 +112,111 @@ public class MeterTreeContractServiceImpl extends BaseServiceImpl<MeterTreeContr
 
         /*增量同步(该接口逻辑与contractSave接口中的划分子级一样)*/
         if (!difference.isEmpty()) {
-            /*构造差集节点id=parentId关系Maps*/
-            Map<Long, Long> idAndParentIdMaps = difference.stream().collect(Collectors.toMap(MeterTreeProject::getId, MeterTreeProject::getParentId));
-
-            /*获取所有要新增的项目级的根节点ids*/
-            Set<Long> rootNodeIds = this.getRootNodeIds(difference);
-            /*获取根节点的父级节点ids*/
-            List<MeterTreeProject> meterTreeProjectsParentNodes = meterTreeProjectMapper.selectList(Wrappers.<MeterTreeProject>lambdaQuery()
-                    .select(MeterTreeProject::getParentId)
-                    .eq(MeterTreeProject::getStatus, 1)
-                    .eq(MeterTreeProject::getTemplateId, templateId)
-                    .eq(MeterTreeProject::getProjectId, projectId)
-                    .in(MeterTreeProject::getId, rootNodeIds)
-            );
-            Set<Long> parentRootNodeIds = meterTreeProjectsParentNodes.stream().map(MeterTreeProject::getParentId).collect(Collectors.toSet());
-
-            /*获取父级节点(即contractSave接口的合同段计量树选择新增节点meterTreeContractNode对象)*/
-            List<MeterTreeContract> meterTreeContractNodesList = baseMapper.selectList(Wrappers.<MeterTreeContract>lambdaQuery()
-                    .eq(MeterTreeContract::getStatus, 1)
-                    .eq(MeterTreeContract::getContractId, contractId)
-                    .eq(MeterTreeContract::getTemplateId, templateId)
-                    .in(MeterTreeContract::getSourceNodeId, parentRootNodeIds) //项目根节点父级 指向合同段原始id字段
-            );
-            Map<Long, List<MeterTreeContract>> meterTreeContractNodesMaps = meterTreeContractNodesList.stream().collect(Collectors.groupingBy(MeterTreeContract::getSourceNodeId));
-
-            for (Long parentRootId : parentRootNodeIds) {
-                /*新增到合同段处的根节点的父级节点信息,由于合同段树新增是从项目选择的(相当于复制),那么sourceNodeId就有相同的,就有N个,所以是多份父级节点*/
-                List<MeterTreeContract> contractParentRootNodeList = meterTreeContractNodesMaps.get(parentRootId);
-                for (MeterTreeContract meterTreeContractNode : contractParentRootNodeList) {
-
-                    for (Long rootNodeId : rootNodeIds) {
-                        /*归纳到自己节点下 TODO 待测试,这里是否需要,项目同步是需要判断的*/
-                        Long rootIdRecordParentId = idAndParentIdMaps.get(rootNodeId);
-                        if (!rootIdRecordParentId.equals(parentRootId)) {
-                            continue;
-                        }
+            try {
+                /*构造差集节点id=parentId关系Maps*/
+                Map<Long, Long> idAndParentIdMaps = difference.stream().collect(Collectors.toMap(MeterTreeProject::getId, MeterTreeProject::getParentId));
+
+                /*获取所有要新增的项目级的根节点ids*/
+                Set<Long> rootNodeIds = this.getRootNodeIds(difference);
+                /*获取根节点的父级节点ids*/
+                List<MeterTreeProject> meterTreeProjectsParentNodes = meterTreeProjectMapper.selectList(Wrappers.<MeterTreeProject>lambdaQuery()
+                        .select(MeterTreeProject::getParentId)
+                        .eq(MeterTreeProject::getStatus, 1)
+                        .eq(MeterTreeProject::getTemplateId, templateId)
+                        .eq(MeterTreeProject::getProjectId, projectId)
+                        .in(MeterTreeProject::getId, rootNodeIds)
+                );
+                Set<Long> parentRootNodeIds = meterTreeProjectsParentNodes.stream().map(MeterTreeProject::getParentId).collect(Collectors.toSet());
+
+                /*获取父级节点(即contractSave接口的合同段计量树选择新增节点meterTreeContractNode对象)*/
+                List<MeterTreeContract> meterTreeContractNodesList = baseMapper.selectList(Wrappers.<MeterTreeContract>lambdaQuery()
+                        .eq(MeterTreeContract::getStatus, 1)
+                        .eq(MeterTreeContract::getContractId, contractId)
+                        .eq(MeterTreeContract::getTemplateId, templateId)
+                        .in(MeterTreeContract::getSourceNodeId, parentRootNodeIds) //项目根节点父级 指向合同段原始id字段
+                );
+                Map<Long, List<MeterTreeContract>> meterTreeContractNodesMaps = meterTreeContractNodesList.stream().collect(Collectors.groupingBy(MeterTreeContract::getSourceNodeId));
+
+                for (Long parentRootId : parentRootNodeIds) {
+                    /*新增到合同段处的根节点的父级节点信息,由于合同段树新增是从项目选择的(相当于复制),那么sourceNodeId就有相同的,就有N个,所以是多份父级节点*/
+                    List<MeterTreeContract> contractParentRootNodeList = meterTreeContractNodesMaps.get(parentRootId);
+                    for (MeterTreeContract meterTreeContractNode : contractParentRootNodeList) {
+
+                        for (Long rootNodeId : rootNodeIds) {
+                            /*归纳到自己节点下 TODO 待测试,这里是否需要,项目同步是需要判断的*/
+                            Long rootIdRecordParentId = idAndParentIdMaps.get(rootNodeId);
+                            if (!rootIdRecordParentId.equals(parentRootId)) {
+                                continue;
+                            }
 
-                        /*获取新增节点的所有子级相关节点*/
-                        List<MeterTreeProject> projectNode = this.getMeterTreeProjectNode(projectId, templateId, rootNodeId);
+                            /*获取新增节点的所有子级相关节点*/
+                            List<MeterTreeProject> projectNode = this.getMeterTreeProjectNode(projectId, templateId, rootNodeId);
 
-                        /*构造数据*/
-                        /*创建旧节点ID和新节点ID的映射Map*/
-                        Map<Long, Long> newRootAndChildNodeIdMap = new HashMap<>(projectNode.size());
-                        List<Long> projectNodeIdList = projectNode.stream().map(MeterTreeProject::getId).collect(Collectors.toList());
-                        for (Long oldNodeId : projectNodeIdList) {
-                            newRootAndChildNodeIdMap.put(oldNodeId, SnowFlakeUtil.getId());
-                        }
-                        /*把项目节点id、parentId、ancestor替换成新的,构造成MeterTreeContract对象*/
-                        List<MeterTreeContract> meterTreeContractResultData = new ArrayList<>(projectNodeIdList.size());
-                        for (MeterTreeProject pObj : projectNode) {
-                            MeterTreeContract cObj = new MeterTreeContract();
-                            BeanUtil.copyProperties(pObj, cObj);
-                            cObj.setContractId(contractId);
-
-                            /*数据源id*/
-                            cObj.setSourceNodeId(pObj.getId());
-                            cObj.setDataSourceType(1); //项目引用
-                            cObj.setUpdateStatus(0); //非编辑
-
-                            /*id*/
-                            cObj.setId(newRootAndChildNodeIdMap.get(pObj.getId()));
-                            /*parentId*/
-                            Long parentId = newRootAndChildNodeIdMap.getOrDefault(pObj.getParentId(), null);
-                            if (parentId == null) {
-                                /*根节点*/
-                                cObj.setParentId(meterTreeContractNode.getId());
-                                /*ancestor(根节点ancestor指向就是 外部合同段树 处选择的节点)*/
-                                cObj.setAncestor(meterTreeContractNode.getAncestor() + "," + cObj.getParentId());
-                            } else {
-                                /*非根节点*/
-                                cObj.setParentId(parentId);
-                                cObj.setAncestor(null); //后面重新计算子级ancestor
+                            /*构造数据*/
+                            /*创建旧节点ID和新节点ID的映射Map*/
+                            Map<Long, Long> newRootAndChildNodeIdMap = new HashMap<>(projectNode.size());
+                            List<Long> projectNodeIdList = projectNode.stream().map(MeterTreeProject::getId).collect(Collectors.toList());
+                            for (Long oldNodeId : projectNodeIdList) {
+                                newRootAndChildNodeIdMap.put(oldNodeId, SnowFlakeUtil.getId());
+                            }
+                            /*把项目节点id、parentId、ancestor替换成新的,构造成MeterTreeContract对象*/
+                            List<MeterTreeContract> meterTreeContractResultData = new ArrayList<>(projectNodeIdList.size());
+                            for (MeterTreeProject pObj : projectNode) {
+                                MeterTreeContract cObj = new MeterTreeContract();
+                                BeanUtil.copyProperties(pObj, cObj);
+                                cObj.setContractId(contractId);
+
+                                /*数据源id*/
+                                cObj.setSourceNodeId(pObj.getId());
+                                cObj.setDataSourceType(1); //项目引用
+                                cObj.setUpdateStatus(0); //非编辑
+
+                                /*id*/
+                                cObj.setId(newRootAndChildNodeIdMap.get(pObj.getId()));
+                                /*parentId*/
+                                Long parentId = newRootAndChildNodeIdMap.getOrDefault(pObj.getParentId(), null);
+                                if (parentId == null) {
+                                    /*根节点*/
+                                    cObj.setParentId(meterTreeContractNode.getId());
+                                    /*ancestor(根节点ancestor指向就是 外部合同段树 处选择的节点)*/
+                                    cObj.setAncestor(meterTreeContractNode.getAncestor() + "," + cObj.getParentId());
+                                } else {
+                                    /*非根节点*/
+                                    cObj.setParentId(parentId);
+                                    cObj.setAncestor(null); //后面重新计算子级ancestor
+                                }
+
+                                meterTreeContractResultData.add(cObj);
                             }
 
-                            meterTreeContractResultData.add(cObj);
-                        }
-
-                        /*层级结构排序*/
-                        List<MeterTreeContract> sortedList = this.sortMeterTreeContracts(meterTreeContractResultData);
-
-                        /*构造ancestor*/
-                        for (MeterTreeContract contract : sortedList) {
-                            if (contract.getAncestor() == null) {
-                                //如果当前元素是子级(ancestor为null),找到对应的父级
-                                Long parentId = contract.getParentId();
-                                String parentAncestor = this.getAncestorForParentId(meterTreeContractResultData, parentId);
-                                //构造新的ancestor字段
-                                String newAncestor = parentAncestor + "," + parentId;
-                                contract.setAncestor(newAncestor);
+                            /*层级结构排序*/
+                            List<MeterTreeContract> sortedList = this.sortMeterTreeContracts(meterTreeContractResultData);
+
+                            /*构造ancestor*/
+                            for (MeterTreeContract contract : sortedList) {
+                                if (contract.getAncestor() == null) {
+                                    //如果当前元素是子级(ancestor为null),找到对应的父级
+                                    Long parentId = contract.getParentId();
+                                    String parentAncestor = this.getAncestorForParentId(meterTreeContractResultData, parentId);
+                                    //构造新的ancestor字段
+                                    String newAncestor = parentAncestor + "," + parentId;
+                                    contract.setAncestor(newAncestor);
+                                }
                             }
-                        }
 
-                        /*入库*/
-                        this.saveBatch(sortedList, 1000);
+                            /*入库*/
+                            this.saveBatch(sortedList, 1000);
+                        }
                     }
                 }
+                return true;
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw new ServiceException("操作异常!");
             }
-            return true;
+
         } else {
-            throw new ServiceException("未获取到需要同步的项目计量单元信息!");
+            throw new ServiceException("未获取到需要同步的项目计量单元信息!");
         }
     }
 
@@ -376,7 +384,8 @@ public class MeterTreeContractServiceImpl extends BaseServiceImpl<MeterTreeContr
         return sortedList;
     }
 
-    private void buildTree(MeterTreeContract currentContract, List<MeterTreeContract> inputList, List<MeterTreeContract> sortedList, int level) {
+    private void buildTree(MeterTreeContract
+                                   currentContract, List<MeterTreeContract> inputList, List<MeterTreeContract> sortedList, int level) {
         sortedList.add(currentContract);
         //找到当前节点的子节点并递归构建树
         for (MeterTreeContract child : inputList) {

+ 179 - 138
blade-service/blade-meter/src/main/java/org/springblade/meter/service/impl/MeterTreeProjectServiceImpl.java

@@ -2,15 +2,21 @@ package org.springblade.meter.service.impl;
 
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.manager.entity.ContractInfo;
 import org.springblade.meter.entity.MeterTreeProject;
 import org.springblade.meter.entity.MeterTreeSystem;
 import org.springblade.meter.mapper.MeterTreeProjectMapper;
 import org.springblade.meter.mapper.MeterTreeSystemMapper;
 import org.springblade.meter.service.MeterTreeProjectService;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -21,7 +27,9 @@ import java.util.stream.Collectors;
 @AllArgsConstructor
 public class MeterTreeProjectServiceImpl extends BaseServiceImpl<MeterTreeProjectMapper, MeterTreeProject> implements MeterTreeProjectService {
 
+    private static Logger logger = LoggerFactory.getLogger(MeterTreeProjectServiceImpl.class);
     private final MeterTreeSystemMapper meterTreeSystemMapper;
+    private final JdbcTemplate jdbcTemplate;
 
     @Override
     public Integer selectMaxSort(Long parentId) {
@@ -30,15 +38,35 @@ public class MeterTreeProjectServiceImpl extends BaseServiceImpl<MeterTreeProjec
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public boolean projectTreeInitOrSync(Long meterTemplateId, Long projectId) {
+    public R<Object> projectTreeInitOrSync(Long meterTemplateId, Long projectId) {
         /*首先判断是否存在项目树*/
         MeterTreeProject rootNode = baseMapper.selectOne(Wrappers.<MeterTreeProject>lambdaQuery()
                 .select(MeterTreeProject::getTemplateId)
+                .eq(MeterTreeProject::getTemplateId, meterTemplateId) //当前模板
                 .eq(MeterTreeProject::getProjectId, projectId)
                 .eq(MeterTreeProject::getParentId, 0L)
                 .eq(MeterTreeProject::getAncestor, "0")
                 .eq(MeterTreeProject::getStatus, 1));
 
+        /*非当前模板,表示已修改项目的系统级模板绑定,那么需要先删除旧模板数据(一个项目只关联了一个模板)*/
+        MeterTreeProject rootNodeOther = baseMapper.selectOne(Wrappers.<MeterTreeProject>lambdaQuery()
+                .select(MeterTreeProject::getTemplateId)
+                .ne(MeterTreeProject::getTemplateId, meterTemplateId) //非当前模板
+                .eq(MeterTreeProject::getProjectId, projectId)
+                .eq(MeterTreeProject::getParentId, 0L)
+                .eq(MeterTreeProject::getAncestor, "0")
+                .eq(MeterTreeProject::getStatus, 1));
+
+        if (rootNodeOther != null) {
+            /*逻辑删除旧项目模板信息*/
+            jdbcTemplate.execute("UPDATE s_meter_tree_project SET is_deleted = 1 WHERE project_id = " + projectId + " AND template_id = " + rootNodeOther.getTemplateId());
+            logger.info(" ==================== 已成功逻辑删除旧系统模板id {} 项目id {} 的项目单元树数据 ==================== ", rootNodeOther.getTemplateId(), projectId);
+
+            /*逻辑删除项目下所有合同段的模板信息*/
+            jdbcTemplate.execute("UPDATE s_meter_tree_contract SET is_deleted = 1 WHERE project_id = " + projectId + " AND template_id = " + rootNodeOther.getTemplateId());
+            logger.info(" ==================== 已成功逻辑删除旧系统模板id {} 项目id {} 的合同段单元树数据 ==================== ", rootNodeOther.getTemplateId(), projectId);
+        }
+
         if (rootNode == null) {
             /*================== 新增初始化 ==================*/
             /*获取系统单元树信息*/
@@ -46,62 +74,69 @@ public class MeterTreeProjectServiceImpl extends BaseServiceImpl<MeterTreeProjec
                     .eq(MeterTreeSystem::getTemplateId, meterTemplateId)
                     .eq(MeterTreeSystem::getStatus, 1)
             );
+            if (meterTreeSystems.size() > 0) {
+                /*创建旧节点ID和新节点ID的映射newNodeIdMap*/
+                List<Long> systemNodeIds = meterTreeSystems.stream().map(MeterTreeSystem::getId).collect(Collectors.toList());
+                Map<Long, Long> newNodeIdMap = new HashMap<>(systemNodeIds.size());
+                for (Long oldNodeId : systemNodeIds) {
+                    newNodeIdMap.put(oldNodeId, SnowFlakeUtil.getId());
+                }
 
-            /*创建旧节点ID和新节点ID的映射newNodeIdMap*/
-            List<Long> systemNodeIds = meterTreeSystems.stream().map(MeterTreeSystem::getId).collect(Collectors.toList());
-            Map<Long, Long> newNodeIdMap = new HashMap<>(systemNodeIds.size());
-            for (Long oldNodeId : systemNodeIds) {
-                newNodeIdMap.put(oldNodeId, SnowFlakeUtil.getId());
-            }
+                /*把项目节点id、parentId、ancestor替换成新的,构造成MeterTreeProject对象*/
+                List<MeterTreeProject> meterTreeProjectsResultData = new ArrayList<>(systemNodeIds.size());
+                for (MeterTreeSystem sObj : meterTreeSystems) {
+                    MeterTreeProject pObj = new MeterTreeProject();
+                    BeanUtil.copyProperties(sObj, pObj);
+                    pObj.setProjectId(projectId);
+
+                    /*数据源id*/
+                    pObj.setSourceNodeId(sObj.getId());
+                    pObj.setDataSourceType(1); //系统引用
+                    pObj.setUpdateStatus(0); //非编辑
+
+                    /*id*/
+                    pObj.setId(newNodeIdMap.get(sObj.getId()));
+                    /*parentId、ancestor*/
+                    Long parentId = newNodeIdMap.getOrDefault(sObj.getParentId(), null);
+                    if (parentId == null) {
+                        /*根节点*/
+                        pObj.setParentId(0L);
+                        pObj.setAncestor("0");
+                    } else {
+                        /*非根节点*/
+                        pObj.setParentId(parentId);
+                        pObj.setAncestor(null); //后面重新计算子级ancestor
+                    }
 
-            /*把项目节点id、parentId、ancestor替换成新的,构造成MeterTreeProject对象*/
-            List<MeterTreeProject> meterTreeProjectsResultData = new ArrayList<>(systemNodeIds.size());
-            for (MeterTreeSystem sObj : meterTreeSystems) {
-                MeterTreeProject pObj = new MeterTreeProject();
-                BeanUtil.copyProperties(sObj, pObj);
-                pObj.setProjectId(projectId);
-
-                /*数据源id*/
-                pObj.setSourceNodeId(sObj.getId());
-                pObj.setDataSourceType(1); //系统引用
-                pObj.setUpdateStatus(0); //非编辑
-
-                /*id*/
-                pObj.setId(newNodeIdMap.get(sObj.getId()));
-                /*parentId、ancestor*/
-                Long parentId = newNodeIdMap.getOrDefault(sObj.getParentId(), null);
-                if (parentId == null) {
-                    /*根节点*/
-                    pObj.setParentId(0L);
-                    pObj.setAncestor("0");
-                } else {
-                    /*非根节点*/
-                    pObj.setParentId(parentId);
-                    pObj.setAncestor(null); //后面重新计算子级ancestor
+                    meterTreeProjectsResultData.add(pObj);
                 }
 
-                meterTreeProjectsResultData.add(pObj);
-            }
-
-            /*层级结构排序*/
-            List<MeterTreeProject> sortedList = this.sortMeterTreeProjects(meterTreeProjectsResultData);
-
-            /*构造ancestor*/
-            for (MeterTreeProject project : sortedList) {
-                if (project.getAncestor() == null) {
-                    //如果当前元素是子级(ancestor为null),找到对应的父级
-                    Long parentId = project.getParentId();
-                    String parentAncestor = this.getAncestorForParentId(meterTreeProjectsResultData, parentId);
-                    //构造新的ancestor字段
-                    String newAncestor = parentAncestor + "," + parentId;
-                    project.setAncestor(newAncestor);
+                /*层级结构排序*/
+                List<MeterTreeProject> sortedList = this.sortMeterTreeProjects(meterTreeProjectsResultData);
+
+                /*构造ancestor*/
+                for (MeterTreeProject project : sortedList) {
+                    if (project.getAncestor() == null) {
+                        //如果当前元素是子级(ancestor为null),找到对应的父级
+                        Long parentId = project.getParentId();
+                        String parentAncestor = this.getAncestorForParentId(meterTreeProjectsResultData, parentId);
+                        //构造新的ancestor字段
+                        String newAncestor = parentAncestor + "," + parentId;
+                        project.setAncestor(newAncestor);
+                    }
                 }
-            }
 
-            if (sortedList.size() == systemNodeIds.size()) {
-                return this.saveBatch(sortedList, 1000);
+                if (sortedList.size() == systemNodeIds.size()) {
+                    if (this.saveBatch(sortedList, 1000)) {
+                        return R.success("操作成功");
+                    } else {
+                        return R.fail("操作失败");
+                    }
+                } else {
+                    throw new ServiceException("数据构造异常!");
+                }
             } else {
-                throw new ServiceException("数据构造异常!");
+                return R.fail("未获取到需要同步的系统级计量单元信息!");
             }
 
         } else {
@@ -129,105 +164,111 @@ public class MeterTreeProjectServiceImpl extends BaseServiceImpl<MeterTreeProjec
 
             /*增量同步(该接口逻辑与MeterTreeContractServiceImpl.contractSave()接口中的划分子级一样)*/
             if (!difference.isEmpty()) {
-                /*构造差集节点id=parentId关系Maps*/
-                Map<Long, Long> idAndParentIdMaps = difference.stream().collect(Collectors.toMap(MeterTreeSystem::getId, MeterTreeSystem::getParentId));
-
-                /*获取所有要新增的系统级的根节点ids*/
-                Set<Long> rootNodeIds = this.getRootNodeIds(difference);
-                /*获取根节点的父级节点ids*/
-                List<MeterTreeSystem> meterTreeSystemsParentNodes = meterTreeSystemMapper.selectList(Wrappers.<MeterTreeSystem>lambdaQuery()
-                        .select(MeterTreeSystem::getParentId)
-                        .eq(MeterTreeSystem::getStatus, 1)
-                        .eq(MeterTreeSystem::getTemplateId, meterTemplateId)
-                        .in(MeterTreeSystem::getId, rootNodeIds)
-                );
-                Set<Long> parentRootNodeIds = meterTreeSystemsParentNodes.stream().map(MeterTreeSystem::getParentId).collect(Collectors.toSet());
-
-                /*获取父级节点(即contractSave接口的合同段计量树选择新增节点meterTreeContractNode对象,对应项目级就是meterTreeProjectNode对象)*/
-                List<MeterTreeProject> meterTreeProjectNodesList = baseMapper.selectList(Wrappers.<MeterTreeProject>lambdaQuery()
-                        .eq(MeterTreeProject::getStatus, 1)
-                        .eq(MeterTreeProject::getProjectId, projectId)
-                        .eq(MeterTreeProject::getTemplateId, meterTemplateId)
-                        .in(MeterTreeProject::getSourceNodeId, parentRootNodeIds) //系统级根节点父级 指向项目原始id字段
-                );
-                Map<Long, List<MeterTreeProject>> meterTreeProjectsNodesMaps = meterTreeProjectNodesList.stream().collect(Collectors.groupingBy(MeterTreeProject::getSourceNodeId));
-
-                for (Long parentRootId : parentRootNodeIds) {
-                    /*项目与合同段不同之处,合同段有N份(合同段新增就是复制,sourceNodeId存在多份一样的),在项目中sourceNodeId源节点id应该是对应一个父级节点*/
-                    List<MeterTreeProject> projectParentRootNodeList = meterTreeProjectsNodesMaps.get(parentRootId);
-                    for (MeterTreeProject meterTreeProjectNode : projectParentRootNodeList) {
-
-                        for (Long rootNodeId : rootNodeIds) {
-                            /*归纳到自己节点下*/
-                            Long rootIdRecordParentId = idAndParentIdMaps.get(rootNodeId);
-                            if (!rootIdRecordParentId.equals(parentRootId)) {
-                                continue;
-                            }
+                try {
+                    /*构造差集节点id=parentId关系Maps*/
+                    Map<Long, Long> idAndParentIdMaps = difference.stream().collect(Collectors.toMap(MeterTreeSystem::getId, MeterTreeSystem::getParentId));
+
+                    /*获取所有要新增的系统级的根节点ids*/
+                    Set<Long> rootNodeIds = this.getRootNodeIds(difference);
+                    /*获取根节点的父级节点ids*/
+                    List<MeterTreeSystem> meterTreeSystemsParentNodes = meterTreeSystemMapper.selectList(Wrappers.<MeterTreeSystem>lambdaQuery()
+                            .select(MeterTreeSystem::getParentId)
+                            .eq(MeterTreeSystem::getStatus, 1)
+                            .eq(MeterTreeSystem::getTemplateId, meterTemplateId)
+                            .in(MeterTreeSystem::getId, rootNodeIds)
+                    );
+                    Set<Long> parentRootNodeIds = meterTreeSystemsParentNodes.stream().map(MeterTreeSystem::getParentId).collect(Collectors.toSet());
+
+                    /*获取父级节点(即contractSave接口的合同段计量树选择新增节点meterTreeContractNode对象,对应项目级就是meterTreeProjectNode对象)*/
+                    List<MeterTreeProject> meterTreeProjectNodesList = baseMapper.selectList(Wrappers.<MeterTreeProject>lambdaQuery()
+                            .eq(MeterTreeProject::getStatus, 1)
+                            .eq(MeterTreeProject::getProjectId, projectId)
+                            .eq(MeterTreeProject::getTemplateId, meterTemplateId)
+                            .in(MeterTreeProject::getSourceNodeId, parentRootNodeIds) //系统级根节点父级 指向项目原始id字段
+                    );
+                    Map<Long, List<MeterTreeProject>> meterTreeProjectsNodesMaps = meterTreeProjectNodesList.stream().collect(Collectors.groupingBy(MeterTreeProject::getSourceNodeId));
+
+                    for (Long parentRootId : parentRootNodeIds) {
+                        /*项目与合同段不同之处,合同段有N份(合同段新增就是复制,sourceNodeId存在多份一样的),在项目中sourceNodeId源节点id应该是对应一个父级节点*/
+                        List<MeterTreeProject> projectParentRootNodeList = meterTreeProjectsNodesMaps.get(parentRootId);
+                        for (MeterTreeProject meterTreeProjectNode : projectParentRootNodeList) {
+
+                            for (Long rootNodeId : rootNodeIds) {
+                                /*归纳到自己节点下*/
+                                Long rootIdRecordParentId = idAndParentIdMaps.get(rootNodeId);
+                                if (!rootIdRecordParentId.equals(parentRootId)) {
+                                    continue;
+                                }
 
-                            /*获取新增节点的所有子级相关节点*/
-                            List<MeterTreeSystem> systemNode = this.getMeterTreeSystemNode(meterTemplateId, rootNodeId);
+                                /*获取新增节点的所有子级相关节点*/
+                                List<MeterTreeSystem> systemNode = this.getMeterTreeSystemNode(meterTemplateId, rootNodeId);
 
-                            /*构造数据*/
-                            /*创建旧节点ID和新节点ID的映射Map*/
-                            Map<Long, Long> newRootAndChildNodeIdMap = new HashMap<>(systemNode.size());
-                            List<Long> systemNodeIdList = systemNode.stream().map(MeterTreeSystem::getId).collect(Collectors.toList());
-                            for (Long oldNodeId : systemNodeIdList) {
-                                newRootAndChildNodeIdMap.put(oldNodeId, SnowFlakeUtil.getId());
-                            }
-
-                            /*把项目节点id、parentId、ancestor替换成新的,构造成MeterTreeProject对象*/
-                            List<MeterTreeProject> meterTreeProjectsResultData = new ArrayList<>(systemNodeIdList.size());
-                            for (MeterTreeSystem sObj : systemNode) {
-                                MeterTreeProject pObj = new MeterTreeProject();
-                                BeanUtil.copyProperties(sObj, pObj);
-                                pObj.setProjectId(projectId);
-
-                                /*数据源id*/
-                                pObj.setSourceNodeId(sObj.getId());
-                                pObj.setDataSourceType(1); //系统引用
-                                pObj.setUpdateStatus(0); //非编辑
-
-                                /*id*/
-                                pObj.setId(newRootAndChildNodeIdMap.get(sObj.getId()));
-                                /*parentId、ancestor*/
-                                Long parentId = newRootAndChildNodeIdMap.getOrDefault(sObj.getParentId(), null);
-                                if (parentId == null) {
-                                    /*根节点*/
-                                    pObj.setParentId(meterTreeProjectNode.getId());
-                                    /*ancestor(根节点ancestor指向就是 项目 的父级节点)*/
-                                    pObj.setAncestor(meterTreeProjectNode.getAncestor() + "," + pObj.getParentId());
-                                } else {
-                                    /*非根节点*/
-                                    pObj.setParentId(parentId);
-                                    pObj.setAncestor(null); //后面重新计算子级ancestor
+                                /*构造数据*/
+                                /*创建旧节点ID和新节点ID的映射Map*/
+                                Map<Long, Long> newRootAndChildNodeIdMap = new HashMap<>(systemNode.size());
+                                List<Long> systemNodeIdList = systemNode.stream().map(MeterTreeSystem::getId).collect(Collectors.toList());
+                                for (Long oldNodeId : systemNodeIdList) {
+                                    newRootAndChildNodeIdMap.put(oldNodeId, SnowFlakeUtil.getId());
                                 }
 
-                                meterTreeProjectsResultData.add(pObj);
-                            }
+                                /*把项目节点id、parentId、ancestor替换成新的,构造成MeterTreeProject对象*/
+                                List<MeterTreeProject> meterTreeProjectsResultData = new ArrayList<>(systemNodeIdList.size());
+                                for (MeterTreeSystem sObj : systemNode) {
+                                    MeterTreeProject pObj = new MeterTreeProject();
+                                    BeanUtil.copyProperties(sObj, pObj);
+                                    pObj.setProjectId(projectId);
+
+                                    /*数据源id*/
+                                    pObj.setSourceNodeId(sObj.getId());
+                                    pObj.setDataSourceType(1); //系统引用
+                                    pObj.setUpdateStatus(0); //非编辑
+
+                                    /*id*/
+                                    pObj.setId(newRootAndChildNodeIdMap.get(sObj.getId()));
+                                    /*parentId、ancestor*/
+                                    Long parentId = newRootAndChildNodeIdMap.getOrDefault(sObj.getParentId(), null);
+                                    if (parentId == null) {
+                                        /*根节点*/
+                                        pObj.setParentId(meterTreeProjectNode.getId());
+                                        /*ancestor(根节点ancestor指向就是 项目 的父级节点)*/
+                                        pObj.setAncestor(meterTreeProjectNode.getAncestor() + "," + pObj.getParentId());
+                                    } else {
+                                        /*非根节点*/
+                                        pObj.setParentId(parentId);
+                                        pObj.setAncestor(null); //后面重新计算子级ancestor
+                                    }
+
+                                    meterTreeProjectsResultData.add(pObj);
+                                }
 
-                            /*层级结构排序*/
-                            List<MeterTreeProject> sortedList = this.sortMeterTreeProjects(meterTreeProjectsResultData);
-
-                            /*构造ancestor*/
-                            for (MeterTreeProject project : sortedList) {
-                                if (project.getAncestor() == null) {
-                                    //如果当前元素是子级(ancestor为null),找到对应的父级
-                                    Long parentId = project.getParentId();
-                                    String parentAncestor = this.getAncestorForParentId(meterTreeProjectsResultData, parentId);
-                                    //构造新的ancestor字段
-                                    String newAncestor = parentAncestor + "," + parentId;
-                                    project.setAncestor(newAncestor);
+                                /*层级结构排序*/
+                                List<MeterTreeProject> sortedList = this.sortMeterTreeProjects(meterTreeProjectsResultData);
+
+                                /*构造ancestor*/
+                                for (MeterTreeProject project : sortedList) {
+                                    if (project.getAncestor() == null) {
+                                        //如果当前元素是子级(ancestor为null),找到对应的父级
+                                        Long parentId = project.getParentId();
+                                        String parentAncestor = this.getAncestorForParentId(meterTreeProjectsResultData, parentId);
+                                        //构造新的ancestor字段
+                                        String newAncestor = parentAncestor + "," + parentId;
+                                        project.setAncestor(newAncestor);
+                                    }
                                 }
-                            }
 
-                            /*入库*/
-                            this.saveBatch(sortedList, 1000);
+                                /*入库*/
+                                this.saveBatch(sortedList, 1000);
+                            }
                         }
+
                     }
+                    return R.success("操作成功");
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    throw new ServiceException("操作异常!");
                 }
-                return true;
             } else {
-                throw new ServiceException("未获取到需要同步的系统计量单元信息!");
+                return R.fail("未获取到需要同步的系统级计量单元信息!");
             }
         }
     }