Files
SecMPS/doc/设计文档/KMS钥匙柜适配器详细设计文档_任务清单.md

13 KiB
Raw Blame History

KMS 钥匙柜适配器 — 任务清单

基准文档: doc/设计文档/KMS钥匙柜适配器详细设计文档.md v2.1 分支: gateway-dev 原则: 严格按照设计文档执行,严禁无中生有。网关/Vol.Pro 改动放倒数第二步,联调放最后。


Phase K0: 项目骨架(预计 15min

K0.1 创建适配器项目

  • gateway/src/ 下执行 dotnet new classlib -n IntegrationGateway.Adapters.Kms -f net8.0
  • 删除自动生成的 Class1.cs
  • 添加项目引用:dotnet add reference ../IntegrationGateway.Core/IntegrationGateway.Core.csproj
  • 将项目加入解决方案:dotnet sln add

K0.2 Host 引用适配器

  • dotnet add Host reference Adapters.Kms

K0.3 编译验证

  • dotnet build → 0 错误

K0 提交点: PhaseK0_scaffold — Kms适配器项目骨架就绪


Phase K1: KmsModels — 数据模型(预计 1h

K1.1 认证模型

  • 创建 KmsModels.cs
  • 添加 KmsTokenResponse { Code, Token, Msg }

K1.2 第三方接口响应模型2.18.X

  • KmsOpenerListResponse { Code, Msg, Rows }
  • KmsLocker { LockerId, LockerName, LockerCode, LockholeList }
  • KmsLockhole { LockholeSort, OpenerId, OpenerName, OpenerType, OpenerState }
  • KmsWarningListResponse { Code, Msg, Total, Rows }
  • KmsWarning { Uuid, LockerName, LockholeSort, OpenerName, Type, WarningTime, Remark, StaffName }
  • KmsRecordListResponse { Code, Msg, Total, Rows }
  • KmsRecord { Uuid, LockerName, LockholeSort, OpenerName, StaffName, BorrowTime, ReturnTime, Type }

K1.3 标准接口响应模型2.3-2.17

  • KmsHandoverInfo — 交接记录
  • KmsPermissionListResponse + KmsPermission — 授权记录
  • KmsStaffListResponse + KmsStaff — 员工
  • KmsLockerListResponse + KmsLockerInfo — 柜体
  • KmsLockholeListResponse + KmsLockholeInfo — 锁孔
  • KmsOpenerListResponse2 + KmsOpenerInfo — 钥匙
  • KmsStaffOpenerListResponse + KmsStaffOpener — 员工可借
  • KmsRemotePermissionRequest — 远程授权请求(联调时确认字段)

K1.4 编译验证

  • dotnet build → 0 错误DTO 引用 Core 的 StandardDevice/StandardAlarm 等确认无编译错误)

K1 提交点: PhaseK1_models — KmsModels.cs 完整定义全部 15 个 DTO


Phase K2: KmsAuthHelper — 认证(预计 30min

K2.1 创建 KmsAuthHelper.cs

  • 构造函数:接收 HttpClient, baseUrl, clientId, clientSecret
  • 属性:_token (string?), _tokenExpiry (DateTime)
  • 依赖:System.Text.Json, System.Net.Http.Json

K2.2 GetTokenAsync

  • POST /prod-api/getToken?clientId=xx&clientSecret=yy
  • 检查 resp.EnsureSuccessStatusCode()
  • 反序列化 KmsTokenResponse
  • 校验 Code == 200
  • 缓存 Token过期时间 = UtcNow.AddMinutes(25)30 分钟效期5 分钟余量)

K2.3 GetAuthenticatedClientAsync

  • 调用 GetTokenAsync()
  • 创建新 HttpClientBaseAddress = _baseUrl
  • 设置 Header Authorization: Bearer {token}
  • 返回 client

K2.4 Invalidate

  • _token = null 强制下次重新获取

K2.5 编译验证

  • dotnet build → 0 错误

K2 提交点: PhaseK2_auth — KmsAuthHelper Bearer Token 认证就绪


Phase K3: KmsAdapter 核心方法(预计 1.5h

K3.1 类定义与构造函数

  • public class KmsAdapter : IHasFlatDevices, IHasAlarms
  • 字段:_http, _auth (KmsAuthHelper), _limiter (RateLimiter(5))
  • 属性:AdapterCode, DisplayName, Capabilities { HasFlatDevices=true, HasAlarms=true }
  • 构造函数:注入 httpClient, baseUrl, clientId, clientSecret

K3.2 InitializeAsync

  • await _auth.GetTokenAsync()

K3.3 HealthCheckAsync2.18.1

  • POST /prod-api/heartBeat (空 body {})
  • 返回 resp.IsSuccessStatusCode
  • 异常捕获返回 false

K3.4 GetDevicesAsync2.18.4 — 柜体+锁孔 → StandardDevice

  • await _limiter.WaitAsync()
  • POST /prod-api/getOpenerList (body {})
  • 反序列化 KmsOpenerListResponse
  • 遍历 Rows
    • 每个 KmsLockerMapLockerToDevice父设备SourceId=locker_{LockerId}
    • 每个 KmsLockholeMapLockholeToDevice子设备ParentSourceId=locker_{LockerId}
  • IsOnline 判断:OpenerState == "在位" → true
  • Extra 字典:{ openerId, openerType, openerState } / { lockerCode, lockholeCount }
  • 返回 PagedResult<StandardDevice>

K3.5 GetAlarmsAsync2.18.7 — 告警列表 → StandardAlarm

  • await _limiter.WaitAsync()
  • POST /prod-api/getWarningList (body {})
  • 反序列化 KmsWarningListResponse
  • 映射:AlarmId=uuid, Title="{lockerName} 锁孔{lockholeSort}: {openerName}", Status=Type==1?"未确认":"已结束", Level="普通"
  • 返回 PagedResult<StandardAlarm>

K3.6 ConfirmAlarmAsync / EndAlarmAsync

  • ConfirmAlarmAsync: POST /prod-api/kms/warning/confirm/{alarmId}
  • EndAlarmAsync: 留空实现KMS 第三方接口不提供结束告警)

K3.7 编译验证

  • dotnet build → 0 错误

K3 提交点: PhaseK3_adapter_core — KmsAdapter 核心4方法就绪(HealthCheck/GetDevices/GetAlarms/Confirm)


Phase K4: KmsAdapter 扩展方法(预计 1h

K4.1 GetBorrowRecordsAsync2.18.6

  • POST /prod-api/getRecordList
  • 参数:from, to DateTime?(联调时确认请求体格式)
  • 返回 PagedResult<KmsRecord>

K4.2 GetPermissionListAsync2.18.5

  • POST /prod-api/getPermissionList
  • 参数:from, to DateTime?
  • 返回 PagedResult<KmsPermission>

K4.3 BatchSyncStaffAsync2.18.3

  • POST /prod-api/batchSyncStaff
  • 请求体:new { staff = staffList }
  • resp.EnsureSuccessStatusCode()

K4.4 BatchDeleteStaffAsync2.18.2

  • POST /prod-api/batchDeleteStaff
  • 请求体:List<string> (staffUuid 数组)
  • resp.EnsureSuccessStatusCode()

K4.5 RemoteAuthorizeAsync2.4.3

  • POST /prod-api/kms/permission/remote
  • 请求体:KmsRemotePermissionRequest(联调确认字段)

K4.6 ThirdPlatLoginAsync2.18.8

  • POST /thirdPlatlogin?username={username}
  • 处理 302 重定向:返回 Location header 或响应体
  • 超时设置 15s

K4.7 编译验证

  • dotnet build → 0 错误

K4 提交点: PhaseK4_adapter_ext — 6个扩展方法全部就绪(记录/同步/授权/登录)


Phase K5: 配置与注册(预计 15min

K5.1 KmsConfig POCO

  • Program.cs 同级新增 KmsConfig
  • 属性:InstanceName?, BaseUrl, ClientId, ClientSecret

K5.2 appsettings.json

  • 新增 KMS 数组配置段
  • 配置项:InstanceName, BaseUrl, ClientId, ClientSecret

K5.3 Program.cs 注册

  • var kmsList = app.Configuration.GetSection("KMS").Get<List<KmsConfig>>() ?? new();
  • foreach 注册 KmsAdapter("KMS:{InstanceName}", http, baseUrl, clientId, clientSecret)
  • 适配器编码加入 adapterTypes 拼接

K5.4 编译验证

  • dotnet build → 0 错误

K5 提交点: PhaseK5_config — KMS多实例配置+Program.cs注册就绪


Phase K6: 编译与自测(预计 15min

K6.1 全量编译

  • dotnet build → 0 错误(确认 KMS 适配器不引入外部依赖)

K6.2 启动测试

  • dotnet run 启动网关
  • 检查控制台输出:[Gateway] N 个适配器已注册: Owl:main,MC4:31ku,KMS:main
  • 确认 KMS 初始化失败时打印错误但不阻塞

K6 提交点: PhaseK6_build — 网关全量编译通过 KMS适配器热加载不阻塞启动


Phase K7: 网关核心与 Host 扩展(预计 1.5h⚠️ 倒数第二步

说明: 此阶段按设计文档附录 B 新增 Core 能力接口 + B 组路由,遵循网关设计原则 §3.4。

K7.1 新增 IAcceptsControl 接口

  • 创建 Core/Abstractions/IAcceptsControl.cs
  • 方法:Task<ControlResult> SendControlAsync(sourceDeviceId, command, parameters)
  • 新增 Core/Models/ControlResult.cs{ Success, Message }

K7.2 新增 IHasBusinessLogs 接口

  • 创建 Core/Abstractions/IHasBusinessLogs.cs
  • 方法:Task<PagedResult<BusinessLogEntry>> GetBusinessLogsAsync(logType, from, to, page, size, filters)
  • 新增 Core/Models/BusinessLogEntry.cs{ LogId, LogType, DeviceSourceId, StaffName, Description, CreatedAt, Extra }

K7.3 新增 IAcceptsDataSync 接口

  • 创建 Core/Abstractions/IAcceptsDataSync.cs
  • 方法:Task<SyncResult> SyncDataAsync(dataType, items)
  • 方法:Task<SyncResult> DeleteDataAsync(dataType, ids)
  • 新增 Core/Models/SyncResult.cs{ SuccessCount, FailCount, Message }

K7.4 KmsAdapter 实现新接口

  • KmsAdapter 增加 : IAcceptsControl, IHasBusinessLogs, IAcceptsDataSync
  • SendControlAsync:调 RemoteAuthorizeAsynccommand="open" 时调 /kms/permission/remote
  • GetBusinessLogsAsync:按 logType 分发到 GetBorrowRecordsAsync / GetPermissionListAsync / 交接记录
  • SyncDataAsyncdataType="staff" 时调 BatchSyncStaffAsync
  • DeleteDataAsyncdataType="staff" 时调 BatchDeleteStaffAsync

K7.5 Program.cs 新增 B 组路由

  • POST /api/gateway/control/{adapter}IAcceptsControl.SendControlAsync
  • GET /api/gateway/logs/{adapter}IHasBusinessLogs.GetBusinessLogsAsync
  • POST /api/gateway/sync/{adapter}IAcceptsDataSync.SyncDataAsync
  • DELETE /api/gateway/sync/{adapter}IAcceptsDataSync.DeleteDataAsync

K7.6 编译验证

  • dotnet build → 0 错误

K7 提交点: PhaseK7_gateway — 3个新Core接口+4条B路由+KmsAdapter多接口实现


Phase K8: Vol.Pro 管理端配套(预计 1h⚠️ 倒数第二步

K8.1 数据字典补充

  • 管理端 → 字典管理 → 设备种类新增:"智能钥匙柜" / "钥匙位"

K8.2 前端操作列扩展

  • 编辑 web.vite/src/views/warehouse/device_manager/base_device.vue
  • onInited 的 render 函数中增加 DeviceGroup==='门禁设备' 分支
  • 显示 "开门" 按钮(调用网关 B8
  • 显示 "权限" 下拉菜单(永久授权/临时授权/取消授权)

K8.3 前端 API 调用

  • fetch() 调网关 http://localhost:5100/api/gateway/control/KMS:main
  • 请求体:{ sourceDeviceId, command: "open", parameters: { openerId, staffId } }

K8.4 编译验证

  • npm run dev → 无编译错误

K8 提交点: PhaseK8_volpro — 字典+前端操作按钮就绪


Phase K9: 联调验证(预计 3h⚠️ 最后

前置条件: KMS 服务端可访问,已分配 clientId/clientSecret

K9.1 认证联调

  • 网关启动 → KmsAdapter.InitializeAsync 成功获取 Token
  • Token 过期自动刷新验证
  • 错误 clientSecret → 网关控制台打印初始化失败日志

K9.2 设备同步联调2.18.4

  • /api/gateway/health 返回 KMS 适配器在线
  • /api/gateway/devices?adapter=KMS:main 返回柜体+锁孔设备树
  • 管理端 base_device 列表显示 KMS 设备AdapterCode=KMS:main

K9.3 告警同步联调2.18.7

  • /api/gateway/alarms/KMS:main 返回告警列表
  • 管理端 iot_alarm 表有记录

K9.4 远程控制联调2.4.3

  • /api/gateway/control/KMS:main → 远程开门 → KMS 端锁孔门开

K9.5 记录查询联调2.18.6

  • /api/gateway/logs/KMS:main?logType=borrow 返回借还记录

K9.6 员工同步联调2.18.3

  • /api/gateway/sync/KMS:main → 批量同步员工成功

K9.7 异常场景

  • KMS 服务离线 → /api/gateway/health 中 KMS 返回 unhealthy
  • KMS 恢复 → 下次心跳自动变 healthy
  • 并发请求超过 5 QPS → 限流生效不崩溃

K9.8 验收

  • 网关 + Vol.Pro + KMS 三端数据一致
  • 管理端可查看 KMS 设备树、告警
  • 前端可远程开门

K9 提交点: PhaseK9_integration — 全链路联调通过


任务总览

Phase 内容 文件数 预计
K0 项目骨架 2 15min
K1 KmsModels 全部 DTO 1 1h
K2 KmsAuthHelper 1 30min
K3 KmsAdapter 核心方法 1 1.5h
K4 KmsAdapter 扩展方法 1 1h
K5 配置与注册 3 15min
K6 编译自测 15min
K7 网关 Core + Host 扩展 6 1.5h
K8 Vol.Pro 管理端配套 2 1h
K9 联调验证 3h
合计 17 ~10h

版本: 1.0 / 2025-05-19 / 严格按照 KMS钥匙柜适配器详细设计文档.md v2.1 制订