package com.ard.data.region.service.impl; import com.ard.common.constant.RegionConstants; import com.ard.common.utils.DateUtils; import com.ard.common.utils.SecurityUtils; import com.ard.common.utils.StringUtils; import com.ard.data.region.domain.ArdDeptRegion; import com.ard.data.region.domain.ConflictCheckResult; import com.ard.data.region.domain.ConflictRegion; import com.ard.data.region.domain.Coordinate; import com.ard.data.region.mapper.ArdDeptRegionMapper; import com.ard.data.region.service.IArdDeptRegionService; import com.ard.data.region.utils.RegionCoordinateUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.List; /** * 部门区域Service业务层处理 * * @author ruoyi */ @Slf4j @Service public class ArdDeptRegionServiceImpl implements IArdDeptRegionService { @Autowired private ArdDeptRegionMapper ardDeptRegionMapper; @Override public ArdDeptRegion selectArdDeptRegionById(Long id) { ArdDeptRegion region = ardDeptRegionMapper.selectArdDeptRegionById(id); if (region != null) { region.setCoordinates(RegionCoordinateUtils.toCoordinates(region.getBoundaryWkt())); } return region; } @Override public List selectArdDeptRegionList(ArdDeptRegion ardDeptRegion) { List list = ardDeptRegionMapper.selectArdDeptRegionList(ardDeptRegion); list.forEach(region -> { region.setCoordinates(RegionCoordinateUtils.toCoordinates(region.getBoundaryWkt())); }); return list; } /** * 校验区域名称是否唯一 */ @Override public boolean checkRegionNameUnique(ArdDeptRegion ardDeptRegion) { Long id = StringUtils.isNull(ardDeptRegion.getId()) ? -1L : ardDeptRegion.getId(); ArdDeptRegion info = ardDeptRegionMapper.checkRegionNameUnique(ardDeptRegion.getRegionName()); if (StringUtils.isNotNull(info) && info.getId().longValue() != id.longValue()) { return RegionConstants.NOT_UNIQUE; } return RegionConstants.UNIQUE; } /** * 检查区域冲突 */ @Override public ConflictCheckResult checkConflict(ArdDeptRegion ardDeptRegion) { ConflictCheckResult result = new ConflictCheckResult(); try { // 1. 验证坐标 List coordinates = ardDeptRegion.getCoordinates(); RegionCoordinateUtils.validateCoordinates(coordinates); // 2. 根据坐标数量自动判断类型 String regionType = RegionCoordinateUtils.getRegionTypeByCoordinates(coordinates); ardDeptRegion.setRegionType(regionType); // 3. 转换为WKT String wkt = RegionCoordinateUtils.toWkt(coordinates); ardDeptRegion.setBoundaryWkt(wkt); // 4. 根据类型检查冲突 List conflicts = null; Long excludeId = ardDeptRegion.getId(); switch (regionType) { case "POINT": conflicts = ardDeptRegionMapper.checkPointConflict( ardDeptRegion.getDeptId(), wkt, excludeId); break; case "LINE": conflicts = ardDeptRegionMapper.checkLineConflict( ardDeptRegion.getDeptId(), wkt, excludeId); break; case "POLYGON": conflicts = ardDeptRegionMapper.checkPolygonConflict( ardDeptRegion.getDeptId(), wkt, excludeId); break; default: result.setHasConflict(true); result.setMessage("不支持的几何类型"); return result; } if (!CollectionUtils.isEmpty(conflicts)) { result.setHasConflict(true); result.setMessage(String.format("该%s与%d个已有区域存在冲突", getRegionTypeName(regionType), conflicts.size())); result.setConflictRegions(conflicts); } else { result.setHasConflict(false); result.setMessage("无冲突,可以添加"); } } catch (Exception e) { log.error("检查冲突失败", e); result.setHasConflict(true); result.setMessage("检查失败: " + e.getMessage()); } return result; } @Override @Transactional public int insertArdDeptRegion(ArdDeptRegion ardDeptRegion) { // 1. 检查冲突 ConflictCheckResult checkResult = checkConflict(ardDeptRegion); if (checkResult.getHasConflict()) { throw new RuntimeException(checkResult.getMessage()); } // 2. 计算中心点和面积 List coordinates = ardDeptRegion.getCoordinates(); Coordinate center = RegionCoordinateUtils.calculateCenter(coordinates); ardDeptRegion.setCenterLat(center != null ? center.getLat() : null); ardDeptRegion.setCenterLng(center != null ? center.getLng() : null); // 只有面类型计算面积 if ("POLYGON".equals(ardDeptRegion.getRegionType())) { ardDeptRegion.setAreaSize(RegionCoordinateUtils.calculateArea(coordinates)); } else { ardDeptRegion.setAreaSize(0.0); } // 3. 设置默认颜色 if (ardDeptRegion.getRegionColor() == null || ardDeptRegion.getRegionColor().isEmpty()) { ardDeptRegion.setRegionColor("#3c8dbc"); } // 4. 插入数据 ardDeptRegion.setCreateBy(SecurityUtils.getUsername()); ardDeptRegion.setCreateTime(DateUtils.getNowDate()); ardDeptRegion.setStatus("0"); return ardDeptRegionMapper.insertArdDeptRegion(ardDeptRegion); } @Override @Transactional public int updateArdDeptRegion(ArdDeptRegion ardDeptRegion) { // 1. 获取原区域 ArdDeptRegion oldRegion = selectArdDeptRegionById(ardDeptRegion.getId()); if (oldRegion == null) { throw new RuntimeException("区域不存在"); } // 2. 如果坐标有变化,检查冲突 if (ardDeptRegion.getCoordinates() != null && !ardDeptRegion.getCoordinates().isEmpty()) { List coordinates = ardDeptRegion.getCoordinates(); RegionCoordinateUtils.validateCoordinates(coordinates); String regionType = RegionCoordinateUtils.getRegionTypeByCoordinates(coordinates); ardDeptRegion.setRegionType(regionType); String wkt = RegionCoordinateUtils.toWkt(coordinates); ardDeptRegion.setBoundaryWkt(wkt); // 根据类型检查冲突 List conflicts = null; switch (regionType) { case "POINT": conflicts = ardDeptRegionMapper.checkPointConflict( ardDeptRegion.getDeptId(), wkt, ardDeptRegion.getId()); break; case "LINE": conflicts = ardDeptRegionMapper.checkLineConflict( ardDeptRegion.getDeptId(), wkt, ardDeptRegion.getId()); break; case "POLYGON": conflicts = ardDeptRegionMapper.checkPolygonConflict( ardDeptRegion.getDeptId(), wkt, ardDeptRegion.getId()); break; } if (!CollectionUtils.isEmpty(conflicts)) { throw new RuntimeException("更新后的区域与已有区域存在冲突"); } // 重新计算中心点和面积 Coordinate center = RegionCoordinateUtils.calculateCenter(coordinates); ardDeptRegion.setCenterLat(center != null ? center.getLat() : null); ardDeptRegion.setCenterLng(center != null ? center.getLng() : null); if ("POLYGON".equals(regionType)) { ardDeptRegion.setAreaSize(RegionCoordinateUtils.calculateArea(coordinates)); } else { ardDeptRegion.setAreaSize(0.0); } } ardDeptRegion.setUpdateBy(SecurityUtils.getUsername()); ardDeptRegion.setUpdateTime(DateUtils.getNowDate()); return ardDeptRegionMapper.updateArdDeptRegion(ardDeptRegion); } /** * 修改状态(启用/禁用) */ @Override public int updateStatus(Long id, String status) { // 检查区域是否存在 ArdDeptRegion region = selectArdDeptRegionById(id); if (region == null) { throw new RuntimeException("区域不存在"); } // 更新状态 return ardDeptRegionMapper.updateStatus(id, status); } @Override public ArdDeptRegion selectRegionByPoint(Double lat, Double lng) { String pointWkt = String.format("POINT(%f %f)", lat, lng); return ardDeptRegionMapper.selectRegionByPoint(pointWkt); } @Override public int deleteArdDeptRegionByIds(String[] ids) { return ardDeptRegionMapper.deleteArdDeptRegionByIds(ids); } @Override public int deleteArdDeptRegionById(Long id) { return ardDeptRegionMapper.deleteArdDeptRegionById(id); } /** * 获取区域类型中文名 */ private String getRegionTypeName(String type) { switch (type) { case "POINT": return "点"; case "LINE": return "线"; case "POLYGON": return "面"; default: return type; } } }