3.9 KiB
Context
现有代理开放接口(internal/service/agent_open_api/service.go)已实现卡维度的流量查询、状态查询、实名查询和钱包购买。设备维度的 Gateway 操作(切网、重启、恢复出厂)已在 internal/service/device/gateway_service.go 中实现,设备级套餐流量查询通过 PackageUsageStore.ListByCarrier(ctx, "device", deviceID, ...) 支持。
本次变更在现有 agent_open_api service 中扩展设备维度能力,复用已有的 device service 和 package usage store,不引入新的数据模型或迁移。
Goals / Non-Goals
Goals:
- 新增 4 个代理开放接口:设备流量查询、切网、重启、恢复出厂
- 复用现有 device service 的 Gateway 调用逻辑,不重复实现
- 权限校验与卡接口保持一致(
shop_id IN SubordinateShopIDs) - 设备标识符支持虚拟号和 IMEI
Non-Goals:
- 不新增数据库表或迁移
- 不修改现有卡接口
- 不支持 SN 作为设备标识符(开放接口只暴露虚拟号/IMEI)
- 不支持批量设备操作
Decisions
决策一:agent_open_api service 注入 device.Service 依赖
选择:在 agent_open_api.Service 结构体中新增 deviceService *device.Service 字段,通过构造函数注入。
理由:device service 已封装了 Gateway 调用、审计日志和设备查询逻辑,直接复用避免重复实现。相比新建独立函数,注入 service 更符合项目分层规范。
替代方案:在 agent_open_api service 中直接注入 deviceStore 和 gatewayClient,自行实现权限校验和 Gateway 调用。缺点是重复了 device service 中已有的审计日志和错误处理逻辑。
决策二:设备权限校验方式
选择:查询设备后,手动检查 device.ShopID != nil && SubordinateShopIDs 包含 *device.ShopID。
理由:ApplyShopFilter 作用于 GORM query,而 device service 的 GetByIdentifier 内部已有自己的查询逻辑。为避免侵入 device service,在 agent_open_api service 层做显式权限校验,与卡接口的 resolveOpenAPICard 模式一致。
实现:新增 resolveOpenAPIDevice(ctx, deviceNo) 私有方法,复用 device.Service.GetDeviceByIdentifier,然后校验 shop_id。
决策三:设备流量查询复用 PackageUsageStore
选择:直接在 agent_open_api.Service 中调用已注入的 packageUsageStore.ListByCarrier(ctx, "device", device.ID, &status)。
理由:packageUsageStore 已在 agent_open_api service 中注入(用于卡流量查询),ListByCarrier 支持 "device" 类型,无需额外改动 store 层。
决策四:切网接口调用 device.Service.GatewaySwitchCard
选择:agent_open_api service 调用 deviceService.GatewaySwitchCard(ctx, identifier, &dto.SwitchCardRequest{ICCID: req.ICCID})。
理由:GatewaySwitchCard 已包含审计日志记录,开放接口复用可保证操作可追溯。
注意:GatewaySwitchCard 内部通过 getGatewayDevice 再次查询设备,存在两次查询。考虑到操作频率低,接受此开销,不做优化。
Risks / Trade-offs
-
[风险] device service 审计日志中的操作者信息:
GatewaySwitchCard等方法通过middleware.GetUserIDFromContext获取操作者 ID。开放接口认证中间件已将代理账号 ID 写入ContextKeyUserID,审计日志可正确记录操作者。→ 无需额外处理。 -
[风险] 设备标识符两次查询:
resolveOpenAPIDevice查一次,GatewaySwitchCard内部再查一次。→ 接受,操作类接口频率低,影响可忽略。 -
[Trade-off] 不支持 SN:admin 接口支持虚拟号/IMEI/SN,开放接口只支持虚拟号/IMEI。→ 简化外部接口,SN 是内部管理标识,不适合对外暴露。
Migration Plan
无数据库变更,无需迁移。直接部署新版本即可。
Open Questions
(无)