# Gateway API 参考文档 ## 概述 本文档提供 Gateway 客户端所有 API 接口的完整参考,包括请求参数、响应格式和使用示例。 **API 分类**: - 流量卡管理(7 个接口) - 设备管理(7 个接口) **基础信息**: - 协议:HTTPS - 请求方法:POST - 内容类型:application/json - 编码方式:UTF-8 - 加密方式:AES-128-ECB + Base64 - 签名方式:MD5 --- ## 流量卡管理 API ### 1. 查询流量卡状态 查询流量卡的当前状态信息。 **方法**: `QueryCardStatus` **请求参数**: ```go type CardStatusReq struct { CardNo string `json:"cardNo" validate:"required"` } ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | CardNo | string | ✅ | 流量卡号(ICCID) | **响应参数**: ```go type CardStatusResp struct { ICCID string `json:"iccid"` CardStatus string `json:"cardStatus"` Extend string `json:"extend,omitempty"` } ``` | 参数 | 类型 | 说明 | |------|------|------| | ICCID | string | 流量卡 ICCID | | CardStatus | string | 卡状态(准备、正常、停机) | | Extend | string | 扩展字段(广电国网特殊参数) | **使用示例**: ```go resp, err := client.QueryCardStatus(ctx, &gateway.CardStatusReq{ CardNo: "898608070422D0010269", }) if err != nil { return err } fmt.Printf("卡状态: %s\n", resp.CardStatus) ``` --- ### 2. 查询流量使用情况 查询流量卡的流量使用详情。 **方法**: `QueryFlow` **请求参数**: ```go type FlowQueryReq struct { CardNo string `json:"cardNo" validate:"required"` } ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | CardNo | string | ✅ | 流量卡号(ICCID) | **响应参数**: ```go type FlowUsageResp struct { UsedFlow int64 `json:"usedFlow"` Unit string `json:"unit"` Extend string `json:"extend,omitempty"` } ``` | 参数 | 类型 | 说明 | |------|------|------| | UsedFlow | int64 | 已用流量 | | Unit | string | 流量单位(MB) | | Extend | string | 扩展字段 | **使用示例**: ```go resp, err := client.QueryFlow(ctx, &gateway.FlowQueryReq{ CardNo: "898608070422D0010269", }) if err != nil { return err } fmt.Printf("已用流量: %d %s\n", resp.UsedFlow, resp.Unit) ``` --- ### 3. 查询实名认证状态 查询流量卡的实名认证状态。 **方法**: `QueryRealnameStatus` **请求参数**: ```go type CardStatusReq struct { CardNo string `json:"cardNo" validate:"required"` } ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | CardNo | string | ✅ | 流量卡号(ICCID) | **响应参数**: ```go type RealnameStatusResp struct { Status string `json:"status"` Extend string `json:"extend,omitempty"` } ``` | 参数 | 类型 | 说明 | |------|------|------| | Status | string | 实名认证状态 | | Extend | string | 扩展字段 | **使用示例**: ```go resp, err := client.QueryRealnameStatus(ctx, &gateway.CardStatusReq{ CardNo: "898608070422D0010269", }) if err != nil { return err } fmt.Printf("实名状态: %s\n", resp.Status) ``` --- ### 4. 流量卡停机 对流量卡执行停机操作。 **方法**: `StopCard` **请求参数**: ```go type CardOperationReq struct { CardNo string `json:"cardNo" validate:"required"` Extend string `json:"extend,omitempty"` } ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | CardNo | string | ✅ | 流量卡号(ICCID) | | Extend | string | ❌ | 扩展字段(广电国网特殊参数) | **响应参数**: 无(成功返回 nil,失败返回 error) **使用示例**: ```go err := client.StopCard(ctx, &gateway.CardOperationReq{ CardNo: "898608070422D0010269", }) if err != nil { return err } fmt.Println("停机成功") ``` --- ### 5. 流量卡复机 对流量卡执行复机操作。 **方法**: `StartCard` **请求参数**: ```go type CardOperationReq struct { CardNo string `json:"cardNo" validate:"required"` Extend string `json:"extend,omitempty"` } ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | CardNo | string | ✅ | 流量卡号(ICCID) | | Extend | string | ❌ | 扩展字段 | **响应参数**: 无(成功返回 nil,失败返回 error) **使用示例**: ```go err := client.StartCard(ctx, &gateway.CardOperationReq{ CardNo: "898608070422D0010269", }) if err != nil { return err } fmt.Println("复机成功") ``` --- ### 6. 获取实名认证跳转链接 获取流量卡实名认证的跳转链接。 **方法**: `GetRealnameLink` **请求参数**: ```go type CardStatusReq struct { CardNo string `json:"cardNo" validate:"required"` } ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | CardNo | string | ✅ | 流量卡号(ICCID) | **响应参数**: ```go type RealnameLinkResp struct { Link string `json:"link"` Extend string `json:"extend,omitempty"` } ``` | 参数 | 类型 | 说明 | |------|------|------| | Link | string | 实名认证跳转链接(HTTPS URL) | | Extend | string | 扩展字段 | **使用示例**: ```go resp, err := client.GetRealnameLink(ctx, &gateway.CardStatusReq{ CardNo: "898608070422D0010269", }) if err != nil { return err } fmt.Printf("实名链接: %s\n", resp.Link) ``` --- ### 7. 批量查询(预留) 批量查询流量卡信息(暂未实现)。 **方法**: `BatchQuery` **请求参数**: ```go type BatchQueryReq struct { CardNos []string `json:"cardNos" validate:"required,min=1,max=100"` } ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | CardNos | []string | ✅ | 流量卡号列表(最多100个) | **响应参数**: ```go type BatchQueryResp struct { Results []CardStatusResp `json:"results"` } ``` **状态**: ⚠️ 暂未实现,调用将返回错误 --- ## 设备管理 API ### 1. 获取设备信息 通过卡号或设备 ID 查询设备的在线状态、信号强度、WiFi 信息等。 **方法**: `GetDeviceInfo` **请求参数**: ```go type DeviceInfoReq struct { CardNo string `json:"cardNo,omitempty"` DeviceID string `json:"deviceId,omitempty"` } ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | CardNo | string | 二选一 | 流量卡号(ICCID) | | DeviceID | string | 二选一 | 设备 ID/IMEI | **响应参数**: ```go type DeviceInfoResp struct { IMEI string `json:"imei"` OnlineStatus int `json:"onlineStatus"` SignalLevel int `json:"signalLevel"` WiFiSSID string `json:"wifiSsid,omitempty"` WiFiEnabled int `json:"wifiEnabled"` UploadSpeed int `json:"uploadSpeed"` DownloadSpeed int `json:"downloadSpeed"` Extend string `json:"extend,omitempty"` } ``` | 参数 | 类型 | 说明 | |------|------|------| | IMEI | string | 设备 IMEI | | OnlineStatus | int | 在线状态(0:离线, 1:在线) | | SignalLevel | int | 信号强度(0-31) | | WiFiSSID | string | WiFi 名称 | | WiFiEnabled | int | WiFi 启用状态(0:禁用, 1:启用) | | UploadSpeed | int | 上行速率(KB/s) | | DownloadSpeed | int | 下行速率(KB/s) | | Extend | string | 扩展字段 | **使用示例**: ```go resp, err := client.GetDeviceInfo(ctx, &gateway.DeviceInfoReq{ DeviceID: "123456789012345", }) if err != nil { return err } fmt.Printf("设备状态: %s, 信号: %d\n", map[int]string{0:"离线", 1:"在线"}[resp.OnlineStatus], resp.SignalLevel, ) ``` --- ### 2. 获取设备卡槽信息 查询设备的所有卡槽及其中的卡信息。 **方法**: `GetSlotInfo` **请求参数**: ```go type DeviceInfoReq struct { CardNo string `json:"cardNo,omitempty"` DeviceID string `json:"deviceId,omitempty"` } ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | CardNo | string | 二选一 | 流量卡号(ICCID) | | DeviceID | string | 二选一 | 设备 ID/IMEI | **响应参数**: ```go type SlotInfoResp struct { IMEI string `json:"imei"` Slots []SlotInfo `json:"slots"` Extend string `json:"extend,omitempty"` } type SlotInfo struct { SlotNo int `json:"slotNo"` ICCID string `json:"iccid"` CardStatus string `json:"cardStatus"` IsActive int `json:"isActive"` Extend string `json:"extend,omitempty"` } ``` | 参数 | 类型 | 说明 | |------|------|------| | IMEI | string | 设备 IMEI | | Slots | []SlotInfo | 卡槽信息列表 | | SlotNo | int | 卡槽编号 | | ICCID | string | 卡槽中的 ICCID | | CardStatus | string | 卡状态(准备、正常、停机) | | IsActive | int | 是否为当前使用的卡槽(0:否, 1:是) | **使用示例**: ```go resp, err := client.GetSlotInfo(ctx, &gateway.DeviceInfoReq{ DeviceID: "123456789012345", }) if err != nil { return err } for _, slot := range resp.Slots { fmt.Printf("卡槽%d: %s (%s)%s\n", slot.SlotNo, slot.ICCID, slot.CardStatus, map[int]string{0:"", 1:" [当前使用]"}[slot.IsActive], ) } ``` --- ### 3. 设置设备限速 设置设备的上行和下行速率限制。 **方法**: `SetSpeedLimit` **请求参数**: ```go type SpeedLimitReq struct { DeviceID string `json:"deviceId" validate:"required"` UploadSpeed int `json:"uploadSpeed" validate:"required,min=1"` DownloadSpeed int `json:"downloadSpeed" validate:"required,min=1"` Extend string `json:"extend,omitempty"` } ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | DeviceID | string | ✅ | 设备 ID/IMEI | | UploadSpeed | int | ✅ | 上行速率(KB/s),最小1 | | DownloadSpeed | int | ✅ | 下行速率(KB/s),最小1 | | Extend | string | ❌ | 扩展字段 | **响应参数**: 无(成功返回 nil,失败返回 error) **使用示例**: ```go err := client.SetSpeedLimit(ctx, &gateway.SpeedLimitReq{ DeviceID: "123456789012345", UploadSpeed: 100, DownloadSpeed: 500, }) if err != nil { return err } fmt.Println("限速设置成功") ``` --- ### 4. 设置设备 WiFi 设置设备的 WiFi 名称、密码和启用状态。 **方法**: `SetWiFi` **请求参数**: ```go type WiFiReq struct { DeviceID string `json:"deviceId" validate:"required"` SSID string `json:"ssid" validate:"required,min=1,max=32"` Password string `json:"password" validate:"required,min=8,max=63"` Enabled int `json:"enabled" validate:"required,oneof=0 1"` Extend string `json:"extend,omitempty"` } ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | DeviceID | string | ✅ | 设备 ID/IMEI | | SSID | string | ✅ | WiFi 名称(1-32字符) | | Password | string | ✅ | WiFi 密码(8-63字符) | | Enabled | int | ✅ | 启用状态(0:禁用, 1:启用) | | Extend | string | ❌ | 扩展字段 | **响应参数**: 无(成功返回 nil,失败返回 error) **使用示例**: ```go err := client.SetWiFi(ctx, &gateway.WiFiReq{ DeviceID: "123456789012345", SSID: "MyWiFi", Password: "password123", Enabled: 1, }) if err != nil { return err } fmt.Println("WiFi设置成功") ``` --- ### 5. 设备切换卡 切换设备当前使用的卡到指定的目标卡。 **方法**: `SwitchCard` **请求参数**: ```go type SwitchCardReq struct { DeviceID string `json:"deviceId" validate:"required"` TargetICCID string `json:"targetIccid" validate:"required"` Extend string `json:"extend,omitempty"` } ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | DeviceID | string | ✅ | 设备 ID/IMEI | | TargetICCID | string | ✅ | 目标卡 ICCID | | Extend | string | ❌ | 扩展字段 | **响应参数**: 无(成功返回 nil,失败返回 error) **使用示例**: ```go err := client.SwitchCard(ctx, &gateway.SwitchCardReq{ DeviceID: "123456789012345", TargetICCID: "898608070422D0010270", }) if err != nil { return err } fmt.Println("切换卡成功") ``` --- ### 6. 设备恢复出厂设置 将设备恢复到出厂设置状态。 **方法**: `ResetDevice` **请求参数**: ```go type DeviceOperationReq struct { DeviceID string `json:"deviceId" validate:"required"` Extend string `json:"extend,omitempty"` } ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | DeviceID | string | ✅ | 设备 ID/IMEI | | Extend | string | ❌ | 扩展字段 | **响应参数**: 无(成功返回 nil,失败返回 error) **使用示例**: ```go err := client.ResetDevice(ctx, &gateway.DeviceOperationReq{ DeviceID: "123456789012345", }) if err != nil { return err } fmt.Println("恢复出厂设置成功") ``` --- ### 7. 设备重启 远程重启设备。 **方法**: `RebootDevice` **请求参数**: ```go type DeviceOperationReq struct { DeviceID string `json:"deviceId" validate:"required"` Extend string `json:"extend,omitempty"` } ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | DeviceID | string | ✅ | 设备 ID/IMEI | | Extend | string | ❌ | 扩展字段 | **响应参数**: 无(成功返回 nil,失败返回 error) **使用示例**: ```go err := client.RebootDevice(ctx, &gateway.DeviceOperationReq{ DeviceID: "123456789012345", }) if err != nil { return err } fmt.Println("重启设备成功") ``` --- ## 通用响应结构 所有 API 的底层响应都遵循统一的 Gateway 响应格式: ```go type GatewayResponse struct { Code int `json:"code"` Msg string `json:"msg"` Data json.RawMessage `json:"data"` TraceID string `json:"trace_id"` } ``` | 参数 | 类型 | 说明 | |------|------|------| | Code | int | 业务状态码(200 = 成功) | | Msg | string | 业务提示信息 | | Data | json.RawMessage | 业务数据(原始 JSON) | | TraceID | string | 链路追踪 ID | **成功响应示例**: ```json { "code": 200, "msg": "成功", "data": { "iccid": "898608070422D0010269", "cardStatus": "正常" }, "trace_id": "abc123xyz" } ``` **失败响应示例**: ```json { "code": 404, "msg": "卡号不存在", "data": null, "trace_id": "abc123xyz" } ``` --- ## 错误码说明 ### Gateway 业务错误码 | 错误码 | 说明 | 解决方案 | |-------|------|---------| | 200 | 成功 | - | | 400 | 请求参数错误 | 检查请求参数格式和内容 | | 401 | 认证失败 | 检查 AppID 和 AppSecret | | 404 | 资源不存在 | 检查卡号或设备 ID 是否正确 | | 500 | 服务器内部错误 | 联系 Gateway 服务提供方 | ### 客户端错误码 客户端封装的统一错误码(`pkg/errors/codes.go`): | 错误码 | 常量 | 说明 | |-------|------|------| | 1110 | CodeGatewayError | Gateway 连接失败 | | 1111 | CodeGatewayTimeout | Gateway 请求超时 | | 1112 | CodeGatewayBusinessError | Gateway 业务错误 | | 1113 | CodeGatewayInvalidResp | Gateway 响应解析失败 | | 1114 | CodeGatewaySignError | Gateway 签名验证失败 | --- ## 请求流程 ### 完整请求流程 ``` 1. 构造业务请求参数 ↓ 2. 序列化为 JSON ↓ 3. AES-128-ECB 加密(Base64 编码) ↓ 4. 生成 MD5 签名(参数排序 + appSecret) ↓ 5. 构造最终请求体 { "appId": "xxx", "data": "encrypted_base64_string", "sign": "md5_signature", "timestamp": 1706620800000 } ↓ 6. POST 请求到 Gateway ↓ 7. 解析响应 JSON ↓ 8. 检查业务状态码 ↓ 9. 解密并解析业务数据 ↓ 10. 返回结果或错误 ``` ### 签名算法 ``` 1. 将请求参数按 key 字母序排序 2. 拼接为 key1=value1&key2=value2 格式 3. 末尾追加 &appSecret=xxx 4. 计算 MD5 哈希 5. 转为大写字符串 ``` **示例**: ``` 参数: {cardNo: "123", appId: "abc"} 排序: appId=abc&cardNo=123 追加: appId=abc&cardNo=123&appSecret=secret MD5: D41D8CD98F00B204E9800998ECF8427E ``` --- ## 相关文档 - [Gateway 客户端使用指南](./gateway-client-usage.md) - 详细的使用指南和最佳实践 - [错误处理指南](./003-error-handling/使用指南.md) - 统一错误处理规范