# 集成中心领域技术方案 **领域编号**: 4.6 **微服务**: ether-hub **最后更新**: 2026-02-10 --- ## 一、领域概述 ### 1.1 领域职责 集成中心领域负责 Ether 平台与外部系统的对接集成: - 外部系统适配(停车系统、门禁系统、政府监管平台) - IoT设备接入与管理 - 数据同步与转换 - 集成日志记录与监控 ### 1.2 核心概念 | 概念 | 说明 | 对应实体 | |------|------|----------| | **集成适配器** | 外部系统连接配置 | IntegrationAdapter | | **集成日志** | 接口调用记录 | IntegrationLog | | **IoT设备** | 物联网设备管理 | IoTDevice | | **数据映射** | 字段转换规则 | DataMapping | --- ## 二、领域模型 ### 2.1 聚合根设计 #### IntegrationAdapter(集成适配器) ```java @Entity @Table(name = "hub_integration_adapter") @Data public class IntegrationAdapter { @Id private UUID id; private UUID projectId; private String name; // 适配器名称 private String systemType; // PARKING/ACCESS/GOVERNMENT/IOT private String description; // 描述 // 协议配置 private String protocol; // HTTP/HTTPS/MQTT/COAP/SOAP private String baseUrl; // 基础URL private Integer timeout; // 超时时间(秒) private Integer retryCount; // 重试次数 // 认证配置 private String authType; // NONE/API_KEY/OAUTH2/JWT/BASIC private String authConfig; // 认证配置(JSON) // API_KEY: {key, value, location: header/query} // OAUTH2: {clientId, clientSecret, tokenUrl, scope} // JWT: {secret, algorithm} // BASIC: {username, password} // 状态 private AdapterStatus status; // ONLINE/OFFLINE/ERROR private LocalDateTime lastPingTime; private String lastErrorMessage; // 启用状态 private Boolean enabled; // 审计字段 private LocalDateTime createdAt; private LocalDateTime updatedAt; } // 适配器状态枚举 public enum AdapterStatus { ONLINE("在线"), OFFLINE("离线"), ERROR("错误"); } ``` #### IntegrationLog(集成日志) ```java @Entity @Table(name = "hub_integration_log") @Data public class IntegrationLog { @Id private UUID id; private UUID adapterId; // 请求信息 private String requestId; // 请求唯一标识 private String operation; // 操作类型 private String requestMethod; // GET/POST/PUT/DELETE private String requestUrl; // 请求URL private String requestHeaders; // 请求头(JSON) private String requestBody; // 请求体 private LocalDateTime requestTime; // 响应信息 private String responseBody; // 响应体 private Integer httpStatus; // HTTP状态码 private String responseHeaders;// 响应头(JSON) private LocalDateTime responseTime; // 执行信息 private Long durationMs; // 耗时(ms) // 状态 private LogStatus status; // SUCCESS/FAIL/TIMEOUT private String errorMessage; // 错误信息 private String errorStack; // 错误堆栈 // 审计字段 private LocalDateTime createdAt; } // 日志状态枚举 public enum LogStatus { SUCCESS("成功"), FAIL("失败"), TIMEOUT("超时"); } ``` #### IoTDevice(IoT设备) ```java @Entity @Table(name = "hub_iot_device") @Data public class IoTDevice { @Id private UUID id; private UUID projectId; // 设备信息 private String deviceId; // 设备唯一标识 private String deviceName; // 设备名称 private String deviceType; // 设备类型: SENSOR/CAMERA/GATE/... private String protocol; // MQTT/CoAP/HTTP/HTTPS // 关联信息 private UUID equipmentId; // 关联设备台账 private UUID spaceNodeId; // 关联空间节点 // MQTT配置 private String mqttBroker; // MQTT服务器地址 private Integer mqttPort; // MQTT端口 private String mqttTopic; // 订阅主题 private String mqttClientId; // 客户端ID // 最后数据 private String lastPayload; // 最后上报数据 private LocalDateTime lastReportTime; // 状态 private DeviceStatus status; // ONLINE/OFFLINE/FAULT private LocalDateTime lastOnlineTime; // 审计字段 private LocalDateTime createdAt; private LocalDateTime updatedAt; } // 设备状态枚举 public enum DeviceStatus { ONLINE("在线"), OFFLINE("离线"), FAULT("故障"); } ``` #### DataMapping(数据映射) ```java @Entity @Table(name = "hub_data_mapping") @Data public class DataMapping { @Id private UUID id; private UUID projectId; private UUID adapterId; // 关联适配器 private String name; // 映射名称 private String entityType; // 实体类型: WORK_ORDER/EQUIPMENT/... // 字段映射 private String fieldMappings; // [{"source": "orderNo", "target": "工单编号", "type": "STRING"}] // 转换规则 private String transformRules; // 数据转换规则(JSON) // 启用状态 private Boolean enabled; // 审计字段 private LocalDateTime createdAt; private LocalDateTime updatedAt; } ``` --- ## 三、集成场景 ### 3.1 停车系统集成 ```java @Service public class ParkingIntegrationService { @Autowired private IntegrationAdapterRepository adapterRepository; @Autowired private IntegrationLogRepository logRepository; // 同步车位状态 public void syncParkingSpaceStatus(UUID projectId) { IntegrationAdapter adapter = adapterRepository .findByProjectIdAndSystemType(projectId, "PARKING") .orElseThrow(() -> new NotFoundException("停车系统适配器未配置")); try { // 调用停车系统API String response = callExternalApi(adapter, "/api/parking/spaces", "GET", null); // 解析响应 List spaces = parseResponse(response); // 更新本地车位状态 for (ParkingSpaceDTO space : spaces) { updateLocalParkingSpace(space); } } catch (Exception e) { log.error("同步车位状态失败", e); throw new IntegrationException("同步车位状态失败: " + e.getMessage()); } } // 车牌识别通知 public void handlePlateRecognition(PlateRecognitionEvent event) { // 处理车牌识别结果 String plateNumber = event.getPlateNumber(); // 查询访客预约 Optional appointment = visitorService .findByPlateNumber(plateNumber); if (appointment.isPresent()) { // 访客车辆,自动抬杆 sendOpenGateCommand(event.getGateId()); // 记录通行 recordVehicleAccess(plateNumber, event.getGateId(), "VISITOR"); } else { // 业主车辆,查询业主信息 Optional owner = ownerService.findByPlateNumber(plateNumber); if (owner.isPresent()) { sendOpenGateCommand(event.getGateId()); recordVehicleAccess(plateNumber, event.getGateId(), "OWNER"); } else { // 陌生车辆,记录并提示 recordVehicleAccess(plateNumber, event.getGateId(), "UNKNOWN"); } } } } ``` ### 3.2 门禁系统集成 ```java @Service public class AccessIntegrationService { // 下发访客二维码到门禁 public void syncVisitorCredentialToAccess(UUID credentialId) { VisitorCredential credential = credentialRepository.findById(credentialId) .orElseThrow(() -> new NotFoundException("凭证不存在")); // 查询门禁系统适配器 IntegrationAdapter adapter = adapterRepository .findByProjectIdAndSystemType(credential.getProjectId(), "ACCESS") .orElseThrow(() -> new NotFoundException("门禁系统适配器未配置")); // 构建下发数据 AccessCredentialDTO dto = new AccessCredentialDTO(); dto.setCredentialCode(credential.getCredentialCode()); dto.setQrCode(credential.getQrCode()); dto.setExpireTime(credential.getExpireTime()); dto.setAccessGates(parseAccessGates(credential.getAccessGates())); // 调用门禁系统API callExternalApi(adapter, "/api/access/credentials", "POST", dto); } // 接收门禁通行记录 @PostMapping("/webhook/access/record") public void receiveAccessRecord(@RequestBody AccessRecordDTO record) { // 保存通行记录 VisitorAccessRecord accessRecord = new VisitorAccessRecord(); accessRecord.setId(UUID.randomUUID()); accessRecord.setCredentialCode(record.getCredentialCode()); accessRecord.setAccessTime(record.getAccessTime()); accessRecord.setGateId(record.getGateId()); accessRecord.setAccessType(record.getAccessType()); // ENTRY/EXIT accessRecord.setPhotoUrl(record.getPhotoUrl()); accessRecordRepository.save(accessRecord); // 更新凭证使用记录 credentialService.updateCredentialUsage(record.getCredentialCode()); // 通知被访人 notificationService.notifyHost(accessRecord); } } ``` ### 3.3 IoT设备接入 ```java @Service public class IoTDeviceService { @Autowired private MqttClient mqttClient; // 设备数据监听 @EventListener public void onDeviceMessage(DeviceMessageEvent event) { String deviceId = event.getDeviceId(); String payload = event.getPayload(); // 查询设备 IoTDevice device = deviceRepository.findByDeviceId(deviceId) .orElse(null); if (device == null) { log.warn("未知设备: {}", deviceId); return; } // 更新设备状态 device.setLastPayload(payload); device.setLastReportTime(LocalDateTime.now()); device.setStatus(DeviceStatus.ONLINE); device.setLastOnlineTime(LocalDateTime.now()); deviceRepository.save(device); // 解析数据 DeviceData data = parseDeviceData(device.getDeviceType(), payload); // 根据设备类型处理 switch (device.getDeviceType()) { case "TEMPERATURE_SENSOR": handleTemperatureData(device, data); break; case "HUMIDITY_SENSOR": handleHumidityData(device, data); break; case "SMOKE_DETECTOR": handleSmokeAlarm(device, data); break; case "WATER_LEAK_DETECTOR": handleWaterLeakAlarm(device, data); break; default: log.info("未处理的设备类型: {}", device.getDeviceType()); } } // 处理烟雾报警 private void handleSmokeAlarm(IoTDevice device, DeviceData data) { Boolean smokeDetected = data.getBoolean("smokeDetected"); if (smokeDetected) { // 创建紧急工单 WorkOrder workOrder = new WorkOrder(); workOrder.setOrderType(WorkOrderType.EMERGENCY); workOrder.setTitle("烟雾报警: " + device.getDeviceName()); workOrder.setDescription("设备位置: " + device.getSpaceNodeId() + "\n报警时间: " + LocalDateTime.now()); workOrder.setPriority(WorkOrderPriority.URGENT); workOrder.setSource(WorkOrderSource.IOT); workOrder.setEquipmentId(device.getEquipmentId()); workOrder.setSpaceNodeId(device.getSpaceNodeId()); workOrderService.create(workOrder); // 发送紧急通知 notificationService.sendEmergencyAlert(device, "烟雾报警"); } } // 下发命令到设备 public void sendCommandToDevice(String deviceId, String command, Map params) { IoTDevice device = deviceRepository.findByDeviceId(deviceId) .orElseThrow(() -> new NotFoundException("设备不存在")); // 构建MQTT消息 MqttMessage message = new MqttMessage(); message.setTopic(device.getMqttTopic() + "/command"); Map payload = new HashMap<>(); payload.put("command", command); payload.put("params", params); payload.put("timestamp", System.currentTimeMillis()); message.setPayload(JsonUtils.toJson(payload).getBytes()); // 发送消息 mqttClient.publish(message); } } ``` --- ## 四、集成适配器框架 ### 4.1 适配器接口 ```java // 集成适配器接口 public interface IntegrationAdapterClient { // 发送请求 String sendRequest(String operation, String method, String path, Map headers, Object body); // 健康检查 boolean healthCheck(); // 获取适配器信息 AdapterInfo getAdapterInfo(); } // HTTP适配器实现 @Component public class HttpIntegrationAdapter implements IntegrationAdapterClient { @Autowired private RestTemplate restTemplate; private IntegrationAdapter config; public HttpIntegrationAdapter(IntegrationAdapter config) { this.config = config; } @Override public String sendRequest(String operation, String method, String path, Map headers, Object body) { String url = config.getBaseUrl() + path; // 构建请求头 HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(MediaType.APPLICATION_JSON); // 添加认证信息 addAuthenticationHeaders(httpHeaders); // 添加自定义头 if (headers != null) { headers.forEach(httpHeaders::add); } // 构建请求体 HttpEntity entity = new HttpEntity<>(body, httpHeaders); // 发送请求 ResponseEntity response = restTemplate.exchange( url, HttpMethod.valueOf(method), entity, String.class ); return response.getBody(); } private void addAuthenticationHeaders(HttpHeaders headers) { String authType = config.getAuthType(); String authConfig = config.getAuthConfig(); switch (authType) { case "API_KEY": Map apiKeyConfig = JsonUtils.fromJson(authConfig, Map.class); String location = apiKeyConfig.get("location"); if ("header".equals(location)) { headers.add(apiKeyConfig.get("key"), apiKeyConfig.get("value")); } break; case "OAUTH2": String token = getOAuth2Token(authConfig); headers.setBearerAuth(token); break; case "BASIC": Map basicConfig = JsonUtils.fromJson(authConfig, Map.class); String credentials = basicConfig.get("username") + ":" + basicConfig.get("password"); String encoded = Base64.getEncoder().encodeToString(credentials.getBytes()); headers.setBasicAuth(encoded); break; } } @Override public boolean healthCheck() { try { sendRequest("healthCheck", "GET", "/health", null, null); return true; } catch (Exception e) { return false; } } } ``` ### 4.2 集成日志记录 ```java @Aspect @Component public class IntegrationLogAspect { @Autowired private IntegrationLogRepository logRepository; @Around("execution(* com.ether.hub.client.IntegrationAdapterClient.*(..))") public Object around(ProceedingJoinPoint point) throws Throwable { // 获取方法参数 Object[] args = point.getArgs(); String operation = (String) args[0]; String method = (String) args[1]; String path = (String) args[2]; Map headers = (Map) args[3]; Object body = args[4]; // 创建日志 IntegrationLog log = new IntegrationLog(); log.setId(UUID.randomUUID()); log.setRequestId(UUID.randomUUID().toString()); log.setOperation(operation); log.setRequestMethod(method); log.setRequestUrl(path); log.setRequestHeaders(JsonUtils.toJson(headers)); log.setRequestBody(JsonUtils.toJson(body)); log.setRequestTime(LocalDateTime.now()); long startTime = System.currentTimeMillis(); try { // 执行目标方法 Object result = point.proceed(); // 记录成功 log.setResponseBody((String) result); log.setHttpStatus(200); log.setStatus(LogStatus.SUCCESS); return result; } catch (Exception e) { // 记录失败 log.setStatus(LogStatus.FAIL); log.setErrorMessage(e.getMessage()); throw e; } finally { log.setDurationMs(System.currentTimeMillis() - startTime); log.setResponseTime(LocalDateTime.now()); log.setCreatedAt(LocalDateTime.now()); // 异步保存日志 logRepository.save(log); } } } ``` --- ## 五、API 接口 ```java @RestController @RequestMapping("/api/v1/hub") @Tag(name = "集成中心") public class IntegrationController { // 适配器管理 @PostMapping("/adapters") @Operation(summary = "创建适配器") public Result createAdapter(@RequestBody @Valid AdapterCreateRequest request); @GetMapping("/adapters") @Operation(summary = "查询适配器列表") public Result> listAdapters(); @GetMapping("/adapters/{id}") @Operation(summary = "获取适配器详情") public Result getAdapter(@PathVariable UUID id); @PutMapping("/adapters/{id}") @Operation(summary = "更新适配器") public Result updateAdapter(@PathVariable UUID id, @RequestBody @Valid AdapterUpdateRequest request); @DeleteMapping("/adapters/{id}") @Operation(summary = "删除适配器") public Result deleteAdapter(@PathVariable UUID id); @PostMapping("/adapters/{id}/test") @Operation(summary = "测试连接") public Result testConnection(@PathVariable UUID id); // 集成日志 @GetMapping("/logs") @Operation(summary = "查询集成日志") public Result> pageLogs(IntegrationLogQueryRequest request); // IoT设备管理 @PostMapping("/iot-devices") @Operation(summary = "注册IoT设备") public Result registerDevice(@RequestBody @Valid IoTDeviceRegisterRequest request); @GetMapping("/iot-devices") @Operation(summary = "查询设备列表") public Result> listDevices(); @PostMapping("/iot-devices/{id}/command") @Operation(summary = "发送设备命令") public Result sendDeviceCommand(@PathVariable UUID id, @RequestBody DeviceCommandRequest request); // 数据映射 @PostMapping("/data-mappings") @Operation(summary = "创建数据映射") public Result createDataMapping(@RequestBody @Valid DataMappingCreateRequest request); @PostMapping("/data-mappings/{id}/transform") @Operation(summary = "测试数据转换") public Result> testTransform(@PathVariable UUID id, @RequestBody Map sourceData); } ``` --- ## 六、实现状态与差异 ### 6.1 实现状态 | 功能模块 | 实现状态 | 备注 | |---------|---------|------| | IntegrationAdapter | 🔴 未实现 | 待开发 | | IntegrationLog | 🔴 未实现 | 待开发 | | IoTDevice | 🔴 未实现 | 待开发 | | DataMapping | 🔴 未实现 | 待开发 | | 停车系统集成 | 🔴 未实现 | 待开发 | | 门禁系统集成 | 🔴 未实现 | 待开发 | | IoT接入 | 🔴 未实现 | 待开发 | ### 6.2 与设计方案的差异 | 设计项 | 设计方案 | 现有实现 | 差异分析 | |--------|----------|----------|----------| | **ether-hub服务** | 完整实现 | 未创建 | 🔴 整个服务缺失 | | **外部系统集成** | 停车/门禁/政府 | 未实现 | 🔴 功能缺失 | | **IoT接入** | MQTT/CoAP | 未实现 | 🔴 功能缺失 | ### 6.3 改进计划 | 优先级 | 改进项 | 说明 | |--------|--------|------| | P2 | 创建ether-hub服务 | 新建集成中心微服务 | | P3 | 实现停车集成 | 对接停车系统API | | P3 | 实现门禁集成 | 对接门禁系统 | | P3 | 实现IoT接入 | MQTT Broker配置 | --- ## 七、数据库表结构 ```sql -- 集成适配器表 CREATE TABLE hub_integration_adapter ( id UUID PRIMARY KEY, project_id UUID NOT NULL, name VARCHAR(100) NOT NULL, system_type VARCHAR(50) NOT NULL, description VARCHAR(500), protocol VARCHAR(20) NOT NULL, base_url VARCHAR(255) NOT NULL, timeout INTEGER DEFAULT 30, retry_count INTEGER DEFAULT 3, auth_type VARCHAR(20) NOT NULL, auth_config JSONB, status VARCHAR(20) DEFAULT 'OFFLINE', last_ping_time TIMESTAMP, last_error_message TEXT, enabled BOOLEAN DEFAULT TRUE, created_at TIMESTAMP NOT NULL DEFAULT NOW(), updated_at TIMESTAMP NOT NULL DEFAULT NOW() ); -- 集成日志表 CREATE TABLE hub_integration_log ( id UUID PRIMARY KEY, adapter_id UUID NOT NULL, request_id VARCHAR(50) NOT NULL, operation VARCHAR(100) NOT NULL, request_method VARCHAR(10) NOT NULL, request_url VARCHAR(255) NOT NULL, request_headers JSONB, request_body TEXT, request_time TIMESTAMP NOT NULL, response_body TEXT, http_status INTEGER, response_headers JSONB, response_time TIMESTAMP, duration_ms BIGINT, status VARCHAR(20) NOT NULL, error_message TEXT, error_stack TEXT, created_at TIMESTAMP NOT NULL DEFAULT NOW() ); -- IoT设备表 CREATE TABLE hub_iot_device ( id UUID PRIMARY KEY, project_id UUID NOT NULL, device_id VARCHAR(100) NOT NULL, device_name VARCHAR(100) NOT NULL, device_type VARCHAR(50) NOT NULL, protocol VARCHAR(20) NOT NULL, equipment_id UUID, space_node_id UUID, mqtt_broker VARCHAR(255), mqtt_port INTEGER, mqtt_topic VARCHAR(255), mqtt_client_id VARCHAR(100), last_payload TEXT, last_report_time TIMESTAMP, status VARCHAR(20) DEFAULT 'OFFLINE', last_online_time TIMESTAMP, created_at TIMESTAMP NOT NULL DEFAULT NOW(), updated_at TIMESTAMP NOT NULL DEFAULT NOW(), UNIQUE(project_id, device_id) ); -- 数据映射表 CREATE TABLE hub_data_mapping ( id UUID PRIMARY KEY, project_id UUID NOT NULL, adapter_id UUID, name VARCHAR(100) NOT NULL, entity_type VARCHAR(50) NOT NULL, field_mappings JSONB, transform_rules JSONB, enabled BOOLEAN DEFAULT TRUE, created_at TIMESTAMP NOT NULL DEFAULT NOW(), updated_at TIMESTAMP NOT NULL DEFAULT NOW() ); -- 创建索引 CREATE INDEX idx_adapter_project ON hub_integration_adapter(project_id); CREATE INDEX idx_adapter_system ON hub_integration_adapter(system_type); CREATE INDEX idx_adapter_status ON hub_integration_adapter(status); CREATE INDEX idx_log_adapter ON hub_integration_log(adapter_id); CREATE INDEX idx_log_request ON hub_integration_log(request_id); CREATE INDEX idx_log_created ON hub_integration_log(created_at); CREATE INDEX idx_iot_device_project ON hub_iot_device(project_id); CREATE INDEX idx_iot_device_status ON hub_iot_device(status); CREATE INDEX idx_mapping_project ON hub_data_mapping(project_id); ``` --- **文档维护**: 本领域技术方案由 ether-hub 服务负责人维护