8.2 KiB
8.2 KiB
05 门禁集成适配器架构与厂商无关接口设计 (Adapter Architecture)
设计核心:强边界解耦与高内聚设计。 住宿业务层(Accommodation Service)对外部物联网厂商的协议细节、Token、URL、整数请求类型完全无感知。 针对门禁控制定义厂商中立的抽象网关接口 (
DoorAccessGateway),DMS 专用协议转换完全收敛在DmsAccessAdapter。
1. 系统分层集成架构图 (Mermaid)
flowchart TD
subgraph UI_Layer["前端与接入层 (Web / Controller)"]
AC["TrainAccommodationController\n(住宿分配 / 换房 / 退宿)"]
DC["TrainDoorAccessController\n(门禁状态查询 / 重试 / 受控应急)"]
end
subgraph Business_Layer["核心业务领域层 (Domain Service)"]
AS["TrainAccommodationService\n(维护住宿事实真源 / 状态推进)"]
AGS["DoorAccessOrchestrationService\n(授权编排: 提早下发 / 补偿 / 批量处理)"]
end
subgraph Gateway_Boundary["厂商无关抽象边界 (Vendor-Agnostic Gateway)"]
DAG["<<interface>>\nDoorAccessGateway\n+grantAccess(GrantCommand): OperationResult\n+revokeAccess(RevokeCommand): OperationResult\n+queryOperation(QueryCommand): OperationStatusResult\n+queryLockHealth(HealthCommand): LockHealthResult\n+remoteUnlock(UnlockCommand): OperationResult"]
end
subgraph Integration_DMS["DMS 专用集成适配层 (ruoyi-train/integration/dms)"]
ADAPTER["DmsDoorAccessGateway\n(协议转换 / 参数映射 / 状态归一化)"]
subgraph DMS_Core["DMS 核心支撑组件"]
TM["DmsTokenManager\n(单飞互斥登录 / 缓存 / 401自愈)"]
PROP["DmsProperties\n(受控环境变量配置)"]
POLLER["DmsOperationPoller\n(Spring/Quartz 10秒对账轮询器)"]
end
subgraph Clients["细分领域 HTTP 客户端 (Feign / RestTemplate)"]
PLC["DmsPlaceClient\n(楼栋/楼层/房间查询)"]
DLC["DmsDoorLockClient\n(门锁列表/电量信号)"]
KC["DmsKeyClient\n(在线密码/在线卡片)"]
OPC["DmsOperationClient\n(query-operation-status)"]
end
end
subgraph Remote_DMS["外部物联网云平台 (DMS IoT Platform)"]
CLOUD["DMS REST API\n(https://dms.dmsiot.com)"]
end
AC --> AS
DC --> AGS
AS --> AGS
AGS --> DAG
DAG <|.. ADAPTER : 实现
ADAPTER --> TM
ADAPTER --> PROP
ADAPTER --> PLC
ADAPTER --> DLC
ADAPTER --> KC
ADAPTER --> OPC
POLLER --> DAG
PLC --> CLOUD
DLC --> CLOUD
KC --> CLOUD
OPC --> CLOUD
2. 厂商无关内部标准接口契约 (Vendor-Agnostic Interface)
为确保沈阳房建公寓段学员管理系统未来平滑支持其他设备供应商(如海康威视、大华或铁路专用门禁系统),设计中立门禁网关接口 DoorAccessGateway:
package com.ruoyi.train.integration.gateway;
import com.ruoyi.train.integration.gateway.dto.*;
/**
* 厂商中立门禁系统服务网关接口
* 严禁在该接口及方法签名中暴露任何具体厂商(如 DMS)的特定字段、类名或数字枚举。
*/
public interface DoorAccessGateway {
/**
* 下发门禁通行授权 (支持在线密码、在线卡片等凭据)
*
* @param command 统一授权下发指令 (包含目标房间、门锁标识、学员信息、时间窗口、凭据要求)
* @return 异步操作受理结果 (包含本地操作ID、外部受理ID、初步状态)
*/
AccessOperationResult grantAccess(GrantAccessCommand command);
/**
* 撤销已生效或下发中的门禁授权 (退宿、退训、换房时调用)
*
* @param command 统一撤销指令 (包含外部钥匙ID、目标硬件标识等)
* @return 异步操作受理结果
*/
AccessOperationResult revokeAccess(RevokeAccessCommand command);
/**
* 统一查询异步操作执行状态 (对账轮询)
*
* @param command 操作状态查询指令 (包含 operationId, hardwareId, 原始业务类型)
* @return 归一化后的设备执行结果 (SUCCESS, UNDONE, FAILED, TIMEOUT)
*/
OperationStatusResult queryOperationStatus(QueryOperationCommand command);
/**
* 查询指定房间/门锁的物理运行健康度 (电量、信号、在线状态)
*
* @param command 查询健康度指令
* @return 归一化设备健康度指标
*/
DeviceHealthResult queryDeviceHealth(QueryHealthCommand command);
/**
* 紧急远程开锁 (受控应急功能,仅限特定权限管理员并记录审计追踪)
*
* @param command 远程开锁指令 (必须携带操作人、两票审核号、操作原因)
* @return 异步操作受理结果
*/
AccessOperationResult remoteUnlock(RemoteUnlockCommand command);
}
3. 推荐工程目录结构规范 (Package Structure)
后续 R.3B 实现时,建议在 ruoyi-train 模块中创建如下包结构,本阶段仅冻结设计,禁止创建 Java 文件:
ruoyi-train
└── src/main/java/com/ruoyi/train
├── domain # 领域实体 (TrainAccommodation, TrainDormitoryInfo, etc.)
├── service # 核心业务服务 (ITrainAccommodationService, etc.)
└── integration # 外部集成根包
├── gateway # 【厂商无关抽象层】
│ ├── DoorAccessGateway.java
│ ├── dto # 统一标准入参/出参 DTO
│ │ ├── GrantAccessCommand.java
│ │ ├── RevokeAccessCommand.java
│ │ ├── AccessOperationResult.java
│ │ └── OperationStatusResult.java
│ └── enums # 标准业务枚举 (CredentialType, NormalizedOpStatus)
└── dms # 【DMS 厂商专用集成适配层】
├── config # 配置类 (DmsProperties, DmsConfiguration)
├── auth # 认证与 Token 管理 (DmsTokenManager, DmsTokenResponse)
├── client # 底层 HTTP 交互客户端
│ ├── DmsBaseClient.java
│ ├── DmsPlaceClient.java
│ ├── DmsDoorLockClient.java
│ ├── DmsKeyClient.java
│ └── DmsOperationClient.java
├── dto # DMS 原始报文映射 DTO (只在 integration.dms 内部可见)
│ ├── request # DMS 专用请求实体 (如 DmsOnlinePasswordCreateRequest)
│ └── response # DMS 专用响应实体 (如 DmsApiResponse, DmsKeyData)
├── adapter # 核心适配器实现
│ └── DmsDoorAccessGateway.java (实现 DoorAccessGateway 接口)
├── scheduler # 异步任务与定时对账
│ └── DmsOperationPoller.java (10秒延迟轮询与超时处理)
└── util # 专用编码工具 (CardNumberCodec: 读卡器十进制与16进制小端转换)
4. 适配器边界与职责隔离红线 (Adapter Boundary Rules)
- DTO 边界完全隔离:
- DMS 的返回体对象(如
DmsApiResponse<DmsKeyData>)的生命周期绝不允许超出com.ruoyi.train.integration.dms包范围。 DmsDoorAccessGateway必须负责将其翻译为中立的AccessOperationResult,禁止向上层抛出 DMS 内部原始 JSON。
- DMS 的返回体对象(如
- 状态与数字编码归一化:
- DMS 使用数字
requestType(1=下发密码, 2=在线卡片, 3=删除密码, 5=远程开锁)。业务 Service 严禁传递数字 1 或 3,必须传递强类型枚举CredentialOperationType.PASSWORD_GRANT。适配器内部完成枚举到数字requestType的转换。 - DMS 返回的
operationStatus字符串("undone","success","failed","timeout")由适配器转换为内部标准领域枚举NormalizedOperationStatus。
- DMS 使用数字
- 第三方异常吞吐隔离:
- 外部网络超时、401 故障、DMS 内部报错统一由适配器包装为
IntegrationException及其子类,不得泄露第三方平台的底层堆栈至前端。
- 外部网络超时、401 故障、DMS 内部报错统一由适配器包装为