From c3b074db2687186f8279c4019a0b1c1909b48be1 Mon Sep 17 00:00:00 2001
From: yexb <553699424@qq.com>
Date: Sat, 9 May 2026 07:52:04 +0800
Subject: [PATCH] =?UTF-8?q?feat(add-ledger):=20=E6=96=B0=E5=A2=9E=E6=95=B0?=
=?UTF-8?q?=E6=8D=AE=E5=8F=B0=E8=B4=A6=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 初始化台账设备相关字典类型和数据
- 添加数据台账常量定义类
- 实现台账配置控制器提供增删改查接口
- 创建台账节点详情、树形结构等视图对象
- 开发工程、设备、测点等数据访问层
- 添加台账ID生成和线路号处理工具类
- 实现台账软删除和查询功能
- 添加测点线路号可用性检查机制
---
README.md | 5 +-
entrance/pom.xml | 5 +
tools/README.md | 12 +-
tools/add-ledger/README.md | 67 +++
tools/add-ledger/pom.xml | 39 ++
.../component/AddLedgerTreeBuilder.java | 55 ++
.../config/AddLedgerMapperConfig.java | 12 +
.../controller/AddLedgerController.java | 126 +++++
.../mapper/AddLedgerEngineeringMapper.java | 15 +
.../mapper/AddLedgerEquipmentMapper.java | 15 +
.../mapper/AddLedgerLedgerMapper.java | 21 +
.../addledger/mapper/AddLedgerLineMapper.java | 21 +
.../mapper/AddLedgerProjectMapper.java | 15 +
.../mapping/AddLedgerEngineeringMapper.xml | 16 +
.../mapping/AddLedgerEquipmentMapper.xml | 16 +
.../mapper/mapping/AddLedgerLedgerMapper.xml | 65 +++
.../mapper/mapping/AddLedgerLineMapper.xml | 38 ++
.../mapper/mapping/AddLedgerProjectMapper.xml | 16 +
.../pojo/constant/AddLedgerConst.java | 50 ++
.../param/AddLedgerEngineeringSaveParam.java | 31 ++
.../param/AddLedgerEquipmentSaveParam.java | 52 ++
.../pojo/param/AddLedgerLineSaveParam.java | 95 ++++
.../pojo/param/AddLedgerProjectSaveParam.java | 31 ++
.../pojo/po/AddLedgerEngineeringPO.java | 31 ++
.../pojo/po/AddLedgerEquipmentPO.java | 63 +++
.../addledger/pojo/po/AddLedgerLedgerPO.java | 43 ++
.../addledger/pojo/po/AddLedgerLinePO.java | 78 +++
.../addledger/pojo/po/AddLedgerProjectPO.java | 29 +
.../addledger/pojo/vo/AddLedgerDetailVO.java | 80 +++
.../pojo/vo/AddLedgerTreeNodeVO.java | 27 +
.../addledger/service/AddLedgerService.java | 32 ++
.../service/impl/AddLedgerServiceImpl.java | 498 ++++++++++++++++++
.../tool/addledger/util/AddLedgerIdUtil.java | 16 +
.../addledger/util/AddLedgerLineNoUtil.java | 31 ++
.../sql/add-ledger/add-ledger-dict-init.sql | 224 ++++++++
.../component/AddLedgerTreeBuilderTest.java | 43 ++
.../util/AddLedgerLineNoUtilTest.java | 33 ++
tools/pom.xml | 1 +
38 files changed, 2044 insertions(+), 3 deletions(-)
create mode 100644 tools/add-ledger/README.md
create mode 100644 tools/add-ledger/pom.xml
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/component/AddLedgerTreeBuilder.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/config/AddLedgerMapperConfig.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/controller/AddLedgerController.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerEngineeringMapper.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerEquipmentMapper.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerLedgerMapper.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerLineMapper.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerProjectMapper.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerEngineeringMapper.xml
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerEquipmentMapper.xml
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerLedgerMapper.xml
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerLineMapper.xml
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerProjectMapper.xml
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/constant/AddLedgerConst.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerEngineeringSaveParam.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerEquipmentSaveParam.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerLineSaveParam.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerProjectSaveParam.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerEngineeringPO.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerEquipmentPO.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerLedgerPO.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerLinePO.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerProjectPO.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/vo/AddLedgerDetailVO.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/vo/AddLedgerTreeNodeVO.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/AddLedgerService.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/impl/AddLedgerServiceImpl.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/util/AddLedgerIdUtil.java
create mode 100644 tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/util/AddLedgerLineNoUtil.java
create mode 100644 tools/add-ledger/src/main/resources/sql/add-ledger/add-ledger-dict-init.sql
create mode 100644 tools/add-ledger/src/test/java/com/njcn/gather/tool/addledger/component/AddLedgerTreeBuilderTest.java
create mode 100644 tools/add-ledger/src/test/java/com/njcn/gather/tool/addledger/util/AddLedgerLineNoUtilTest.java
diff --git a/README.md b/README.md
index c2f5289..66c53ee 100644
--- a/README.md
+++ b/README.md
@@ -27,6 +27,7 @@ CN_Tool 是一个基于 Spring Boot 的多模块后端聚合工程,当前仓
- `activate-tool`
- `add-data`
+- `add-ledger`
- `mms-mapping`
- `wave-tool`
@@ -36,7 +37,7 @@ CN_Tool 是一个基于 Spring Boot 的多模块后端聚合工程,当前仓
- `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`
- 当前提供电能质量 13 张表批量补数、任务状态查询和模板规则查询能力
+- `tools/add-ledger`
+ - 当前为数据台账工具预留空模块
- `tools/mms-mapping`
- 负责 ICD 文件解析与 MMS 映射数据生成能力
- `tools/wave-tool`
diff --git a/entrance/pom.xml b/entrance/pom.xml
index 2a3e7b2..f467996 100644
--- a/entrance/pom.xml
+++ b/entrance/pom.xml
@@ -53,6 +53,11 @@
add-data
1.0.0
+
+ com.njcn.gather
+ add-ledger
+ 1.0.0
+
diff --git a/tools/README.md b/tools/README.md
index 1fd9766..f0ad21e 100644
--- a/tools/README.md
+++ b/tools/README.md
@@ -8,10 +8,11 @@
- `activate-tool`
- `add-data`
+- `add-ledger`
- `mms-mapping`
- `wave-tool`
-因此,`tools` 现阶段仍然是聚合模块,但当前已实际承载激活工具、电能质量数据补录工具、ICD/MMS 映射工具和波形查看工具四个子模块。
+因此,`tools` 现阶段仍然是聚合模块,但当前已实际承载激活工具、电能质量数据补录工具、数据台账工具空模块、ICD/MMS 映射工具和波形查看工具五个子模块。
## 当前结构
@@ -19,6 +20,7 @@
tools/
├── activate-tool/
├── add-data/
+├── add-ledger/
├── mms-mapping/
└── wave-tool/
```
@@ -37,6 +39,12 @@ tools/
模块内部已按职责拆分 `controller`、`service`、`service/impl`、`component`、`pojo`、`config` 和 `util`,并通过 `JdbcTemplate + INSERT IGNORE` 执行批量补数。
+## add-ledger 的职责
+
+`add-ledger` 当前仅完成 Maven 空模块接入,后续用于承载数据台账相关能力。
+
+当前未提供业务接口、Java 分层骨架、配置项或持久化逻辑。目录中的 `ledger.sql` 仅作为原始脚本保留,暂未接入运行时资源解析。
+
## 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:spingboot2.3.12`
diff --git a/tools/add-ledger/README.md b/tools/add-ledger/README.md
new file mode 100644
index 0000000..b6ff6e4
--- /dev/null
+++ b/tools/add-ledger/README.md
@@ -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` 职责边界扩展,不回退为单一大类承载全部接口。
diff --git a/tools/add-ledger/pom.xml b/tools/add-ledger/pom.xml
new file mode 100644
index 0000000..a448bd6
--- /dev/null
+++ b/tools/add-ledger/pom.xml
@@ -0,0 +1,39 @@
+
+
+ 4.0.0
+
+ com.njcn.gather
+ tools
+ 1.0.0
+
+
+ add-ledger
+
+
+
+ com.njcn
+ njcn-common
+ 0.0.1
+
+
+
+ com.njcn
+ mybatis-plus
+ 0.0.1
+
+
+
+ com.njcn
+ spingboot2.3.12
+ 2.3.12
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/component/AddLedgerTreeBuilder.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/component/AddLedgerTreeBuilder.java
new file mode 100644
index 0000000..0e7c415
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/component/AddLedgerTreeBuilder.java
@@ -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 buildTree(List ledgers) {
+ Map nodeMap = new LinkedHashMap();
+ if (ledgers == null || ledgers.isEmpty()) {
+ return new ArrayList();
+ }
+ 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 roots = new ArrayList();
+ 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 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());
+ }
+ }
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/config/AddLedgerMapperConfig.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/config/AddLedgerMapperConfig.java
new file mode 100644
index 0000000..5ffed9f
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/config/AddLedgerMapperConfig.java
@@ -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 {
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/controller/AddLedgerController.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/controller/AddLedgerController.java
new file mode 100644
index 0000000..1ec5e3d
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/controller/AddLedgerController.java
@@ -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> tree(@RequestParam(value = "keyword", required = false) String keyword) {
+ String methodDescribe = getMethodDescribe("tree");
+ LogUtil.njcnDebug(log, "{},开始查询台账树,keyword={}", methodDescribe, keyword);
+ List result = addLedgerService.tree(keyword);
+ return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
+ }
+
+ @OperateInfo(info = LogEnum.BUSINESS_COMMON)
+ @ApiOperation("查询台账节点详情")
+ @GetMapping("/detail")
+ public HttpResult 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 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 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 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 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> 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 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 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);
+ }
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerEngineeringMapper.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerEngineeringMapper.java
new file mode 100644
index 0000000..94b21f7
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerEngineeringMapper.java
@@ -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 {
+
+ int softDeleteByIds(@Param("ids") List ids, @Param("updateBy") String updateBy);
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerEquipmentMapper.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerEquipmentMapper.java
new file mode 100644
index 0000000..b84d492
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerEquipmentMapper.java
@@ -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 {
+
+ int softDeleteByIds(@Param("ids") List ids, @Param("updateBy") String updateBy);
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerLedgerMapper.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerLedgerMapper.java
new file mode 100644
index 0000000..e851a43
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerLedgerMapper.java
@@ -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 {
+
+ List selectTree(@Param("keyword") String keyword);
+
+ AddLedgerLedgerPO selectActiveNode(@Param("id") String id, @Param("level") Integer level);
+
+ List selectActiveSubtree(@Param("id") String id);
+
+ int softDeleteByIds(@Param("ids") List ids, @Param("updateBy") String updateBy);
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerLineMapper.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerLineMapper.java
new file mode 100644
index 0000000..7e8e3d7
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerLineMapper.java
@@ -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 {
+
+ List 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 ids, @Param("updateBy") String updateBy);
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerProjectMapper.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerProjectMapper.java
new file mode 100644
index 0000000..bf2d44e
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/AddLedgerProjectMapper.java
@@ -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 {
+
+ int softDeleteByIds(@Param("ids") List ids, @Param("updateBy") String updateBy);
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerEngineeringMapper.xml b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerEngineeringMapper.xml
new file mode 100644
index 0000000..8ee6767
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerEngineeringMapper.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ UPDATE cs_engineering
+ SET status = 0,
+ update_by = #{updateBy},
+ update_time = NOW()
+ WHERE id IN
+
+ #{id}
+
+
+
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerEquipmentMapper.xml b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerEquipmentMapper.xml
new file mode 100644
index 0000000..8ded964
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerEquipmentMapper.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ UPDATE cs_equipment_delivery
+ SET run_status = 0,
+ update_by = #{updateBy},
+ update_time = NOW()
+ WHERE id IN
+
+ #{id}
+
+
+
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerLedgerMapper.xml b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerLedgerMapper.xml
new file mode 100644
index 0000000..39923dd
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerLedgerMapper.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+ UPDATE cs_ledger
+ SET State = 0,
+ Update_By = #{updateBy},
+ Update_Time = NOW()
+ WHERE Id IN
+
+ #{id}
+
+ AND State = 1
+
+
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerLineMapper.xml b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerLineMapper.xml
new file mode 100644
index 0000000..4a2cc82
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerLineMapper.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+ UPDATE cs_line
+ SET status = 0,
+ update_by = #{updateBy},
+ update_time = NOW()
+ WHERE line_id IN
+
+ #{id}
+
+
+
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerProjectMapper.xml b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerProjectMapper.xml
new file mode 100644
index 0000000..e4c57df
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/mapper/mapping/AddLedgerProjectMapper.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+ UPDATE cs_project
+ SET status = 0,
+ update_by = #{updateBy},
+ update_time = NOW()
+ WHERE id IN
+
+ #{id}
+
+
+
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/constant/AddLedgerConst.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/constant/AddLedgerConst.java
new file mode 100644
index 0000000..6d3b017
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/constant/AddLedgerConst.java
@@ -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 CON_TYPES = new LinkedHashSet(Arrays.asList(0, 1, 2));
+
+ public static final Set VOL_GRADES = new LinkedHashSet(Arrays.asList(
+ new BigDecimal("0.38"),
+ new BigDecimal("10"),
+ new BigDecimal("35"),
+ new BigDecimal("110"),
+ new BigDecimal("220"),
+ new BigDecimal("500")
+ ));
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerEngineeringSaveParam.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerEngineeringSaveParam.java
new file mode 100644
index 0000000..a00a713
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerEngineeringSaveParam.java
@@ -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;
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerEquipmentSaveParam.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerEquipmentSaveParam.java
new file mode 100644
index 0000000..60fa491
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerEquipmentSaveParam.java
@@ -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;
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerLineSaveParam.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerLineSaveParam.java
new file mode 100644
index 0000000..2617baa
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerLineSaveParam.java
@@ -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;
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerProjectSaveParam.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerProjectSaveParam.java
new file mode 100644
index 0000000..32977a8
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/param/AddLedgerProjectSaveParam.java
@@ -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;
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerEngineeringPO.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerEngineeringPO.java
new file mode 100644
index 0000000..0e5a1ac
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerEngineeringPO.java
@@ -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;
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerEquipmentPO.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerEquipmentPO.java
new file mode 100644
index 0000000..8b60496
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerEquipmentPO.java
@@ -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;
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerLedgerPO.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerLedgerPO.java
new file mode 100644
index 0000000..54cf608
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerLedgerPO.java
@@ -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;
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerLinePO.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerLinePO.java
new file mode 100644
index 0000000..b3e9a78
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerLinePO.java
@@ -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;
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerProjectPO.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerProjectPO.java
new file mode 100644
index 0000000..cde0b77
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/po/AddLedgerProjectPO.java
@@ -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;
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/vo/AddLedgerDetailVO.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/vo/AddLedgerDetailVO.java
new file mode 100644
index 0000000..b1611f2
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/vo/AddLedgerDetailVO.java
@@ -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;
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/vo/AddLedgerTreeNodeVO.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/vo/AddLedgerTreeNodeVO.java
new file mode 100644
index 0000000..f473e70
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/pojo/vo/AddLedgerTreeNodeVO.java
@@ -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 children = new ArrayList();
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/AddLedgerService.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/AddLedgerService.java
new file mode 100644
index 0000000..e78a643
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/AddLedgerService.java
@@ -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 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 availableLineNos(String deviceId, String lineId);
+
+ boolean deleteNode(String id, Integer level);
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/impl/AddLedgerServiceImpl.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/impl/AddLedgerServiceImpl.java
new file mode 100644
index 0000000..d5cb9f7
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/service/impl/AddLedgerServiceImpl.java
@@ -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 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 availableLineNos(String deviceId, String lineId) {
+ AddLedgerLedgerPO equipmentLedger = requireLedger(deviceId, AddLedgerConst.LEVEL_EQUIPMENT);
+ List 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 subtree = ledgerMapper.selectActiveSubtree(id);
+ if (subtree.isEmpty()) {
+ return false;
+ }
+ List engineeringIds = new ArrayList();
+ List projectIds = new ArrayList();
+ List equipmentIds = new ArrayList();
+ List lineIds = new ArrayList();
+ List ledgerIds = new ArrayList();
+ 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()
+ .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()
+ .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()
+ .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()
+ .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 "未知用户";
+ }
+ }
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/util/AddLedgerIdUtil.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/util/AddLedgerIdUtil.java
new file mode 100644
index 0000000..27f5911
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/util/AddLedgerIdUtil.java
@@ -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("-", "");
+ }
+}
diff --git a/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/util/AddLedgerLineNoUtil.java b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/util/AddLedgerLineNoUtil.java
new file mode 100644
index 0000000..5229410
--- /dev/null
+++ b/tools/add-ledger/src/main/java/com/njcn/gather/tool/addledger/util/AddLedgerLineNoUtil.java
@@ -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 resolveAvailableLineNos(List usedLineNos, Integer currentLineNo) {
+ Set usedSet = new HashSet();
+ if (usedLineNos != null) {
+ usedSet.addAll(usedLineNos);
+ }
+ List result = new ArrayList();
+ 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;
+ }
+}
diff --git a/tools/add-ledger/src/main/resources/sql/add-ledger/add-ledger-dict-init.sql b/tools/add-ledger/src/main/resources/sql/add-ledger/add-ledger-dict-init.sql
new file mode 100644
index 0000000..f34a1db
--- /dev/null
+++ b/tools/add-ledger/src/main/resources/sql/add-ledger/add-ledger-dict-init.sql
@@ -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
+);
diff --git a/tools/add-ledger/src/test/java/com/njcn/gather/tool/addledger/component/AddLedgerTreeBuilderTest.java b/tools/add-ledger/src/test/java/com/njcn/gather/tool/addledger/component/AddLedgerTreeBuilderTest.java
new file mode 100644
index 0000000..3336c96
--- /dev/null
+++ b/tools/add-ledger/src/test/java/com/njcn/gather/tool/addledger/component/AddLedgerTreeBuilderTest.java
@@ -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 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;
+ }
+}
diff --git a/tools/add-ledger/src/test/java/com/njcn/gather/tool/addledger/util/AddLedgerLineNoUtilTest.java b/tools/add-ledger/src/test/java/com/njcn/gather/tool/addledger/util/AddLedgerLineNoUtilTest.java
new file mode 100644
index 0000000..107d6db
--- /dev/null
+++ b/tools/add-ledger/src/test/java/com/njcn/gather/tool/addledger/util/AddLedgerLineNoUtilTest.java
@@ -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 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 result = AddLedgerLineNoUtil.resolveAvailableLineNos(Arrays.asList(1, 2, 20), 2);
+
+ Assertions.assertTrue(result.contains(2));
+ Assertions.assertFalse(result.contains(1));
+ Assertions.assertFalse(result.contains(20));
+ }
+}
diff --git a/tools/pom.xml b/tools/pom.xml
index 0ac4fcc..c1d5dcf 100644
--- a/tools/pom.xml
+++ b/tools/pom.xml
@@ -22,6 +22,7 @@
mms-mapping
wave-tool
add-data
+ add-ledger