docs: 新增 Gateway 集成和微信公众号支付集成的 OpenSpec 规划文档
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 43s

This commit is contained in:
2026-01-30 16:09:32 +08:00
parent 1cf17e8f14
commit 4856a88d41
14 changed files with 4079 additions and 0 deletions

View File

@@ -0,0 +1,118 @@
# 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 个任务)
- 流量卡 API7 个接口)
- 设备 API7 个接口)
- 单元测试
### 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
- 新增方法: SyncCardStatusGateway 集成示例)
- **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 个(保留但不作为实施任务)

File diff suppressed because it is too large Load Diff