From c7bdf7d773ffc56bee758b4e23e15bab4a6cba2d Mon Sep 17 00:00:00 2001 From: lzh Date: Wed, 25 Mar 2026 11:30:24 +0800 Subject: [PATCH] =?UTF-8?q?refactor(security):=20=E6=B8=85=E7=90=86=20secu?= =?UTF-8?q?rity-biz=20=E4=B8=AD=E6=97=A7=E7=9A=84=20vsp=20=E6=96=87?= =?UTF-8?q?=E4=BB=B6=EF=BC=8C=E6=9B=B4=E6=96=B0=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除 security-biz/integration/vsp/ 旧目录(已迁移至 ops-biz/infrastructure/vsp/) - 更新 SecurityOrderEventListenerVspTest import 路径 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../integration/vsp/VspNotifyClient.java | 21 --- .../integration/vsp/VspNotifyClientImpl.java | 65 ------- .../vsp/config/VspNotifyConfig.java | 21 --- .../vsp/config/VspNotifyProperties.java | 19 --- .../integration/vsp/dto/VspResponseDTO.java | 13 -- .../vsp/dto/VspSendCardReqDTO.java | 28 --- .../vsp/dto/VspSyncStatusReqDTO.java | 19 --- .../SecurityOrderEventListenerVspTest.java | 8 +- .../vsp/VspNotifyClientImplTest.java | 161 ------------------ 9 files changed, 4 insertions(+), 351 deletions(-) delete mode 100644 viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/VspNotifyClient.java delete mode 100644 viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/VspNotifyClientImpl.java delete mode 100644 viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/config/VspNotifyConfig.java delete mode 100644 viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/config/VspNotifyProperties.java delete mode 100644 viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/dto/VspResponseDTO.java delete mode 100644 viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/dto/VspSendCardReqDTO.java delete mode 100644 viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/dto/VspSyncStatusReqDTO.java delete mode 100644 viewsh-module-ops/viewsh-module-security-biz/src/test/java/com/viewsh/module/ops/security/integration/vsp/VspNotifyClientImplTest.java diff --git a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/VspNotifyClient.java b/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/VspNotifyClient.java deleted file mode 100644 index 8e56dac..0000000 --- a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/VspNotifyClient.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.viewsh.module.ops.security.integration.vsp; - -import com.viewsh.module.ops.security.integration.vsp.dto.VspSendCardReqDTO; -import com.viewsh.module.ops.security.integration.vsp.dto.VspSyncStatusReqDTO; - -public interface VspNotifyClient { - - /** - * 发送企微工单卡片 - * - * @param req 卡片内容 - */ - void sendCard(VspSendCardReqDTO req); - - /** - * 同步工单状态到 vsp-service - * - * @param req 状态信息 - */ - void syncStatus(VspSyncStatusReqDTO req); -} diff --git a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/VspNotifyClientImpl.java b/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/VspNotifyClientImpl.java deleted file mode 100644 index 2307f51..0000000 --- a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/VspNotifyClientImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.viewsh.module.ops.security.integration.vsp; - -import com.viewsh.module.ops.security.integration.vsp.config.VspNotifyProperties; -import com.viewsh.module.ops.security.integration.vsp.dto.VspResponseDTO; -import com.viewsh.module.ops.security.integration.vsp.dto.VspSendCardReqDTO; -import com.viewsh.module.ops.security.integration.vsp.dto.VspSyncStatusReqDTO; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestClientException; -import org.springframework.web.client.RestTemplate; - -@Slf4j -@Component -public class VspNotifyClientImpl implements VspNotifyClient { - - private final RestTemplate restTemplate; - private final VspNotifyProperties properties; - - public VspNotifyClientImpl(@Qualifier("vspRestTemplate") RestTemplate restTemplate, - VspNotifyProperties properties) { - this.restTemplate = restTemplate; - this.properties = properties; - } - - @Override - public void sendCard(VspSendCardReqDTO req) { - if (!properties.isEnabled()) return; - String url = properties.getBaseUrl() + "/api/wechat/notify/send-card"; - executeWithRetry(url, req, "sendCard", req.getOrderId(), req.getAlarmId()); - } - - @Override - public void syncStatus(VspSyncStatusReqDTO req) { - if (!properties.isEnabled()) return; - String url = properties.getBaseUrl() + "/api/wechat/notify/sync-status"; - executeWithRetry(url, req, "syncStatus", req.getOrderId(), req.getAlarmId()); - } - - private void executeWithRetry(String url, Object req, - String action, String orderId, String alarmId) { - for (int i = 0; i <= properties.getMaxRetry(); i++) { - try { - VspResponseDTO resp = restTemplate.postForObject(url, req, VspResponseDTO.class); - if (resp != null && resp.isSuccess()) { - log.info("[{}] vsp通知成功, orderId={}, alarmId={}", action, orderId, alarmId); - return; - } - // 业务失败不重试 - log.warn("[{}] vsp返回失败: code={}, msg={}, orderId={}", - action, resp != null ? resp.getCode() : null, - resp != null ? resp.getMsg() : null, orderId); - return; - } catch (RestClientException e) { - if (i < properties.getMaxRetry()) { - log.warn("[{}] 第{}次调用失败, orderId={}, 将重试", - action, i + 1, orderId); - } else { - log.error("[{}] 调用vsp失败, 重试耗尽, orderId={}, alarmId={}", - action, orderId, alarmId, e); - } - } - } - } -} diff --git a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/config/VspNotifyConfig.java b/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/config/VspNotifyConfig.java deleted file mode 100644 index 9ac3e96..0000000 --- a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/config/VspNotifyConfig.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.viewsh.module.ops.security.integration.vsp.config; - -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.client.SimpleClientHttpRequestFactory; -import org.springframework.web.client.RestTemplate; - -@Configuration -@EnableConfigurationProperties(VspNotifyProperties.class) -public class VspNotifyConfig { - - @Bean("vspRestTemplate") - public RestTemplate vspRestTemplate(VspNotifyProperties properties) { - SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); - factory.setConnectTimeout(properties.getConnectTimeout()); - factory.setReadTimeout(properties.getReadTimeout()); - RestTemplate restTemplate = new RestTemplate(factory); - return restTemplate; - } -} diff --git a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/config/VspNotifyProperties.java b/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/config/VspNotifyProperties.java deleted file mode 100644 index 918ea9f..0000000 --- a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/config/VspNotifyProperties.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.viewsh.module.ops.security.integration.vsp.config; - -import lombok.Data; -import org.springframework.boot.context.properties.ConfigurationProperties; - -@Data -@ConfigurationProperties(prefix = "viewsh.ops.vsp-notify") -public class VspNotifyProperties { - /** 是否启用 vsp 通知 */ - private boolean enabled = true; - /** vsp-service 基础 URL */ - private String baseUrl = "http://124.221.55.225:8000"; - /** 连接超时(ms) */ - private int connectTimeout = 5000; - /** 读取超时(ms) */ - private int readTimeout = 10000; - /** 最大重试次数(网络异常时) */ - private int maxRetry = 2; -} diff --git a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/dto/VspResponseDTO.java b/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/dto/VspResponseDTO.java deleted file mode 100644 index 7e1c698..0000000 --- a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/dto/VspResponseDTO.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.viewsh.module.ops.security.integration.vsp.dto; - -import lombok.Data; - -@Data -public class VspResponseDTO { - private Integer code; - private String msg; - - public boolean isSuccess() { - return code != null && code == 0; - } -} diff --git a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/dto/VspSendCardReqDTO.java b/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/dto/VspSendCardReqDTO.java deleted file mode 100644 index 4286ce1..0000000 --- a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/dto/VspSendCardReqDTO.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.viewsh.module.ops.security.integration.vsp.dto; - -import lombok.Builder; -import lombok.Data; -import java.util.List; - -@Data -@Builder -public class VspSendCardReqDTO { - /** 关联告警ID */ - private String alarmId; - /** 工单ID */ - private String orderId; - /** 接收人企微 userId 列表 */ - private List userIds; - /** 卡片标题(告警类型) */ - private String title; - /** 区域名称 */ - private String areaName; - /** 摄像头名称 */ - private String cameraName; - /** 告警时间,格式 MM-dd HH:mm */ - private String eventTime; - /** 告警级别(0紧急 1重要 2普通 3轻微) */ - private Integer level; - /** 告警截图URL */ - private String snapshotUrl; -} diff --git a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/dto/VspSyncStatusReqDTO.java b/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/dto/VspSyncStatusReqDTO.java deleted file mode 100644 index 1bb0ffe..0000000 --- a/viewsh-module-ops/viewsh-module-security-biz/src/main/java/com/viewsh/module/ops/security/integration/vsp/dto/VspSyncStatusReqDTO.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.viewsh.module.ops.security.integration.vsp.dto; - -import lombok.Builder; -import lombok.Data; - -@Data -@Builder -public class VspSyncStatusReqDTO { - /** 关联告警ID */ - private String alarmId; - /** 工单ID */ - private String orderId; - /** 工单状态 */ - private String status; - /** 操作人企微 userId */ - private String operator; - /** 备注 */ - private String remark; -} diff --git a/viewsh-module-ops/viewsh-module-security-biz/src/test/java/com/viewsh/module/ops/security/integration/listener/SecurityOrderEventListenerVspTest.java b/viewsh-module-ops/viewsh-module-security-biz/src/test/java/com/viewsh/module/ops/security/integration/listener/SecurityOrderEventListenerVspTest.java index 5f75505..415e7b5 100644 --- a/viewsh-module-ops/viewsh-module-security-biz/src/test/java/com/viewsh/module/ops/security/integration/listener/SecurityOrderEventListenerVspTest.java +++ b/viewsh-module-ops/viewsh-module-security-biz/src/test/java/com/viewsh/module/ops/security/integration/listener/SecurityOrderEventListenerVspTest.java @@ -10,11 +10,11 @@ import com.viewsh.module.ops.enums.WorkOrderStatusEnum; import com.viewsh.module.ops.infrastructure.log.recorder.EventLogRecorder; import com.viewsh.module.ops.security.dal.dataobject.workorder.OpsOrderSecurityExtDO; import com.viewsh.module.ops.security.dal.mysql.workorder.OpsOrderSecurityExtMapper; -import com.viewsh.module.ops.security.integration.vsp.VspNotifyClient; -import com.viewsh.module.ops.security.integration.vsp.dto.VspSendCardReqDTO; -import com.viewsh.module.ops.security.integration.vsp.dto.VspSyncStatusReqDTO; +import com.viewsh.module.ops.infrastructure.vsp.VspNotifyClient; +import com.viewsh.module.ops.infrastructure.vsp.dto.VspSendCardReqDTO; +import com.viewsh.module.ops.infrastructure.vsp.dto.VspSyncStatusReqDTO; import com.viewsh.module.ops.service.area.OpsBusAreaService; -import com.viewsh.module.ops.controller.admin.area.vo.OpsBusAreaRespVO; +import com.viewsh.module.ops.dal.dataobject.vo.area.OpsBusAreaRespVO; import com.viewsh.module.system.api.social.SocialUserApi; import com.viewsh.module.system.api.social.dto.SocialUserRespDTO; import org.junit.jupiter.api.Test; diff --git a/viewsh-module-ops/viewsh-module-security-biz/src/test/java/com/viewsh/module/ops/security/integration/vsp/VspNotifyClientImplTest.java b/viewsh-module-ops/viewsh-module-security-biz/src/test/java/com/viewsh/module/ops/security/integration/vsp/VspNotifyClientImplTest.java deleted file mode 100644 index ed9d9b2..0000000 --- a/viewsh-module-ops/viewsh-module-security-biz/src/test/java/com/viewsh/module/ops/security/integration/vsp/VspNotifyClientImplTest.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.viewsh.module.ops.security.integration.vsp; - -import com.viewsh.module.ops.security.integration.vsp.config.VspNotifyProperties; -import com.viewsh.module.ops.security.integration.vsp.dto.VspResponseDTO; -import com.viewsh.module.ops.security.integration.vsp.dto.VspSendCardReqDTO; -import com.viewsh.module.ops.security.integration.vsp.dto.VspSyncStatusReqDTO; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.web.client.RestClientException; -import org.springframework.web.client.RestTemplate; - -import java.util.List; - -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -/** - * VspNotifyClientImpl 单元测试 - * - * @author lzh - */ -@ExtendWith(MockitoExtension.class) -public class VspNotifyClientImplTest { - - @Mock - private RestTemplate restTemplate; - - private VspNotifyProperties properties; - - private VspNotifyClientImpl client; - - private static final String BASE_URL = "http://localhost:8000"; - - @BeforeEach - void setUp() { - properties = new VspNotifyProperties(); - properties.setEnabled(true); - properties.setBaseUrl(BASE_URL); - properties.setMaxRetry(2); - client = new VspNotifyClientImpl(restTemplate, properties); - } - - // ==================== sendCard 测试 ==================== - - @Test - void sendCard_success() { - VspSendCardReqDTO req = buildSendCardReq(); - - VspResponseDTO resp = new VspResponseDTO(); - resp.setCode(0); - resp.setMsg("ok"); - - when(restTemplate.postForObject(anyString(), any(), eq(VspResponseDTO.class))) - .thenReturn(resp); - - // 执行 - client.sendCard(req); - - // 验证只调用一次 - verify(restTemplate, times(1)).postForObject( - eq(BASE_URL + "/api/wechat/notify/send-card"), - eq(req), - eq(VspResponseDTO.class)); - } - - @Test - void sendCard_retryOnNetworkError() { - VspSendCardReqDTO req = buildSendCardReq(); - - when(restTemplate.postForObject(anyString(), any(), eq(VspResponseDTO.class))) - .thenThrow(new RestClientException("Connection refused")); - - // 执行 - client.sendCard(req); - - // maxRetry=2,总共调用 1 + 2 = 3 次 - verify(restTemplate, times(3)).postForObject( - eq(BASE_URL + "/api/wechat/notify/send-card"), - eq(req), - eq(VspResponseDTO.class)); - } - - @Test - void sendCard_noRetryOnBusinessError() { - VspSendCardReqDTO req = buildSendCardReq(); - - VspResponseDTO resp = new VspResponseDTO(); - resp.setCode(-1); - resp.setMsg("业务失败"); - - when(restTemplate.postForObject(anyString(), any(), eq(VspResponseDTO.class))) - .thenReturn(resp); - - // 执行 - client.sendCard(req); - - // 业务失败不重试,只调用一次 - verify(restTemplate, times(1)).postForObject(anyString(), any(), eq(VspResponseDTO.class)); - } - - @Test - void sendCard_disabled() { - properties.setEnabled(false); - - VspSendCardReqDTO req = buildSendCardReq(); - - // 执行 - client.sendCard(req); - - // 未启用时不调用 RestTemplate - verify(restTemplate, never()).postForObject(anyString(), any(), any()); - } - - // ==================== syncStatus 测试 ==================== - - @Test - void syncStatus_success() { - VspSyncStatusReqDTO req = VspSyncStatusReqDTO.builder() - .alarmId("alarm-001") - .orderId("10001") - .status("confirmed") - .operator("wechat_user_1") - .remark("确认接单") - .build(); - - VspResponseDTO resp = new VspResponseDTO(); - resp.setCode(0); - resp.setMsg("ok"); - - when(restTemplate.postForObject(anyString(), any(), eq(VspResponseDTO.class))) - .thenReturn(resp); - - // 执行 - client.syncStatus(req); - - // 验证使用 sync-status URL - verify(restTemplate, times(1)).postForObject( - eq(BASE_URL + "/api/wechat/notify/sync-status"), - eq(req), - eq(VspResponseDTO.class)); - } - - // ==================== 辅助方法 ==================== - - private VspSendCardReqDTO buildSendCardReq() { - return VspSendCardReqDTO.builder() - .alarmId("alarm-001") - .orderId("10001") - .userIds(List.of("wechat_user_1")) - .title("入侵告警") - .areaName("A栋大堂") - .cameraName("大堂摄像头") - .eventTime("03-24 10:00") - .level(1) - .snapshotUrl("http://example.com/snapshot.jpg") - .build(); - } -}