Просмотр исходного кода

feat(base): 添加监测点管理功能

- 新增 MonitorPointController 提供监测点的 CRUD 操作接口
- 实现监测点分页查询、批量操作和设备关联功能
- 添加监测点编码唯一性校验和关联管网设施验证
- 集成 Swagger 文档注解和日志记录功能
- 实现监测点与设备的绑定/解绑关系管理
- 提供监测点详情查询(包含关联设备和管网信息)
林仔 1 месяц назад
Родитель
Сommit
cd65f9d894

+ 148 - 0
pipe-network-service/zksy-admin/src/main/java/com/zksy/web/controller/base/MonitorPointController.java

@@ -0,0 +1,148 @@
+package com.zksy.web.controller.base;
+
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zksy.base.domain.MonitorPoint;
+import com.zksy.base.service.MonitorPointService;
+import com.zksy.common.annotation.Anonymous;
+import com.zksy.common.annotation.Log;
+import com.zksy.common.core.domain.AjaxResult;
+import com.zksy.common.enums.BusinessType;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@RestController
+@RequestMapping("/MonitorPoint")
+@Api(tags = "关键监测点管理")
+public class MonitorPointController {
+
+    @Autowired
+    private MonitorPointService service;
+
+    @GetMapping("/getById/{id}")
+    @ApiOperation(value = "获取监测点详情")
+    @Anonymous
+    public AjaxResult getById(@PathVariable String id) {
+        MonitorPoint entity = service.getById(id);
+        if (entity == null) {
+            return AjaxResult.error("该监测点信息不存在");
+        }
+        return AjaxResult.success(entity);
+    }
+
+    @Anonymous
+    @GetMapping("/findByPage")
+    @ApiOperation(value = "监测点分页查询")
+    public Page findByPage(
+            @ApiParam("页码") @RequestParam(defaultValue = "1") long pageNum,
+            @ApiParam("每页数量") @RequestParam(defaultValue = "10") long pageSize,
+            @ApiParam("监测点编码") @RequestParam(required = false) String pointCode,
+            @ApiParam("监测点名称") @RequestParam(required = false) String pointName,
+            @ApiParam("监测点类型") @RequestParam(required = false) String pointType,
+            @ApiParam("状态") @RequestParam(required = false) String status) {
+        return service.findByPage(pageNum, pageSize, pointCode, pointName, pointType, status);
+    }
+
+    @Anonymous
+    @GetMapping("/getList")
+    @ApiOperation(value = "查询所有监测点")
+    public AjaxResult getList() {
+        return AjaxResult.success(service.list());
+    }
+
+    @Anonymous
+    @GetMapping("/byNetwork/{networkId}")
+    @ApiOperation(value = "根据管网设施查询监测点")
+    public AjaxResult getPointsByNetwork(@PathVariable String networkId) {
+        List<MonitorPoint> list = service.getPointsByNetwork(networkId);
+        return AjaxResult.success(list);
+    }
+
+    @PostMapping("/save")
+    @ApiOperation(value = "新增监测点")
+    @Log(title = "新增监测点", businessType = BusinessType.INSERT)
+    public AjaxResult save(@RequestBody MonitorPoint entity) {
+        boolean saved = service.saveWithCheck(entity);
+        return saved ? AjaxResult.success("新增成功", saved)
+                : AjaxResult.error("新增失败", saved);
+    }
+
+    @PostMapping("/saveBatch")
+    @ApiOperation(value = "监测点批量新增")
+    @Log(title = "批量新增监测点", businessType = BusinessType.INSERT)
+    public AjaxResult saveBatch(@RequestBody List<MonitorPoint> entityList) {
+        if (CollectionUtils.isEmpty(entityList)) {
+            return AjaxResult.error("批量新增失败:列表不能为空");
+        }
+        boolean saved = service.saveBatchWithCheck(entityList);
+        return saved ? AjaxResult.success("新增成功", saved)
+                : AjaxResult.error("新增失败", saved);
+    }
+
+    @PutMapping("/updateById")
+    @ApiOperation(value = "监测点修改")
+    @Log(title = "修改监测点", businessType = BusinessType.UPDATE)
+    public AjaxResult updateById(@RequestBody MonitorPoint entity) {
+        boolean updated = service.updateWithCheck(entity);
+        return updated ? AjaxResult.success("修改成功", updated)
+                : AjaxResult.error("修改失败", updated);
+    }
+
+    @DeleteMapping("/deleteById")
+    @ApiOperation(value = "监测点删除")
+    @Log(title = "删除监测点", businessType = BusinessType.DELETE)
+    public AjaxResult deleteById(String id) {
+        boolean deleted = service.removeWithCheck(id);
+        return deleted ? AjaxResult.success("删除成功", deleted)
+                : AjaxResult.error("删除失败", deleted);
+    }
+
+    @DeleteMapping("/deleteBatchById")
+    @ApiOperation(value = "监测点批量删除")
+    @Log(title = "监测点批量删除", businessType = BusinessType.DELETE)
+    public AjaxResult deleteBatchById(@RequestParam List<String> ids) {
+        boolean deleted = service.removeBatchWithCheck(ids);
+        return deleted ? AjaxResult.success("删除成功", deleted)
+                : AjaxResult.error("删除失败", deleted);
+    }
+
+    @PostMapping("/bindEquipment")
+    @ApiOperation(value = "监测点关联设备")
+    @Log(title = "监测点关联设备", businessType = BusinessType.UPDATE)
+    @Anonymous
+    public AjaxResult bindEquipment(
+            @ApiParam("监测点ID") @RequestParam String pointId,
+            @ApiParam("设备ID列表") @RequestParam List<String> equipmentIds) {
+        boolean bound = service.bindEquipment(pointId, equipmentIds);
+        return bound ? AjaxResult.success("关联成功")
+                : AjaxResult.error("关联失败");
+    }
+
+    @PostMapping("/unbindEquipment")
+    @ApiOperation(value = "监测点取消关联设备")
+    @Log(title = "监测点取消关联设备", businessType = BusinessType.UPDATE)
+    @Anonymous
+    public AjaxResult unbindEquipment(
+            @ApiParam("监测点ID") @RequestParam String pointId,
+            @ApiParam("设备ID列表") @RequestParam List<String> equipmentIds) {
+        boolean unbound = service.unbindEquipment(pointId, equipmentIds);
+        return unbound ? AjaxResult.success("取消关联成功")
+                : AjaxResult.error("取消关联失败");
+    }
+
+    @GetMapping("/pointDetail/{pointId}")
+    @ApiOperation(value = "监测点详情(含关联设备和管网)")
+    @Anonymous
+    public AjaxResult getPointDetail(@PathVariable String pointId) {
+        Map<String, Object> detail = service.getPointDetail(pointId);
+        return AjaxResult.success(detail);
+    }
+}

+ 9 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/mapper/MonitorPointMapper.java

@@ -0,0 +1,9 @@
+package com.zksy.base.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zksy.base.domain.MonitorPoint;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface MonitorPointMapper extends BaseMapper<MonitorPoint> {
+}

+ 33 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/MonitorPointService.java

@@ -0,0 +1,33 @@
+package com.zksy.base.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zksy.base.domain.MonitorPoint;
+
+import java.util.List;
+import java.util.Map;
+
+public interface MonitorPointService extends IService<MonitorPoint> {
+
+    Page<MonitorPoint> findByPage(long pageNum, long pageSize,
+                                    String pointCode, String pointName,
+                                    String pointType, String status);
+
+    boolean saveWithCheck(MonitorPoint entity);
+
+    boolean saveBatchWithCheck(List<MonitorPoint> entityList);
+
+    boolean updateWithCheck(MonitorPoint entity);
+
+    boolean removeWithCheck(String id);
+
+    boolean removeBatchWithCheck(List<String> ids);
+
+    boolean bindEquipment(String pointId, List<String> equipmentIds);
+
+    boolean unbindEquipment(String pointId, List<String> equipmentIds);
+
+    Map<String, Object> getPointDetail(String pointId);
+
+    List<MonitorPoint> getPointsByNetwork(String networkId);
+}

+ 259 - 0
pipe-network-service/zksy-system/src/main/java/com/zksy/base/service/impl/MonitorPointServiceImpl.java

@@ -0,0 +1,259 @@
+package com.zksy.base.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zksy.base.domain.EquipmentBase;
+import com.zksy.base.domain.EquipmentPointRel;
+import com.zksy.base.domain.MonitorPoint;
+import com.zksy.base.domain.PipeNetworkBase;
+import com.zksy.base.mapper.EquipmentBaseMapper;
+import com.zksy.base.mapper.EquipmentPointRelMapper;
+import com.zksy.base.mapper.MonitorPointMapper;
+import com.zksy.base.mapper.PipeNetworkBaseMapper;
+import com.zksy.base.service.MonitorPointService;
+import com.zksy.common.exception.ServiceException;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class MonitorPointServiceImpl extends ServiceImpl<MonitorPointMapper, MonitorPoint>
+        implements MonitorPointService {
+
+    @Autowired
+    private EquipmentPointRelMapper equipmentPointRelMapper;
+
+    @Autowired
+    private EquipmentBaseMapper equipmentBaseMapper;
+
+    @Autowired
+    private PipeNetworkBaseMapper pipeNetworkBaseMapper;
+
+    @Override
+    public Page<MonitorPoint> findByPage(long pageNum, long pageSize,
+                                          String pointCode, String pointName,
+                                          String pointType, String status) {
+        Page<MonitorPoint> page = new Page<>(pageNum, pageSize);
+        LambdaQueryWrapper<MonitorPoint> queryWrapper = new LambdaQueryWrapper<>();
+        if (pointCode != null && !pointCode.isEmpty()) {
+            queryWrapper.like(MonitorPoint::getPointCode, pointCode);
+        }
+        if (pointName != null && !pointName.isEmpty()) {
+            queryWrapper.like(MonitorPoint::getPointName, pointName);
+        }
+        if (pointType != null && !pointType.isEmpty()) {
+            queryWrapper.eq(MonitorPoint::getPointType, pointType);
+        }
+        if (status != null && !status.isEmpty()) {
+            queryWrapper.eq(MonitorPoint::getStatus, status);
+        }
+        queryWrapper.orderByDesc(MonitorPoint::getCreateTime);
+        return this.page(page, queryWrapper);
+    }
+
+    @Override
+    public boolean saveWithCheck(MonitorPoint entity) {
+        if (entity.getNetworkId() != null) {
+            PipeNetworkBase network = pipeNetworkBaseMapper.selectById(entity.getNetworkId());
+            if (network == null) {
+                throw new ServiceException("关联管网设施不存在:" + entity.getNetworkId());
+            }
+        }
+        LambdaQueryWrapper<MonitorPoint> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(MonitorPoint::getPointCode, entity.getPointCode());
+        long count = this.count(queryWrapper);
+        if (count > 0) {
+            throw new ServiceException("监测点编码已存在,请更换:" + entity.getPointCode());
+        }
+        return this.save(entity);
+    }
+
+    @Override
+    public boolean saveBatchWithCheck(List<MonitorPoint> entityList) {
+        Set<String> codeSet = new HashSet<>();
+        for (MonitorPoint entity : entityList) {
+            String code = entity.getPointCode();
+            if (codeSet.contains(code)) {
+                throw new ServiceException("列表中存在重复编码:" + code);
+            }
+            codeSet.add(code);
+        }
+
+        for (MonitorPoint entity : entityList) {
+            if (entity.getNetworkId() != null) {
+                if (pipeNetworkBaseMapper.selectById(entity.getNetworkId()) == null) {
+                    throw new ServiceException("关联管网设施不存在:" + entity.getNetworkId());
+                }
+            }
+            LambdaQueryWrapper<MonitorPoint> wrapper = new LambdaQueryWrapper<>();
+            wrapper.eq(MonitorPoint::getPointCode, entity.getPointCode());
+            if (this.count(wrapper) > 0) {
+                throw new ServiceException("监测点编码已存在:" + entity.getPointCode());
+            }
+        }
+        return this.saveBatch(entityList);
+    }
+
+    @Override
+    @Transactional
+    public boolean updateWithCheck(MonitorPoint entity) {
+        String pointId = entity.getPointId();
+        if (this.getById(pointId) == null) {
+            throw new ServiceException("监测点不存在,无法修改:" + pointId);
+        }
+
+        if (entity.getNetworkId() != null) {
+            if (pipeNetworkBaseMapper.selectById(entity.getNetworkId()) == null) {
+                throw new ServiceException("关联管网设施不存在:" + entity.getNetworkId());
+            }
+        }
+
+        String newCode = entity.getPointCode();
+        if (newCode != null) {
+            LambdaQueryWrapper<MonitorPoint> wrapper = new LambdaQueryWrapper<>();
+            wrapper.eq(MonitorPoint::getPointCode, newCode)
+                    .ne(MonitorPoint::getPointId, pointId);
+            if (this.count(wrapper) > 0) {
+                throw new ServiceException("监测点编码已被使用:" + newCode);
+            }
+        }
+        return this.updateById(entity);
+    }
+
+    @Override
+    @Transactional
+    public boolean removeWithCheck(String pointId) {
+        MonitorPoint point = this.getById(pointId);
+        if (point == null) {
+            throw new ServiceException("监测点不存在:" + pointId);
+        }
+
+        LambdaQueryWrapper<EquipmentPointRel> relWrapper = new LambdaQueryWrapper<>();
+        relWrapper.eq(EquipmentPointRel::getPointId, pointId);
+        equipmentPointRelMapper.delete(relWrapper);
+        log.info("已删除监测点[{}]的设备关联关系", pointId);
+
+        return this.baseMapper.deleteById(pointId) > 0;
+    }
+
+    @Override
+    @Transactional
+    public boolean removeBatchWithCheck(List<String> pointIds) {
+        if (CollectionUtils.isEmpty(pointIds)) {
+            throw new ServiceException("批量删除失败:监测点ID列表不能为空");
+        }
+
+        List<MonitorPoint> existPoints = this.listByIds(pointIds);
+        if (existPoints.isEmpty()) {
+            throw new ServiceException("批量删除失败:所有监测点ID均不存在");
+        }
+
+        List<String> existIds = existPoints.stream()
+                .map(MonitorPoint::getPointId)
+                .collect(Collectors.toList());
+
+        List<String> invalidIds = pointIds.stream()
+                .filter(id -> !existIds.contains(id))
+                .collect(Collectors.toList());
+        if (!invalidIds.isEmpty()) {
+            log.warn("批量删除中存在无效监测点ID:{}", invalidIds);
+        }
+
+        LambdaQueryWrapper<EquipmentPointRel> relWrapper = new LambdaQueryWrapper<>();
+        relWrapper.in(EquipmentPointRel::getPointId, existIds);
+        equipmentPointRelMapper.delete(relWrapper);
+        log.info("已批量删除{}条监测点的设备关联关系", existIds.size());
+
+        return this.removeByIds(existIds);
+    }
+
+    @Override
+    @Transactional
+    public boolean bindEquipment(String pointId, List<String> equipmentIds) {
+        MonitorPoint point = this.getById(pointId);
+        if (point == null) {
+            throw new ServiceException("监测点不存在:" + pointId);
+        }
+
+        for (String equipmentId : equipmentIds) {
+            EquipmentBase equipment = equipmentBaseMapper.selectById(equipmentId);
+            if (equipment == null) {
+                throw new ServiceException("设备不存在:" + equipmentId);
+            }
+            LambdaQueryWrapper<EquipmentPointRel> checkWrapper = new LambdaQueryWrapper<>();
+            checkWrapper.eq(EquipmentPointRel::getPointId, pointId)
+                    .eq(EquipmentPointRel::getEquipmentId, equipmentId);
+            if (equipmentPointRelMapper.selectCount(checkWrapper) > 0) {
+                throw new ServiceException("设备已绑定此监测点:" + equipmentId);
+            }
+        }
+
+        List<EquipmentPointRel> relList = new ArrayList<>();
+        for (String equipmentId : equipmentIds) {
+            EquipmentPointRel rel = new EquipmentPointRel();
+            rel.setPointId(pointId);
+            rel.setEquipmentId(equipmentId);
+            relList.add(rel);
+        }
+
+        // 逐个插入或批量插入,因为 relList 类型和 this.saveBatch 不匹配
+        int count = 0;
+        for (EquipmentPointRel rel : relList) {
+            count += equipmentPointRelMapper.insert(rel);
+        }
+        return count > 0;
+    }
+
+    @Override
+    @Transactional
+    public boolean unbindEquipment(String pointId, List<String> equipmentIds) {
+        LambdaQueryWrapper<EquipmentPointRel> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(EquipmentPointRel::getPointId, pointId)
+                .in(EquipmentPointRel::getEquipmentId, equipmentIds);
+        return equipmentPointRelMapper.delete(wrapper) > 0;
+    }
+
+    @Override
+    public Map<String, Object> getPointDetail(String pointId) {
+        MonitorPoint point = this.getById(pointId);
+        if (point == null) {
+            throw new ServiceException("监测点不存在:" + pointId);
+        }
+
+        Map<String, Object> result = new HashMap<>();
+        result.put("pointInfo", point);
+
+        if (point.getNetworkId() != null) {
+            PipeNetworkBase network = pipeNetworkBaseMapper.selectById(point.getNetworkId());
+            result.put("networkInfo", network);
+        }
+
+        LambdaQueryWrapper<EquipmentPointRel> relWrapper = new LambdaQueryWrapper<>();
+        relWrapper.eq(EquipmentPointRel::getPointId, pointId);
+        List<EquipmentPointRel> relList = equipmentPointRelMapper.selectList(relWrapper);
+        if (!relList.isEmpty()) {
+            List<String> equipmentIds = relList.stream()
+                    .map(EquipmentPointRel::getEquipmentId)
+                    .collect(Collectors.toList());
+            List<EquipmentBase> equipmentList = equipmentBaseMapper.selectBatchIds(equipmentIds);
+            result.put("equipmentList", equipmentList);
+        }
+
+        return result;
+    }
+
+    @Override
+    public List<MonitorPoint> getPointsByNetwork(String networkId) {
+        LambdaQueryWrapper<MonitorPoint> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(MonitorPoint::getNetworkId, networkId);
+        wrapper.orderByDesc(MonitorPoint::getCreateTime);
+        return this.list(wrapper);
+    }
+}