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<ArdDeptRegion> selectArdDeptRegionList(ArdDeptRegion ardDeptRegion)
|
{
|
List<ArdDeptRegion> 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<Coordinate> 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<ConflictRegion> 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<Coordinate> 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<Coordinate> coordinates = ardDeptRegion.getCoordinates();
|
RegionCoordinateUtils.validateCoordinates(coordinates);
|
|
String regionType = RegionCoordinateUtils.getRegionTypeByCoordinates(coordinates);
|
ardDeptRegion.setRegionType(regionType);
|
|
String wkt = RegionCoordinateUtils.toWkt(coordinates);
|
ardDeptRegion.setBoundaryWkt(wkt);
|
|
// 根据类型检查冲突
|
List<ConflictRegion> 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;
|
}
|
}
|
}
|