11 KiB
11 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 内部报错统一由适配器包装为
5. Wave 1 Implementation Result (Wave 1 implemented)
- 阶段状态:Wave 1 implemented。
- 持久化层落地:
- 完成外部资源映射实体
TrainExternalResourceMapping与操作流水实体TrainExternalOperation。 - 完成持久化 Mapper 与 Service (
IExternalResourceMappingService,IExternalOperationService)。 - 落地
train_external_resource_mapping(支持一房多锁、Active 唯一性)与train_external_operation(支持 DoorAuthorization 1:N 流水追踪)。
- 完成外部资源映射实体
- 零外部耦合红线:
- 本 Wave 严格保持
DMS_HTTP_CLIENT_COUNT = 0,DMS_TOKEN_MANAGER_COUNT = 0。 - 零 RestTemplate / WebClient / HttpClient 网络调用,零明文敏感凭据。
- 本 Wave 严格保持
- 数据库 Migration:
008_external_resource_operation.sql验证通过,生产库未执行。
6. Wave 2 Implementation Result (Wave 2 implemented against Mock DMS only)
- 阶段状态:Wave 2 implemented against Mock DMS only。
- 适配层核心交付清单:
config/DmsProperties:受控配置中心,dms.enabled = false(安全默认),支持参数化超时、提前刷新窗口、Token Cookie 头名称。auth/DmsTokenManager:全应用唯一集中 Token 缓存,基于 ReentrantLock + DCL 的 Single-Flight 并发互斥锁,支持滑动延展 (markSuccessfulUse) 与 401 集中失效自愈。client/DmsHttpClient:基础底层 HTTP 客户端,统一 Cookie 传输,脱敏日志(密码、Token、Secret 全程保护),写操作读取超时严禁盲目自动重试 (AMBIGUOUS_MUTATION_AUTO_RETRY = NO)。client/DmsLocationClient与gateway/ExternalLocationGateway:位置资源查询与 Place 空间定位。client/DmsDoorLockClient与gateway/ExternalDoorLockGateway:门锁适配器,严格支持 0 把锁(返回空列表,非 NPE)、1 把锁与多把锁(完整返回全部锁)。client/DmsPasswordClient与gateway/ExternalCredentialGateway:在线限时密码创建与删除适配器,支持 4~8 位数字,密码明文内存短暂留存,零落库零输出。client/DmsOperationStatusClient与gateway/DmsOperationStatusMapper:异步状态查询与集中映射器(success->SUCCESS, undone->PENDING, failed->FAILED, timeout->TIMEOUT, 未知状态->UNKNOWN 严禁判定为 SUCCESS)。poller/DmsOperationPoller:异步对账轮询调度器,仅在dms.enabled=true启用,单进程并发防重,终态不可篡改保护,错误分类退避持久化。mock/MockDmsServer:轻量内嵌测试服务器,精准模拟 DMS 服务端登录互斥、读超时、多锁/零锁与状态流转。
- 环境纪律与迁移标记:
DMS_DEFAULT_ENABLED = FALSELIVE_DMS_REQUEST_COUNT = 0FRONTEND_MODIFIED = 0008_RUNTIME_FIRST_RUN = NOT_EXECUTED,008_RUNTIME_SECOND_RUN = NOT_EXECUTEDRUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED