# Draft: Gateway Integration 工作计划 ## 用户需求确认 **目标**: 封装 Gateway API 为统一的能力模块,提供类型安全的接口、统一的错误处理和配置管理。 **核心交付物**: - Gateway 客户端封装(`internal/gateway/` 包) - 14 个 API 接口(流量卡 7 个 + 设备 7 个) - AES-128-ECB 加密 + MD5 签名机制 - 配置集成(环境变量) - 错误码定义(1110-1119) - 依赖注入(Bootstrap) - 完整测试覆盖 **总任务数**: 51 个实施任务 + 10 个验收标准 ## 初步任务分组 ### Phase 1: 基础结构搭建(13 个任务) - 目录结构创建 - 加密/签名工具实现 - 客户端基础结构 - DTO 定义 ### Phase 2: API 接口封装(17 个任务) - 流量卡 API(7 个接口) - 设备 API(7 个接口) - 单元测试 ### Phase 3: 配置和错误码集成(7 个任务) - Gateway 配置 - Gateway 错误码 ### Phase 4: 依赖注入和集成(6 个任务) - Bootstrap 初始化 - Service 层集成 ### Phase 5: 集成测试和文档(8 个任务) - 集成测试 - 文档更新 ## 用户决策(已确认) ### 1. Gateway 测试环境配置 ✅ - **BaseURL**: `https://lplan.whjhft.com/openapi` - **AppID**: `60bgt1X8i7AvXqkd` - **AppSecret**: `BZeQttaZQt0i73moF` - **测试 ICCID**: `8986062580006141710` - **设备测试**: 不需要测试 ### 2. 加密/签名算法验证 ✅ - **文档来源**: Apifox 文档(https://omp5mq28pq.apifox.cn/7819761m0) - **加密方案**: AES-128-ECB + PKCS5Padding + Base64(密钥为 AppSecret 的 MD5) - **签名方案**: MD5(排序参数&key=AppSecret),大写输出 - **安全警告**: ⚠️ 遗留系统,添加安全警告注释(ECB 模式泄漏 + MD5 碰撞风险) ### 3. Service 层集成范围 ✅ - **集成位置**: `internal/service/iot_card/service.go`(已存在) - **集成方法**: 新增 `SyncCardStatus(ctx, iccid)` 方法作为示例 - **范围**: 仅提供一个集成示例 ### 4. 批量查询接口 ✅ - **决定**: ❌ 完全不实施(连预留接口都不需要) - **理由**: 用户明确表示"根本就不会有批量查询接口" ### 5. 错误处理策略 ✅ - **重试逻辑**: ✅ 需要自动重试(最多 3 次,指数退避:1s, 2s, 4s) - **降级策略**: ❌ 不需要 - **超时处理**: 超时错误不重试,直接返回 - **实现方式**: 在 `doRequest` 内置简单循环重试(无需第三方库) ## 研究发现 ### 项目现有架构 - **分层结构**: Handler → Service → Store → Model(严格分离) - **依赖注入**: Bootstrap 按顺序初始化(Stores → Services → Handlers) - **配置管理**: Viper 加载,支持环境变量覆盖(前缀 `JUNHONG_`) - **错误处理**: 统一错误码系统(1000-1999: 4xx, 2000-2999: 5xx) - **测试模式**: Table-driven tests + testutils(全局单例 DB/Redis) - **HTTP 客户端参考**: `/pkg/sms/` 使用接口 + 依赖注入模式 ### 加密/签名安全警告 - **AES-128-ECB**: ⚠️ 密码学上已被破解(模式泄漏),仅用于遗留系统 - **MD5 签名**: ⚠️ 存在碰撞攻击漏洞,建议使用 HMAC-SHA256 - **理由**: 如果 Gateway API 是遗留系统且无法更改,则必须使用 ECB + MD5 ### 最佳实践建议 1. **HTTP 客户端**: 使用 `http.Transport` 精细配置超时(Dial、TLS、ResponseHeader) 2. **API 客户端**: 导出接口而非具体类型(可测试性) 3. **集成测试**: 使用真实 Gateway 环境 + 测试 ICCID 4. **错误处理**: 区分超时错误 vs 其他网络错误 5. **重试策略**: 内置简单循环重试(无需第三方库) ### 现有代码结构 - **iot_card Service**: 已存在于 `internal/service/iot_card/service.go` - 当前方法: ListStandalone, GetByICCID, AllocateCards, RecallCards, BatchSetSeriesBinding - 新增方法: SyncCardStatus(Gateway 集成示例) - **HTTP 客户端参考**: `pkg/sms/http_client.go`(无重试逻辑,使用 context 超时) - **重试模式**: 项目使用 Asynq 任务队列重试(常量:`DefaultRetryMax = 5`) ## 任务调整 ### 删除任务 - **Task 20**: "预留 BatchQuery(批量查询,未来扩展)" → ❌ 删除 ### 新增任务 - **Task 1.5**: "在 doRequest 中实现 HTTP 重试逻辑(3 次,指数退避)" - **Task 4.3**: "在 iot_card Service 中新增 SyncCardStatus 方法" ### 修改任务 - **Task 5.1**: 使用真实配置进行集成测试(测试 ICCID: `8986062580006141710`) - **Task 2.1**: 移除 BatchQuery 实现 - **Task 2.2**: 设备 API 只实现方法签名(测试时跳过真实调用) ### 调整后任务数 - **实施任务**: 51 个(原 51 - 1 个删除 + 1 个新增 = 51) - **验收标准**: 10 个(保留但不作为实施任务)