16 Commits

Author SHA1 Message Date
wzy-warehouse d4f892fad6 水库不显示的问题 2026-06-17 16:02:12 +08:00
wzy-warehouse bfd80887b2 调整返回前端的数据顺序 2026-06-17 15:42:10 +08:00
wzy-warehouse e33105a467 添加预测概率 2026-06-17 14:22:53 +08:00
wzy-warehouse f4af9975d6 添加崩塌隐患点 2026-06-16 10:19:22 +08:00
wzy-warehouse 3c6b716007 统一数据库映射 2026-06-12 10:08:20 +08:00
wzy-warehouse 7ff67f8a37 修改配置文件 2026-06-02 10:25:42 +08:00
wzy-warehouse 9d95700787 对降雨栅格添加websocket响应 2026-05-18 17:26:00 +08:00
wzy-warehouse 2fe0db36df websocket配置 2026-05-18 10:17:02 +08:00
wzy-warehouse d2fc460c35 去掉隐藏字符 2026-05-18 10:16:41 +08:00
wzy-warehouse e4e3a09c47 修改加解密逻辑,允许使用通配符进行过滤 2026-05-18 10:16:26 +08:00
wzy-warehouse 2b40f2e13b 暴雨图层加载功能 2026-05-05 19:22:25 +08:00
wzy-warehouse 0018d43f09 添加geoserver说明 2026-05-05 19:19:12 +08:00
wzy-warehouse babb835ca4 修改名称 2026-04-28 10:06:58 +08:00
wzy-warehouse 668190dcd9 细化隐患点类型 2026-04-28 09:28:48 +08:00
wzy-warehouse 233959e918 细化隐患点类型 2026-04-27 22:50:32 +08:00
wzy-warehouse 601cb300bc 为所有点类表映射name属性 2026-04-27 21:34:48 +08:00
48 changed files with 1308 additions and 150 deletions
+15
View File
@@ -106,5 +106,20 @@ bin\package.bat
- `application-database-dev.yml`: 开发环境数据库配置 - `application-database-dev.yml`: 开发环境数据库配置
- `application-database-prod.yml`: 生产环境数据库配置 - `application-database-prod.yml`: 生产环境数据库配置
# geo_server相关说明
1. 版本:2.28.3
2. 安装:
```
docker pull docker.osgeo.org/geoserver:2.28.3
docker run -d \
--log-driver none \
--name geoserver \
-p 8080:4020 \
-e GEOSERVER_ADMIN_USER=admin \
-e GEOSERVER_ADMIN_PASSWORD=geoserver \
-v /mydata/geoserver/data_dir:/data_dir \
kartoza/geoserver
```
## 许可证 ## 许可证
本项目基于 [MIT License](LICENSE) 开源,详情请查看LICENSE文件。 本项目基于 [MIT License](LICENSE) 开源,详情请查看LICENSE文件。
@@ -5,12 +5,14 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableScheduling;
/** /**
* 后台启动入口 * 后台启动入口
* 启动时过滤DataSourceAutoConfiguration,避免数据源自动配置 * 启动时过滤DataSourceAutoConfiguration,避免数据源自动配置
*/ */
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class) @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableScheduling // 启用定时任务支持
@MapperScan("com.gis.xian.mapper") // 扫描MyBatis的Mapper接口 @MapperScan("com.gis.xian.mapper") // 扫描MyBatis的Mapper接口
public class XianApplication { public class XianApplication {
@@ -0,0 +1,19 @@
package com.gis.xian.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 算法服务器配置属性
*/
@Data
@Component
@ConfigurationProperties(prefix = "algorithm.server")
public class AlgorithmServerProperties {
/**
* 算法服务器地址
*/
private String url;
}
@@ -0,0 +1,25 @@
package com.gis.xian.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 降雨网格配置属性类
* 从application.yml中读取rainfall.grid配置
*/
@Data
@Component
@ConfigurationProperties(prefix = "rainfall.grid")
public class RainfallGridProperties {
/**
* 降雨站点网格数据 Redis Key
*/
private String stationGrid;
/**
* 降雨站点标识符 Redis Key
*/
private String stationIdentifier;
}
@@ -0,0 +1,28 @@
package com.gis.xian.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker // 启用WebSocket消息代理
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
// 启用简单的内存消息代理,客户端订阅以 "/topic" 开头的目的地
registry.enableSimpleBroker("/topic");
// 设置客户端发送消息的前缀,即 "/app"
registry.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// 注册端点 "/websocket",客户端将通过此路径建立连接
registry.addEndpoint("/websocket")
.setAllowedOriginPatterns("*") // 允许所有源,支持携带凭证
.withSockJS();
}
}
@@ -0,0 +1,222 @@
package com.gis.xian.controller;
import com.alibaba.fastjson2.JSON;
import com.gis.xian.config.AlgorithmServerProperties;
import com.gis.xian.domain.ApiResponse;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.Map;
/**
* 算法代理控制器
* 所有以 /algorithm-api 开头的请求都会转发到算法服务器
*/
@RestController
@RequestMapping("/algorithm-api")
@Slf4j
public class AlgorithmProxyController extends BaseController {
@Resource
private AlgorithmServerProperties algorithmServerProperties;
private final RestTemplate restTemplate = new RestTemplate();
/**
* 处理所有 GET 请求
*/
@GetMapping("/**")
public ApiResponse<Object> proxyGet(HttpServletRequest request) {
return proxyRequest(request, HttpMethod.GET);
}
/**
* 处理所有 POST 请求
*/
@PostMapping("/**")
public ApiResponse<Object> proxyPost(HttpServletRequest request) throws IOException {
return proxyRequest(request, HttpMethod.POST);
}
/**
* 处理所有 PUT 请求
*/
@PutMapping("/**")
public ApiResponse<Object> proxyPut(HttpServletRequest request) throws IOException {
return proxyRequest(request, HttpMethod.PUT);
}
/**
* 处理所有 DELETE 请求
*/
@DeleteMapping("/**")
public ApiResponse<Object> proxyDelete(HttpServletRequest request) {
return proxyRequest(request, HttpMethod.DELETE);
}
/**
* 处理所有 PATCH 请求
*/
@PatchMapping("/**")
public ApiResponse<Object> proxyPatch(HttpServletRequest request) throws IOException {
return proxyRequest(request, HttpMethod.PATCH);
}
/**
* 通用的请求代理方法
*/
@SuppressWarnings("unchecked")
private ApiResponse<Object> proxyRequest(HttpServletRequest request, HttpMethod httpMethod) {
long startTime = System.currentTimeMillis();
try {
// 构建目标 URL
String targetUrl = buildTargetUrl(request);
log.info("代理请求: {} -> {}", request.getRequestURI(), targetUrl);
// 构建请求头
HttpHeaders headers = buildRequestHeaders(request);
// 构建请求体
Object requestBody = null;
if (httpMethod == HttpMethod.POST || httpMethod == HttpMethod.PUT || httpMethod == HttpMethod.PATCH) {
String contentType = request.getContentType();
if (contentType != null && !contentType.isEmpty()) {
headers.setContentType(MediaType.parseMediaType(contentType));
// 读取请求体
byte[] bodyBytes = StreamUtils.copyToByteArray(request.getInputStream());
if (bodyBytes.length > 0) {
// 尝试解析为 JSON,如果不是 JSON 则直接使用字节数组
if (contentType.contains("application/json")) {
String jsonBody = new String(bodyBytes, StandardCharsets.UTF_8);
try {
requestBody = JSON.parse(jsonBody);
} catch (Exception e) {
requestBody = jsonBody;
}
} else {
requestBody = bodyBytes;
}
}
}
}
// 创建 HTTP 实体
HttpEntity<Object> entity = new HttpEntity<>(requestBody, headers);
// 发送请求到算法服务器
ResponseEntity<String> response = restTemplate.exchange(
targetUrl,
httpMethod,
entity,
String.class
);
// 解析响应
long endTime = System.currentTimeMillis();
log.info("代理请求完成: {} -> {}, 耗时: {}ms, 状态码: {}",
request.getRequestURI(), targetUrl, (endTime - startTime), response.getStatusCode());
// 尝试将响应解析为 ApiResponse
String responseBody = response.getBody();
if (responseBody != null && !responseBody.isEmpty()) {
try {
// 尝试解析为 ApiResponse 格式
Map<String, Object> responseMap = JSON.parseObject(responseBody, Map.class);
if (responseMap.containsKey("code") && responseMap.containsKey("message")) {
// 如果已经是 ApiResponse 格式,直接返回
Integer code = (Integer) responseMap.get("code");
String message = (String) responseMap.get("message");
Object data = responseMap.get("data");
return new ApiResponse<>(code, message, data);
}
} catch (Exception e) {
log.debug("响应不是标准 ApiResponse 格式,将作为数据返回");
}
// 如果不是 ApiResponse 格式,将整个响应作为 data 返回
return ApiResponse.ok((Object) responseBody);
}
return ApiResponse.ok((Object) null);
} catch (Exception e) {
long endTime = System.currentTimeMillis();
log.error("代理请求失败: {} , 耗时: {}ms, 错误: {}",
request.getRequestURI(), (endTime - startTime), e.getMessage(), e);
return ApiResponse.error(502, "算法服务调用失败: " + e.getMessage(), null);
}
}
/**
* 构建目标 URL
*/
private String buildTargetUrl(HttpServletRequest request) {
// 获取原始请求路径,去掉 /algorithm-api 前缀
String requestUri = request.getRequestURI();
String path = requestUri.substring("/algorithm-api".length());
// 确保路径以 / 开头
if (!path.startsWith("/")) {
path = "/" + path;
}
// 拼接算法服务器地址和路径
String baseUrl = algorithmServerProperties.getUrl();
if (baseUrl.endsWith("/") && path.startsWith("/")) {
baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
}
String targetUrl = baseUrl + path;
// 添加查询参数
String queryString = request.getQueryString();
if (queryString != null && !queryString.isEmpty()) {
targetUrl += "?" + queryString;
}
return targetUrl;
}
/**
* 构建请求头
*/
private HttpHeaders buildRequestHeaders(HttpServletRequest request) {
HttpHeaders headers = new HttpHeaders();
// 复制所有请求头(排除一些特定的头)
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
// 排除一些不应该转发的头
if (!shouldExcludeHeader(headerName)) {
Enumeration<String> headerValues = request.getHeaders(headerName);
while (headerValues.hasMoreElements()) {
headers.add(headerName, headerValues.nextElement());
}
}
}
return headers;
}
/**
* 判断是否应该排除该请求头
*/
private boolean shouldExcludeHeader(String headerName) {
String lowerName = headerName.toLowerCase();
// 排除 Host、Content-Length 等头
return lowerName.equals("host") ||
lowerName.equals("content-length") ||
lowerName.equals("transfer-encoding");
}
}
@@ -0,0 +1,82 @@
package com.gis.xian.controller;
import com.gis.xian.domain.ApiResponse;
import com.gis.xian.service.RainfallGridService;
import com.gis.xian.vo.RainfallGridVo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.atomic.AtomicReference;
/**
* 降雨网格控制器
*/
@Slf4j
@RestController
public class RainfallGridController extends BaseController {
@Resource
private SimpMessagingTemplate messagingTemplate;
@Resource
private RainfallGridService rainfallGridService;
// 存储上一次的 ID,用于检测变化
private final AtomicReference<String> lastIdentifier = new AtomicReference<>(null);
/**
* 处理客户端订阅请求,首次订阅时返回当前数据
* 客户端发送任意消息到 /app/rainfall/grid 即可触发
*/
@MessageMapping("/rainfall/grid")
@SendTo("/topic/rainfall/grid/messages")
public ApiResponse<RainfallGridVo> handleSubscription() {
RainfallGridVo data = rainfallGridService.getRainfallGridData();
// 记录当前 identifier,用于后续变化检测
String currentIdentifier = rainfallGridService.getCurrentIdentifier();
if (currentIdentifier != null) {
lastIdentifier.set(currentIdentifier);
log.info("客户端订阅,记录初始 identifier: {}", currentIdentifier);
}
log.info("响应客户端订阅请求: id={}", data.getId());
return ApiResponse.ok(data);
}
/**
* 每秒检查 Redis 中的 identifier 是否变化,如果变化则推送新数据
*/
@Scheduled(fixedRate = 1000)
public void checkAndPushIfChanged() {
try {
String currentIdentifier = rainfallGridService.getCurrentIdentifier();
// 如果 identifier 为空,跳过
if (currentIdentifier == null) {
return;
}
// 检查 identifier 是否发生变化
String previousIdentifier = lastIdentifier.get();
if (previousIdentifier == null || !previousIdentifier.equals(currentIdentifier)) {
log.info("检测到 identifier 变化: {} -> {}", previousIdentifier, currentIdentifier);
// 获取最新数据并推送
RainfallGridVo data = rainfallGridService.getRainfallGridData();
messagingTemplate.convertAndSend("/topic/rainfall/grid/messages", ApiResponse.ok(data));
log.info("推送更新数据: id={}", data.getId());
// 更新记录的 identifier
lastIdentifier.set(currentIdentifier);
}
} catch (Exception e) {
log.error("检查并推送数据失败: {}", e.getMessage(), e);
}
}
}
@@ -17,12 +17,13 @@ public class XianHiddenDangerSpotsController extends BaseController{
private XianHiddenDangerSpotsService xianHiddenDangerSpotsService; private XianHiddenDangerSpotsService xianHiddenDangerSpotsService;
@GetMapping("/base-points") @GetMapping("/base-points")
public ApiResponse<List<XianHiddenDangerSpotsBasePointVo>> getBasePoints(@RequestParam String disasterType) { public ApiResponse<List<XianHiddenDangerSpotsBasePointVo>> getBasePoints(
@RequestParam(required = false) String disasterType) {
return ApiResponse.ok(xianHiddenDangerSpotsService.getBasePoints(disasterType)); return ApiResponse.ok(xianHiddenDangerSpotsService.getBasePoints(disasterType));
} }
@GetMapping("point-detail/{id}") @GetMapping("point-detail/{id}/{simulationId}")
public ApiResponse<XianHiddenDangerSpotsPointDetailVo> getPointDetailById(@PathVariable String id) { public ApiResponse<XianHiddenDangerSpotsPointDetailVo> getPointDetailById(@PathVariable String id, @PathVariable String simulationId) {
return ApiResponse.ok(xianHiddenDangerSpotsService.getPointDetailById(Long.parseLong(id))); return ApiResponse.ok(xianHiddenDangerSpotsService.getPointDetailById(Long.parseLong(id), Long.parseLong(simulationId)));
} }
} }
@@ -24,8 +24,8 @@ public class XianRiskSpotsController {
return ApiResponse.ok(xianRiskSpotsService.getBasePoints()); return ApiResponse.ok(xianRiskSpotsService.getBasePoints());
} }
@GetMapping("point-detail/{id}") @GetMapping("point-detail/{id}/{simulationId}")
public ApiResponse<XianRiskSpotsPointDetailVo> getPointDetailById(@PathVariable String id) { public ApiResponse<XianRiskSpotsPointDetailVo> getPointDetailById(@PathVariable String id, @PathVariable String simulationId) {
return ApiResponse.ok(xianRiskSpotsService.getPointDetailById(Long.parseLong(id))); return ApiResponse.ok(xianRiskSpotsService.getPointDetailById(Long.parseLong(id), Long.parseLong(simulationId)));
} }
} }
@@ -86,7 +86,7 @@ public class XianBridge {
/** /**
* 位置 * 位置
*/ */
private Object point; private Object geom;
/** /**
* 逻辑删除标识,0未删除,1已删除 * 逻辑删除标识,0未删除,1已删除
@@ -120,7 +120,7 @@ public class XianBridge {
&& (this.getMaster() == null ? other.getMaster() == null : this.getMaster().equals(other.getMaster())) && (this.getMaster() == null ? other.getMaster() == null : this.getMaster().equals(other.getMaster()))
&& (this.getMaint() == null ? other.getMaint() == null : this.getMaint().equals(other.getMaint())) && (this.getMaint() == null ? other.getMaint() == null : this.getMaint().equals(other.getMaint()))
&& (this.getNote() == null ? other.getNote() == null : this.getNote().equals(other.getNote())) && (this.getNote() == null ? other.getNote() == null : this.getNote().equals(other.getNote()))
&& (this.getPoint() == null ? other.getPoint() == null : this.getPoint().equals(other.getPoint())) && (this.getGeom() == null ? other.getGeom() == null : this.getGeom().equals(other.getGeom()))
&& (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete())); && (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete()));
} }
@@ -143,7 +143,7 @@ public class XianBridge {
result = prime * result + ((getMaster() == null) ? 0 : getMaster().hashCode()); result = prime * result + ((getMaster() == null) ? 0 : getMaster().hashCode());
result = prime * result + ((getMaint() == null) ? 0 : getMaint().hashCode()); result = prime * result + ((getMaint() == null) ? 0 : getMaint().hashCode());
result = prime * result + ((getNote() == null) ? 0 : getNote().hashCode()); result = prime * result + ((getNote() == null) ? 0 : getNote().hashCode());
result = prime * result + ((getPoint() == null) ? 0 : getPoint().hashCode()); result = prime * result + ((getGeom() == null) ? 0 : getGeom().hashCode());
result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode()); result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode());
return result; return result;
} }
@@ -169,7 +169,7 @@ public class XianBridge {
sb.append(", master=").append(master); sb.append(", master=").append(master);
sb.append(", maint=").append(maint); sb.append(", maint=").append(maint);
sb.append(", note=").append(note); sb.append(", note=").append(note);
sb.append(", point=").append(point); sb.append(", geom=").append(geom);
sb.append(", isDelete=").append(isDelete); sb.append(", isDelete=").append(isDelete);
sb.append("]"); sb.append("]");
return sb.toString(); return sb.toString();
@@ -201,7 +201,7 @@ public class XianDangerousSource {
/** /**
* *
*/ */
private Object point; private Object geom;
/** /**
* 逻辑删除标识,0未删除,1已删除 * 逻辑删除标识,0未删除,1已删除
@@ -258,7 +258,7 @@ public class XianDangerousSource {
&& (this.getWriteTime() == null ? other.getWriteTime() == null : this.getWriteTime().equals(other.getWriteTime())) && (this.getWriteTime() == null ? other.getWriteTime() == null : this.getWriteTime().equals(other.getWriteTime()))
&& (this.getLon() == null ? other.getLon() == null : this.getLon().equals(other.getLon())) && (this.getLon() == null ? other.getLon() == null : this.getLon().equals(other.getLon()))
&& (this.getLat() == null ? other.getLat() == null : this.getLat().equals(other.getLat())) && (this.getLat() == null ? other.getLat() == null : this.getLat().equals(other.getLat()))
&& (this.getPoint() == null ? other.getPoint() == null : this.getPoint().equals(other.getPoint())) && (this.getGeom() == null ? other.getGeom() == null : this.getGeom().equals(other.getGeom()))
&& (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete())); && (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete()));
} }
@@ -304,7 +304,7 @@ public class XianDangerousSource {
result = prime * result + ((getWriteTime() == null) ? 0 : getWriteTime().hashCode()); result = prime * result + ((getWriteTime() == null) ? 0 : getWriteTime().hashCode());
result = prime * result + ((getLon() == null) ? 0 : getLon().hashCode()); result = prime * result + ((getLon() == null) ? 0 : getLon().hashCode());
result = prime * result + ((getLat() == null) ? 0 : getLat().hashCode()); result = prime * result + ((getLat() == null) ? 0 : getLat().hashCode());
result = prime * result + ((getPoint() == null) ? 0 : getPoint().hashCode()); result = prime * result + ((getGeom() == null) ? 0 : getGeom().hashCode());
result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode()); result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode());
return result; return result;
} }
@@ -353,7 +353,7 @@ public class XianDangerousSource {
sb.append(", writeTime=").append(writeTime); sb.append(", writeTime=").append(writeTime);
sb.append(", lon=").append(lon); sb.append(", lon=").append(lon);
sb.append(", lat=").append(lat); sb.append(", lat=").append(lat);
sb.append(", point=").append(point); sb.append(", geom=").append(geom);
sb.append(", isDelete=").append(isDelete); sb.append(", isDelete=").append(isDelete);
sb.append("]"); sb.append("]");
return sb.toString(); return sb.toString();
@@ -71,7 +71,7 @@ public class XianEmergencyShelter {
/** /**
* 位置 * 位置
*/ */
private Object point; private Object geom;
/** /**
* 逻辑删除标识,0未删除,1已删除 * 逻辑删除标识,0未删除,1已删除
@@ -102,7 +102,7 @@ public class XianEmergencyShelter {
&& (this.getEffectiveNumberOfRefugees() == null ? other.getEffectiveNumberOfRefugees() == null : this.getEffectiveNumberOfRefugees().equals(other.getEffectiveNumberOfRefugees())) && (this.getEffectiveNumberOfRefugees() == null ? other.getEffectiveNumberOfRefugees() == null : this.getEffectiveNumberOfRefugees().equals(other.getEffectiveNumberOfRefugees()))
&& (this.getLon() == null ? other.getLon() == null : this.getLon().equals(other.getLon())) && (this.getLon() == null ? other.getLon() == null : this.getLon().equals(other.getLon()))
&& (this.getLat() == null ? other.getLat() == null : this.getLat().equals(other.getLat())) && (this.getLat() == null ? other.getLat() == null : this.getLat().equals(other.getLat()))
&& (this.getPoint() == null ? other.getPoint() == null : this.getPoint().equals(other.getPoint())) && (this.getGeom() == null ? other.getGeom() == null : this.getGeom().equals(other.getGeom()))
&& (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete())); && (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete()));
} }
@@ -122,7 +122,7 @@ public class XianEmergencyShelter {
result = prime * result + ((getEffectiveNumberOfRefugees() == null) ? 0 : getEffectiveNumberOfRefugees().hashCode()); result = prime * result + ((getEffectiveNumberOfRefugees() == null) ? 0 : getEffectiveNumberOfRefugees().hashCode());
result = prime * result + ((getLon() == null) ? 0 : getLon().hashCode()); result = prime * result + ((getLon() == null) ? 0 : getLon().hashCode());
result = prime * result + ((getLat() == null) ? 0 : getLat().hashCode()); result = prime * result + ((getLat() == null) ? 0 : getLat().hashCode());
result = prime * result + ((getPoint() == null) ? 0 : getPoint().hashCode()); result = prime * result + ((getGeom() == null) ? 0 : getGeom().hashCode());
result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode()); result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode());
return result; return result;
} }
@@ -145,7 +145,7 @@ public class XianEmergencyShelter {
sb.append(", effectiveNumberOfRefugees=").append(effectiveNumberOfRefugees); sb.append(", effectiveNumberOfRefugees=").append(effectiveNumberOfRefugees);
sb.append(", lon=").append(lon); sb.append(", lon=").append(lon);
sb.append(", lat=").append(lat); sb.append(", lat=").append(lat);
sb.append(", point=").append(point); sb.append(", geom=").append(geom);
sb.append(", isDelete=").append(isDelete); sb.append(", isDelete=").append(isDelete);
sb.append("]"); sb.append("]");
return sb.toString(); return sb.toString();
@@ -281,7 +281,7 @@ public class XianFirefighter {
/** /**
* *
*/ */
private Object point; private Object geom;
/** /**
* 逻辑删除标识,0未删除,1已删除 * 逻辑删除标识,0未删除,1已删除
@@ -354,7 +354,7 @@ public class XianFirefighter {
&& (this.getWriteTime() == null ? other.getWriteTime() == null : this.getWriteTime().equals(other.getWriteTime())) && (this.getWriteTime() == null ? other.getWriteTime() == null : this.getWriteTime().equals(other.getWriteTime()))
&& (this.getLon() == null ? other.getLon() == null : this.getLon().equals(other.getLon())) && (this.getLon() == null ? other.getLon() == null : this.getLon().equals(other.getLon()))
&& (this.getLat() == null ? other.getLat() == null : this.getLat().equals(other.getLat())) && (this.getLat() == null ? other.getLat() == null : this.getLat().equals(other.getLat()))
&& (this.getPoint() == null ? other.getPoint() == null : this.getPoint().equals(other.getPoint())) && (this.getGeom() == null ? other.getGeom() == null : this.getGeom().equals(other.getGeom()))
&& (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete())); && (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete()));
} }
@@ -416,7 +416,7 @@ public class XianFirefighter {
result = prime * result + ((getWriteTime() == null) ? 0 : getWriteTime().hashCode()); result = prime * result + ((getWriteTime() == null) ? 0 : getWriteTime().hashCode());
result = prime * result + ((getLon() == null) ? 0 : getLon().hashCode()); result = prime * result + ((getLon() == null) ? 0 : getLon().hashCode());
result = prime * result + ((getLat() == null) ? 0 : getLat().hashCode()); result = prime * result + ((getLat() == null) ? 0 : getLat().hashCode());
result = prime * result + ((getPoint() == null) ? 0 : getPoint().hashCode()); result = prime * result + ((getGeom() == null) ? 0 : getGeom().hashCode());
result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode()); result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode());
return result; return result;
} }
@@ -481,7 +481,7 @@ public class XianFirefighter {
sb.append(", writeTime=").append(writeTime); sb.append(", writeTime=").append(writeTime);
sb.append(", lon=").append(lon); sb.append(", lon=").append(lon);
sb.append(", lat=").append(lat); sb.append(", lat=").append(lat);
sb.append(", point=").append(point); sb.append(", geom=").append(geom);
sb.append(", isDelete=").append(isDelete); sb.append(", isDelete=").append(isDelete);
sb.append("]"); sb.append("]");
return sb.toString(); return sb.toString();
@@ -3,7 +3,7 @@ package com.gis.xian.entity;
import lombok.Data; import lombok.Data;
/** /**
* 地质灾害隐患点 * 隐患点(滑坡、泥石流、山洪、内涝)
* @TableName xian_hidden_danger_spots * @TableName xian_hidden_danger_spots
*/ */
@Data @Data
@@ -111,23 +111,23 @@ public class XianHiddenDangerSpots {
} }
XianHiddenDangerSpots other = (XianHiddenDangerSpots) that; XianHiddenDangerSpots other = (XianHiddenDangerSpots) that;
return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId())) return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
&& (this.getFieldCode() == null ? other.getFieldCode() == null : this.getFieldCode().equals(other.getFieldCode())) && (this.getFieldCode() == null ? other.getFieldCode() == null : this.getFieldCode().equals(other.getFieldCode()))
&& (this.getProvince() == null ? other.getProvince() == null : this.getProvince().equals(other.getProvince())) && (this.getProvince() == null ? other.getProvince() == null : this.getProvince().equals(other.getProvince()))
&& (this.getProvinceId() == null ? other.getProvinceId() == null : this.getProvinceId().equals(other.getProvinceId())) && (this.getProvinceId() == null ? other.getProvinceId() == null : this.getProvinceId().equals(other.getProvinceId()))
&& (this.getCity() == null ? other.getCity() == null : this.getCity().equals(other.getCity())) && (this.getCity() == null ? other.getCity() == null : this.getCity().equals(other.getCity()))
&& (this.getCityId() == null ? other.getCityId() == null : this.getCityId().equals(other.getCityId())) && (this.getCityId() == null ? other.getCityId() == null : this.getCityId().equals(other.getCityId()))
&& (this.getCounty() == null ? other.getCounty() == null : this.getCounty().equals(other.getCounty())) && (this.getCounty() == null ? other.getCounty() == null : this.getCounty().equals(other.getCounty()))
&& (this.getCountyId() == null ? other.getCountyId() == null : this.getCountyId().equals(other.getCountyId())) && (this.getCountyId() == null ? other.getCountyId() == null : this.getCountyId().equals(other.getCountyId()))
&& (this.getVillage() == null ? other.getVillage() == null : this.getVillage().equals(other.getVillage())) && (this.getVillage() == null ? other.getVillage() == null : this.getVillage().equals(other.getVillage()))
&& (this.getDisasterName() == null ? other.getDisasterName() == null : this.getDisasterName().equals(other.getDisasterName())) && (this.getDisasterName() == null ? other.getDisasterName() == null : this.getDisasterName().equals(other.getDisasterName()))
&& (this.getLon() == null ? other.getLon() == null : this.getLon().equals(other.getLon())) && (this.getLon() == null ? other.getLon() == null : this.getLon().equals(other.getLon()))
&& (this.getLat() == null ? other.getLat() == null : this.getLat().equals(other.getLat())) && (this.getLat() == null ? other.getLat() == null : this.getLat().equals(other.getLat()))
&& (this.getGeom() == null ? other.getGeom() == null : this.getGeom().equals(other.getGeom())) && (this.getGeom() == null ? other.getGeom() == null : this.getGeom().equals(other.getGeom()))
&& (this.getPosition() == null ? other.getPosition() == null : this.getPosition().equals(other.getPosition())) && (this.getPosition() == null ? other.getPosition() == null : this.getPosition().equals(other.getPosition()))
&& (this.getDisasterType() == null ? other.getDisasterType() == null : this.getDisasterType().equals(other.getDisasterType())) && (this.getDisasterType() == null ? other.getDisasterType() == null : this.getDisasterType().equals(other.getDisasterType()))
&& (this.getScaleGrade() == null ? other.getScaleGrade() == null : this.getScaleGrade().equals(other.getScaleGrade())) && (this.getScaleGrade() == null ? other.getScaleGrade() == null : this.getScaleGrade().equals(other.getScaleGrade()))
&& (this.getRiskGrade() == null ? other.getRiskGrade() == null : this.getRiskGrade().equals(other.getRiskGrade())) && (this.getRiskGrade() == null ? other.getRiskGrade() == null : this.getRiskGrade().equals(other.getRiskGrade()))
&& (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete())); && (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete()));
} }
@Override @Override
@@ -316,7 +316,7 @@ public class XianHospitals {
/** /**
* *
*/ */
private Object point; private Object geom;
/** /**
* 逻辑删除标识,0未删除,1已删除 * 逻辑删除标识,0未删除,1已删除
@@ -396,7 +396,7 @@ public class XianHospitals {
&& (this.getWriteTime() == null ? other.getWriteTime() == null : this.getWriteTime().equals(other.getWriteTime())) && (this.getWriteTime() == null ? other.getWriteTime() == null : this.getWriteTime().equals(other.getWriteTime()))
&& (this.getLon() == null ? other.getLon() == null : this.getLon().equals(other.getLon())) && (this.getLon() == null ? other.getLon() == null : this.getLon().equals(other.getLon()))
&& (this.getLat() == null ? other.getLat() == null : this.getLat().equals(other.getLat())) && (this.getLat() == null ? other.getLat() == null : this.getLat().equals(other.getLat()))
&& (this.getPoint() == null ? other.getPoint() == null : this.getPoint().equals(other.getPoint())) && (this.getGeom() == null ? other.getGeom() == null : this.getGeom().equals(other.getGeom()))
&& (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete())); && (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete()));
} }
@@ -465,7 +465,7 @@ public class XianHospitals {
result = prime * result + ((getWriteTime() == null) ? 0 : getWriteTime().hashCode()); result = prime * result + ((getWriteTime() == null) ? 0 : getWriteTime().hashCode());
result = prime * result + ((getLon() == null) ? 0 : getLon().hashCode()); result = prime * result + ((getLon() == null) ? 0 : getLon().hashCode());
result = prime * result + ((getLat() == null) ? 0 : getLat().hashCode()); result = prime * result + ((getLat() == null) ? 0 : getLat().hashCode());
result = prime * result + ((getPoint() == null) ? 0 : getPoint().hashCode()); result = prime * result + ((getGeom() == null) ? 0 : getGeom().hashCode());
result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode()); result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode());
return result; return result;
} }
@@ -537,7 +537,7 @@ public class XianHospitals {
sb.append(", writeTime=").append(writeTime); sb.append(", writeTime=").append(writeTime);
sb.append(", lon=").append(lon); sb.append(", lon=").append(lon);
sb.append(", lat=").append(lat); sb.append(", lat=").append(lat);
sb.append(", point=").append(point); sb.append(", geom=").append(geom);
sb.append(", isDelete=").append(isDelete); sb.append(", isDelete=").append(isDelete);
sb.append("]"); sb.append("]");
return sb.toString(); return sb.toString();
@@ -0,0 +1,221 @@
package com.gis.xian.entity;
import java.util.Date;
/**
* 推理结果表
* @TableName xian_inference_result
*/
public class XianInferenceResult {
/**
* 主键ID
*/
private Long id;
/**
* 名称
*/
private String name;
/**
* 事件类型
*/
private String eventType;
/**
* 发生时间
*/
private Date occurredTime;
/**
* 操作类型
*/
private String operationType;
/**
* 推理结果(JSONB
*/
private Object result;
/**
* 条件(JSONB
*/
private Object condition;
/**
* 文件路径(JSONB
*/
private Object filePath;
/**
* 创建时间
*/
private Date createTime;
/**
* 是否删除(0: 未删除, 1: 已删除)
*/
private Integer isDelete;
// 构造方法
public XianInferenceResult() {
}
public XianInferenceResult(Long id, String name, String eventType, Date occurredTime,
String operationType, Object result, Object condition,
Object filePath, Date createTime, Integer isDelete) {
this.id = id;
this.name = name;
this.eventType = eventType;
this.occurredTime = occurredTime;
this.operationType = operationType;
this.result = result;
this.condition = condition;
this.filePath = filePath;
this.createTime = createTime;
this.isDelete = isDelete;
}
// Getter 和 Setter 方法
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEventType() {
return eventType;
}
public void setEventType(String eventType) {
this.eventType = eventType;
}
public Date getOccurredTime() {
return occurredTime;
}
public void setOccurredTime(Date occurredTime) {
this.occurredTime = occurredTime;
}
public String getOperationType() {
return operationType;
}
public void setOperationType(String operationType) {
this.operationType = operationType;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
public Object getCondition() {
return condition;
}
public void setCondition(Object condition) {
this.condition = condition;
}
public Object getFilePath() {
return filePath;
}
public void setFilePath(Object filePath) {
this.filePath = filePath;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Integer getIsDelete() {
return isDelete;
}
public void setIsDelete(Integer isDelete) {
this.isDelete = isDelete;
}
@Override
public boolean equals(Object that) {
if (this == that) {
return true;
}
if (that == null) {
return false;
}
if (getClass() != that.getClass()) {
return false;
}
XianInferenceResult other = (XianInferenceResult) that;
return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
&& (this.getName() == null ? other.getName() == null : this.getName().equals(other.getName()))
&& (this.getEventType() == null ? other.getEventType() == null : this.getEventType().equals(other.getEventType()))
&& (this.getOccurredTime() == null ? other.getOccurredTime() == null : this.getOccurredTime().equals(other.getOccurredTime()))
&& (this.getOperationType() == null ? other.getOperationType() == null : this.getOperationType().equals(other.getOperationType()))
&& (this.getResult() == null ? other.getResult() == null : this.getResult().equals(other.getResult()))
&& (this.getCondition() == null ? other.getCondition() == null : this.getCondition().equals(other.getCondition()))
&& (this.getFilePath() == null ? other.getFilePath() == null : this.getFilePath().equals(other.getFilePath()))
&& (this.getCreateTime() == null ? other.getCreateTime() == null : this.getCreateTime().equals(other.getCreateTime()))
&& (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete()));
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
result = prime * result + ((getEventType() == null) ? 0 : getEventType().hashCode());
result = prime * result + ((getOccurredTime() == null) ? 0 : getOccurredTime().hashCode());
result = prime * result + ((getOperationType() == null) ? 0 : getOperationType().hashCode());
result = prime * result + ((getResult() == null) ? 0 : getResult().hashCode());
result = prime * result + ((getCondition() == null) ? 0 : getCondition().hashCode());
result = prime * result + ((getFilePath() == null) ? 0 : getFilePath().hashCode());
result = prime * result + ((getCreateTime() == null) ? 0 : getCreateTime().hashCode());
result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode());
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", id=").append(id);
sb.append(", name=").append(name);
sb.append(", eventType=").append(eventType);
sb.append(", occurredTime=").append(occurredTime);
sb.append(", operationType=").append(operationType);
sb.append(", result=").append(result);
sb.append(", condition=").append(condition);
sb.append(", filePath=").append(filePath);
sb.append(", createTime=").append(createTime);
sb.append(", isDelete=").append(isDelete);
sb.append("]");
return sb.toString();
}
}
@@ -251,7 +251,7 @@ public class XianStorePoints {
/** /**
* *
*/ */
private Object point; private Object geom;
/** /**
* *
@@ -318,7 +318,7 @@ public class XianStorePoints {
&& (this.getOverwriteTime() == null ? other.getOverwriteTime() == null : this.getOverwriteTime().equals(other.getOverwriteTime())) && (this.getOverwriteTime() == null ? other.getOverwriteTime() == null : this.getOverwriteTime().equals(other.getOverwriteTime()))
&& (this.getLon() == null ? other.getLon() == null : this.getLon().equals(other.getLon())) && (this.getLon() == null ? other.getLon() == null : this.getLon().equals(other.getLon()))
&& (this.getLat() == null ? other.getLat() == null : this.getLat().equals(other.getLat())) && (this.getLat() == null ? other.getLat() == null : this.getLat().equals(other.getLat()))
&& (this.getPoint() == null ? other.getPoint() == null : this.getPoint().equals(other.getPoint())) && (this.getGeom() == null ? other.getGeom() == null : this.getGeom().equals(other.getGeom()))
&& (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete())); && (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete()));
} }
@@ -374,7 +374,7 @@ public class XianStorePoints {
result = prime * result + ((getOverwriteTime() == null) ? 0 : getOverwriteTime().hashCode()); result = prime * result + ((getOverwriteTime() == null) ? 0 : getOverwriteTime().hashCode());
result = prime * result + ((getLon() == null) ? 0 : getLon().hashCode()); result = prime * result + ((getLon() == null) ? 0 : getLon().hashCode());
result = prime * result + ((getLat() == null) ? 0 : getLat().hashCode()); result = prime * result + ((getLat() == null) ? 0 : getLat().hashCode());
result = prime * result + ((getPoint() == null) ? 0 : getPoint().hashCode()); result = prime * result + ((getGeom() == null) ? 0 : getGeom().hashCode());
result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode()); result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode());
return result; return result;
} }
@@ -433,7 +433,7 @@ public class XianStorePoints {
sb.append(", overwriteTime=").append(overwriteTime); sb.append(", overwriteTime=").append(overwriteTime);
sb.append(", lon=").append(lon); sb.append(", lon=").append(lon);
sb.append(", lat=").append(lat); sb.append(", lat=").append(lat);
sb.append(", point=").append(point); sb.append(", point=").append(geom);
sb.append(", isDelete=").append(isDelete); sb.append(", isDelete=").append(isDelete);
sb.append("]"); sb.append("]");
return sb.toString(); return sb.toString();
@@ -61,7 +61,7 @@ public class XianSubwayStations {
/** /**
* 站点经纬度 * 站点经纬度
*/ */
private Object point; private Object geom;
/** /**
* 逻辑删除标识,0未删除,1已删除 * 逻辑删除标识,0未删除,1已删除
@@ -90,7 +90,7 @@ public class XianSubwayStations {
&& (this.getPointOtherDefenses() == null ? other.getPointOtherDefenses() == null : this.getPointOtherDefenses().equals(other.getPointOtherDefenses())) && (this.getPointOtherDefenses() == null ? other.getPointOtherDefenses() == null : this.getPointOtherDefenses().equals(other.getPointOtherDefenses()))
&& (this.getLon() == null ? other.getLon() == null : this.getLon().equals(other.getLon())) && (this.getLon() == null ? other.getLon() == null : this.getLon().equals(other.getLon()))
&& (this.getLat() == null ? other.getLat() == null : this.getLat().equals(other.getLat())) && (this.getLat() == null ? other.getLat() == null : this.getLat().equals(other.getLat()))
&& (this.getPoint() == null ? other.getPoint() == null : this.getPoint().equals(other.getPoint())) && (this.getGeom() == null ? other.getGeom() == null : this.getGeom().equals(other.getGeom()))
&& (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete())); && (this.getIsDelete() == null ? other.getIsDelete() == null : this.getIsDelete().equals(other.getIsDelete()));
} }
@@ -108,7 +108,7 @@ public class XianSubwayStations {
result = prime * result + ((getPointOtherDefenses() == null) ? 0 : getPointOtherDefenses().hashCode()); result = prime * result + ((getPointOtherDefenses() == null) ? 0 : getPointOtherDefenses().hashCode());
result = prime * result + ((getLon() == null) ? 0 : getLon().hashCode()); result = prime * result + ((getLon() == null) ? 0 : getLon().hashCode());
result = prime * result + ((getLat() == null) ? 0 : getLat().hashCode()); result = prime * result + ((getLat() == null) ? 0 : getLat().hashCode());
result = prime * result + ((getPoint() == null) ? 0 : getPoint().hashCode()); result = prime * result + ((getGeom() == null) ? 0 : getGeom().hashCode());
result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode()); result = prime * result + ((getIsDelete() == null) ? 0 : getIsDelete().hashCode());
return result; return result;
} }
@@ -129,7 +129,7 @@ public class XianSubwayStations {
sb.append(", pointOtherDefenses=").append(pointOtherDefenses); sb.append(", pointOtherDefenses=").append(pointOtherDefenses);
sb.append(", lon=").append(lon); sb.append(", lon=").append(lon);
sb.append(", lat=").append(lat); sb.append(", lat=").append(lat);
sb.append(", point=").append(point); sb.append(", geom=").append(geom);
sb.append(", isDelete=").append(isDelete); sb.append(", isDelete=").append(isDelete);
sb.append("]"); sb.append("]");
return sb.toString(); return sb.toString();
@@ -4,12 +4,30 @@ import lombok.Getter;
@Getter @Getter
public enum DisasterTypeEnum { public enum DisasterTypeEnum {
RAINSTORM("rainstorm"), // 具体灾害类型
EARTHQUAKE("earthquake"); LANDSLIDE("landslide", "滑坡"),
COLLAPSE("collapse", "崩塌"),
DEBRIS_FLOW("debris_flow", "泥石流"),
FLASH_FLOOD("flash_flood", "山洪"),
WATER_LOGGING("water_logging", "内涝");
private final String type; private final String type;
private final String description;
DisasterTypeEnum(String type) { DisasterTypeEnum(String type, String description) {
this.type = type; this.type = type;
this.description = description;
}
/**
* 根据type获取枚举
*/
public static DisasterTypeEnum getByType(String type) {
for (DisasterTypeEnum e : values()) {
if (e.getType().equals(type)) {
return e;
}
}
return null;
} }
} }
@@ -3,6 +3,7 @@ package com.gis.xian.filter;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference; import com.alibaba.fastjson2.TypeReference;
import com.gis.xian.config.CryptoProperties; import com.gis.xian.config.CryptoProperties;
import com.gis.xian.utils.PathMatcherUtils;
import com.gis.xian.utils.safety.SM2Utils; import com.gis.xian.utils.safety.SM2Utils;
import com.gis.xian.utils.safety.SM4Utils; import com.gis.xian.utils.safety.SM4Utils;
import com.gis.xian.wrapper.Sm4KeyHolder; import com.gis.xian.wrapper.Sm4KeyHolder;
@@ -85,15 +86,10 @@ public class DecryptFilter implements Filter {
} }
/** /**
* 检查是否为无需解密的路径 * 检查是否为无需解密的路径(支持通配符匹配)
*/ */
private boolean isNoDecryptPath(String requestUri) { private boolean isNoDecryptPath(String requestUri) {
for (String path : cryptoProperties.getNoDecryptPaths()) { return PathMatcherUtils.matches(requestUri, cryptoProperties.getNoDecryptPaths());
if (requestUri.contains(path)) {
return true;
}
}
return false;
} }
/** /**
@@ -13,6 +13,7 @@ import java.util.List;
public interface XianHiddenDangerSpotsMapper { public interface XianHiddenDangerSpotsMapper {
/** /**
* 获取所有基础点:滑坡、泥石流、山洪、内涝 * 获取所有基础点:滑坡、泥石流、山洪、内涝
* @param disasterType 具体灾害类型(landslide-滑坡, debris_flow-泥石流, flash_flood-山洪, water_logging-内涝),可选
* @return 基础点列表 * @return 基础点列表
*/ */
List<XianHiddenDangerSpots> getBasePoints(String disasterType); List<XianHiddenDangerSpots> getBasePoints(String disasterType);
@@ -0,0 +1,21 @@
package com.gis.xian.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* @author wzy
* @description 针对表【xian_inference_result(预测结果表)】的数据库操作Mapper
* @createDate 2026-06-17 11:58:32
* @Entity com.gis.xian.entity.XianInferenceResult
*/
@Mapper
public interface XianInferenceResultMapper {
/**
* 根据id和pointId获取概率
* @param id 预测结果id
* @param pointId 隐患点/风险点id和类型
* @return 预测概率
*/
String getProbabilityByIdAndPointId(@Param("id") Long id, @Param("pointId") String pointId);
}
@@ -0,0 +1,21 @@
package com.gis.xian.service;
import com.gis.xian.vo.RainfallGridVo;
/**
* 降雨网格服务接口
*/
public interface RainfallGridService {
/**
* 从 Redis 获取降雨网格数据
* @return 降雨网格数据
*/
RainfallGridVo getRainfallGridData();
/**
* 获取当前的降雨站点标识符
* @return 标识符
*/
String getCurrentIdentifier();
}
@@ -9,6 +9,7 @@ public interface XianHiddenDangerSpotsService {
/** /**
* 获取所有基础点:滑坡、泥石流、山洪、内涝 * 获取所有基础点:滑坡、泥石流、山洪、内涝
* @param disasterType 具体灾害类型(landslide-滑坡, debris_flow-泥石流, flash_flood-山洪, water_logging-内涝),可选
* @return 基础点列表 * @return 基础点列表
*/ */
List<XianHiddenDangerSpotsBasePointVo> getBasePoints(String disasterType); List<XianHiddenDangerSpotsBasePointVo> getBasePoints(String disasterType);
@@ -16,7 +17,8 @@ public interface XianHiddenDangerSpotsService {
/** /**
* 根据id获取隐患点详情 * 根据id获取隐患点详情
* @param id 隐患点id * @param id 隐患点id
* @param simulationId 模拟id
* @return 隐患点详情 * @return 隐患点详情
*/ */
XianHiddenDangerSpotsPointDetailVo getPointDetailById(Long id); XianHiddenDangerSpotsPointDetailVo getPointDetailById(Long id, Long simulationId);
} }
@@ -15,7 +15,8 @@ public interface XianRiskSpotsService {
/** /**
* 根据id获取风险点详情 * 根据id获取风险点详情
* @param id 风险点id * @param id 风险点id
* @param simulationId 模拟id
* @return 风险点详情 * @return 风险点详情
*/ */
XianRiskSpotsPointDetailVo getPointDetailById(Long id); XianRiskSpotsPointDetailVo getPointDetailById(Long id, Long simulationId);
} }
@@ -2,9 +2,9 @@ package com.gis.xian.service.impl;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.gis.xian.entity.XianHiddenDangerSpots; import com.gis.xian.entity.XianHiddenDangerSpots;
import com.gis.xian.mapper.XianInferenceResultMapper;
import com.gis.xian.vo.XianHiddenDangerSpotsBasePointVo; import com.gis.xian.vo.XianHiddenDangerSpotsBasePointVo;
import com.gis.xian.vo.XianHiddenDangerSpotsPointDetailVo; import com.gis.xian.vo.XianHiddenDangerSpotsPointDetailVo;
import com.gis.xian.enums.DisasterTypeEnum;
import com.gis.xian.mapper.XianHiddenDangerSpotsMapper; import com.gis.xian.mapper.XianHiddenDangerSpotsMapper;
import com.gis.xian.service.XianHiddenDangerSpotsService; import com.gis.xian.service.XianHiddenDangerSpotsService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@@ -23,39 +23,80 @@ public class IXianHiddenDangerSpotsServiceImpl implements XianHiddenDangerSpotsS
@Resource @Resource
private XianHiddenDangerSpotsMapper xianHiddenDangerSpotsMapper; private XianHiddenDangerSpotsMapper xianHiddenDangerSpotsMapper;
@Value("${init.data.base-points.hidden-danger.rainstorm}") @Resource
private String rainstormBasePointsKey; private XianInferenceResultMapper xianInferenceResultMapper;
@Value("${init.data.base-points.hidden-danger.earthquake}") @Value("${init.data.base-points.hidden-danger.all}")
private String earthquakeBasePointsKey; private String allBasePointsKey;
@Value("${init.data.base-points.hidden-danger.landslide}")
private String landslideKey;
@Value("${init.data.base-points.hidden-danger.collapse}")
private String collapseKey;
@Value("${init.data.base-points.hidden-danger.debris-flow}")
private String debrisFlowKey;
@Value("${init.data.base-points.hidden-danger.flash-flood}")
private String flashFloodKey;
@Value("${init.data.base-points.hidden-danger.water-logging}")
private String waterLoggingKey;
@Override @Override
public List<XianHiddenDangerSpotsBasePointVo> getBasePoints(String disasterType) { public List<XianHiddenDangerSpotsBasePointVo> getBasePoints(String disasterType) {
// 从redis中读取基础点信息 // 构建Redis key
Object data = null; String redisKey = buildRedisKey(disasterType);
if(DisasterTypeEnum.RAINSTORM.getType().equals(disasterType)) { // 从redis中读取基础点信息
data = redisTemplate.opsForValue().get(rainstormBasePointsKey); Object data = redisTemplate.opsForValue().get(redisKey);
}else {
data = redisTemplate.opsForValue().get(earthquakeBasePointsKey);
}
if (data == null) { if (data == null) {
List<XianHiddenDangerSpotsBasePointVo> basePoints = XianHiddenDangerSpotsBasePointVo.entity2Vo(xianHiddenDangerSpotsMapper.getBasePoints(disasterType)); // 从数据库查询
List<XianHiddenDangerSpotsBasePointVo> basePoints =
XianHiddenDangerSpotsBasePointVo.entity2Vo(xianHiddenDangerSpotsMapper.getBasePoints(disasterType));
if(DisasterTypeEnum.RAINSTORM.getType().equals(disasterType)) { // 存入Redis
redisTemplate.opsForValue().set(rainstormBasePointsKey, JSON.toJSONString(basePoints)); redisTemplate.opsForValue().set(redisKey, JSON.toJSONString(basePoints));
}else {
redisTemplate.opsForValue().set(earthquakeBasePointsKey, JSON.toJSONString(basePoints));
}
return basePoints; return basePoints;
} }
return JSON.parseArray(data.toString(), XianHiddenDangerSpotsBasePointVo.class); return JSON.parseArray(data.toString(), XianHiddenDangerSpotsBasePointVo.class);
} }
/**
* 根据disasterType构建Redis key
*/
private String buildRedisKey(String disasterType) {
if (disasterType == null || disasterType.isEmpty()) {
return allBasePointsKey;
}
switch (disasterType) {
case "landslide":
return landslideKey;
case "collapse":
return collapseKey;
case "debris_flow":
return debrisFlowKey;
case "flash_flood":
return flashFloodKey;
case "water_logging":
return waterLoggingKey;
default:
return allBasePointsKey;
}
}
@Override @Override
public XianHiddenDangerSpotsPointDetailVo getPointDetailById(Long id) { public XianHiddenDangerSpotsPointDetailVo getPointDetailById(Long id, Long simulationId) {
return XianHiddenDangerSpotsPointDetailVo.entity2Vo(xianHiddenDangerSpotsMapper.getPointDetailById(id)); XianHiddenDangerSpotsPointDetailVo pointDetail = XianHiddenDangerSpotsPointDetailVo.entity2Vo(xianHiddenDangerSpotsMapper.getPointDetailById(id));
// 根据模拟id和id获取预测结果
if(simulationId != null && simulationId != -1L) {
pointDetail.setProbability(xianInferenceResultMapper.getProbabilityByIdAndPointId(simulationId, id + "_1") + "%");
}
return pointDetail;
} }
} }
@@ -1,6 +1,8 @@
package com.gis.xian.service.impl; package com.gis.xian.service.impl;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.gis.xian.mapper.XianInferenceResultMapper;
import com.gis.xian.vo.XianHiddenDangerSpotsPointDetailVo;
import com.gis.xian.vo.XianRiskSpotsBasePointVo; import com.gis.xian.vo.XianRiskSpotsBasePointVo;
import com.gis.xian.vo.XianRiskSpotsPointDetailVo; import com.gis.xian.vo.XianRiskSpotsPointDetailVo;
import com.gis.xian.mapper.XianRiskSpotsMapper; import com.gis.xian.mapper.XianRiskSpotsMapper;
@@ -21,6 +23,9 @@ public class IXianRiskSpotsServiceImpl implements XianRiskSpotsService {
@Resource @Resource
private RedisTemplate<String, Object> redisTemplate; private RedisTemplate<String, Object> redisTemplate;
@Resource
private XianInferenceResultMapper xianInferenceResultMapper;
@Value("${init.data.base-points.risk}") @Value("${init.data.base-points.risk}")
private String riskPointKey; private String riskPointKey;
@@ -39,7 +44,14 @@ public class IXianRiskSpotsServiceImpl implements XianRiskSpotsService {
} }
@Override @Override
public XianRiskSpotsPointDetailVo getPointDetailById(Long id) { public XianRiskSpotsPointDetailVo getPointDetailById(Long id, Long simulationId) {
return XianRiskSpotsPointDetailVo.entity2Vo(xianRiskSpotsMapper.getPointDetailById(id)); XianRiskSpotsPointDetailVo pointDetail = XianRiskSpotsPointDetailVo.entity2Vo(xianRiskSpotsMapper.getPointDetailById(id));
// 根据模拟id和id获取预测结果
if(simulationId != null && simulationId != -1L) {
pointDetail.setProbability(xianInferenceResultMapper.getProbabilityByIdAndPointId(simulationId, id + "_2") + "%");
}
return pointDetail;
} }
} }
@@ -0,0 +1,173 @@
package com.gis.xian.service.impl;
import com.alibaba.fastjson2.JSON;
import com.gis.xian.config.RainfallGridProperties;
import com.gis.xian.service.RainfallGridService;
import com.gis.xian.service.ex.ServiceException;
import com.gis.xian.vo.RainfallGridVo;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
/**
* 降雨网格服务实现类
*/
@Service
public class RainfallGridServiceImpl implements RainfallGridService {
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Resource
private RainfallGridProperties rainfallGridProperties;
@Override
public RainfallGridVo getRainfallGridData() {
try {
String redisKey = rainfallGridProperties.getStationGrid();
Object gridDataObj = redisTemplate.opsForValue().get(redisKey);
if (gridDataObj == null) {
throw new ServiceException("降雨网格数据不存在,Redis Key: " + redisKey);
}
// 将 Redis 中的 JSON 字符串解析为 Map
String gridDataJson;
if (gridDataObj instanceof String) {
gridDataJson = (String) gridDataObj;
} else {
gridDataJson = JSON.toJSONString(gridDataObj);
}
// 解析 JSON 为 Map(下划线命名)
Map<String, Object> gridDataMap = JSON.parseObject(gridDataJson, Map.class);
// 转换为 RainfallGridVo(小驼峰命名)
return convertToVo(gridDataMap);
} catch (Exception e) {
throw new ServiceException("解析降雨网格数据失败: " + e.getMessage(), e);
}
}
@Override
public String getCurrentIdentifier() {
try {
String redisKey = rainfallGridProperties.getStationIdentifier();
Object identifierObj = redisTemplate.opsForValue().get(redisKey);
if (identifierObj == null) {
return null;
}
return identifierObj.toString();
} catch (Exception e) {
throw new ServiceException("获取降雨站点标识符失败: " + e.getMessage(), e);
}
}
/**
* 将 Map 转换为 RainfallGridVo
*/
@SuppressWarnings("unchecked")
private RainfallGridVo convertToVo(Map<String, Object> gridDataMap) {
RainfallGridVo vo = new RainfallGridVo();
// 基本字段
vo.setId(getLongValue(gridDataMap, "id"));
vo.setPngPath((String) gridDataMap.get("png_path"));
vo.setResolution(getDoubleValue(gridDataMap, "resolution"));
vo.setStationCount(getIntValue(gridDataMap, "station_count"));
// 解析 query_time
String queryTimeStr = (String) gridDataMap.get("query_time");
if (queryTimeStr != null) {
vo.setQueryTime(LocalDateTime.parse(
queryTimeStr.replace(" ", "T"),
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")
));
}
// 解析 cesium_config
Map<String, Object> cesiumConfigMap = (Map<String, Object>) gridDataMap.get("cesium_config");
if (cesiumConfigMap != null) {
vo.setCesiumConfig(parseCesiumConfig(cesiumConfigMap));
}
return vo;
}
/**
* 解析 Cesium 配置
*/
@SuppressWarnings("unchecked")
private RainfallGridVo.CesiumConfig parseCesiumConfig(Map<String, Object> cesiumConfigMap) {
RainfallGridVo.CesiumConfig cesiumConfig = new RainfallGridVo.CesiumConfig();
cesiumConfig.setWidth(getDoubleValue(cesiumConfigMap, "width"));
cesiumConfig.setHeight(getDoubleValue(cesiumConfigMap, "height"));
// 解析 rectangle
Map<String, Object> rectangleMap = (Map<String, Object>) cesiumConfigMap.get("rectangle");
if (rectangleMap != null) {
cesiumConfig.setRectangle(parseRectangle(rectangleMap));
}
return cesiumConfig;
}
/**
* 解析矩形区域
*/
private RainfallGridVo.CesiumConfig.Rectangle parseRectangle(Map<String, Object> rectangleMap) {
RainfallGridVo.CesiumConfig.Rectangle rectangle = new RainfallGridVo.CesiumConfig.Rectangle();
rectangle.setWest(getDoubleValue(rectangleMap, "west"));
rectangle.setSouth(getDoubleValue(rectangleMap, "south"));
rectangle.setEast(getDoubleValue(rectangleMap, "east"));
rectangle.setNorth(getDoubleValue(rectangleMap, "north"));
return rectangle;
}
/**
* 辅助方法:从 Map 中获取 Long 值
*/
private Long getLongValue(Map<String, Object> map, String key) {
Object value = map.get(key);
if (value == null) {
return null;
}
if (value instanceof Number) {
return ((Number) value).longValue();
}
return Long.parseLong(value.toString());
}
/**
* 辅助方法:从 Map 中获取 Double 值
*/
private Double getDoubleValue(Map<String, Object> map, String key) {
Object value = map.get(key);
if (value == null) {
return null;
}
if (value instanceof Number) {
return ((Number) value).doubleValue();
}
return Double.parseDouble(value.toString());
}
/**
* 辅助方法:从 Map 中获取 Integer 值
*/
private Integer getIntValue(Map<String, Object> map, String key) {
Object value = map.get(key);
if (value == null) {
return null;
}
if (value instanceof Number) {
return ((Number) value).intValue();
}
return Integer.parseInt(value.toString());
}
}
@@ -1,7 +1,6 @@
package com.gis.xian.task; package com.gis.xian.task;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.gis.xian.enums.DisasterTypeEnum;
import com.gis.xian.mapper.*; import com.gis.xian.mapper.*;
import com.gis.xian.vo.*; import com.gis.xian.vo.*;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@@ -58,11 +57,23 @@ public class InitializeData {
@Resource @Resource
RedisTemplate<String, Object> redisTemplate; RedisTemplate<String, Object> redisTemplate;
@Value("${init.data.base-points.hidden-danger.rainstorm}") @Value("${init.data.base-points.hidden-danger.all}")
private String rainstormBasePointsKey; private String allBasePointsKey;
@Value("${init.data.base-points.hidden-danger.earthquake}") @Value("${init.data.base-points.hidden-danger.landslide}")
private String earthquakeBasePointsKey; private String landslideKey;
@Value("${init.data.base-points.hidden-danger.collapse}")
private String collapseKey;
@Value("${init.data.base-points.hidden-danger.debris-flow}")
private String debrisFlowKey;
@Value("${init.data.base-points.hidden-danger.flash-flood}")
private String flashFloodKey;
@Value("${init.data.base-points.hidden-danger.water-logging}")
private String waterLoggingKey;
@Value("${init.data.base-points.risk}") @Value("${init.data.base-points.risk}")
private String riskBasePointsKey; private String riskBasePointsKey;
@@ -99,22 +110,65 @@ public class InitializeData {
public void init() { public void init() {
log.info("开始初始化数据"); log.info("开始初始化数据");
// 并行执行所有数据库查询和Redis写入 // 并行执行所有数据库查询和Redis写入
CompletableFuture<Void> rainstormFuture = CompletableFuture.runAsync(() -> {
redisTemplate.opsForValue().set(rainstormBasePointsKey, JSON.toJSONString( // 隐患点 - 总体
CompletableFuture<Void> allFuture = CompletableFuture.runAsync(() -> {
redisTemplate.opsForValue().set(allBasePointsKey, JSON.toJSONString(
XianHiddenDangerSpotsBasePointVo.entity2Vo( XianHiddenDangerSpotsBasePointVo.entity2Vo(
xianHiddenDangerSpotsMapper.getBasePoints(DisasterTypeEnum.RAINSTORM.getType())) xianHiddenDangerSpotsMapper.getBasePoints(null))
) )
); );
log.info("加载暴雨隐患点信息并写入redis完成"); log.info("加载隐患点信息(总体)并写入redis完成");
}); });
CompletableFuture<Void> earthquakeFuture = CompletableFuture.runAsync(() -> { // 隐患点 - 滑坡
redisTemplate.opsForValue().set(earthquakeBasePointsKey, JSON.toJSONString( CompletableFuture<Void> landslideFuture = CompletableFuture.runAsync(() -> {
redisTemplate.opsForValue().set(landslideKey, JSON.toJSONString(
XianHiddenDangerSpotsBasePointVo.entity2Vo( XianHiddenDangerSpotsBasePointVo.entity2Vo(
xianHiddenDangerSpotsMapper.getBasePoints(DisasterTypeEnum.EARTHQUAKE.getType())) xianHiddenDangerSpotsMapper.getBasePoints("landslide"))
) )
); );
log.info("加载地震隐患点信息并写入redis完成"); log.info("加载隐患点信息(滑坡)并写入redis完成");
});
// 隐患点 - 崩塌
CompletableFuture<Void> collapseFuture = CompletableFuture.runAsync(() -> {
redisTemplate.opsForValue().set(collapseKey, JSON.toJSONString(
XianHiddenDangerSpotsBasePointVo.entity2Vo(
xianHiddenDangerSpotsMapper.getBasePoints("collapse"))
)
);
log.info("加载隐患点信息(崩塌)并写入redis完成");
});
// 隐患点 - 泥石流
CompletableFuture<Void> debrisFlowFuture = CompletableFuture.runAsync(() -> {
redisTemplate.opsForValue().set(debrisFlowKey, JSON.toJSONString(
XianHiddenDangerSpotsBasePointVo.entity2Vo(
xianHiddenDangerSpotsMapper.getBasePoints("debris_flow"))
)
);
log.info("加载隐患点信息(泥石流)并写入redis完成");
});
// 隐患点 - 山洪
CompletableFuture<Void> flashFloodFuture = CompletableFuture.runAsync(() -> {
redisTemplate.opsForValue().set(flashFloodKey, JSON.toJSONString(
XianHiddenDangerSpotsBasePointVo.entity2Vo(
xianHiddenDangerSpotsMapper.getBasePoints("flash_flood"))
)
);
log.info("加载隐患点信息(山洪)并写入redis完成");
});
// 隐患点 - 内涝
CompletableFuture<Void> waterLoggingFuture = CompletableFuture.runAsync(() -> {
redisTemplate.opsForValue().set(waterLoggingKey, JSON.toJSONString(
XianHiddenDangerSpotsBasePointVo.entity2Vo(
xianHiddenDangerSpotsMapper.getBasePoints("water_logging"))
)
);
log.info("加载隐患点信息(内涝)并写入redis完成");
}); });
CompletableFuture<Void> riskFuture = CompletableFuture.runAsync(() -> { CompletableFuture<Void> riskFuture = CompletableFuture.runAsync(() -> {
@@ -209,7 +263,9 @@ public class InitializeData {
// 等待所有任务完成 // 等待所有任务完成
CompletableFuture.allOf( CompletableFuture.allOf(
rainstormFuture, earthquakeFuture, riskFuture, hospitalsFuture, allFuture, landslideFuture, collapseFuture, debrisFlowFuture,
flashFloodFuture, waterLoggingFuture,
riskFuture, hospitalsFuture,
dangerousSourceFuture, emergencyShelterFuture, firefighterFuture, storePointsFuture, schoolFuture, dangerousSourceFuture, emergencyShelterFuture, firefighterFuture, storePointsFuture, schoolFuture,
bridgeFuture, reservoirFuture, subwayFuture bridgeFuture, reservoirFuture, subwayFuture
).join(); ).join();
@@ -0,0 +1,38 @@
package com.gis.xian.utils;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import java.util.List;
/**
* 路径匹配工具类
* 支持 Ant 风格通配符:
* - ? 匹配一个字符
* - * 匹配零个或多个字符(不包括路径分隔符)
* - ** 匹配零个或多个目录
*/
public class PathMatcherUtils {
private static final PathMatcher pathMatcher = new AntPathMatcher();
/**
* 检查请求路径是否匹配给定的模式列表
*
* @param requestUri 请求URI
* @param patterns 通配符模式列表
* @return 如果匹配返回true,否则返回false
*/
public static boolean matches(String requestUri, List<String> patterns) {
if (patterns == null || patterns.isEmpty()) {
return false;
}
for (String pattern : patterns) {
if (pathMatcher.match(pattern, requestUri)) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,44 @@
package com.gis.xian.vo;
import lombok.Data;
import java.time.LocalDateTime;
@Data
public class RainfallGridVo {
public RainfallGridVo() {
this.cesiumConfig = new CesiumConfig();
}
private Long id;
private String pngPath;
private LocalDateTime queryTime;
private Double resolution;
private Integer stationCount;
private CesiumConfig cesiumConfig;
@Data
public static class CesiumConfig {
public CesiumConfig() {
this.rectangle = new Rectangle();
}
private Rectangle rectangle;
private Double width;
private Double height;
@Data
public static class Rectangle {
public Rectangle() {
this.west = 0.0;
this.south = 0.0;
this.east = 0.0;
this.north = 0.0;
}
private Double west;
private Double south;
private Double east;
private Double north;
}
}
}
@@ -23,6 +23,11 @@ public class XianBridgeBasePointVo {
*/ */
private String bridgeName; private String bridgeName;
/**
* 通用名称字段(用于统一访问)
*/
private String name;
/** /**
* 经度 * 经度
*/ */
@@ -37,17 +42,18 @@ public class XianBridgeBasePointVo {
public boolean equals(Object o) { public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
XianBridgeBasePointVo that = (XianBridgeBasePointVo) o; XianBridgeBasePointVo that = (XianBridgeBasePointVo) o;
return Objects.equals(id, that.id) && Objects.equals(bridgeName, that.bridgeName) && Objects.equals(lon, that.lon) && Objects.equals(lat, that.lat); return Objects.equals(id, that.id) && Objects.equals(bridgeName, that.bridgeName) && Objects.equals(name, that.name) && Objects.equals(lon, that.lon) && Objects.equals(lat, that.lat);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(id, bridgeName, lon, lat); return Objects.hash(id, bridgeName, name, lon, lat);
} }
public static XianBridgeBasePointVo entity2Vo(XianBridge entity) { public static XianBridgeBasePointVo entity2Vo(XianBridge entity) {
XianBridgeBasePointVo vo = new XianBridgeBasePointVo(); XianBridgeBasePointVo vo = new XianBridgeBasePointVo();
vo.setId(entity.getId()); vo.setId(entity.getId());
vo.setBridgeName(entity.getBridgeName()); vo.setBridgeName(entity.getBridgeName());
vo.setName(entity.getBridgeName()); // 设置通用name字段
vo.setLon(entity.getLon() != null ? entity.getLon().doubleValue() : null); vo.setLon(entity.getLon() != null ? entity.getLon().doubleValue() : null);
vo.setLat(entity.getLat() != null ? entity.getLat().doubleValue() : null); vo.setLat(entity.getLat() != null ? entity.getLat().doubleValue() : null);
return vo; return vo;
@@ -22,6 +22,11 @@ public class XianFirefighterBasePointVo {
*/ */
private String teamName; private String teamName;
/**
* 通用名称字段(用于统一访问)
*/
private String name;
/** /**
* 经度 * 经度
@@ -37,6 +42,7 @@ public class XianFirefighterBasePointVo {
XianFirefighterBasePointVo vo = new XianFirefighterBasePointVo(); XianFirefighterBasePointVo vo = new XianFirefighterBasePointVo();
vo.setId(entity.getId()); vo.setId(entity.getId());
vo.setTeamName(entity.getTeamName()); vo.setTeamName(entity.getTeamName());
vo.setName(entity.getTeamName()); // 设置通用name字段
vo.setLon(entity.getLon() != null ? entity.getLon().doubleValue() : null); vo.setLon(entity.getLon() != null ? entity.getLon().doubleValue() : null);
vo.setLat(entity.getLat() != null ? entity.getLat().doubleValue() : null); vo.setLat(entity.getLat() != null ? entity.getLat().doubleValue() : null);
return vo; return vo;
@@ -55,11 +61,11 @@ public class XianFirefighterBasePointVo {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
XianFirefighterBasePointVo that = (XianFirefighterBasePointVo) o; XianFirefighterBasePointVo that = (XianFirefighterBasePointVo) o;
return Objects.equals(id, that.id) && Objects.equals(teamName, that.teamName) && Objects.equals(lon, that.lon) && Objects.equals(lat, that.lat); return Objects.equals(id, that.id) && Objects.equals(teamName, that.teamName) && Objects.equals(name, that.name) && Objects.equals(lon, that.lon) && Objects.equals(lat, that.lat);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(id, teamName,lon, lat); return Objects.hash(id, teamName, name, lon, lat);
} }
} }
@@ -22,6 +22,11 @@ public class XianHiddenDangerSpotsBasePointVo {
* 灾害点名称 * 灾害点名称
*/ */
private String disasterName; private String disasterName;
/**
* 通用名称字段(用于统一访问)
*/
private String name;
/** /**
* 经度 * 经度
*/ */
@@ -36,6 +41,7 @@ public class XianHiddenDangerSpotsBasePointVo {
XianHiddenDangerSpotsBasePointVo vo = new XianHiddenDangerSpotsBasePointVo(); XianHiddenDangerSpotsBasePointVo vo = new XianHiddenDangerSpotsBasePointVo();
vo.setId(entity.getId()); vo.setId(entity.getId());
vo.setDisasterName(entity.getDisasterName()); vo.setDisasterName(entity.getDisasterName());
vo.setName(entity.getDisasterName()); // 设置通用name字段
vo.setLon(entity.getLon()); vo.setLon(entity.getLon());
vo.setLat(entity.getLat()); vo.setLat(entity.getLat());
vo.setDisasterType(entity.getDisasterType()); vo.setDisasterType(entity.getDisasterType());
@@ -60,11 +66,11 @@ public class XianHiddenDangerSpotsBasePointVo {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
XianHiddenDangerSpotsBasePointVo that = (XianHiddenDangerSpotsBasePointVo) o; XianHiddenDangerSpotsBasePointVo that = (XianHiddenDangerSpotsBasePointVo) o;
return Objects.equals(id, that.id) && Objects.equals(disasterName, that.disasterName) && Objects.equals(lon, that.lon) && Objects.equals(lat, that.lat) && Objects.equals(disasterType, that.disasterType); return Objects.equals(id, that.id) && Objects.equals(disasterName, that.disasterName) && Objects.equals(name, that.name) && Objects.equals(lon, that.lon) && Objects.equals(lat, that.lat) && Objects.equals(disasterType, that.disasterType);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(id, disasterName, lon, lat, disasterType); return Objects.hash(id, disasterName, name, lon, lat, disasterType);
} }
} }
@@ -9,6 +9,11 @@ import java.util.Objects;
@Data @Data
public class XianHiddenDangerSpotsPointDetailVo { public class XianHiddenDangerSpotsPointDetailVo {
/**
* 概率
*/
private String probability;
/** /**
* 序号 * 序号
*/ */
@@ -23,6 +23,11 @@ public class XianReservoirListBasePointVo {
*/ */
private String reservoirName; private String reservoirName;
/**
* 通用名称字段(用于统一访问)
*/
private String name;
/** /**
* 经度 * 经度
*/ */
@@ -37,6 +42,7 @@ public class XianReservoirListBasePointVo {
XianReservoirListBasePointVo vo = new XianReservoirListBasePointVo(); XianReservoirListBasePointVo vo = new XianReservoirListBasePointVo();
vo.setId(entity.getId()); vo.setId(entity.getId());
vo.setReservoirName(entity.getReservoirName()); vo.setReservoirName(entity.getReservoirName());
vo.setName(entity.getReservoirName()); // 设置通用name字段
vo.setLon(entity.getLon()); vo.setLon(entity.getLon());
vo.setLat(entity.getLat()); vo.setLat(entity.getLat());
return vo; return vo;
@@ -55,12 +61,12 @@ public class XianReservoirListBasePointVo {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
XianReservoirListBasePointVo that = (XianReservoirListBasePointVo) o; XianReservoirListBasePointVo that = (XianReservoirListBasePointVo) o;
return Objects.equals(id, that.id) && Objects.equals(reservoirName, that.reservoirName) return Objects.equals(id, that.id) && Objects.equals(reservoirName, that.reservoirName) && Objects.equals(name, that.name)
&& Objects.equals(lon, that.lon) && Objects.equals(lat, that.lat); && Objects.equals(lon, that.lon) && Objects.equals(lat, that.lat);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(id, reservoirName, lon, lat); return Objects.hash(id, reservoirName, name, lon, lat);
} }
} }
@@ -19,6 +19,11 @@ public class XianRiskSpotsBasePointVo {
*/ */
private String riskName; private String riskName;
/**
* 通用名称字段(用于统一访问)
*/
private String name;
/** /**
* 经度 * 经度
*/ */
@@ -33,6 +38,7 @@ public class XianRiskSpotsBasePointVo {
XianRiskSpotsBasePointVo vo = new XianRiskSpotsBasePointVo(); XianRiskSpotsBasePointVo vo = new XianRiskSpotsBasePointVo();
vo.setId(entity.getId()); vo.setId(entity.getId());
vo.setRiskName(entity.getRiskName()); vo.setRiskName(entity.getRiskName());
vo.setName(entity.getRiskName()); // 设置通用name字段
vo.setLon(entity.getLon()); vo.setLon(entity.getLon());
vo.setLat(entity.getLat()); vo.setLat(entity.getLat());
return vo; return vo;
@@ -51,11 +57,11 @@ public class XianRiskSpotsBasePointVo {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
XianRiskSpotsBasePointVo that = (XianRiskSpotsBasePointVo) o; XianRiskSpotsBasePointVo that = (XianRiskSpotsBasePointVo) o;
return Objects.equals(id, that.id) && Objects.equals(riskName, that.riskName) && Objects.equals(lon, that.lon) && Objects.equals(lat, that.lat); return Objects.equals(id, that.id) && Objects.equals(riskName, that.riskName) && Objects.equals(name, that.name) && Objects.equals(lon, that.lon) && Objects.equals(lat, that.lat);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(id, riskName, lon, lat); return Objects.hash(id, riskName, name, lon, lat);
} }
} }
@@ -9,6 +9,11 @@ import java.util.Objects;
@Data @Data
public class XianRiskSpotsPointDetailVo { public class XianRiskSpotsPointDetailVo {
/**
* 概率
*/
private String probability;
/** /**
* 序号 * 序号
*/ */
@@ -23,6 +23,11 @@ public class XianSchoolBasePointVo {
*/ */
private String schoolName; private String schoolName;
/**
* 通用名称字段(用于统一访问)
*/
private String name;
/** /**
* 经度 * 经度
*/ */
@@ -37,6 +42,7 @@ public class XianSchoolBasePointVo {
XianSchoolBasePointVo vo = new XianSchoolBasePointVo(); XianSchoolBasePointVo vo = new XianSchoolBasePointVo();
vo.setId(entity.getId()); vo.setId(entity.getId());
vo.setSchoolName(entity.getSchoolName()); vo.setSchoolName(entity.getSchoolName());
vo.setName(entity.getSchoolName()); // 设置通用name字段
vo.setLon(entity.getLon()); vo.setLon(entity.getLon());
vo.setLat(entity.getLat()); vo.setLat(entity.getLat());
return vo; return vo;
@@ -55,11 +61,11 @@ public class XianSchoolBasePointVo {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
XianSchoolBasePointVo that = (XianSchoolBasePointVo) o; XianSchoolBasePointVo that = (XianSchoolBasePointVo) o;
return Objects.equals(id, that.id) && Objects.equals(schoolName, that.schoolName) && Objects.equals(lon, that.lon) && Objects.equals(lat, that.lat); return Objects.equals(id, that.id) && Objects.equals(schoolName, that.schoolName) && Objects.equals(name, that.name) && Objects.equals(lon, that.lon) && Objects.equals(lat, that.lat);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(id, schoolName, lon, lat); return Objects.hash(id, schoolName, name, lon, lat);
} }
} }
@@ -23,6 +23,11 @@ public class XianSubwayStationsBasePointVo {
*/ */
private String stationName; private String stationName;
/**
* 通用名称字段(用于统一访问)
*/
private String name;
/** /**
* 经度 * 经度
*/ */
@@ -37,6 +42,7 @@ public class XianSubwayStationsBasePointVo {
XianSubwayStationsBasePointVo vo = new XianSubwayStationsBasePointVo(); XianSubwayStationsBasePointVo vo = new XianSubwayStationsBasePointVo();
vo.setId(entity.getId()); vo.setId(entity.getId());
vo.setStationName(entity.getStationName()); vo.setStationName(entity.getStationName());
vo.setName(entity.getStationName()); // 设置通用name字段
vo.setLon(entity.getLon()); vo.setLon(entity.getLon());
vo.setLat(entity.getLat()); vo.setLat(entity.getLat());
return vo; return vo;
@@ -55,12 +61,12 @@ public class XianSubwayStationsBasePointVo {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
XianSubwayStationsBasePointVo that = (XianSubwayStationsBasePointVo) o; XianSubwayStationsBasePointVo that = (XianSubwayStationsBasePointVo) o;
return Objects.equals(id, that.id) && Objects.equals(stationName, that.stationName) return Objects.equals(id, that.id) && Objects.equals(stationName, that.stationName) && Objects.equals(name, that.name)
&& Objects.equals(lon, that.lon) && Objects.equals(lat, that.lat); && Objects.equals(lon, that.lon) && Objects.equals(lat, that.lat);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(id, stationName, lon, lat); return Objects.hash(id, stationName, name, lon, lat);
} }
} }
@@ -2,6 +2,7 @@ package com.gis.xian.wrapper;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.gis.xian.config.CryptoProperties; import com.gis.xian.config.CryptoProperties;
import com.gis.xian.utils.PathMatcherUtils;
import com.gis.xian.utils.safety.SM4Utils; import com.gis.xian.utils.safety.SM4Utils;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
@@ -29,7 +30,7 @@ public class EncryptResponseAdvice implements ResponseBodyAdvice<Object> {
private CryptoProperties cryptoProperties; private CryptoProperties cryptoProperties;
/** /**
* 判断是否需要加密:排除特定路径,其余全部加密 * 判断是否需要加密:排除特定路径,其余全部加密(支持通配符匹配)
*/ */
@Override @Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
@@ -41,19 +42,12 @@ public class EncryptResponseAdvice implements ResponseBodyAdvice<Object> {
HttpServletRequest request = attributes.getRequest(); HttpServletRequest request = attributes.getRequest();
String requestUri = request.getRequestURI(); String requestUri = request.getRequestURI();
// 检查是否为无需加密的路径 // 检查是否为无需加密的路径(支持通配符)
for (String path : cryptoProperties.getNoEncryptPaths()) { return !PathMatcherUtils.matches(requestUri, cryptoProperties.getNoEncryptPaths());
if (requestUri.contains(path)) {
return false; // 排除路径,不加密
}
}
// 其余路径均需要加密
return true;
} }
/** /**
* 响应体加密逻辑(保持不变) * 响应体加密逻辑
*/ */
@Override @Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
@@ -61,15 +55,17 @@ public class EncryptResponseAdvice implements ResponseBodyAdvice<Object> {
ServerHttpRequest request, ServerHttpResponse response) { ServerHttpRequest request, ServerHttpResponse response) {
try { try {
String sm4Key = Sm4KeyHolder.getSm4Key(); String sm4Key = Sm4KeyHolder.getSm4Key();
// 如果SM4密钥不存在,直接返回原始数据(不加密)
if (sm4Key == null || sm4Key.length() != 32) { if (sm4Key == null || sm4Key.length() != 32) {
throw new RuntimeException("SM4密钥不存在或格式错误,无法加密响应"); return body;
} }
String plaintext = objectMapper.writeValueAsString(body); String plaintext = objectMapper.writeValueAsString(body);
String encryptedText = SM4Utils.encrypt(sm4Key, plaintext); String encryptedText = SM4Utils.encrypt(sm4Key, plaintext);
return encryptedText; return encryptedText;
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("响应数据加密失败: " + e.getMessage(), e); // 加密失败时返回原始数据,避免影响业务
return body;
} finally { } finally {
Sm4KeyHolder.clear(); // 清除线程本地存储,避免内存泄漏 Sm4KeyHolder.clear(); // 清除线程本地存储,避免内存泄漏
} }
+10
View File
@@ -41,7 +41,17 @@ safety:
no-encrypt-paths: no-encrypt-paths:
- /crypto/sm2/public-key - /crypto/sm2/public-key
- /druid - /druid
- /websocket/info
- /websocket/**
# 请求无需解密的路径 # 请求无需解密的路径
no-decrypt-paths: no-decrypt-paths:
- /crypto/sm2/public-key - /crypto/sm2/public-key
- /druid - /druid
- /websocket/info
- /websocket/**
# 算法服务器配置
algorithm:
server:
# 开发环境算法服务器地址
url: http://localhost:8082
+8
View File
@@ -41,6 +41,14 @@ safety:
# 响应无需加密的路径 # 响应无需加密的路径
no-encrypt-paths: no-encrypt-paths:
- /crypto/sm2/public-key - /crypto/sm2/public-key
- /websocket/**
# 请求无需解密的路径 # 请求无需解密的路径
no-decrypt-paths: no-decrypt-paths:
- /crypto/sm2/public-key - /crypto/sm2/public-key
- /websocket/**
# 算法服务器配置
algorithm:
server:
# 生产环境算法服务器地址
url: http://localhost:8081
+2 -2
View File
@@ -7,7 +7,7 @@ spring:
# MyBatis 配置 # MyBatis 配置
mybatis: mybatis:
mapper-locations: classpath:mapper/*.xml mapper-locations: classpath:com/gis/xian/mapper/*.xml
type-aliases-package: com.gis.basic_template_not_login_back.entity type-aliases-package: com.gis.xian.entity
configuration: configuration:
map-underscore-to-camel-case: true map-underscore-to-camel-case: true
@@ -25,19 +25,31 @@
<result property="isDelete" column="is_delete" /> <result property="isDelete" column="is_delete" />
</resultMap> </resultMap>
<!-- 获取所有基础点:滑坡、泥石流、山洪、内涝 --> <!-- 获取所有基础点:滑坡、崩塌、泥石流、山洪、内涝 -->
<select id="getBasePoints" resultMap="XianHiddenDangerSpotsResultMap"> <select id="getBasePoints" resultMap="XianHiddenDangerSpotsResultMap">
SELECT id, disaster_name, lon, lat, disaster_type FROM xian_hidden_danger_spots SELECT id, disaster_name, lon, lat, disaster_type FROM xian_hidden_danger_spots
<where> <where>
<choose> is_delete = 0
<when test='disasterType == "rainstorm"'> AND disaster_type IN('滑坡', '崩塌', '泥石流', '山洪', '内涝')
disaster_type IN('滑坡', '泥石流', '山洪', '内涝') <if test="disasterType != null and disasterType != ''">
</when> <choose>
<otherwise> <when test="disasterType == 'landslide'">
disaster_type IN('滑坡', '泥石流') AND disaster_type = '滑坡'
</otherwise> </when>
</choose> <when test="disasterType == 'collapse'">
AND is_delete = 0 AND disaster_type = '崩塌'
</when>
<when test="disasterType == 'debris_flow'">
AND disaster_type = '泥石流'
</when>
<when test="disasterType == 'flash_flood'">
AND disaster_type = '山洪'
</when>
<when test="disasterType == 'water_logging'">
AND disaster_type = '内涝'
</when>
</choose>
</if>
</where> </where>
</select> </select>
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gis.xian.mapper.XianInferenceResultMapper">
<resultMap id="XianInferenceResultResultMap" type="com.gis.xian.entity.XianInferenceResult">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="eventType" column="event_type" />
<result property="occurredTime" column="occurred_time" />
<result property="operationType" column="operation_type" />
<result property="result" column="result" />
<result property="condition" column="condition" />
<result property="filePath" column="file_path" />
<result property="createTime" column="create_time" />
<result property="isDelete" column="is_delete" />
</resultMap>
<!-- 根据id和pointId获取概率 -->
<select id="getProbabilityByIdAndPointId" resultType="java.lang.String">
SELECT result->>#{pointId} FROM xian_inference_result
<where>
id = #{id}
</where>
</select>
</mapper>
@@ -17,15 +17,15 @@
<result property="projectScale" column="project_scale" /> <result property="projectScale" column="project_scale" />
<result property="hasHiddenDanger" column="has_hidden_danger" /> <result property="hasHiddenDanger" column="has_hidden_danger" />
<result property="note1" column="note1" /> <result property="note1" column="note1" />
<result property="lon" column="longitude" /> <result property="lon" column="lon" />
<result property="lat" column="latitude" /> <result property="lat" column="lat" />
<result property="geom" column="geom" /> <result property="geom" column="geom" />
<result property="isDelete" column="is_delete" /> <result property="isDelete" column="is_delete" />
</resultMap> </resultMap>
<!-- 获取所有水库基础点 --> <!-- 获取所有水库基础点 -->
<select id="getBasePoints" resultMap="BaseResultMap"> <select id="getBasePoints" resultMap="BaseResultMap">
SELECT id, reservoir_name, longitude, latitude FROM xian_reservoir_list SELECT id, reservoir_name, lon, lat FROM xian_reservoir_list
<where> <where>
is_delete = 0 is_delete = 0
</where> </where>
@@ -33,7 +33,7 @@
<!-- 根据id获取水库详情 --> <!-- 根据id获取水库详情 -->
<select id="getPointDetailById" resultMap="BaseResultMap"> <select id="getPointDetailById" resultMap="BaseResultMap">
SELECT id, reservoir_name, location, safety_assess_result, longitude, latitude FROM xian_reservoir_list SELECT id, reservoir_name, location, safety_assess_result, lon, lat FROM xian_reservoir_list
<where> <where>
id = #{id} AND is_delete = 0 id = #{id} AND is_delete = 0
</where> </where>
+15 -2
View File
@@ -5,14 +5,27 @@ safety:
global: 'xian:sm2:keypair:global' global: 'xian:sm2:keypair:global'
# 降雨网格数据
rainfall:
grid:
# 降雨站点网格数据
station-grid: 'xian:rainfall:rain_station_grid'
# 降雨站点标识符
station-identifier: 'xian:rainfall:rain_station_identifier'
# 初始化数据存储 # 初始化数据存储
init: init:
data: data:
# 基础信息点数据:滑坡、泥石流、山洪、内涝 # 基础信息点数据:滑坡、泥石流、山洪、内涝
base-points: base-points:
hidden-danger: hidden-danger:
rainstorm: 'xian:init:data:base-points:hidden-danger:rainstorm' all: 'xian:init:data:base-points:hidden-danger:all'
earthquake: 'xian:init:data:base-points:hidden-danger:earthquake' landslide: 'xian:init:data:base-points:hidden-danger:landslide'
collapse: 'xian:init:data:base-points:hidden-danger:collapse'
debris-flow: 'xian:init:data:base-points:hidden-danger:debris_flow'
flash-flood: 'xian:init:data:base-points:hidden-danger:flash_flood'
water-logging: 'xian:init:data:base-points:hidden-danger:water_logging'
risk: 'xian:init:data:base-points:risk' risk: 'xian:init:data:base-points:risk'
hospitals: 'xian:init:data:base-points:hospitals' hospitals: 'xian:init:data:base-points:hospitals'
dangerous-source: 'xian:init:data:base-points:dangerous-source' dangerous-source: 'xian:init:data:base-points:dangerous-source'