# 钥匙柜(KMS)整合方案 v1.0 > **版本**: 1.0 > **日期**: 2025-05-19 > **数据源**: doc/对接文档/钥匙管理系统软件接口.docx > **架构**: IntegrationGateway 适配器模式 + Vol.Pro 管理端 --- ## 1. 现状分析 ### 1.1 KMS 系统概览 钥匙管理系统是一个独立的 REST API 服务,管理智能钥匙柜的硬件设备。 | 项目 | 说明 | |------|------| | 技术栈 | Java/Spring Boot (推测) | | 认证方式 | clientId/clientSecret → Bearer Token (30分钟) | | 数据模型 | 柜体(locker) → 锁孔(lockhole) → 钥匙(opener) | | 用户体系 | 员工(staff) + 员工组(staff group) | | 核心业务 | 借还记录、交接记录、远程授权、告警记录 | ### 1.2 KMS 第三方集成接口(第2.18节) KMS 预留了 8 个专用于第三方对接的接口: | 接口 | 路径 | 用途 | |------|------|------| | 心跳 | `/prod-api/kms/thirdparty/heartbeat` | 检测 KMS 存活 | | 批量删除员工 | `/prod-api/kms/staff/batchDelete` | 同步删除 | | 批量同步员工 | `/prod-api/kms/staff/batchSync` | 同步员工信息 | | 查询柜体钥匙 | `/prod-api/kms/thirdparty/locker/keys` | 获取所有柜体及其钥匙列表 | | 授权记录 | `/prod-api/kms/thirdparty/auth/records` | 查询远程授权历史 | | 借还记录 | `/prod-api/kms/thirdparty/borrow/records` | 查询借还日志 | | 告警记录 | `/prod-api/kms/thirdparty/alarm/records` | 查询告警列表 | | 事件记录 | `/prod-api/kms/thirdparty/event/records` | 查询系统事件 | 认证方式:所有接口需要在 `Authorization: Bearer ` 头中携带 Token。 ### 1.3 Vol.Pro 端现存钥匙相关模块 | 表/模块 | 说明 | 来源 | |----------|------|------| | `warehouse_keys` | 钥匙管理(自主) | Vol.Pro 代码生成 | | `warehouse_keyapply` | 钥匙领用申请 | Vol.Pro 代码生成 | | `warehouse_keylog` | 钥匙使用日志 | Vol.Pro 代码生成 | 这些是 Vol.Pro 自建的钥匙管理流程(申请→审批→记录),与硬件 KMS 系统平行运行。 --- ## 2. 整合策略 ### 2.1 核心决策 **KMS 作为一个独立的物联网子系统接入 IntegrationGateway**,与 Owl、MC4.0 平级。 通过适配器模式,KMS 的能力被抽象为统一的网关接口,Vol.Pro 管理端通过网关调用 KMS,无需直接对 KMS 编程。 ### 2.2 KMS 能力评估 | 能力 | KMS 支持 | 统一接口 | 实现优先级 | |------|:---:|------|:---:| | 设备列表 | ✅ (钥匙柜+钥匙) | `IHasFlatDevices` | Phase 1 | | 告警 | ✅ (告警记录) | `IHasAlarms` | Phase 1 | | 实时状态 | ❌ | 无 | — | | 远程控制 | ✅ (远程授权/开门) | `IAcceptsControl` (新增) | Phase 2 | | 借还记录 | ✅ | 新增接口 | Phase 2 | | 员工同步 | ✅ | 无 (单向推送) | Phase 2 | ### 2.3 设备模型映射 KMS 的物理拓扑是 **柜体 → 锁孔 → 钥匙**。映射到 `StandardDevice`: ``` KMS 柜体 (locker) → StandardDevice { DeviceGroup="门禁设备", DeviceCategory="智能钥匙柜", IsParent=true } KMS 锁孔 (lockhole) → StandardDevice { DeviceGroup="门禁设备", DeviceCategory="钥匙位", IsParent=false, ParentSourceId=柜体SourceId } (钥匙本身是一个逻辑实体,不映射为设备) ``` **示例**: ``` KMS "10位智能公共钥匙柜" (lockerId=25) ├── 钥孔1 "仓库大门钥匙" (lockholeSort=1) ├── 钥孔2 "机房钥匙" (lockholeSort=2) ├── ... └── 钥孔10 "配电室钥匙" (lockholeSort=10) ``` 每个锁孔又是一个 `StandardDevice`,其 `Extra` 字段承载钥匙状态(在位/离位/借出)。 --- ## 3. 网关改造 ### 3.1 新增 `IntegrationGateway.Adapters.Kms` ``` gateway/src/IntegrationGateway.Adapters.Kms/ ├── KmsAdapter.cs # IHasFlatDevices + IHasAlarms └── KmsAuthHelper.cs # clientId/clientSecret → Bearer Token ``` ### 3.2 KmsAuthHelper ```csharp /// 认证流程: POST /prod-api/kms/token?clientId=xxx&clientSecret=yyy → { code, token } /// Token 有效期 30 分钟, 过期前 5 分钟自动刷新 public class KmsAuthHelper { public async Task GetTokenAsync() { ... } public async Task GetAuthenticatedClientAsync() { ... } } ``` ### 3.3 KmsAdapter 能力接口 ```csharp public class KmsAdapter : IHasFlatDevices, IHasAlarms { public string AdapterCode { get; } // "KMS:main" public AdapterCapabilities Capabilities => new() { HasFlatDevices = true, HasAlarms = true }; // IHasFlatDevices: 查询柜体钥匙信息 → List public async Task> GetDevicesAsync(int page, int size, string? keyword) { // 调 2.18.4 GET /prod-api/kms/thirdparty/locker/keys // 展开为: 每个柜体 → 1个父设备, 每个锁孔 → 1个子设备 } // IHasAlarms: 查询告警记录 public async Task> GetAlarmsAsync(...) { // 调 2.18.7 GET /prod-api/kms/thirdparty/alarm/records // KMS 告警类型: 1=当前告警, 2=历史告警 } public async Task ConfirmAlarmAsync(string alarmId) { ... } public async Task EndAlarmAsync(string alarmId) { ... } } ``` ### 3.4 配置新增 ```json // appsettings.json { "KMS": { "InstanceName": "main", "BaseUrl": "http://192.168.1.50:8080", "ClientId": "your_client_id", "ClientSecret": "your_client_secret" } } ``` ### 3.5 Program.cs 注册 ```csharp var kmsList = app.Configuration.GetSection("KMS").Get>() ?? new(); foreach (var k in kmsList) registry.Register(new KmsAdapter($"KMS:{k.InstanceName ?? "default"}", http, k.BaseUrl, k.ClientId, k.ClientSecret)); ``` --- ## 4. Vol.Pro 管理端改动 ### 4.1 数据流向 ``` KMS 硬件柜 IntegrationGateway Vol.Pro ─────── ────────────── ────── 钥匙在位/离位 ────→ KmsAdapter.GetDevices ────→ base_device 表 (AdapterCode="KMS:main") (DeviceCategory="钥匙位") 告警事件 ────→ KmsAdapter.GetAlarms ────→ iot_alarm 表 远程授权开门 ←──── B-interface (Phase2) ←──── 管理端操作 ``` ### 4.2 不需要改的内容 - `warehouse_keys` / `warehouse_keyapply` / `warehouse_keylog` — 保留现有体系,不与 KMS 冲突 - `base_device` 表 — 已支持 `DeviceCategory="钥匙位"`、`DeviceGroup="门禁设备"` - 前端操作列 — 已预留 `AccessDeviceActions` / `AlarmDeviceActions` 骨架 - 管理端设备列表 — 自动显示 KMS 同步的设备 ### 4.3 需要新增的内容 | 项 | 说明 | |------|------| | KMS 数据字典项 | `设备种类` 字典增加 "智能钥匙柜"、"钥匙位" | | 前端 KMS 操作按钮 | `KeyDeviceActions.vue` — 显示钥匙状态 + 远程授权入口 (Phase 2) | --- ## 5. 数据映射表 ### 5.1 KMS 柜体 → StandardDevice | KMS 字段 | StandardDevice 字段 | |------|------| | lockerId | SourceId | | lockerName | Name | | "智能钥匙柜" | Category | | "门禁设备" | Group | | true | IsParent | | lockerCode | Extra.lockerCode | | online (健康检查) | IsOnline | ### 5.2 KMS 锁孔 → StandardDevice | KMS 字段 | StandardDevice 字段 | |------|------| | lockerId.lockholeSort | SourceId (组合) | | openerName (钥匙名) | Name | | "钥匙位" | Category | | "门禁设备" | Group | | false | IsParent | | lockerId | ParentSourceId | | openerState (在位/离位) | Extra.openerState | | openerType (永久授权/一次性授权/应急授权) | Extra.openerType | ### 5.3 KMS 告警 → StandardAlarm | KMS 字段 | StandardAlarm 字段 | |------|------| | uuid | AlarmId (SourceAlarmId) | | warningTime | OccurTime | | alarmType 映射 | Level (提示/普通/重要) | | lockerName + openerName | Title | | remark | Content | --- ## 6. 实施计划 | 阶段 | 内容 | 预计工时 | |------|------|:---:| | K1 | 创建 `IntegrationGateway.Adapters.Kms` 项目骨架 | 0.5h | | K2 | 实现 `KmsAuthHelper` (clientId/secret → Token) | 1h | | K3 | 实现 `KmsAdapter` — `IHasFlatDevices` (设备同步) | 2h | | K4 | 实现 `KmsAdapter` — `IHasAlarms` (告警同步) | 1h | | K5 | 网关配置 + Program.cs 注册 | 0.5h | | K6 | 字典补充(智能钥匙柜/钥匙位) | 0.5h | | K7 | 联调验证 (需 KMS 环境) | 2h | | K8 | Phase 2: 远程授权/开门 + 前端按钮 | 3h | --- > **风险**: KMS 的实际 API 路径和响应格式需在真实环境验证,文档中的路径格式可能与实际部署有差异(如 `/prod-api/kms/` 前缀可能变化)。