|
|
@@ -0,0 +1,182 @@
|
|
|
+package com.zksy.drainage.service.impl;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.zksy.common.exception.ServiceException;
|
|
|
+import com.zksy.drainage.domain.DrainagePartition;
|
|
|
+import com.zksy.drainage.domain.EngineeringFacility;
|
|
|
+import com.zksy.drainage.domain.PipeNetworkInfo;
|
|
|
+import com.zksy.drainage.domain.WaterloggingPoint;
|
|
|
+import com.zksy.drainage.mapper.DrainagePartitionMapper;
|
|
|
+import com.zksy.drainage.mapper.EngineeringFacilityMapper;
|
|
|
+import com.zksy.drainage.mapper.PipeNetworkInfoMapper;
|
|
|
+import com.zksy.drainage.mapper.WaterloggingPointMapper;
|
|
|
+import com.zksy.drainage.service.DrainageEquipmentBindingService;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.LinkedHashMap;
|
|
|
+import java.util.LinkedHashSet;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Set;
|
|
|
+
|
|
|
+/** 排水设备全局唯一关联实现。 */
|
|
|
+@Service
|
|
|
+public class DrainageEquipmentBindingServiceImpl implements DrainageEquipmentBindingService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private DrainagePartitionMapper drainagePartitionMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private PipeNetworkInfoMapper pipeNetworkInfoMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private EngineeringFacilityMapper engineeringFacilityMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private WaterloggingPointMapper waterloggingPointMapper;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, String> findBoundEquipment(String excludeType, String excludeId) {
|
|
|
+ validateSourceType(excludeType, true);
|
|
|
+ Map<String, String> result = new LinkedHashMap<>();
|
|
|
+
|
|
|
+ for (DrainagePartition item : drainagePartitionMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<DrainagePartition>().select(
|
|
|
+ DrainagePartition::getId, DrainagePartition::getName, DrainagePartition::getEquipmentId))) {
|
|
|
+ addBindings(result, TYPE_PARTITION, item.getId(), item.getName(), item.getEquipmentId(),
|
|
|
+ excludeType, excludeId, "排水分区");
|
|
|
+ }
|
|
|
+ for (PipeNetworkInfo item : pipeNetworkInfoMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<PipeNetworkInfo>().select(
|
|
|
+ PipeNetworkInfo::getId, PipeNetworkInfo::getName, PipeNetworkInfo::getEquipmentId))) {
|
|
|
+ addBindings(result, TYPE_PIPE_NETWORK, item.getId(), item.getName(), item.getEquipmentId(),
|
|
|
+ excludeType, excludeId, "排水管网");
|
|
|
+ }
|
|
|
+ for (EngineeringFacility item : engineeringFacilityMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<EngineeringFacility>().select(
|
|
|
+ EngineeringFacility::getId, EngineeringFacility::getName,
|
|
|
+ EngineeringFacility::getFacilityType, EngineeringFacility::getEquipmentId))) {
|
|
|
+ // 泵站设施的 equipment_id 保存的是泵站ID,不属于监测设备关联。
|
|
|
+ if ("泵站".equals(item.getFacilityType())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ addBindings(result, TYPE_FACILITY, item.getId(), item.getName(), item.getEquipmentId(),
|
|
|
+ excludeType, excludeId, "工程设施");
|
|
|
+ }
|
|
|
+ for (WaterloggingPoint item : waterloggingPointMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<WaterloggingPoint>().select(
|
|
|
+ WaterloggingPoint::getId, WaterloggingPoint::getName, WaterloggingPoint::getEquipmentId))) {
|
|
|
+ addBindings(result, TYPE_WATERLOGGING, item.getId(), item.getName(), item.getEquipmentId(),
|
|
|
+ excludeType, excludeId, "易积水点");
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 同一个服务实例串行完成检查和保存,防止单实例内并发抢占同一设备。 */
|
|
|
+ @Override
|
|
|
+ @Transactional
|
|
|
+ public synchronized boolean bindEquipment(String sourceType, String sourceId, List<String> equipmentIds) {
|
|
|
+ validateSourceType(sourceType, false);
|
|
|
+ if (sourceId == null || sourceId.trim().isEmpty()) {
|
|
|
+ throw new ServiceException("关联对象ID不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ List<String> normalizedIds = normalizeEquipmentIds(equipmentIds);
|
|
|
+ if (normalizedIds.isEmpty()) {
|
|
|
+ throw new ServiceException("请选择要关联的设备");
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, String> occupied = findBoundEquipment(sourceType, sourceId);
|
|
|
+ List<String> conflicts = new ArrayList<>();
|
|
|
+ for (String equipmentId : normalizedIds) {
|
|
|
+ String sourceName = occupied.get(equipmentId);
|
|
|
+ if (sourceName != null) {
|
|
|
+ conflicts.add(equipmentId + "(" + sourceName + ")");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!conflicts.isEmpty()) {
|
|
|
+ throw new ServiceException("设备已被其他位置关联,不能重复关联:" + String.join("、", conflicts));
|
|
|
+ }
|
|
|
+
|
|
|
+ String value = String.join(",", normalizedIds);
|
|
|
+ switch (sourceType) {
|
|
|
+ case TYPE_PARTITION:
|
|
|
+ DrainagePartition partition = drainagePartitionMapper.selectById(sourceId);
|
|
|
+ if (partition == null) return false;
|
|
|
+ partition.setEquipmentId(value);
|
|
|
+ return drainagePartitionMapper.updateById(partition) > 0;
|
|
|
+ case TYPE_PIPE_NETWORK:
|
|
|
+ PipeNetworkInfo pipeNetwork = pipeNetworkInfoMapper.selectById(sourceId);
|
|
|
+ if (pipeNetwork == null) return false;
|
|
|
+ pipeNetwork.setEquipmentId(value);
|
|
|
+ return pipeNetworkInfoMapper.updateById(pipeNetwork) > 0;
|
|
|
+ case TYPE_FACILITY:
|
|
|
+ EngineeringFacility facility = engineeringFacilityMapper.selectById(sourceId);
|
|
|
+ if (facility == null) return false;
|
|
|
+ if ("泵站".equals(facility.getFacilityType())) {
|
|
|
+ throw new ServiceException("泵站设施请使用关联泵站功能");
|
|
|
+ }
|
|
|
+ facility.setEquipmentId(value);
|
|
|
+ return engineeringFacilityMapper.updateById(facility) > 0;
|
|
|
+ case TYPE_WATERLOGGING:
|
|
|
+ WaterloggingPoint waterloggingPoint = waterloggingPointMapper.selectById(sourceId);
|
|
|
+ if (waterloggingPoint == null) return false;
|
|
|
+ waterloggingPoint.setEquipmentId(value);
|
|
|
+ return waterloggingPointMapper.updateById(waterloggingPoint) > 0;
|
|
|
+ default:
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void addBindings(Map<String, String> result, String sourceType, String sourceId,
|
|
|
+ String sourceName, String equipmentIds, String excludeType,
|
|
|
+ String excludeId, String sourceLabel) {
|
|
|
+ if (sourceType.equals(excludeType) && sourceId != null && sourceId.equals(excludeId)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for (String equipmentId : splitEquipmentIds(equipmentIds)) {
|
|
|
+ String displayName = sourceName == null || sourceName.trim().isEmpty() ? sourceId : sourceName;
|
|
|
+ result.putIfAbsent(equipmentId, sourceLabel + " / " + displayName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<String> normalizeEquipmentIds(List<String> equipmentIds) {
|
|
|
+ Set<String> result = new LinkedHashSet<>();
|
|
|
+ if (equipmentIds != null) {
|
|
|
+ for (String equipmentId : equipmentIds) {
|
|
|
+ if (equipmentId != null && !equipmentId.trim().isEmpty()) {
|
|
|
+ result.add(equipmentId.trim());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return new ArrayList<>(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<String> splitEquipmentIds(String equipmentIds) {
|
|
|
+ List<String> result = new ArrayList<>();
|
|
|
+ if (equipmentIds == null || equipmentIds.trim().isEmpty()) {
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ for (String equipmentId : equipmentIds.split(",")) {
|
|
|
+ if (!equipmentId.trim().isEmpty()) {
|
|
|
+ result.add(equipmentId.trim());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void validateSourceType(String sourceType, boolean allowEmpty) {
|
|
|
+ if (allowEmpty && (sourceType == null || sourceType.trim().isEmpty())) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!TYPE_PARTITION.equals(sourceType)
|
|
|
+ && !TYPE_PIPE_NETWORK.equals(sourceType)
|
|
|
+ && !TYPE_FACILITY.equals(sourceType)
|
|
|
+ && !TYPE_WATERLOGGING.equals(sourceType)) {
|
|
|
+ throw new ServiceException("不支持的排水设备关联类型:" + sourceType);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|