Files
SecMPS/doc/设计文档/网关KMS模块检查报告20260604.md

10 KiB
Raw Blame History

网关 KMS 模块检查报告 2026-06-04

基准文档: doc/对接文档/钥匙管理系统软件接口.docx (KMS API v1.0.4) 检查范围: gateway/src/IntegrationGateway.Adapters.Kms/ (KmsAdapter.cs / KmsAuthHelper.cs / KmsModels.cs) + Program.cs B10-B13 路由 方法: 逐接口比对文档 → 代码 → 路由


1. 覆盖率总览

模块 KMS 文档端点数 Gateway 覆盖 覆盖率
2.9 Token 获取 1 1 100%
2.18 开放接口 8 8 100%
总计 (Phase 1) 9 9 100%
2.3-2.17 标准接口 38 1 (确认告警) 3%

2. 逐接口检查

2.18.1 心跳 — GET /prod-api/heartBeat

检查项 Gateway 实现 文档规范 状态
请求方法 client.GetAsync(...) GET
请求路径 /prod-api/heartBeat /prod-api/heartBeat
请求体
错误处理 catch (Exception ex) { Console.Error.WriteLine; return false; }

2.18.2 批量删除员工 — POST /prod-api/batchDeleteStaff

检查项 Gateway 实现 文档规范 状态
请求方法 PostAsJsonAsync(...) POST
请求路径 /prod-api/batchDeleteStaff /prod-api/batchDeleteStaff
请求体 List<string> (staffUuid 数组) ["uuid1","uuid2",...]
参数类型 数组 数组 (v1.0.2 修正)

2.18.3 批量同步员工 — POST /prod-api/batchSyncStaff

检查项 Gateway 实现 文档规范 状态
请求方法 PostAsJsonAsync(...) POST
请求路径 /prod-api/batchSyncStaff /prod-api/batchSyncStaff
请求体 new { staff = staffList } staff 数组 ⚠️
account 字段 模型中有 Account? v1.0.4 新增 account ⚠️ 待验证

风险: 文档 v1.0.4 新增了 account (登录账号) 字段。KmsStaff 模型需确认包含此字段。网关包装为 { staff: [...] } 可能与 KMS 期望的裸数组不一致。

2.18.4 查询柜体钥匙 — POST /prod-api/getOpenerList

检查项 Gateway 实现 文档规范 状态
请求方法 POST POST
请求路径 /prod-api/getOpenerList /prod-api/getOpenerList
请求体 "{}" 无明确要求 / 空对象
响应 → StandardDevice 柜体→父设备, 锁孔→子设备 树状结构

2.18.5 查询授权记录 — POST /prod-api/getPermissionList

检查项 Gateway 实现 文档规范 状态
请求方法 POST POST
请求路径 /prod-api/getPermissionList /prod-api/getPermissionList
请求体 "{}" 授权记录业务对象 (含 lockerName, lendStaffName 等 20+ 字段) 🔴
时间范围 DateTime? from, DateTime? to 参数未传入请求体 beginApplyTime/endApplyTime 🔴
分页 page/size 参数未传入请求体 pageNum/pageSize 🔴

致命问题: 网关注入 from/to/page/size 参数但从未传入 KMS 请求体。代码注释 // 联调时加入时间范围 确认这是已知缺口。当前实现等价于无过滤全量查询,无法按时间范围分页。

2.18.6 查询借还记录 — POST /prod-api/getRecordList

与 2.18.5 完全相同的致命问题: from/to/page/size 参数未传入 KMS 请求体。此外文档标记 lockerNamelockholeSortopenerCnName 为必填字段,但网关传 "{}" 无这些字段。

2.18.7 查询告警记录 — POST /prod-api/getWarningList

检查项 Gateway 实现 文档规范 状态
请求方法 POST POST
请求路径 /prod-api/getWarningList /prod-api/getWarningList
请求体 "{}" 告警业务对象 (含 type, beginWarningTime 等) 🔴
时间范围 未传 beginWarningTime/endWarningTime 🔴
告警类型 未传 (type=1当前/2历史) 文档支持过滤 🔴
响应映射 Type==1 ? "未确认" : "已结束" type 1=当前告警, 2=历史告警 🔴

状态映射错误: type 字段在告警接口中表示 1=当前告警 / 2=历史告警,不是 1=未确认 / 2=已结束。代码将 type=1 映射为 Status="未确认"、type=2 映射为 Status="已结束",语义错误。正确的映射应该是 type=1 → "活跃", type=2 → "历史"。

2.18.8 单点登录 — POST /thirdPlatlogin

检查项 Gateway 实现 文档规范 状态
请求方法 POST POST
请求路径 /thirdPlatlogin?username={x} /thirdPlatlogin?username={x}
重定向处理 捕获 302, 返回 Location header 文档说明"调用成功后直接重定向"
超时 无显式设置 🟡

2.9 Token 获取 — POST /prod-api/getToken

检查项 Gateway 实现 文档规范 状态
请求方法 http.PostAsync(url, null) POST
参数位置 query string: ?clientId=&clientSecret= query string
响应校验 Code != 200 → 抛异常 code: 200 = 成功
缓存策略 25分钟 (30分钟效期-5分钟余量) 30分钟效期

注意: 文档 2.9.1 显示 POST /prod-api/getToken 参数在 body 中 ({ clientId, clientSecret }),但 2.9 节概述描述为 query 参数。两种方式 KMS 可能都支持。当前实现用 query string联调时需确认兼容。


3. 模型映射核对

3.1 KMS 柜体 → StandardDevice

文档字段 代码映射 准确性
lockerId SourceId = $"locker_{lockerId}"
lockerName Name = lockerName
lockerCode Extra["lockerCode"]
lockholeList 遍历展开为子设备
IsParent true

3.2 KMS 锁孔 → StandardDevice

文档字段 代码映射 准确性
lockholeSort SourceId = $"lockhole_{lockerId}_{lockholeSort}"
openerName Name = openerName
openerType Extra["openerType"] (1/2/3 数值)
openerState Extra["openerState"] + IsOnline = (openerState=="在位") 🔴
ParentSourceId $"locker_{lockerId}"

openerState 映射错误: 根据文档数据字典§4openerState 是数值编码:

  • 1 = 在柜
  • 2 = 借出
  • 3 = 录入
  • 10 = 丢失

代码用 openerState == "在位" 做字符串比较,永远不成立。需改为 openerState == "1" 或解析为 int 后判断。

3.3 KMS 借还记录 → BusinessLogEntry

文档字段 代码映射 准确性
uuid LogId
lockerName 拼入 DeviceSourceId
staffName StaffName
borrowTime CreatedAt
openerName Description (不充分) 🟡

3.4 KMS 告警 → StandardAlarm

文档字段 代码映射 准确性
uuid AlarmId
warningTime OccurTime
remark Content
type (1/2) Status = Type==1 ? "未确认""已结束" 🔴
level 固定 "普通" 🟡

type 语义错误: 见 2.18.7 说明。文档明确 type 表示告警分类(1=当前,2=历史),而非确认状态。


4. B 路由链路检查

B 路由 对应 KMS 能力 适配器方法 参数传递 状态
B1 /health 心跳 2.18.1 HealthCheckAsync
B2 /devices 柜体钥匙 2.18.4 GetDevicesAsync
B8 /alarms 告警 2.18.7 GetAlarmsAsync (映射有误)
B9 /alarms/{id}/confirm 确认告警 ConfirmAlarmAsync ⚠️ 端点未确认
B10 /control 远程控制 SendControlAsync ⚠️
B11 /logs 业务记录 GetBusinessLogsAsync ⚠️
B12 /sync (POST) 员工同步 2.18.3 SyncDataAsync ⚠️
B13 /sync (DELETE) 删除员工 2.18.2 DeleteDataAsync

5. 问题汇总

🔴 致命问题 (需联调前修复)

# 问题 影响
R1 2.18.5/2.18.6/2.18.7 请求体只传 "{}",忽略 from/to/page/size 参数 无法按时间分页查询,联调时大概率返回全量数据或报错
R2 2.18.7 type 字段语义错误 (1=当前告警被映射为"未确认") 告警状态全部错误
R3 openerState 字符串比较 vs 文档数值编码 所有锁孔 IsOnline 永远为 false

🟠 严重问题

# 问题 影响
S1 2.18.6 必填字段 (lockerName, lockholeSort, openerCnName) 未传 借还记录查询可能被 KMS 拒绝
S2 ConfirmAlarmAsync 端点 (/prod-api/kms/warning/confirm/{id}) 未在文档中确认存在 告警确认功能不可用
S3 2.18.5 请求体结构未知 (文档未给完整示例) 授权记录查询格式需联调验证

🟡 改善项

# 问题 建议
M1 KmsModels.cs 包含大量 Phase 2 DTO 但未使用 保留Phase 2 可用
M2 B10 控制指令 command == "open"command == "authorize" 都调同一方法 区分"开门"和"授权"两种指令
M3 ThirdPlatLoginAsync 无超时设置 加 15s 超时
M4 SyncDevicesJob 中 gwRepo.Update(node) vs gwSvc.UpdateAsync(node) 不一致 统一风格

6. 需联调验证项

# 验证项 说明
V1 Token 获取用 query string vs body 文档 2.9.1 标记为 body 参数2.9 节概述为 query
V2 batchSyncStaff body 格式 { staff: [...] } vs [...]
V3 KmsStaff 是否需 account 字段 v1.0.4 新增
V4 getOpenerList 返回的 openerState 是数值还是中文 决定映射逻辑
V5 getRecordList 必填字段是否真的必填 决定请求体最小字段集
V6 getPermissionList 请求体完整格式 文档示例不完整
V7 warning/confirm 端点存在性 调标准管理接口

结论: 9 个 Phase 1 接口全部实现覆盖100%),但 3 个致命问题R1-R3需在联调前修复——核心是请求体格式、type 语义映射、openerState 编码映射。其余 4 个严重问题需联调验证后确认。