package cn.gistack.sm.sjztmd.service.impl;
|
|
import cn.gistack.sm.intelligentCall.mapper.CallTaskMapper;
|
import cn.gistack.sm.sjztmd.constant.RainfallConstant;
|
import cn.gistack.sm.sjztmd.dto.AttResBaseUserDTO;
|
import cn.gistack.sm.sjztmd.entity.AttAdBase;
|
import cn.gistack.sm.sjztmd.entity.AttResBase;
|
import cn.gistack.sm.sjztmd.entity.RelResLabel;
|
import cn.gistack.sm.sjztmd.excel.AttResBaseUserExcel;
|
import cn.gistack.sm.sjztmd.mapper.AttResBaseMapper;
|
import cn.gistack.sm.sjztmd.service.IAttResBaseService;
|
import cn.gistack.sm.sjztmd.service.IRelResLabelService;
|
import cn.gistack.sm.sjztmd.vo.*;
|
import cn.gistack.system.feign.ISysClient;
|
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.util.StrUtil;
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.databind.JsonNode;
|
import cn.hutool.http.HttpRequest;
|
import cn.hutool.http.HttpResponse;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springblade.core.log.exception.ServiceException;
|
import org.springblade.core.secure.BladeUser;
|
import org.springblade.core.secure.utils.AuthUtil;
|
import org.springblade.core.tool.utils.DateUtil;
|
import org.springblade.core.tool.utils.StringUtil;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.web.bind.annotation.RequestParam;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* @ClassName AttResBaseServiceImpl
|
* @Description TODO
|
* @Author aix
|
* @Date 2023/4/21 20:01
|
* @Version 1.0
|
*/
|
|
@Slf4j
|
@Service
|
@DS("zt")
|
public class AttResBaseServiceImpl extends ServiceImpl<AttResBaseMapper, AttResBase> implements IAttResBaseService {
|
private static final ObjectMapper objectMapper = new ObjectMapper();
|
|
@Autowired
|
private CallTaskMapper callTaskMapper;
|
|
@Autowired
|
private IRelResLabelService relResLabelService;
|
|
@Autowired
|
private ISysClient sysClient;
|
|
|
@Override
|
public IPage<AttResBase> selectAttResBasePage(IPage<AttResBase> page, AttResBase attResBase) {
|
return page.setRecords(baseMapper.selectAttResBasePage(page,attResBase));
|
}
|
|
@Override
|
public Object selectAttResBaseGeneralInvestigation(IPage<AttResBaseGeneralInvestigationVO> page, AttResBaseGeneralInvestigationVO attResBase) {
|
|
if (attResBase.getIsPage()){
|
return page.setRecords(baseMapper.selectAttResBaseGeneralInvestigation(page,attResBase));
|
}else {
|
return baseMapper.selectAttResBaseGeneralInvestigation(null,attResBase);
|
}
|
}
|
|
@Override
|
public IPage<AttResBaseVO> getListByRegion(IPage<AttResBaseVO> page,Map<String, Object> obj) {
|
return page.setRecords(baseMapper.getListByRegion(page,obj));
|
}
|
|
@Override
|
public AttResBase getDetailByCode(String code) {
|
return baseMapper.getDetailByCode(code);
|
}
|
|
/**
|
* 获取水库对应责任人分页数据
|
* @param params 条件查询参数对象
|
* @param page 分页查询参数对象
|
* @return
|
*/
|
@Override
|
public Object getAttResBaseUserPage(IPage<AttResBaseUserDTO> page,Map<String, Object> params) {
|
|
Object isExport = params.get("isExport");
|
// 判断是否导出,导出不分页
|
if (null != isExport && !isExport.equals("")) {
|
return baseMapper.getAttResBaseUserPage(null,params);
|
}
|
List<AttResBaseUserDTO> attResBaseUserDTOList = baseMapper.getAttResBaseUserPage(page,params);
|
// 返回数据
|
return page.setRecords(attResBaseUserDTOList);
|
}
|
|
|
@Override
|
public List<AttResBaseUserExcel> exportAttResBaseUser(Map<String, Object> params) {
|
|
|
List<AttResBaseUserExcel> attResBaseUserDTOList = baseMapper.getAttResBaseUserExcel(params);
|
return attResBaseUserDTOList;
|
}
|
|
@Override
|
public List<AttResWithRainfall> getAttResByRainfall(String minRainfall, String maxRainfall, String dayIndex) {
|
if (StrUtil.isNotEmpty(dayIndex) && !Arrays.asList(0,1,2).contains(Integer.parseInt(dayIndex))) {
|
throw new ServiceException("无效的dayIndex");
|
}
|
Double minRainfallDouble = null;
|
Double maxRainfallDouble = null;
|
if (StrUtil.isNotEmpty(minRainfall)) {
|
minRainfallDouble = Double.parseDouble(minRainfall);
|
}
|
if (StrUtil.isNotEmpty(minRainfall)) {
|
maxRainfallDouble = Double.parseDouble(maxRainfall);
|
}
|
// 调用气象预报服务接口
|
String resJsonNodeStr;
|
try (HttpResponse httpResponse = HttpRequest.post(RainfallConstant.FORECAST_SERVICE_URL)
|
.header("Content-Type", "application/json")
|
.header("X-token", RainfallConstant.X_TOKEN)
|
.contentType("application/json")
|
.body(String.format(RainfallConstant.REQUEST_JSON_BODY, StrUtil.isEmpty(dayIndex) ? "0" : dayIndex)).execute()) {
|
JsonNode resJsonNode = objectMapper.readTree(httpResponse.body());
|
resJsonNodeStr = resJsonNode.toString();
|
} catch (Exception e) {
|
throw new ServiceException("调用气象预报服务接口失败,详情:" + e.getMessage());
|
}
|
RainfallGridData gridData;
|
try {
|
gridData = objectMapper.readValue(resJsonNodeStr, RainfallGridData.class);
|
} catch (JsonProcessingException e) {
|
throw new ServiceException("转换降雨栅格数据失败,详情:" + e.getMessage());
|
}
|
RainfallGridData.Data data = gridData.getData();
|
String fileName = data.getFileName();
|
RainfallGridData.GridInfo gridInfo = data.getGridInfo();
|
List<List<Double>> gridDataList = data.getGridData();
|
if (gridDataList == null || gridDataList.isEmpty()) {
|
log.warn("gridDataList为空!");
|
return new ArrayList<>();
|
}
|
// 获取网格信息
|
int lonNum = gridInfo.getLonNum(); // 网格横向(经度)
|
double lonMax = gridInfo.getLonMax();
|
double lonSpan = gridInfo.getLonSpan(); // 每个网格单元的经度跨度
|
double latSpan = gridInfo.getLatSpan(); // 每个网格单元的纬度跨度
|
double latMin = gridInfo.getLatMin(); // 网格的最小纬度
|
double lonMin = gridInfo.getLonMin(); // 网格的最小经度
|
double latMax = gridInfo.getLatMax();
|
int latNum = gridInfo.getLatNum(); // 网格纵向(纬度)
|
|
// 将网格数据转换为二维数组
|
double[][] grid = new double[latNum][lonNum];
|
for (int i = 0; i < latNum; i++) {
|
List<Double> row = gridDataList.get(i);
|
for (int j = 0; j < lonNum; j++) {
|
grid[i][j] = row.get(j);
|
}
|
}
|
|
LambdaQueryWrapper<AttResBase> queryWrapper = Wrappers.<AttResBase>query().lambda();
|
List<AttResBase> attResBases = baseMapper.selectList(queryWrapper);
|
List<AttResWithRainfall> attResWithRainfallList = new ArrayList<>();
|
|
for (AttResBase attResBase : attResBases) {
|
if (null == attResBase.getCenterLat() || attResBase.getCenterLong() == null) {
|
log.warn("过滤掉经度或者纬度为空的水库,水库名称:{}", attResBase.getName());
|
continue;
|
}
|
// 横向索引(lonIndex):(站点的经度 - 网格最小经度) / 每个网格单元的经度跨度
|
int lonIndex = (int) ((Double.parseDouble(attResBase.getCenterLong()) - lonMin) / lonSpan);
|
// 纵向索引(latIndex):(站点的纬度 - 网格最小纬度) / 每个网格单元的纬度跨度
|
int latIndex = (int) ((Double.parseDouble(attResBase.getCenterLat()) - latMin) / latSpan);
|
if (lonIndex >= 0 && lonIndex < lonNum && latIndex >= 0 && latIndex < latNum) {
|
double rainfall = grid[latIndex][lonIndex];
|
// 降雨量 <= 最小值的站点,都过滤掉, 降雨量为0除外
|
if (null != minRainfallDouble && rainfall != 0 && rainfall <= minRainfallDouble) {
|
continue;
|
}
|
// 降雨量 > 最大值的站点,都过滤掉
|
if (null != maxRainfallDouble && rainfall > maxRainfallDouble) {
|
continue;
|
}
|
AttResWithRainfall attResWithRainfall = new AttResWithRainfall();
|
BeanUtil.copyProperties(attResBase, attResWithRainfall);
|
attResWithRainfall.setRainfall(String.valueOf(rainfall));
|
attResWithRainfall.setFileName(fileName);
|
attResWithRainfallList.add(attResWithRainfall);
|
} else {
|
log.warn("水库 {} 超出栅格范围. 中心点经度: {}, 中心点纬度: {}", attResBase.getName(),
|
attResBase.getCenterLong(), attResBase.getCenterLat());
|
}
|
}
|
return attResWithRainfallList;
|
}
|
|
@Override
|
public int[] getAttResNumByRainfall(String dayIndex) {
|
List<AttResWithRainfall> attResByRainfall;
|
// 获取站点降雨量失败或者返回站点列表为空时,直接返回空数组
|
try {
|
attResByRainfall = getAttResByRainfall(null, null, dayIndex);
|
} catch (Exception e) {
|
return RainfallConstant.EMPTY_ATT_RES_NUM_ARRAY;
|
}
|
if (attResByRainfall == null || attResByRainfall.isEmpty()) {
|
return RainfallConstant.EMPTY_ATT_RES_NUM_ARRAY;
|
}
|
// 降雨范围-站点数量
|
Map<String, Integer> rainfallRangeAttResNumMap = attResByRainfall.stream()
|
.collect(Collectors.groupingBy(attResWithRainfall -> {
|
int rainfall = Integer.parseInt(attResWithRainfall.getRainfall());
|
if (rainfall > 250) {
|
return "(250,+)";
|
} else if (rainfall > 100) {
|
return "(100,250]";
|
} else if (rainfall > 50) {
|
return "(50,100]";
|
} else if (rainfall > 25) {
|
return "(25,50]";
|
} else if (rainfall > 10) {
|
return "(10,25]";
|
} else if (rainfall > 5) {
|
return "(5,10]";
|
} else if (rainfall > 0.1) {
|
return "(0.1,5]";
|
} else if (rainfall >= 0) {
|
return "[0,0.1]";
|
} else {
|
throw new ServiceException("无效的降雨值:" + rainfall);
|
}
|
}, Collectors.collectingAndThen(Collectors.counting(), Long::intValue)));
|
int[] attResNumArray = new int[RainfallConstant.RAIN_FALL_RANGES.size()];
|
for (int i = 0; i < RainfallConstant.RAIN_FALL_RANGES.size(); i++) {
|
String range = RainfallConstant.RAIN_FALL_RANGES.get(i);
|
attResNumArray[i] = rainfallRangeAttResNumMap.getOrDefault(range, 0);
|
}
|
return attResNumArray;
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Boolean updateResBaseByGuid(AttResBase attResBase) {
|
attResBase.setUpdateTime(DateUtil.now());
|
|
String updateBy = baseMapper.getUpdateLog(attResBase.getGuid());
|
if (StringUtil.isBlank(updateBy)){
|
updateBy = "";
|
}
|
BladeUser user = AuthUtil.getUser();
|
//修改人基础信息
|
String account = user.getAccount();
|
String userName = user.getUserName();
|
String nowTime = DateUtil.format(DateUtil.now(),DateUtil.PATTERN_DATETIME);
|
|
String updateUser = StringUtil.format("[{}-{}-{}]",account,userName,nowTime);
|
|
//修改的东西
|
String interiorAdGuid = attResBase.getInteriorAdGuid();
|
String label = attResBase.getLabel();
|
String heightBaseStdTp = attResBase.getHeightBaseStdTp();
|
String isGate = attResBase.getIsGate();
|
|
String updateLog = "";
|
List<String> strList = new ArrayList<>();
|
if (StringUtil.isNotBlank(interiorAdGuid)){
|
strList.add("行政区划修改为"+ interiorAdGuid);
|
}
|
strList.add("标签修改为"+label);
|
strList.add("高程基准面修改为"+heightBaseStdTp);
|
strList.add("是否有闸修改为"+isGate);
|
|
String updateContent = String.join("、",strList);
|
|
updateLog = updateUser + updateContent + ";";
|
updateBy = updateBy + updateLog;
|
//向水库标签表中更新数据
|
relResLabelService.updateEntity(attResBase.getGuid(),attResBase.getLabel());
|
|
//更新机构表中的水库位置
|
sysClient.updateDeptByTb(interiorAdGuid,attResBase.getGuid());
|
|
//向操作记录表中增加记录
|
baseMapper.updateRelResUpdateLoc(attResBase.getGuid(),updateBy);
|
return baseMapper.updateResBaseByGuid(attResBase);
|
}
|
|
/**
|
* 查询当前水库对应的市级编号和县区编号
|
* @param res_cd
|
* @return
|
*/
|
@Override
|
public AttResBaseVO getCityCountyCodeByResGuid(String res_cd) {
|
return baseMapper.getCityCountyCodeByResGuid(res_cd);
|
}
|
|
/**
|
* 根据水库编码获取行政区数据
|
* @param guid
|
* @return
|
*/
|
@Override
|
public AttResAdVO getWaterRegionInfoByResGuid(String guid) {
|
return baseMapper.getWaterRegionInfoByResGuid(guid);
|
}
|
|
@Override
|
public int getDimResInfoACount() {
|
return baseMapper.getDimResInfoACount();
|
}
|
|
@Override
|
public Boolean updateIsShowStatus(String ids, Integer status) {
|
return baseMapper.updateIsShowStatus(ids,status);
|
}
|
|
/**
|
* 根据水库名称、所在区域查询改水库的数量
|
* @param resName 水库名称
|
* @param countyCode 区县
|
* @return
|
*/
|
@Override
|
public Integer getWaterCountByResNameAndCountyName(String resName, String countyCode) {
|
return baseMapper.getWaterCountByResNameAndCountyName(resName,countyCode);
|
}
|
|
@Override
|
public AttResAdVO getResAd(String resId) {
|
return baseMapper.getResAd(resId);
|
}
|
|
@Override
|
public AttAdBase getYwxtResInfo(String cityName, String countyName) {
|
return baseMapper.getYwxtResInfo(cityName,countyName);
|
}
|
|
}
|