feat(add-ledger): 新增数据台账管理功能

- 初始化台账设备相关字典类型和数据
- 添加数据台账常量定义类
- 实现台账配置控制器提供增删改查接口
- 创建台账节点详情、树形结构等视图对象
- 开发工程、设备、测点等数据访问层
- 添加台账ID生成和线路号处理工具类
- 实现台账软删除和查询功能
- 添加测点线路号可用性检查机制
This commit is contained in:
2026-05-09 07:52:04 +08:00
parent 2c1d926261
commit c3b074db26
38 changed files with 2044 additions and 3 deletions

View File

@@ -27,6 +27,7 @@ CN_Tool 是一个基于 Spring Boot 的多模块后端聚合工程,当前仓
- `activate-tool` - `activate-tool`
- `add-data` - `add-data`
- `add-ledger`
- `mms-mapping` - `mms-mapping`
- `wave-tool` - `wave-tool`
@@ -36,7 +37,7 @@ CN_Tool 是一个基于 Spring Boot 的多模块后端聚合工程,当前仓
- `entrance/src/main/java/com/njcn/gather/EntranceApplication.java` - `entrance/src/main/java/com/njcn/gather/EntranceApplication.java`
`entrance` 模块聚合了 `system``disk-monitor``user``detection``activate-tool``add-data``wave-tool``mms-mapping`,是当前运行时主入口。 `entrance` 模块聚合了 `system``disk-monitor``user``detection``activate-tool``add-data``add-ledger``wave-tool``mms-mapping`,是当前运行时主入口。
## 技术基线 ## 技术基线
@@ -85,6 +86,8 @@ P0 已补齐基线文档,建议按以下顺序阅读:
- 负责激活码生成、激活码验证、许可证读取等能力 - 负责激活码生成、激活码验证、许可证读取等能力
- `tools/add-data` - `tools/add-data`
- 当前提供电能质量 13 张表批量补数、任务状态查询和模板规则查询能力 - 当前提供电能质量 13 张表批量补数、任务状态查询和模板规则查询能力
- `tools/add-ledger`
- 当前为数据台账工具预留空模块
- `tools/mms-mapping` - `tools/mms-mapping`
- 负责 ICD 文件解析与 MMS 映射数据生成能力 - 负责 ICD 文件解析与 MMS 映射数据生成能力
- `tools/wave-tool` - `tools/wave-tool`

View File

@@ -53,6 +53,11 @@
<artifactId>add-data</artifactId> <artifactId>add-data</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
</dependency> </dependency>
<dependency>
<groupId>com.njcn.gather</groupId>
<artifactId>add-ledger</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@@ -8,10 +8,11 @@
- `activate-tool` - `activate-tool`
- `add-data` - `add-data`
- `add-ledger`
- `mms-mapping` - `mms-mapping`
- `wave-tool` - `wave-tool`
因此,`tools` 现阶段仍然是聚合模块但当前已实际承载激活工具、电能质量数据补录工具、ICD/MMS 映射工具和波形查看工具个子模块。 因此,`tools` 现阶段仍然是聚合模块,但当前已实际承载激活工具、电能质量数据补录工具、数据台账工具空模块、ICD/MMS 映射工具和波形查看工具个子模块。
## 当前结构 ## 当前结构
@@ -19,6 +20,7 @@
tools/ tools/
├── activate-tool/ ├── activate-tool/
├── add-data/ ├── add-data/
├── add-ledger/
├── mms-mapping/ ├── mms-mapping/
└── wave-tool/ └── wave-tool/
``` ```
@@ -37,6 +39,12 @@ tools/
模块内部已按职责拆分 `controller``service``service/impl``component``pojo``config``util`,并通过 `JdbcTemplate + INSERT IGNORE` 执行批量补数。 模块内部已按职责拆分 `controller``service``service/impl``component``pojo``config``util`,并通过 `JdbcTemplate + INSERT IGNORE` 执行批量补数。
## add-ledger 的职责
`add-ledger` 当前仅完成 Maven 空模块接入,后续用于承载数据台账相关能力。
当前未提供业务接口、Java 分层骨架、配置项或持久化逻辑。目录中的 `ledger.sql` 仅作为原始脚本保留,暂未接入运行时资源解析。
## activate-tool 的职责 ## activate-tool 的职责
`activate-tool` 当前提供的能力主要围绕设备授权与许可证: `activate-tool` 当前提供的能力主要围绕设备授权与许可证:
@@ -90,7 +98,7 @@ tools/
## 依赖关系 ## 依赖关系
`tools/activate-tool``tools/add-data``tools/mms-mapping``tools/wave-tool` 当前主要依赖: `tools/activate-tool``tools/add-data``tools/add-ledger``tools/mms-mapping``tools/wave-tool` 当前主要依赖:
- `com.njcn:njcn-common` - `com.njcn:njcn-common`
- `com.njcn:spingboot2.3.12` - `com.njcn:spingboot2.3.12`

View File

@@ -0,0 +1,67 @@
# add-ledger 模块说明
## 模块定位
`add-ledger``tools` 下的数据台账配置工具模块,当前基于 `ledger.sql` 中的工程、项目、设备、监测点和台账树表结构,提供后端配置接口。
本次范围不包含:
- 前端真实页面代码
- 自动执行 SQL 初始化
- 自动数据库迁移
- 设备通信、WebSocket 或 Netty 链路改造
目录中的 `ledger.sql` 仅作为原始表结构脚本保留,当前模块不加载、不解析该脚本。
## 当前结构
```text
add-ledger/
├── ledger.sql
├── pom.xml
├── README.md
├── src/main/java/com/njcn/gather/tool/addledger/
│ ├── component/
│ ├── config/
│ ├── controller/
│ ├── mapper/
│ ├── pojo/
│ ├── service/
│ └── util/
└── src/main/resources/sql/add-ledger/
```
## 当前接口
完整调试说明见 [API_DEBUG.md](./API_DEBUG.md)。
- `GET /addLedger/tree`
- 查询台账树,支持按节点名称关键字过滤。
- `GET /addLedger/detail`
- 根据 `id``level` 查询工程、项目、设备或测点详情。
- `POST /addLedger/engineering/save`
- 新增或保存工程,并同步 `cs_ledger` 工程节点。
- `POST /addLedger/project/save`
- 新增或保存项目,并同步 `cs_ledger` 项目节点。
- `POST /addLedger/equipment/save`
- 新增或保存设备,并同步 `cs_ledger` 设备节点。
- `POST /addLedger/line/save`
- 新增或保存测点,并同步 `cs_ledger` 测点节点。
- `GET /addLedger/line/availableLineNos`
- 查询设备下 `1-20` 中可用的线路号。
- `DELETE /addLedger/node`
- 软删除指定节点,父节点会级联软删除下级业务数据和台账节点。
## 实现说明
- 台账层级固定为:工程 -> 项目 -> 设备 -> 监测点。
- 新增时绑定父级节点;编辑时只更新当前业务数据和台账节点名称,不搬迁节点。
- 保存业务表和 `cs_ledger` 在同一事务内完成。
- 设备保存时同步 `associated_engineering``associated_project`
- 测点新增时生成 32 位 UUID 作为 `line_id`
- 测点 `line_no` 后端限制为 `1-20`,且同设备下正常测点不可重复。
- 删除采用软删除:工程、项目、测点更新 `status=0`,设备更新 `run_status=0`,台账节点更新 `State=0`
## 后续扩展约束
后续如果新增更多台账能力,应沿当前 `controller -> service -> mapper -> XML` 职责边界扩展,不回退为单一大类承载全部接口。

39
tools/add-ledger/pom.xml Normal file
View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.njcn.gather</groupId>
<artifactId>tools</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>add-ledger</artifactId>
<dependencies>
<dependency>
<groupId>com.njcn</groupId>
<artifactId>njcn-common</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.njcn</groupId>
<artifactId>mybatis-plus</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.njcn</groupId>
<artifactId>spingboot2.3.12</artifactId>
<version>2.3.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,55 @@
package com.njcn.gather.tool.addledger.component;
import com.njcn.gather.tool.addledger.pojo.constant.AddLedgerConst;
import com.njcn.gather.tool.addledger.pojo.po.AddLedgerLedgerPO;
import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerTreeNodeVO;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* 数据台账树组装器。
*/
@Component
public class AddLedgerTreeBuilder {
public List<AddLedgerTreeNodeVO> buildTree(List<AddLedgerLedgerPO> ledgers) {
Map<String, AddLedgerTreeNodeVO> nodeMap = new LinkedHashMap<String, AddLedgerTreeNodeVO>();
if (ledgers == null || ledgers.isEmpty()) {
return new ArrayList<AddLedgerTreeNodeVO>();
}
for (AddLedgerLedgerPO ledger : ledgers) {
AddLedgerTreeNodeVO node = new AddLedgerTreeNodeVO();
node.setId(ledger.getId());
node.setParentId(ledger.getPid());
node.setParentIds(ledger.getPids());
node.setName(ledger.getName());
node.setLevel(ledger.getLevel());
node.setSort(ledger.getSort());
nodeMap.put(node.getId(), node);
}
List<AddLedgerTreeNodeVO> roots = new ArrayList<AddLedgerTreeNodeVO>();
for (AddLedgerTreeNodeVO node : nodeMap.values()) {
AddLedgerTreeNodeVO parent = nodeMap.get(node.getParentId());
if (parent == null || AddLedgerConst.ROOT_PARENT_ID.equals(node.getParentId())) {
roots.add(node);
} else {
parent.getChildren().add(node);
}
}
sortTree(roots);
return roots;
}
private void sortTree(List<AddLedgerTreeNodeVO> nodes) {
nodes.sort(Comparator.comparing(AddLedgerTreeNodeVO::getSort, Comparator.nullsLast(Integer::compareTo))
.thenComparing(AddLedgerTreeNodeVO::getName, Comparator.nullsLast(String::compareTo)));
for (AddLedgerTreeNodeVO node : nodes) {
sortTree(node.getChildren());
}
}
}

View File

@@ -0,0 +1,12 @@
package com.njcn.gather.tool.addledger.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
/**
* 数据台账 Mapper 扫描配置。
*/
@Configuration
@MapperScan("com.njcn.gather.tool.addledger.mapper")
public class AddLedgerMapperConfig {
}

View File

@@ -0,0 +1,126 @@
package com.njcn.gather.tool.addledger.controller;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.constant.OperateType;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.LogUtil;
import com.njcn.gather.tool.addledger.pojo.param.AddLedgerEngineeringSaveParam;
import com.njcn.gather.tool.addledger.pojo.param.AddLedgerEquipmentSaveParam;
import com.njcn.gather.tool.addledger.pojo.param.AddLedgerLineSaveParam;
import com.njcn.gather.tool.addledger.pojo.param.AddLedgerProjectSaveParam;
import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerDetailVO;
import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerTreeNodeVO;
import com.njcn.gather.tool.addledger.service.AddLedgerService;
import com.njcn.web.controller.BaseController;
import com.njcn.web.utils.HttpResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 数据台账配置接口。
*/
@Validated
@Slf4j
@Api(tags = "数据台账配置")
@RestController
@RequestMapping("/addLedger")
@RequiredArgsConstructor
public class AddLedgerController extends BaseController {
private final AddLedgerService addLedgerService;
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@ApiOperation("查询台账树")
@GetMapping("/tree")
public HttpResult<List<AddLedgerTreeNodeVO>> tree(@RequestParam(value = "keyword", required = false) String keyword) {
String methodDescribe = getMethodDescribe("tree");
LogUtil.njcnDebug(log, "{}开始查询台账树keyword={}", methodDescribe, keyword);
List<AddLedgerTreeNodeVO> result = addLedgerService.tree(keyword);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@ApiOperation("查询台账节点详情")
@GetMapping("/detail")
public HttpResult<AddLedgerDetailVO> detail(@RequestParam("id") String id, @RequestParam("level") Integer level) {
String methodDescribe = getMethodDescribe("detail");
LogUtil.njcnDebug(log, "{}开始查询台账节点详情id={}, level={}", methodDescribe, id, level);
AddLedgerDetailVO result = addLedgerService.detail(id, level);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.ADD)
@ApiOperation("新增或保存工程")
@PostMapping("/engineering/save")
public HttpResult<AddLedgerDetailVO> saveEngineering(@RequestBody @Validated AddLedgerEngineeringSaveParam param) {
String methodDescribe = getMethodDescribe("saveEngineering");
LogUtil.njcnDebug(log, "{}开始保存工程id={}", methodDescribe, param.getId());
AddLedgerDetailVO result = addLedgerService.saveEngineering(param);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.ADD)
@ApiOperation("新增或保存项目")
@PostMapping("/project/save")
public HttpResult<AddLedgerDetailVO> saveProject(@RequestBody @Validated AddLedgerProjectSaveParam param) {
String methodDescribe = getMethodDescribe("saveProject");
LogUtil.njcnDebug(log, "{}开始保存项目id={}", methodDescribe, param.getId());
AddLedgerDetailVO result = addLedgerService.saveProject(param);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.ADD)
@ApiOperation("新增或保存设备")
@PostMapping("/equipment/save")
public HttpResult<AddLedgerDetailVO> saveEquipment(@RequestBody @Validated AddLedgerEquipmentSaveParam param) {
String methodDescribe = getMethodDescribe("saveEquipment");
LogUtil.njcnDebug(log, "{}开始保存设备id={}", methodDescribe, param.getId());
AddLedgerDetailVO result = addLedgerService.saveEquipment(param);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.ADD)
@ApiOperation("新增或保存测点")
@PostMapping("/line/save")
public HttpResult<AddLedgerDetailVO> saveLine(@RequestBody @Validated AddLedgerLineSaveParam param) {
String methodDescribe = getMethodDescribe("saveLine");
LogUtil.njcnDebug(log, "{}开始保存测点lineId={}", methodDescribe, param.getLineId());
AddLedgerDetailVO result = addLedgerService.saveLine(param);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@ApiOperation("查询设备可用线路号")
@GetMapping("/line/availableLineNos")
public HttpResult<List<Integer>> availableLineNos(@RequestParam("deviceId") String deviceId,
@RequestParam(value = "lineId", required = false) String lineId) {
String methodDescribe = getMethodDescribe("availableLineNos");
LogUtil.njcnDebug(log, "{}开始查询可用线路号deviceId={}, lineId={}", methodDescribe, deviceId, lineId);
List<Integer> result = addLedgerService.availableLineNos(deviceId, lineId);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON, operateType = OperateType.DELETE)
@ApiOperation("删除台账节点")
@DeleteMapping("/node")
public HttpResult<Boolean> deleteNode(@RequestParam("id") String id, @RequestParam("level") Integer level) {
String methodDescribe = getMethodDescribe("deleteNode");
LogUtil.njcnDebug(log, "{}开始删除台账节点id={}, level={}", methodDescribe, id, level);
boolean result = addLedgerService.deleteNode(id, level);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
}

View File

@@ -0,0 +1,15 @@
package com.njcn.gather.tool.addledger.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.gather.tool.addledger.pojo.po.AddLedgerEngineeringPO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 工程信息 Mapper。
*/
public interface AddLedgerEngineeringMapper extends BaseMapper<AddLedgerEngineeringPO> {
int softDeleteByIds(@Param("ids") List<String> ids, @Param("updateBy") String updateBy);
}

View File

@@ -0,0 +1,15 @@
package com.njcn.gather.tool.addledger.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.gather.tool.addledger.pojo.po.AddLedgerEquipmentPO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 设备信息 Mapper。
*/
public interface AddLedgerEquipmentMapper extends BaseMapper<AddLedgerEquipmentPO> {
int softDeleteByIds(@Param("ids") List<String> ids, @Param("updateBy") String updateBy);
}

View File

@@ -0,0 +1,21 @@
package com.njcn.gather.tool.addledger.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.gather.tool.addledger.pojo.po.AddLedgerLedgerPO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 台账树 Mapper。
*/
public interface AddLedgerLedgerMapper extends BaseMapper<AddLedgerLedgerPO> {
List<AddLedgerLedgerPO> selectTree(@Param("keyword") String keyword);
AddLedgerLedgerPO selectActiveNode(@Param("id") String id, @Param("level") Integer level);
List<AddLedgerLedgerPO> selectActiveSubtree(@Param("id") String id);
int softDeleteByIds(@Param("ids") List<String> ids, @Param("updateBy") String updateBy);
}

View File

@@ -0,0 +1,21 @@
package com.njcn.gather.tool.addledger.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.gather.tool.addledger.pojo.po.AddLedgerLinePO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 监测点 Mapper。
*/
public interface AddLedgerLineMapper extends BaseMapper<AddLedgerLinePO> {
List<Integer> selectUsedLineNos(@Param("deviceId") String deviceId, @Param("lineId") String lineId);
int countActiveLineNo(@Param("deviceId") String deviceId,
@Param("lineNo") Integer lineNo,
@Param("lineId") String lineId);
int softDeleteByIds(@Param("ids") List<String> ids, @Param("updateBy") String updateBy);
}

View File

@@ -0,0 +1,15 @@
package com.njcn.gather.tool.addledger.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.njcn.gather.tool.addledger.pojo.po.AddLedgerProjectPO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 项目信息 Mapper。
*/
public interface AddLedgerProjectMapper extends BaseMapper<AddLedgerProjectPO> {
int softDeleteByIds(@Param("ids") List<String> ids, @Param("updateBy") String updateBy);
}

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.njcn.gather.tool.addledger.mapper.AddLedgerEngineeringMapper">
<update id="softDeleteByIds">
UPDATE cs_engineering
SET status = 0,
update_by = #{updateBy},
update_time = NOW()
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
</mapper>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.njcn.gather.tool.addledger.mapper.AddLedgerEquipmentMapper">
<update id="softDeleteByIds">
UPDATE cs_equipment_delivery
SET run_status = 0,
update_by = #{updateBy},
update_time = NOW()
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
</mapper>

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.njcn.gather.tool.addledger.mapper.AddLedgerLedgerMapper">
<select id="selectTree" resultType="com.njcn.gather.tool.addledger.pojo.po.AddLedgerLedgerPO">
SELECT Id AS id,
Pid AS pid,
Pids AS pids,
Name AS name,
Level AS level,
Sort AS sort,
Remark AS remark,
State AS state
FROM cs_ledger
WHERE State = 1
<if test="keyword != null and keyword != ''">
AND Name LIKE CONCAT('%', #{keyword}, '%')
</if>
ORDER BY Level ASC, Sort ASC, Name ASC
</select>
<select id="selectActiveNode" resultType="com.njcn.gather.tool.addledger.pojo.po.AddLedgerLedgerPO">
SELECT Id AS id,
Pid AS pid,
Pids AS pids,
Name AS name,
Level AS level,
Sort AS sort,
Remark AS remark,
State AS state
FROM cs_ledger
WHERE Id = #{id}
AND Level = #{level}
AND State = 1
LIMIT 1
</select>
<select id="selectActiveSubtree" resultType="com.njcn.gather.tool.addledger.pojo.po.AddLedgerLedgerPO">
SELECT Id AS id,
Pid AS pid,
Pids AS pids,
Name AS name,
Level AS level,
Sort AS sort,
Remark AS remark,
State AS state
FROM cs_ledger
WHERE State = 1
AND (Id = #{id} OR FIND_IN_SET(#{id}, Pids) &gt; 0)
ORDER BY Level DESC
</select>
<update id="softDeleteByIds">
UPDATE cs_ledger
SET State = 0,
Update_By = #{updateBy},
Update_Time = NOW()
WHERE Id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
AND State = 1
</update>
</mapper>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.njcn.gather.tool.addledger.mapper.AddLedgerLineMapper">
<select id="selectUsedLineNos" resultType="java.lang.Integer">
SELECT line_no
FROM cs_line
WHERE device_id = #{deviceId}
AND status = 1
<if test="lineId != null and lineId != ''">
AND line_id &lt;&gt; #{lineId}
</if>
AND line_no BETWEEN 1 AND 20
</select>
<select id="countActiveLineNo" resultType="java.lang.Integer">
SELECT COUNT(1)
FROM cs_line
WHERE device_id = #{deviceId}
AND line_no = #{lineNo}
AND status = 1
<if test="lineId != null and lineId != ''">
AND line_id &lt;&gt; #{lineId}
</if>
</select>
<update id="softDeleteByIds">
UPDATE cs_line
SET status = 0,
update_by = #{updateBy},
update_time = NOW()
WHERE line_id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
</mapper>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.njcn.gather.tool.addledger.mapper.AddLedgerProjectMapper">
<update id="softDeleteByIds">
UPDATE cs_project
SET status = 0,
update_by = #{updateBy},
update_time = NOW()
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
</mapper>

View File

@@ -0,0 +1,50 @@
package com.njcn.gather.tool.addledger.pojo.constant;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* 数据台账常量。
*/
public final class AddLedgerConst {
private AddLedgerConst() {
}
public static final String ROOT_PARENT_ID = "0";
public static final int LEVEL_ENGINEERING = 0;
public static final int LEVEL_PROJECT = 1;
public static final int LEVEL_EQUIPMENT = 2;
public static final int LEVEL_LINE = 3;
public static final int STATE_DELETED = 0;
public static final int STATE_NORMAL = 1;
public static final int EQUIPMENT_RUN_STATUS_DELETED = 0;
public static final int EQUIPMENT_RUN_STATUS_OFFLINE = 1;
public static final int EQUIPMENT_STATUS_UNREGISTERED = 1;
public static final int EQUIPMENT_PROCESS_RUNNING = 4;
public static final int ENABLE = 1;
public static final int DISABLE = 0;
public static final int LINE_RUN_STATUS_RUNNING = 0;
public static final int LINE_INTERVAL_DEFAULT = 1;
public static final String LOG_LEVEL_WARN = "WARN";
public static final int MIN_LINE_NO = 1;
public static final int MAX_LINE_NO = 20;
public static final Set<Integer> CON_TYPES = new LinkedHashSet<Integer>(Arrays.asList(0, 1, 2));
public static final Set<BigDecimal> VOL_GRADES = new LinkedHashSet<BigDecimal>(Arrays.asList(
new BigDecimal("0.38"),
new BigDecimal("10"),
new BigDecimal("35"),
new BigDecimal("110"),
new BigDecimal("220"),
new BigDecimal("500")
));
}

View File

@@ -0,0 +1,31 @@
package com.njcn.gather.tool.addledger.pojo.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 工程保存参数。
*/
@Data
@ApiModel("工程保存参数")
public class AddLedgerEngineeringSaveParam {
@ApiModelProperty("工程ID")
private String id;
@ApiModelProperty(value = "工程名称", required = true)
@NotBlank(message = "工程名称不能为空")
private String name;
@ApiModelProperty("")
private String province;
@ApiModelProperty("")
private String city;
@ApiModelProperty("描述")
private String description;
}

View File

@@ -0,0 +1,52 @@
package com.njcn.gather.tool.addledger.pojo.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 设备保存参数。
*/
@Data
@ApiModel("设备保存参数")
public class AddLedgerEquipmentSaveParam {
@ApiModelProperty("设备ID")
private String id;
@ApiModelProperty("父级项目ID")
private String projectId;
@ApiModelProperty(value = "装置名称", required = true)
@NotBlank(message = "设备名称不能为空")
private String name;
@ApiModelProperty(value = "网络设备ID", required = true)
@NotBlank(message = "设备 ndid 不能为空")
private String ndid;
@ApiModelProperty(value = "装置 MAC 地址", required = true)
@NotBlank(message = "设备 mac 不能为空")
private String mac;
@ApiModelProperty("装置类型")
private String devType;
@ApiModelProperty(value = "装置型号", required = true)
@NotBlank(message = "设备 dev_model 不能为空")
private String devModel;
@ApiModelProperty("装置接入方式")
private String devAccessMethod;
@ApiModelProperty("前置服务器IP")
private String nodeId;
@ApiModelProperty("前置进程号")
private Integer nodeProcess;
@ApiModelProperty("是否支持升级")
private Integer upgrade;
}

View File

@@ -0,0 +1,95 @@
package com.njcn.gather.tool.addledger.pojo.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
/**
* 测点保存参数。
*/
@Data
@ApiModel("测点保存参数")
public class AddLedgerLineSaveParam {
@ApiModelProperty("测点ID")
private String lineId;
@ApiModelProperty("父级设备ID")
private String deviceId;
@ApiModelProperty(value = "监测点名", required = true)
@NotBlank(message = "测点名称不能为空")
private String name;
@ApiModelProperty(value = "线路号", required = true)
@NotNull(message = "line_no 不能为空")
@Min(value = 1, message = "line_no 必须在 1-20 之间")
@Max(value = 20, message = "line_no 必须在 1-20 之间")
private Integer lineNo;
@ApiModelProperty(value = "接线方式", required = true)
@NotNull(message = "conType 不能为空")
private Integer conType;
@ApiModelProperty(value = "电压等级", required = true)
@NotNull(message = "vol_grade 不能为空")
private BigDecimal volGrade;
@ApiModelProperty("安装位置")
private String position;
@ApiModelProperty(value = "CT 一次额定值", required = true)
@NotNull(message = "ct_ratio 不能为空")
@DecimalMin(value = "0", inclusive = true, message = "ct_ratio 不能为负数")
private BigDecimal ctRatio;
@ApiModelProperty(value = "CT 二次额定值", required = true)
@NotNull(message = "ct2_ratio 不能为空")
@DecimalMin(value = "0", inclusive = true, message = "ct2_ratio 不能为负数")
private BigDecimal ct2Ratio;
@ApiModelProperty(value = "PT 一次额定值", required = true)
@NotNull(message = "pt_ratio 不能为空")
@DecimalMin(value = "0", inclusive = true, message = "pt_ratio 不能为负数")
private BigDecimal ptRatio;
@ApiModelProperty(value = "PT 二次额定值", required = true)
@NotNull(message = "pt2_ratio 不能为空")
@DecimalMin(value = "0", inclusive = true, message = "pt2_ratio 不能为负数")
private BigDecimal pt2Ratio;
@ApiModelProperty("最小短路容量(MVA)")
@DecimalMin(value = "0", inclusive = true, message = "short_circuit_capacity 不能为负数")
private BigDecimal shortCircuitCapacity;
@ApiModelProperty("供电设备容量(MVA)")
@DecimalMin(value = "0", inclusive = true, message = "dev_capacity 不能为负数")
private BigDecimal devCapacity;
@ApiModelProperty("基准短路容量(MVA)")
@DecimalMin(value = "0", inclusive = true, message = "basic_capacity 不能为负数")
private BigDecimal basicCapacity;
@ApiModelProperty("用户协议容量(MVA)")
@DecimalMin(value = "0", inclusive = true, message = "protocol_capacity 不能为负数")
private BigDecimal protocolCapacity;
@ApiModelProperty("监测对象类型")
private String monitorObj;
@ApiModelProperty("是否治理")
private Integer isGovern;
@ApiModelProperty("敏感用户")
private String monitorUser;
@ApiModelProperty("是否主要监测点")
private Integer isImportant;
}

View File

@@ -0,0 +1,31 @@
package com.njcn.gather.tool.addledger.pojo.param;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* 项目保存参数。
*/
@Data
@ApiModel("项目保存参数")
public class AddLedgerProjectSaveParam {
@ApiModelProperty("项目ID")
private String id;
@ApiModelProperty("父级工程ID")
private String engineeringId;
@ApiModelProperty(value = "项目名称", required = true)
@NotBlank(message = "项目名称不能为空")
private String name;
@ApiModelProperty("相对位置")
private String area;
@ApiModelProperty("项目描述")
private String description;
}

View File

@@ -0,0 +1,31 @@
package com.njcn.gather.tool.addledger.pojo.po;
import com.baomidou.mybatisplus.annotation.TableName;
import com.njcn.db.mybatisplus.bo.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 工程信息。
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("cs_engineering")
public class AddLedgerEngineeringPO extends BaseEntity {
private static final long serialVersionUID = 1L;
private String id;
private String name;
private String province;
private String city;
private String description;
private Integer status;
private Integer sort;
}

View File

@@ -0,0 +1,63 @@
package com.njcn.gather.tool.addledger.pojo.po;
import com.baomidou.mybatisplus.annotation.TableName;
import com.njcn.db.mybatisplus.bo.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 设备出厂信息。
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("cs_equipment_delivery")
public class AddLedgerEquipmentPO extends BaseEntity {
private static final long serialVersionUID = 1L;
private String id;
private String name;
private String ndid;
private String mac;
private String devType;
private String devModel;
private String cntractNo;
private Integer runStatus;
private Integer status;
private String devAccessMethod;
private String softinfoId;
private Integer moduleNumber;
private Integer process;
private String qrPath;
private Integer usageStatus;
private Integer sort;
private String nodeId;
private Integer nodeProcess;
private String devLogLevel;
private String associatedEngineering;
private String associatedProject;
private String icd;
private Integer upgrade;
}

View File

@@ -0,0 +1,43 @@
package com.njcn.gather.tool.addledger.pojo.po;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.njcn.db.mybatisplus.bo.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 台账树节点。
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("cs_ledger")
public class AddLedgerLedgerPO extends BaseEntity {
private static final long serialVersionUID = 1L;
@TableId("Id")
private String id;
@TableField("Pid")
private String pid;
@TableField("Pids")
private String pids;
@TableField("Name")
private String name;
@TableField("Level")
private Integer level;
@TableField("Sort")
private Integer sort;
@TableField("Remark")
private String remark;
@TableField("State")
private Integer state;
}

View File

@@ -0,0 +1,78 @@
package com.njcn.gather.tool.addledger.pojo.po;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.njcn.db.mybatisplus.bo.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
/**
* 监测点信息。
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("cs_line")
public class AddLedgerLinePO extends BaseEntity {
private static final long serialVersionUID = 1L;
@TableId("line_id")
private String lineId;
private String name;
private String deviceId;
private String dataSetId;
private String dataModelId;
private String position;
private BigDecimal volGrade;
private Integer runStatus;
@TableField("conType")
private Integer conType;
private BigDecimal ptRatio;
private BigDecimal pt2Ratio;
private BigDecimal ctRatio;
private BigDecimal ct2Ratio;
private Integer status;
@TableField("clDid")
private Integer clDid;
private Integer lineInterval;
private Integer lineNo;
private BigDecimal shortCircuitCapacity;
private BigDecimal devCapacity;
private BigDecimal basicCapacity;
private BigDecimal protocolCapacity;
private String monitorObj;
private Integer isGovern;
private String monitorUser;
private String reportFilePath;
private String lineLogLevel;
private Integer isImportant;
}

View File

@@ -0,0 +1,29 @@
package com.njcn.gather.tool.addledger.pojo.po;
import com.baomidou.mybatisplus.annotation.TableName;
import com.njcn.db.mybatisplus.bo.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 项目信息。
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("cs_project")
public class AddLedgerProjectPO extends BaseEntity {
private static final long serialVersionUID = 1L;
private String id;
private String name;
private String area;
private String description;
private Integer status;
private Integer sort;
}

View File

@@ -0,0 +1,80 @@
package com.njcn.gather.tool.addledger.pojo.vo;
import lombok.Data;
import java.math.BigDecimal;
/**
* 台账节点详情。
*/
@Data
public class AddLedgerDetailVO {
private String id;
private Integer level;
private String parentId;
private String parentIds;
private String name;
private Integer sort;
private String province;
private String city;
private String description;
private String area;
private String ndid;
private String mac;
private String devType;
private String devModel;
private String devAccessMethod;
private String nodeId;
private Integer nodeProcess;
private Integer upgrade;
private String position;
private Integer lineNo;
private Integer conType;
private BigDecimal volGrade;
private BigDecimal ctRatio;
private BigDecimal ct2Ratio;
private BigDecimal ptRatio;
private BigDecimal pt2Ratio;
private BigDecimal shortCircuitCapacity;
private BigDecimal devCapacity;
private BigDecimal basicCapacity;
private BigDecimal protocolCapacity;
private String monitorObj;
private Integer isGovern;
private String monitorUser;
private Integer isImportant;
}

View File

@@ -0,0 +1,27 @@
package com.njcn.gather.tool.addledger.pojo.vo;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
* 台账树节点。
*/
@Data
public class AddLedgerTreeNodeVO {
private String id;
private String parentId;
private String parentIds;
private String name;
private Integer level;
private Integer sort;
private List<AddLedgerTreeNodeVO> children = new ArrayList<AddLedgerTreeNodeVO>();
}

View File

@@ -0,0 +1,32 @@
package com.njcn.gather.tool.addledger.service;
import com.njcn.gather.tool.addledger.pojo.param.AddLedgerEngineeringSaveParam;
import com.njcn.gather.tool.addledger.pojo.param.AddLedgerEquipmentSaveParam;
import com.njcn.gather.tool.addledger.pojo.param.AddLedgerLineSaveParam;
import com.njcn.gather.tool.addledger.pojo.param.AddLedgerProjectSaveParam;
import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerDetailVO;
import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerTreeNodeVO;
import java.util.List;
/**
* 数据台账服务。
*/
public interface AddLedgerService {
List<AddLedgerTreeNodeVO> tree(String keyword);
AddLedgerDetailVO detail(String id, Integer level);
AddLedgerDetailVO saveEngineering(AddLedgerEngineeringSaveParam param);
AddLedgerDetailVO saveProject(AddLedgerProjectSaveParam param);
AddLedgerDetailVO saveEquipment(AddLedgerEquipmentSaveParam param);
AddLedgerDetailVO saveLine(AddLedgerLineSaveParam param);
List<Integer> availableLineNos(String deviceId, String lineId);
boolean deleteNode(String id, Integer level);
}

View File

@@ -0,0 +1,498 @@
package com.njcn.gather.tool.addledger.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.njcn.gather.tool.addledger.component.AddLedgerTreeBuilder;
import com.njcn.gather.tool.addledger.mapper.AddLedgerEngineeringMapper;
import com.njcn.gather.tool.addledger.mapper.AddLedgerEquipmentMapper;
import com.njcn.gather.tool.addledger.mapper.AddLedgerLedgerMapper;
import com.njcn.gather.tool.addledger.mapper.AddLedgerLineMapper;
import com.njcn.gather.tool.addledger.mapper.AddLedgerProjectMapper;
import com.njcn.gather.tool.addledger.pojo.constant.AddLedgerConst;
import com.njcn.gather.tool.addledger.pojo.param.AddLedgerEngineeringSaveParam;
import com.njcn.gather.tool.addledger.pojo.param.AddLedgerEquipmentSaveParam;
import com.njcn.gather.tool.addledger.pojo.param.AddLedgerLineSaveParam;
import com.njcn.gather.tool.addledger.pojo.param.AddLedgerProjectSaveParam;
import com.njcn.gather.tool.addledger.pojo.po.AddLedgerEngineeringPO;
import com.njcn.gather.tool.addledger.pojo.po.AddLedgerEquipmentPO;
import com.njcn.gather.tool.addledger.pojo.po.AddLedgerLedgerPO;
import com.njcn.gather.tool.addledger.pojo.po.AddLedgerLinePO;
import com.njcn.gather.tool.addledger.pojo.po.AddLedgerProjectPO;
import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerDetailVO;
import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerTreeNodeVO;
import com.njcn.gather.tool.addledger.service.AddLedgerService;
import com.njcn.gather.tool.addledger.util.AddLedgerIdUtil;
import com.njcn.gather.tool.addledger.util.AddLedgerLineNoUtil;
import com.njcn.web.utils.RequestUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* 数据台账服务实现。
*/
@Service
@RequiredArgsConstructor
public class AddLedgerServiceImpl implements AddLedgerService {
private final AddLedgerEngineeringMapper engineeringMapper;
private final AddLedgerProjectMapper projectMapper;
private final AddLedgerEquipmentMapper equipmentMapper;
private final AddLedgerLineMapper lineMapper;
private final AddLedgerLedgerMapper ledgerMapper;
private final AddLedgerTreeBuilder treeBuilder;
@Override
public List<AddLedgerTreeNodeVO> tree(String keyword) {
return treeBuilder.buildTree(ledgerMapper.selectTree(trimToNull(keyword)));
}
@Override
public AddLedgerDetailVO detail(String id, Integer level) {
AddLedgerLedgerPO ledger = requireLedger(id, level);
if (AddLedgerConst.LEVEL_ENGINEERING == level) {
return buildEngineeringDetail(ledger, requireEngineering(id));
}
if (AddLedgerConst.LEVEL_PROJECT == level) {
return buildProjectDetail(ledger, requireProject(id));
}
if (AddLedgerConst.LEVEL_EQUIPMENT == level) {
return buildEquipmentDetail(ledger, requireEquipment(id));
}
if (AddLedgerConst.LEVEL_LINE == level) {
return buildLineDetail(ledger, requireLine(id));
}
throw new IllegalArgumentException("不支持的台账层级");
}
@Override
@Transactional
public AddLedgerDetailVO saveEngineering(AddLedgerEngineeringSaveParam param) {
String name = requireText(param == null ? null : param.getName(), "工程名称不能为空");
boolean create = isBlank(param.getId());
String id = create ? AddLedgerIdUtil.nextId() : param.getId().trim();
AddLedgerEngineeringPO engineering = create ? new AddLedgerEngineeringPO() : requireEngineering(id);
engineering.setId(id);
engineering.setName(name);
engineering.setProvince(trimToNull(param.getProvince()));
engineering.setCity(trimToNull(param.getCity()));
engineering.setDescription(trimToNull(param.getDescription()));
if (create) {
engineering.setStatus(AddLedgerConst.STATE_NORMAL);
engineering.setSort(0);
engineeringMapper.insert(engineering);
saveLedger(id, AddLedgerConst.ROOT_PARENT_ID, AddLedgerConst.ROOT_PARENT_ID, name, AddLedgerConst.LEVEL_ENGINEERING);
} else {
engineeringMapper.updateById(engineering);
updateLedgerName(id, AddLedgerConst.LEVEL_ENGINEERING, name);
}
return detail(id, AddLedgerConst.LEVEL_ENGINEERING);
}
@Override
@Transactional
public AddLedgerDetailVO saveProject(AddLedgerProjectSaveParam param) {
String name = requireText(param == null ? null : param.getName(), "项目名称不能为空");
boolean create = isBlank(param.getId());
String id = create ? AddLedgerIdUtil.nextId() : param.getId().trim();
AddLedgerLedgerPO parentLedger;
if (create) {
parentLedger = requireLedger(param.getEngineeringId(), AddLedgerConst.LEVEL_ENGINEERING);
} else {
parentLedger = requireLedger(requireLedger(id, AddLedgerConst.LEVEL_PROJECT).getPid(), AddLedgerConst.LEVEL_ENGINEERING);
}
AddLedgerProjectPO project = create ? new AddLedgerProjectPO() : requireProject(id);
project.setId(id);
project.setName(name);
project.setArea(trimToNull(param.getArea()));
project.setDescription(trimToNull(param.getDescription()));
if (create) {
project.setStatus(AddLedgerConst.STATE_NORMAL);
project.setSort(0);
projectMapper.insert(project);
saveLedger(id, parentLedger.getId(), buildChildPids(parentLedger), name, AddLedgerConst.LEVEL_PROJECT);
} else {
projectMapper.updateById(project);
updateLedgerName(id, AddLedgerConst.LEVEL_PROJECT, name);
}
return detail(id, AddLedgerConst.LEVEL_PROJECT);
}
@Override
@Transactional
public AddLedgerDetailVO saveEquipment(AddLedgerEquipmentSaveParam param) {
validateEquipmentParam(param);
boolean create = isBlank(param.getId());
String id = create ? AddLedgerIdUtil.nextId() : param.getId().trim();
AddLedgerLedgerPO projectLedger;
if (create) {
projectLedger = requireLedger(param.getProjectId(), AddLedgerConst.LEVEL_PROJECT);
} else {
projectLedger = requireLedger(requireLedger(id, AddLedgerConst.LEVEL_EQUIPMENT).getPid(), AddLedgerConst.LEVEL_PROJECT);
}
AddLedgerLedgerPO engineeringLedger = requireLedger(projectLedger.getPid(), AddLedgerConst.LEVEL_ENGINEERING);
AddLedgerEquipmentPO equipment = create ? new AddLedgerEquipmentPO() : requireEquipment(id);
equipment.setId(id);
equipment.setName(param.getName().trim());
equipment.setNdid(param.getNdid().trim());
equipment.setMac(param.getMac().trim());
equipment.setDevType(trimToNull(param.getDevType()));
equipment.setDevModel(param.getDevModel().trim());
equipment.setDevAccessMethod(trimToNull(param.getDevAccessMethod()));
equipment.setNodeId(trimToNull(param.getNodeId()));
equipment.setNodeProcess(param.getNodeProcess());
equipment.setUpgrade(param.getUpgrade() == null ? AddLedgerConst.DISABLE : param.getUpgrade());
equipment.setAssociatedEngineering(engineeringLedger.getId());
equipment.setAssociatedProject(projectLedger.getId());
if (create) {
equipment.setRunStatus(AddLedgerConst.EQUIPMENT_RUN_STATUS_OFFLINE);
equipment.setStatus(AddLedgerConst.EQUIPMENT_STATUS_UNREGISTERED);
equipment.setProcess(AddLedgerConst.EQUIPMENT_PROCESS_RUNNING);
equipment.setUsageStatus(AddLedgerConst.ENABLE);
equipment.setSort(0);
equipmentMapper.insert(equipment);
saveLedger(id, projectLedger.getId(), buildChildPids(projectLedger), equipment.getName(), AddLedgerConst.LEVEL_EQUIPMENT);
} else {
equipmentMapper.updateById(equipment);
updateLedgerName(id, AddLedgerConst.LEVEL_EQUIPMENT, equipment.getName());
}
return detail(id, AddLedgerConst.LEVEL_EQUIPMENT);
}
@Override
@Transactional
public AddLedgerDetailVO saveLine(AddLedgerLineSaveParam param) {
validateLineParam(param);
boolean create = isBlank(param.getLineId());
String id = create ? AddLedgerIdUtil.nextId() : param.getLineId().trim();
AddLedgerLedgerPO equipmentLedger;
if (create) {
equipmentLedger = requireLedger(param.getDeviceId(), AddLedgerConst.LEVEL_EQUIPMENT);
} else {
equipmentLedger = requireLedger(requireLedger(id, AddLedgerConst.LEVEL_LINE).getPid(), AddLedgerConst.LEVEL_EQUIPMENT);
}
assertLineNoUnique(equipmentLedger.getId(), param.getLineNo(), create ? null : id);
AddLedgerLinePO line = create ? new AddLedgerLinePO() : requireLine(id);
line.setLineId(id);
line.setName(param.getName().trim());
line.setDeviceId(equipmentLedger.getId());
line.setLineNo(param.getLineNo());
line.setConType(param.getConType());
line.setVolGrade(param.getVolGrade());
line.setPosition(trimToNull(param.getPosition()));
line.setCtRatio(param.getCtRatio());
line.setCt2Ratio(param.getCt2Ratio());
line.setPtRatio(param.getPtRatio());
line.setPt2Ratio(param.getPt2Ratio());
line.setShortCircuitCapacity(param.getShortCircuitCapacity());
line.setDevCapacity(param.getDevCapacity());
line.setBasicCapacity(param.getBasicCapacity());
line.setProtocolCapacity(param.getProtocolCapacity());
line.setMonitorObj(trimToNull(param.getMonitorObj()));
line.setIsGovern(param.getIsGovern() == null ? AddLedgerConst.DISABLE : param.getIsGovern());
line.setMonitorUser(trimToNull(param.getMonitorUser()));
line.setIsImportant(param.getIsImportant() == null ? AddLedgerConst.DISABLE : param.getIsImportant());
if (create) {
line.setStatus(AddLedgerConst.STATE_NORMAL);
line.setRunStatus(AddLedgerConst.LINE_RUN_STATUS_RUNNING);
line.setLineInterval(AddLedgerConst.LINE_INTERVAL_DEFAULT);
line.setLineLogLevel(AddLedgerConst.LOG_LEVEL_WARN);
lineMapper.insert(line);
saveLedger(id, equipmentLedger.getId(), buildChildPids(equipmentLedger), line.getName(), AddLedgerConst.LEVEL_LINE);
} else {
lineMapper.updateById(line);
updateLedgerName(id, AddLedgerConst.LEVEL_LINE, line.getName());
}
return detail(id, AddLedgerConst.LEVEL_LINE);
}
@Override
public List<Integer> availableLineNos(String deviceId, String lineId) {
AddLedgerLedgerPO equipmentLedger = requireLedger(deviceId, AddLedgerConst.LEVEL_EQUIPMENT);
List<Integer> usedLineNos = lineMapper.selectUsedLineNos(equipmentLedger.getId(), trimToNull(lineId));
return AddLedgerLineNoUtil.resolveAvailableLineNos(usedLineNos, null);
}
@Override
@Transactional
public boolean deleteNode(String id, Integer level) {
requireLedger(id, level);
List<AddLedgerLedgerPO> subtree = ledgerMapper.selectActiveSubtree(id);
if (subtree.isEmpty()) {
return false;
}
List<String> engineeringIds = new ArrayList<String>();
List<String> projectIds = new ArrayList<String>();
List<String> equipmentIds = new ArrayList<String>();
List<String> lineIds = new ArrayList<String>();
List<String> ledgerIds = new ArrayList<String>();
for (AddLedgerLedgerPO node : subtree) {
ledgerIds.add(node.getId());
if (AddLedgerConst.LEVEL_ENGINEERING == node.getLevel()) {
engineeringIds.add(node.getId());
} else if (AddLedgerConst.LEVEL_PROJECT == node.getLevel()) {
projectIds.add(node.getId());
} else if (AddLedgerConst.LEVEL_EQUIPMENT == node.getLevel()) {
equipmentIds.add(node.getId());
} else if (AddLedgerConst.LEVEL_LINE == node.getLevel()) {
lineIds.add(node.getId());
}
}
String updateBy = currentUserId();
if (!lineIds.isEmpty()) {
lineMapper.softDeleteByIds(lineIds, updateBy);
}
if (!equipmentIds.isEmpty()) {
equipmentMapper.softDeleteByIds(equipmentIds, updateBy);
}
if (!projectIds.isEmpty()) {
projectMapper.softDeleteByIds(projectIds, updateBy);
}
if (!engineeringIds.isEmpty()) {
engineeringMapper.softDeleteByIds(engineeringIds, updateBy);
}
ledgerMapper.softDeleteByIds(ledgerIds, updateBy);
return true;
}
private void validateEquipmentParam(AddLedgerEquipmentSaveParam param) {
if (param == null) {
throw new IllegalArgumentException("设备参数不能为空");
}
requireText(param.getName(), "设备名称不能为空");
requireText(param.getNdid(), "设备 ndid 不能为空");
requireText(param.getMac(), "设备 mac 不能为空");
requireText(param.getDevModel(), "设备 dev_model 不能为空");
}
private void validateLineParam(AddLedgerLineSaveParam param) {
if (param == null) {
throw new IllegalArgumentException("测点参数不能为空");
}
requireText(param.getName(), "测点名称不能为空");
if (param.getLineNo() == null
|| param.getLineNo() < AddLedgerConst.MIN_LINE_NO
|| param.getLineNo() > AddLedgerConst.MAX_LINE_NO) {
throw new IllegalArgumentException("line_no 必须在 1-20 之间");
}
if (!AddLedgerConst.CON_TYPES.contains(param.getConType())) {
throw new IllegalArgumentException("conType 只能是 0、1、2");
}
if (!containsVolGrade(param.getVolGrade())) {
throw new IllegalArgumentException("vol_grade 只能是 0.38、10、35、110、220、500");
}
requireNonNegative(param.getCtRatio(), "ct_ratio 不能为空且不能为负数");
requireNonNegative(param.getCt2Ratio(), "ct2_ratio 不能为空且不能为负数");
requireNonNegative(param.getPtRatio(), "pt_ratio 不能为空且不能为负数");
requireNonNegative(param.getPt2Ratio(), "pt2_ratio 不能为空且不能为负数");
requireNonNegativeIfPresent(param.getShortCircuitCapacity(), "short_circuit_capacity 不能为负数");
requireNonNegativeIfPresent(param.getDevCapacity(), "dev_capacity 不能为负数");
requireNonNegativeIfPresent(param.getBasicCapacity(), "basic_capacity 不能为负数");
requireNonNegativeIfPresent(param.getProtocolCapacity(), "protocol_capacity 不能为负数");
}
private void assertLineNoUnique(String deviceId, Integer lineNo, String lineId) {
int count = lineMapper.countActiveLineNo(deviceId, lineNo, lineId);
if (count > 0) {
throw new IllegalArgumentException("同设备下 line_no 不可重复");
}
}
private AddLedgerLedgerPO requireLedger(String id, Integer level) {
String nodeId = requireText(id, "台账节点 ID 不能为空");
if (level == null) {
throw new IllegalArgumentException("台账节点层级不能为空");
}
AddLedgerLedgerPO ledger = ledgerMapper.selectActiveNode(nodeId, level);
if (ledger == null) {
throw new IllegalArgumentException("台账节点不存在或已删除");
}
return ledger;
}
private AddLedgerEngineeringPO requireEngineering(String id) {
AddLedgerEngineeringPO engineering = engineeringMapper.selectOne(new LambdaQueryWrapper<AddLedgerEngineeringPO>()
.eq(AddLedgerEngineeringPO::getId, id)
.eq(AddLedgerEngineeringPO::getStatus, AddLedgerConst.STATE_NORMAL));
if (engineering == null) {
throw new IllegalArgumentException("工程不存在或已删除");
}
return engineering;
}
private AddLedgerProjectPO requireProject(String id) {
AddLedgerProjectPO project = projectMapper.selectOne(new LambdaQueryWrapper<AddLedgerProjectPO>()
.eq(AddLedgerProjectPO::getId, id)
.eq(AddLedgerProjectPO::getStatus, AddLedgerConst.STATE_NORMAL));
if (project == null) {
throw new IllegalArgumentException("项目不存在或已删除");
}
return project;
}
private AddLedgerEquipmentPO requireEquipment(String id) {
AddLedgerEquipmentPO equipment = equipmentMapper.selectOne(new LambdaQueryWrapper<AddLedgerEquipmentPO>()
.eq(AddLedgerEquipmentPO::getId, id)
.ne(AddLedgerEquipmentPO::getRunStatus, AddLedgerConst.EQUIPMENT_RUN_STATUS_DELETED));
if (equipment == null) {
throw new IllegalArgumentException("设备不存在或已删除");
}
return equipment;
}
private AddLedgerLinePO requireLine(String id) {
AddLedgerLinePO line = lineMapper.selectOne(new LambdaQueryWrapper<AddLedgerLinePO>()
.eq(AddLedgerLinePO::getLineId, id)
.eq(AddLedgerLinePO::getStatus, AddLedgerConst.STATE_NORMAL));
if (line == null) {
throw new IllegalArgumentException("测点不存在或已删除");
}
return line;
}
private void saveLedger(String id, String pid, String pids, String name, Integer level) {
AddLedgerLedgerPO ledger = new AddLedgerLedgerPO();
ledger.setId(id);
ledger.setPid(pid);
ledger.setPids(pids);
ledger.setName(name);
ledger.setLevel(level);
ledger.setSort(0);
ledger.setState(AddLedgerConst.STATE_NORMAL);
ledgerMapper.insert(ledger);
}
private void updateLedgerName(String id, Integer level, String name) {
AddLedgerLedgerPO ledger = requireLedger(id, level);
ledger.setName(name);
ledgerMapper.updateById(ledger);
}
private String buildChildPids(AddLedgerLedgerPO parent) {
return parent.getPids() + "," + parent.getId();
}
private AddLedgerDetailVO buildEngineeringDetail(AddLedgerLedgerPO ledger, AddLedgerEngineeringPO engineering) {
AddLedgerDetailVO detail = buildBaseDetail(ledger);
detail.setName(engineering.getName());
detail.setProvince(engineering.getProvince());
detail.setCity(engineering.getCity());
detail.setDescription(engineering.getDescription());
return detail;
}
private AddLedgerDetailVO buildProjectDetail(AddLedgerLedgerPO ledger, AddLedgerProjectPO project) {
AddLedgerDetailVO detail = buildBaseDetail(ledger);
detail.setName(project.getName());
detail.setArea(project.getArea());
detail.setDescription(project.getDescription());
return detail;
}
private AddLedgerDetailVO buildEquipmentDetail(AddLedgerLedgerPO ledger, AddLedgerEquipmentPO equipment) {
AddLedgerDetailVO detail = buildBaseDetail(ledger);
detail.setName(equipment.getName());
detail.setNdid(equipment.getNdid());
detail.setMac(equipment.getMac());
detail.setDevType(equipment.getDevType());
detail.setDevModel(equipment.getDevModel());
detail.setDevAccessMethod(equipment.getDevAccessMethod());
detail.setNodeId(equipment.getNodeId());
detail.setNodeProcess(equipment.getNodeProcess());
detail.setUpgrade(equipment.getUpgrade());
return detail;
}
private AddLedgerDetailVO buildLineDetail(AddLedgerLedgerPO ledger, AddLedgerLinePO line) {
AddLedgerDetailVO detail = buildBaseDetail(ledger);
detail.setName(line.getName());
detail.setLineNo(line.getLineNo());
detail.setConType(line.getConType());
detail.setVolGrade(line.getVolGrade());
detail.setPosition(line.getPosition());
detail.setCtRatio(line.getCtRatio());
detail.setCt2Ratio(line.getCt2Ratio());
detail.setPtRatio(line.getPtRatio());
detail.setPt2Ratio(line.getPt2Ratio());
detail.setShortCircuitCapacity(line.getShortCircuitCapacity());
detail.setDevCapacity(line.getDevCapacity());
detail.setBasicCapacity(line.getBasicCapacity());
detail.setProtocolCapacity(line.getProtocolCapacity());
detail.setMonitorObj(line.getMonitorObj());
detail.setIsGovern(line.getIsGovern());
detail.setMonitorUser(line.getMonitorUser());
detail.setIsImportant(line.getIsImportant());
return detail;
}
private AddLedgerDetailVO buildBaseDetail(AddLedgerLedgerPO ledger) {
AddLedgerDetailVO detail = new AddLedgerDetailVO();
detail.setId(ledger.getId());
detail.setLevel(ledger.getLevel());
detail.setParentId(ledger.getPid());
detail.setParentIds(ledger.getPids());
detail.setSort(ledger.getSort());
detail.setName(ledger.getName());
return detail;
}
private boolean containsVolGrade(BigDecimal volGrade) {
if (volGrade == null) {
return false;
}
for (BigDecimal supported : AddLedgerConst.VOL_GRADES) {
if (supported.compareTo(volGrade) == 0) {
return true;
}
}
return false;
}
private void requireNonNegative(BigDecimal value, String message) {
if (value == null || value.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException(message);
}
}
private void requireNonNegativeIfPresent(BigDecimal value, String message) {
if (value != null && value.compareTo(BigDecimal.ZERO) < 0) {
throw new IllegalArgumentException(message);
}
}
private String requireText(String value, String message) {
String text = trimToNull(value);
if (text == null) {
throw new IllegalArgumentException(message);
}
return text;
}
private String trimToNull(String value) {
if (value == null) {
return null;
}
String trimmed = value.trim();
return trimmed.isEmpty() ? null : trimmed;
}
private boolean isBlank(String value) {
return trimToNull(value) == null;
}
private String currentUserId() {
try {
String userId = RequestUtil.getUserId();
return isBlank(userId) ? "未知用户" : userId;
} catch (Exception e) {
return "未知用户";
}
}
}

View File

@@ -0,0 +1,16 @@
package com.njcn.gather.tool.addledger.util;
import java.util.UUID;
/**
* 数据台账 ID 工具。
*/
public final class AddLedgerIdUtil {
private AddLedgerIdUtil() {
}
public static String nextId() {
return UUID.randomUUID().toString().replace("-", "");
}
}

View File

@@ -0,0 +1,31 @@
package com.njcn.gather.tool.addledger.util;
import com.njcn.gather.tool.addledger.pojo.constant.AddLedgerConst;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 数据台账测点线路号工具。
*/
public final class AddLedgerLineNoUtil {
private AddLedgerLineNoUtil() {
}
public static List<Integer> resolveAvailableLineNos(List<Integer> usedLineNos, Integer currentLineNo) {
Set<Integer> usedSet = new HashSet<Integer>();
if (usedLineNos != null) {
usedSet.addAll(usedLineNos);
}
List<Integer> result = new ArrayList<Integer>();
for (int lineNo = AddLedgerConst.MIN_LINE_NO; lineNo <= AddLedgerConst.MAX_LINE_NO; lineNo++) {
if (!usedSet.contains(lineNo) || Integer.valueOf(lineNo).equals(currentLineNo)) {
result.add(lineNo);
}
}
return result;
}
}

View File

@@ -0,0 +1,224 @@
/*
Navicat/MySQL 初始化脚本
用途:
1. 初始化 add-ledger 台账设备相关字典。
2. 脚本可重复执行,按字典编码避免重复插入。
说明:
- dev_type 对应 cs_equipment_delivery.dev_type保存 sys_dict_data.id。
- dev_model 对应 cs_equipment_delivery.dev_model保存 sys_dict_data.id。
*/
SET NAMES utf8mb4;
-- ----------------------------
-- 字典类型:装置类型
-- ----------------------------
SET @ledger_device_type_type_id := (
SELECT `id`
FROM `sys_dict_type`
WHERE `code` = 'ledger_device_type'
AND `state` = 1
LIMIT 1
);
INSERT INTO `sys_dict_type` (
`id`, `name`, `code`, `sort`, `open_level`, `open_describe`, `remark`, `state`,
`create_by`, `create_time`, `update_by`, `update_time`
)
SELECT
'7f91c2a1e9f44b47a6e7c8b227d00101',
'装置类型',
'ledger_device_type',
1,
0,
0,
'数据台账设备装置类型',
1,
'system',
NOW(),
'system',
NOW()
WHERE @ledger_device_type_type_id IS NULL;
SET @ledger_device_type_type_id := (
SELECT `id`
FROM `sys_dict_type`
WHERE `code` = 'ledger_device_type'
AND `state` = 1
LIMIT 1
);
INSERT INTO `sys_dict_data` (
`id`, `type_id`, `name`, `code`, `sort`, `level`, `algo_describe`, `value`, `open_value`, `state`,
`create_by`, `create_time`, `update_by`, `update_time`
)
SELECT
'7f91c2a1e9f44b47a6e7c8b227d10101',
@ledger_device_type_type_id,
'直连设备',
'direct_device',
1,
0,
NULL,
NULL,
0,
1,
'system',
NOW(),
'system',
NOW()
WHERE NOT EXISTS (
SELECT 1
FROM `sys_dict_data`
WHERE `type_id` = @ledger_device_type_type_id
AND `code` = 'direct_device'
AND `state` = 1
);
INSERT INTO `sys_dict_data` (
`id`, `type_id`, `name`, `code`, `sort`, `level`, `algo_describe`, `value`, `open_value`, `state`,
`create_by`, `create_time`, `update_by`, `update_time`
)
SELECT
'7f91c2a1e9f44b47a6e7c8b227d10102',
@ledger_device_type_type_id,
'网关',
'gateway',
2,
0,
NULL,
NULL,
0,
1,
'system',
NOW(),
'system',
NOW()
WHERE NOT EXISTS (
SELECT 1
FROM `sys_dict_data`
WHERE `type_id` = @ledger_device_type_type_id
AND `code` = 'gateway'
AND `state` = 1
);
INSERT INTO `sys_dict_data` (
`id`, `type_id`, `name`, `code`, `sort`, `level`, `algo_describe`, `value`, `open_value`, `state`,
`create_by`, `create_time`, `update_by`, `update_time`
)
SELECT
'7f91c2a1e9f44b47a6e7c8b227d10103',
@ledger_device_type_type_id,
'装置',
'device',
3,
0,
NULL,
NULL,
0,
1,
'system',
NOW(),
'system',
NOW()
WHERE NOT EXISTS (
SELECT 1
FROM `sys_dict_data`
WHERE `type_id` = @ledger_device_type_type_id
AND `code` = 'device'
AND `state` = 1
);
-- ----------------------------
-- 字典类型:装置型号
-- ----------------------------
SET @ledger_device_model_type_id := (
SELECT `id`
FROM `sys_dict_type`
WHERE `code` = 'ledger_device_model'
AND `state` = 1
LIMIT 1
);
INSERT INTO `sys_dict_type` (
`id`, `name`, `code`, `sort`, `open_level`, `open_describe`, `remark`, `state`,
`create_by`, `create_time`, `update_by`, `update_time`
)
SELECT
'7f91c2a1e9f44b47a6e7c8b227d00201',
'装置型号',
'ledger_device_model',
2,
0,
0,
'数据台账设备装置型号',
1,
'system',
NOW(),
'system',
NOW()
WHERE @ledger_device_model_type_id IS NULL;
SET @ledger_device_model_type_id := (
SELECT `id`
FROM `sys_dict_type`
WHERE `code` = 'ledger_device_model'
AND `state` = 1
LIMIT 1
);
INSERT INTO `sys_dict_data` (
`id`, `type_id`, `name`, `code`, `sort`, `level`, `algo_describe`, `value`, `open_value`, `state`,
`create_by`, `create_time`, `update_by`, `update_time`
)
SELECT
'7f91c2a1e9f44b47a6e7c8b227d20101',
@ledger_device_model_type_id,
'PQS588',
'pqs588',
1,
0,
NULL,
NULL,
0,
1,
'system',
NOW(),
'system',
NOW()
WHERE NOT EXISTS (
SELECT 1
FROM `sys_dict_data`
WHERE `type_id` = @ledger_device_model_type_id
AND `code` = 'pqs588'
AND `state` = 1
);
INSERT INTO `sys_dict_data` (
`id`, `type_id`, `name`, `code`, `sort`, `level`, `algo_describe`, `value`, `open_value`, `state`,
`create_by`, `create_time`, `update_by`, `update_time`
)
SELECT
'7f91c2a1e9f44b47a6e7c8b227d20102',
@ledger_device_model_type_id,
'PQS680',
'pqs680',
2,
0,
NULL,
NULL,
0,
1,
'system',
NOW(),
'system',
NOW()
WHERE NOT EXISTS (
SELECT 1
FROM `sys_dict_data`
WHERE `type_id` = @ledger_device_model_type_id
AND `code` = 'pqs680'
AND `state` = 1
);

View File

@@ -0,0 +1,43 @@
package com.njcn.gather.tool.addledger.component;
import com.njcn.gather.tool.addledger.pojo.po.AddLedgerLedgerPO;
import com.njcn.gather.tool.addledger.pojo.vo.AddLedgerTreeNodeVO;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.List;
/**
* 台账树组装测试。
*/
class AddLedgerTreeBuilderTest {
private final AddLedgerTreeBuilder treeBuilder = new AddLedgerTreeBuilder();
@Test
void shouldBuildFourLevelTreeFromFlatLedgerNodes() {
AddLedgerLedgerPO engineering = buildLedger("engineering-1", "0", 0, "工程");
AddLedgerLedgerPO project = buildLedger("project-1", "engineering-1", 1, "项目");
AddLedgerLedgerPO equipment = buildLedger("equipment-1", "project-1", 2, "设备");
AddLedgerLedgerPO line = buildLedger("line-1", "equipment-1", 3, "测点");
List<AddLedgerTreeNodeVO> result = treeBuilder.buildTree(Arrays.asList(line, equipment, project, engineering));
Assertions.assertEquals(1, result.size());
Assertions.assertEquals("engineering-1", result.get(0).getId());
Assertions.assertEquals("project-1", result.get(0).getChildren().get(0).getId());
Assertions.assertEquals("equipment-1", result.get(0).getChildren().get(0).getChildren().get(0).getId());
Assertions.assertEquals("line-1", result.get(0).getChildren().get(0).getChildren().get(0).getChildren().get(0).getId());
}
private AddLedgerLedgerPO buildLedger(String id, String parentId, Integer level, String name) {
AddLedgerLedgerPO ledger = new AddLedgerLedgerPO();
ledger.setId(id);
ledger.setPid(parentId);
ledger.setLevel(level);
ledger.setName(name);
ledger.setSort(0);
return ledger;
}
}

View File

@@ -0,0 +1,33 @@
package com.njcn.gather.tool.addledger.util;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.List;
/**
* 台账测点线路号工具测试。
*/
class AddLedgerLineNoUtilTest {
@Test
void shouldReturnOnlyUnusedLineNosWhenCreateLine() {
List<Integer> result = AddLedgerLineNoUtil.resolveAvailableLineNos(Arrays.asList(1, 2, 20), null);
Assertions.assertEquals(17, result.size());
Assertions.assertFalse(result.contains(1));
Assertions.assertFalse(result.contains(2));
Assertions.assertFalse(result.contains(20));
Assertions.assertTrue(result.contains(3));
}
@Test
void shouldKeepCurrentLineNoAvailableWhenEditLine() {
List<Integer> result = AddLedgerLineNoUtil.resolveAvailableLineNos(Arrays.asList(1, 2, 20), 2);
Assertions.assertTrue(result.contains(2));
Assertions.assertFalse(result.contains(1));
Assertions.assertFalse(result.contains(20));
}
}

View File

@@ -22,6 +22,7 @@
<module>mms-mapping</module> <module>mms-mapping</module>
<module>wave-tool</module> <module>wave-tool</module>
<module>add-data</module> <module>add-data</module>
<module>add-ledger</module>
</modules> </modules>
</project> </project>