# 前端接口变更说明 > 最后更新:2026-03-19 --- ## 目录 1. [接口变更概览](#一接口变更概览) 2. [删除的接口](#二删除的接口) 3. [修改的后台接口](#三修改的后台接口) 4. [新增的后台接口](#四新增的后台接口) 5. [新增的 C 端接口](#五新增的-c-端接口) 6. [认证方式说明](#六认证方式说明) 7. [统一响应格式](#七统一响应格式) --- ## 一、接口变更概览 **C 端接口统一前缀**:`/api/c/v1/` **后台接口统一前缀**:`/api/admin/` ### 删除 | 接口 | 说明 | |------|------| | `POST /api/personal/login` | 旧个人客户登录,已下线 | | `POST /api/personal/send-code` | 旧验证码发送,已下线 | | `POST /api/personal/wechat-oauth-login` | 旧微信登录,已下线 | | `POST /api/personal/bind-wechat` | 旧微信绑定,已下线 | | `GET /api/personal/profile` | 旧个人信息,已下线 | | `/api/h5/*` 下所有路由 | 旧 H5 接口全部下线 | ### 修改(后台) | 接口 | 变更内容 | |------|----------| | `POST /api/admin/shop-package-batch-pricing/batch-update` | 仅支持批量调整成本价(移除 `pricing_target`) | | 所有返回 `PackageResponse` 的套餐列表接口 | 响应新增 `retail_price` 字段 | | 运营商创建/编辑接口 | 新增 `realname_link_type` 和 `realname_link_template` 字段 | ### 新增(后台) | 接口 | 说明 | |------|------| | `PATCH /api/admin/packages/:id/retail-price` | 代理修改自己的套餐零售价 | | `PATCH /api/admin/iot-cards/:id/deactivate` | 手动停用 IoT 卡 | | `PATCH /api/admin/devices/:id/deactivate` | 手动停用设备 | | `POST /api/admin/exchanges` | 发起换货单 | | `GET /api/admin/exchanges` | 换货单列表 | | `GET /api/admin/exchanges/:id` | 换货单详情 | | `POST /api/admin/exchanges/:id/ship` | 发货 | | `POST /api/admin/exchanges/:id/complete` | 确认完成 | | `POST /api/admin/exchanges/:id/cancel` | 取消换货 | | `POST /api/admin/exchanges/:id/renew` | 旧资产转新(generation+1) | ### 新增(C 端) | 接口 | 说明 | |------|------| | `POST /api/c/v1/auth/verify-asset` | 资产验证 | | `POST /api/c/v1/auth/wechat-login` | 公众号登录 | | `POST /api/c/v1/auth/miniapp-login` | 小程序登录 | | `POST /api/c/v1/auth/send-code` | 发送验证码 | | `POST /api/c/v1/auth/bind-phone` | 绑定手机号 | | `POST /api/c/v1/auth/change-phone` | 换绑手机号 | | `POST /api/c/v1/auth/logout` | 退出登录 | | `GET /api/c/v1/asset/info` | 资产基本信息 | | `GET /api/c/v1/asset/packages` | 可购套餐列表 | | `GET /api/c/v1/asset/package-history` | 历史套餐列表 | | `POST /api/c/v1/asset/refresh` | 手动刷新资产状态 | | `GET /api/c/v1/wallet/detail` | 钱包详情 | | `GET /api/c/v1/wallet/transactions` | 钱包流水列表 | | `GET /api/c/v1/wallet/recharge-check` | 充值预检 | | `POST /api/c/v1/wallet/recharge` | 创建充值订单 | | `GET /api/c/v1/wallet/recharges` | 充值记录列表 | | `POST /api/c/v1/orders/create` | 创建套餐购买订单 | | `GET /api/c/v1/orders` | 订单列表 | | `GET /api/c/v1/orders/:id` | 订单详情 | | `GET /api/c/v1/realname/link` | 获取实名跳转链接 | | `GET /api/c/v1/device/cards` | 设备卡列表 | | `POST /api/c/v1/device/reboot` | 设备重启 | | `POST /api/c/v1/device/factory-reset` | 恢复出厂设置 | | `POST /api/c/v1/device/wifi` | WiFi 配置 | | `POST /api/c/v1/device/switch-card` | 切卡 | | `GET /api/c/v1/exchange/pending` | 查询进行中的换货通知 | | `POST /api/c/v1/exchange/:id/shipping-info` | 填写收货信息 | --- ## 二、删除的接口 以下接口已全部下线,请停止调用: **旧 H5 接口(`/api/h5/` 下所有路由)** **旧个人客户接口(`/api/personal/` 下):** - `POST /api/personal/login` - `POST /api/personal/send-code` - `POST /api/personal/wechat-oauth-login` - `POST /api/personal/bind-wechat` - `GET /api/personal/profile` 以上接口由新 C 端认证接口(`/api/c/v1/auth/`)替代。 --- ## 三、修改的后台接口 ### 批量调价接口移除 `pricing_target` 字段 ``` POST /api/admin/shop-package-batch-pricing/batch-update ``` **移除请求字段:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `pricing_target` | string | 否 | 已移除,不再支持通过该接口调整零售价 | **变更说明**:该接口现仅支持批量调整成本价,零售价调整改为独立接口 `PATCH /api/admin/packages/:id/retail-price`。 --- ### 套餐列表响应新增 `retail_price` 字段 所有返回 `PackageResponse` 的套餐列表接口,响应体新增字段: | 字段 | 类型 | 说明 | |------|------|------| | `retail_price` | int64 | 零售价(单位:分),代理商可见 | --- ### 运营商管理 DTO 新增实名相关字段 运营商创建/编辑接口新增以下字段: | 字段 | 类型 | 说明 | |------|------|------| | `realname_link_type` | string | 实名链接类型:`none`(无需实名)/ `template`(模板实名)/ `gateway`(网关实名) | | `realname_link_template` | string | 实名链接模板(`realname_link_type` 为 `template` 时使用) | --- ## 四、新增的后台接口 ### 资产停用 #### 手动停用 IoT 卡 ``` PATCH /api/admin/iot-cards/:id/deactivate ``` - **认证**:需要后台 Bearer Token - **路径参数**:`id`(IoT 卡 ID) - **说明**:将卡的 `asset_status` 设为 4(已停用) --- #### 手动停用设备 ``` PATCH /api/admin/devices/:id/deactivate ``` - **认证**:需要后台 Bearer Token - **路径参数**:`id`(设备 ID) - **说明**:将设备的 `asset_status` 设为 4(已停用) --- ### 换货管理 #### H1 发起换货单 ``` POST /api/admin/exchanges ``` **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `old_asset_type` | string | 是 | 旧资产类型:`iot_card`(物联网卡)/ `device`(设备) | | `old_identifier` | string | 是 | 旧资产标识符(ICCID/虚拟号/IMEI/SN),1~100 字符 | | `exchange_reason` | string | 是 | 换货原因,1~100 字符 | | `remark` | string | 否 | 备注,最多 500 字符 | --- #### H2 换货单列表 ``` GET /api/admin/exchanges ``` **Query 参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `page` | int | 否 | 页码,最小 1 | | `page_size` | int | 否 | 每页数量,1~100 | | `status` | int | 否 | 换货状态:1(待填写信息)/ 2(待发货)/ 3(已发货待确认)/ 4(已完成)/ 5(已取消) | | `identifier` | string | 否 | 资产标识符模糊搜索(旧资产/新资产均可) | | `created_at_start` | string | 否 | 创建时间起始 | | `created_at_end` | string | 否 | 创建时间结束 | **响应体(list 中每项)**:见下方 `ExchangeOrderResponse` 字段说明。 --- #### H3 换货单详情 ``` GET /api/admin/exchanges/:id ``` **路径参数**:`id`(换货单 ID) **响应体(`ExchangeOrderResponse`):** | 字段 | 类型 | 说明 | |------|------|------| | `id` | uint | 换货单 ID | | `exchange_no` | string | 换货单号 | | `old_asset_type` | string | 旧资产类型 | | `old_asset_id` | uint | 旧资产 ID | | `old_asset_identifier` | string | 旧资产标识符 | | `new_asset_type` | string | 新资产类型 | | `new_asset_id` | uint | 新资产 ID(可为空) | | `new_asset_identifier` | string | 新资产标识符 | | `recipient_name` | string | 收件人姓名 | | `recipient_phone` | string | 收件人电话 | | `recipient_address` | string | 收货地址 | | `express_company` | string | 快递公司 | | `express_no` | string | 快递单号 | | `migrate_data` | bool | 是否执行全量迁移 | | `migration_completed` | bool | 迁移是否已完成 | | `migration_balance` | int64 | 迁移转移金额(分) | | `exchange_reason` | string | 换货原因 | | `remark` | string | 备注(可为空) | | `status` | int | 换货状态(1~5) | | `status_text` | string | 换货状态文本 | | `shop_id` | uint | 所属店铺 ID(可为空) | | `created_at` | string | 创建时间 | | `updated_at` | string | 更新时间 | | `creator` | uint | 创建人 ID | | `updater` | uint | 更新人 ID | --- #### H4 发货 ``` POST /api/admin/exchanges/:id/ship ``` **路径参数**:`id`(换货单 ID) **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `express_company` | string | 是 | 快递公司,1~100 字符 | | `express_no` | string | 是 | 快递单号,1~100 字符 | | `new_identifier` | string | 是 | 新资产标识符(ICCID/虚拟号/IMEI/SN),1~100 字符 | | `migrate_data` | bool | 是 | 是否执行全量迁移(true:执行,false:不执行) | --- #### H5 确认完成 ``` POST /api/admin/exchanges/:id/complete ``` **路径参数**:`id`(换货单 ID) **请求体**:无 **说明**:若发货时 `migrate_data=true`,确认完成时会执行全量数据迁移(钱包余额、套餐记录等从旧资产迁移到新资产)。 --- #### H6 取消换货 ``` POST /api/admin/exchanges/:id/cancel ``` **路径参数**:`id`(换货单 ID) **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `remark` | string | 否 | 取消备注,最多 500 字符 | **限制**:仅 `status=1`(待填写信息)或 `status=2`(待发货)时可取消。 --- #### H7 旧资产转新(generation+1) ``` POST /api/admin/exchanges/:id/renew ``` **路径参数**:`id`(换货单 ID) **请求体**:无 **说明**:将旧资产的 `generation` 字段加 1,使其可重新销售。 --- ### 换货业务流程 ```mermaid flowchart TD A["后台发起换货\nH1 POST /admin/exchanges"] --> B[换货单创建\nstatus=1 待填写信息] B --> C["客户端轮询通知\nG1 GET /exchange/pending"] C --> D["客户端填写收货信息\nG2 POST /exchange/:id/shipping-info"] D --> E[status=2 待发货] E --> F["后台发货\nH4 POST /exchanges/:id/ship\n填写快递信息和新资产标识符"] F --> G[status=3 已发货待确认] G --> H["后台确认完成\nH5 POST /exchanges/:id/complete"] H --> I{migrate_data=true?} I -->|是| J[执行全量数据迁移\n钱包余额、套餐记录迁移到新资产] I -->|否| K[直接完成] J --> L[status=4 已完成] K --> L L --> M{需要回收旧资产?} M -->|是| N["后台转新\nH7 POST /exchanges/:id/renew\n旧资产 generation+1 可重新销售"] M -->|否| O[流程结束] N --> O ``` **取消流程:** ```mermaid flowchart TD A[status=1 待填写信息] -->|H6 取消| C[status=5 已取消] B[status=2 待发货] -->|H6 取消| C ``` ### 换货状态机 | 状态值 | 状态名 | 可执行操作 | |--------|--------|-----------| | 1 | 待填写信息 | 客户端填写收货信息(G2)、后台取消(H6) | | 2 | 待发货 | 后台发货(H4)、后台取消(H6) | | 3 | 已发货待确认 | 后台确认完成(H5) | | 4 | 已完成 | 后台转新(H7,可选) | | 5 | 已取消 | 无 | --- ## 五、新增的 C 端接口 所有接口位于 `/api/c/v1/` 下,**认证接口(`/auth/`)无需登录,其余全部需要 JWT 认证**(`Authorization: Bearer `)。 --- ### 认证(/api/c/v1/auth/) #### A1 资产验证(无需认证) ``` POST /api/c/v1/auth/verify-asset ``` **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `identifier` | string | 是 | 资产标识符(SN/IMEI/虚拟号/ICCID/MSISDN),1~50 字符 | **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `asset_token` | string | 资产令牌,5 分钟有效,用于后续登录接口 | | `expires_in` | int | 过期时间(秒),固定 300 | --- #### A2 公众号登录(无需认证) ``` POST /api/c/v1/auth/wechat-login ``` **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `code` | string | 是 | 微信 OAuth 授权码 | | `asset_token` | string | 是 | A1 返回的资产令牌 | **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `token` | string | 登录 JWT 令牌 | | `need_bind_phone` | bool | 是否需要绑定手机号(true 时引导用户完成 A4+A5) | | `is_new_user` | bool | 是否新注册用户 | --- #### A3 小程序登录(无需认证) ``` POST /api/c/v1/auth/miniapp-login ``` **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `code` | string | 是 | 小程序登录凭证 | | `asset_token` | string | 是 | A1 返回的资产令牌 | | `nickname` | string | 否 | 用户昵称(前端授权后传入) | | `avatar_url` | string | 否 | 用户头像 URL(前端授权后传入) | **响应体**:同 A2(`token` / `need_bind_phone` / `is_new_user`) --- #### A4 发送验证码(无需认证) ``` POST /api/c/v1/auth/send-code ``` **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `phone` | string | 是 | 手机号,固定 11 位 | | `scene` | string | 是 | 业务场景:`bind_phone`(绑定手机)/ `change_phone_old`(换绑旧手机验证)/ `change_phone_new`(换绑新手机验证) | **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `cooldown_seconds` | int | 冷却秒数,期间不可重复发送 | --- #### A5 绑定手机号(需 JWT 认证) ``` POST /api/c/v1/auth/bind-phone ``` **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `phone` | string | 是 | 手机号,固定 11 位 | | `code` | string | 是 | 验证码,固定 6 位 | **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `phone` | string | 已绑定手机号 | | `bound_at` | string | 绑定时间 | --- #### A6 换绑手机号(需 JWT 认证) ``` POST /api/c/v1/auth/change-phone ``` **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `old_phone` | string | 是 | 旧手机号,固定 11 位 | | `old_code` | string | 是 | 旧手机号验证码,固定 6 位 | | `new_phone` | string | 是 | 新手机号,固定 11 位 | | `new_code` | string | 是 | 新手机号验证码,固定 6 位 | **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `phone` | string | 换绑后手机号 | | `changed_at` | string | 换绑时间 | --- #### A7 退出登录(需 JWT 认证) ``` POST /api/c/v1/auth/logout ``` **请求体**:无 **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `success` | bool | 是否成功 | --- ### 认证登录完整流程 ```mermaid flowchart TD A[用户打开客户端] --> B[输入资产标识符\nSN/IMEI/ICCID/虚拟号] B --> C["A1 POST /auth/verify-asset\n获得 asset_token(5分钟有效)"] C --> D{选择登录方式} D -->|公众号| E["A2 POST /auth/wechat-login\n传入 code + asset_token"] D -->|小程序| F["A3 POST /auth/miniapp-login\n传入 code + asset_token"] E --> G{need_bind_phone?} F --> G G -->|true 需要绑定| H["A4 POST /auth/send-code\nscene=bind_phone"] H --> I["A5 POST /auth/bind-phone\n传入 phone + code"] I --> J[进入主页面] G -->|false 已绑定| J ``` **换绑手机号流程:** ```mermaid flowchart TD A[用户申请换绑] --> B["A4 POST /auth/send-code\nscene=change_phone_old\n发送旧手机验证码"] B --> C["A4 POST /auth/send-code\nscene=change_phone_new\n发送新手机验证码"] C --> D["A6 POST /auth/change-phone\n传入 old_phone+old_code+new_phone+new_code"] D --> E[换绑成功] ``` --- ### 资产(/api/c/v1/asset/) #### B1 资产基本信息 ``` GET /api/c/v1/asset/info?identifier=xxx ``` **Query 参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `identifier` | string | 是 | 资产标识符,1~50 字符 | **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `asset_type` | string | 资产类型:`card`(卡)/ `device`(设备) | | `asset_id` | uint | 资产 ID | | `identifier` | string | 资产标识符 | | `virtual_no` | string | 虚拟号 | | `status` | int | 状态:0(禁用)/ 1(启用) | | `real_name_status` | int | 实名状态:0(未实名)/ 1(已实名) | | `carrier_name` | string | 运营商名称 | | `generation` | string | 制式 | | `wallet_balance` | int64 | 钱包余额(分) | --- #### B2 可购套餐列表 ``` GET /api/c/v1/asset/packages?identifier=xxx ``` **Query 参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `identifier` | string | 是 | 资产标识符,1~50 字符 | **响应体:** ```json { "packages": [ { "package_id": 1, "package_name": "月套餐30G", "package_type": "formal", "retail_price": 2900, "cost_price": 2000, "validity_days": 30, "is_addon": false, "data_allowance": 30720, "data_unit": "MB", "description": "每月30G流量" } ] } ``` | 字段 | 类型 | 说明 | |------|------|------| | `package_id` | uint | 套餐 ID | | `package_name` | string | 套餐名称 | | `package_type` | string | 套餐类型:`formal`(正式套餐)/ `addon`(加油包) | | `retail_price` | int64 | 零售价(分) | | `cost_price` | int64 | 成本价(分) | | `validity_days` | int | 有效天数 | | `is_addon` | bool | 是否加油包 | | `data_allowance` | int64 | 流量额度 | | `data_unit` | string | 流量单位 | | `description` | string | 套餐说明 | --- #### B3 历史套餐列表 ``` GET /api/c/v1/asset/package-history?identifier=xxx&page=1&page_size=20 ``` **Query 参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `identifier` | string | 是 | 资产标识符 | | `page` | int | 是 | 页码,最小 1 | | `page_size` | int | 是 | 每页数量,1~100 | **响应体**:分页列表,包含 `list` / `total` / `page` / `page_size`。 --- #### B4 手动刷新资产状态 ``` POST /api/c/v1/asset/refresh ``` **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `identifier` | string | 是 | 资产标识符,1~50 字符 | **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `refresh_type` | string | 刷新类型:`card`(卡)/ `device`(设备) | | `accepted` | bool | 是否已受理 | | `cooldown_seconds` | int | 冷却秒数(期间不可重复刷新) | --- ### 钱包(/api/c/v1/wallet/) #### C1 钱包详情 ``` GET /api/c/v1/wallet/detail?identifier=xxx ``` **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `wallet_id` | uint | 钱包 ID | | `resource_type` | string | 资源类型:`iot_card`(物联网卡)/ `device`(设备) | | `resource_id` | uint | 资源 ID | | `balance` | int64 | 可用余额(分) | | `frozen_balance` | int64 | 冻结余额(分) | | `updated_at` | string | 更新时间 | --- #### C2 钱包流水列表 ``` GET /api/c/v1/wallet/transactions?identifier=xxx&page=1&page_size=20 ``` **Query 参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `identifier` | string | 是 | 资产标识符 | | `transaction_type` | string | 否 | 流水类型筛选 | | `start_time` | string | 否 | 开始时间 | | `end_time` | string | 否 | 结束时间 | | `page` | int | 是 | 页码 | | `page_size` | int | 是 | 每页数量,1~100 | **响应体(list 中每项):** | 字段 | 类型 | 说明 | |------|------|------| | `transaction_id` | uint | 流水 ID | | `type` | string | 流水类型 | | `amount` | int64 | 变动金额(分) | | `balance_after` | int64 | 变动后余额(分) | | `created_at` | string | 创建时间 | | `remark` | string | 备注 | --- #### C3 充值预检 ``` GET /api/c/v1/wallet/recharge-check?identifier=xxx ``` **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `need_force_recharge` | bool | 是否需要强制充值 | | `force_recharge_amount` | int64 | 强制充值金额(分) | | `trigger_type` | string | 触发类型 | | `min_amount` | int64 | 最小充值金额(分) | | `max_amount` | int64 | 最大充值金额(分) | | `message` | string | 提示信息 | --- #### C4 创建充值订单 ``` POST /api/c/v1/wallet/recharge ``` **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `identifier` | string | 是 | 资产标识符,1~50 字符 | | `amount` | int64 | 是 | 充值金额(分),100~10000000 | | `payment_method` | string | 是 | 支付方式,目前仅支持 `wechat` | | `app_type` | string | 是 | 应用类型:`official_account`(公众号)/ `miniapp`(小程序) | **响应体:** ```json { "recharge": { "recharge_id": 1, "recharge_no": "RC20260319001", "amount": 10000, "status": 0 }, "pay_config": { "app_id": "wx...", "timestamp": "1710000000", "nonce_str": "abc123", "package": "prepay_id=wx...", "sign_type": "RSA", "pay_sign": "..." } } ``` `pay_config` 字段直接传给微信 JSAPI 调起支付。 --- #### C5 充值记录列表 ``` GET /api/c/v1/wallet/recharges?identifier=xxx&page=1&page_size=20 ``` **Query 参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `identifier` | string | 是 | 资产标识符 | | `status` | int | 否 | 充值状态:0(待支付)/ 1(已支付)/ 2(已关闭) | | `page` | int | 是 | 页码 | | `page_size` | int | 是 | 每页数量,1~100 | **响应体(list 中每项):** | 字段 | 类型 | 说明 | |------|------|------| | `recharge_id` | uint | 充值 ID | | `recharge_no` | string | 充值单号 | | `amount` | int64 | 充值金额(分) | | `status` | int | 状态:0(待支付)/ 1(已支付)/ 2(已关闭) | | `payment_method` | string | 支付方式 | | `created_at` | string | 创建时间 | | `auto_purchase_status` | string | 自动购包状态 | --- ### 钱包充值流程 ```mermaid flowchart TD A[用户进入充值页] --> B["C3 GET /wallet/recharge-check\n预检是否需要强充"] B --> C{need_force_recharge} C -->|true 需要强充| D[展示强制充值金额\n用户确认] C -->|false 自由充值| E[用户输入充值金额] D --> F["C4 POST /wallet/recharge\n创建充值订单"] E --> F F --> G[调起微信支付\n使用 pay_config] G --> H[支付成功] H --> I[后端回调处理\n余额增加] I --> J[充值完成] ``` --- ### 订单(/api/c/v1/orders/) #### D1 创建套餐购买订单(核心接口) ``` POST /api/c/v1/orders/create ``` **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `identifier` | string | 是 | 资产标识符,1~50 字符 | | `package_ids` | []uint | 是 | 套餐 ID 列表,至少 1 个 | | `app_type` | string | 是 | 应用类型:`official_account`(公众号)/ `miniapp`(小程序) | **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `order_type` | string | 订单类型:`package`(套餐订单)/ `recharge`(充值订单) | | `order` | object | 套餐订单信息(`order_type=package` 时有值) | | `recharge` | object | 充值订单信息(`order_type=recharge` 时有值) | | `pay_config` | object | 微信支付配置,直接传给 JSAPI | | `linked_package_info` | object | 关联套餐信息(强充场景下有值) | `order` 字段结构: | 字段 | 类型 | 说明 | |------|------|------| | `order_id` | uint | 订单 ID | | `order_no` | string | 订单号 | | `total_amount` | int64 | 订单总金额(分) | | `payment_status` | int | 支付状态:0(待支付)/ 1(已支付)/ 2(已取消) | | `created_at` | string | 创建时间 | `recharge` 字段结构: | 字段 | 类型 | 说明 | |------|------|------| | `recharge_id` | uint | 充值 ID | | `recharge_no` | string | 充值单号 | | `amount` | int64 | 充值金额(分) | | `status` | int | 状态:0(待支付)/ 1(已支付)/ 2(已关闭) | | `auto_purchase_status` | string | 自动购包状态 | `linked_package_info` 字段结构(强充场景): | 字段 | 类型 | 说明 | |------|------|------| | `package_names` | []string | 套餐名称列表 | | `total_package_amount` | int64 | 套餐总金额(分) | | `force_recharge_amount` | int64 | 强制充值金额(分) | | `wallet_credit` | int64 | 钱包抵扣金额(分) | > **注意**:当余额不足时,后端会自动创建充值订单(`order_type=recharge`),用户支付充值后系统自动购买套餐,前端无需二次调用购买接口。 --- #### D2 订单列表 ``` GET /api/c/v1/orders?identifier=xxx&page=1&page_size=20 ``` **Query 参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `identifier` | string | 是 | 资产标识符 | | `payment_status` | int | 否 | 支付状态:0(待支付)/ 1(已支付)/ 2(已取消) | | `page` | int | 是 | 页码 | | `page_size` | int | 是 | 每页数量,1~100 | **响应体(list 中每项):** | 字段 | 类型 | 说明 | |------|------|------| | `order_id` | uint | 订单 ID | | `order_no` | string | 订单号 | | `total_amount` | int64 | 订单总金额(分) | | `payment_status` | int | 支付状态 | | `created_at` | string | 创建时间 | | `package_names` | []string | 套餐名称列表 | --- #### D3 订单详情 ``` GET /api/c/v1/orders/:id ``` **路径参数**:`id`(订单 ID) **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `order_id` | uint | 订单 ID | | `order_no` | string | 订单号 | | `total_amount` | int64 | 订单总金额(分) | | `payment_status` | int | 支付状态:0(待支付)/ 1(已支付)/ 2(已取消) | | `payment_method` | string | 支付方式 | | `created_at` | string | 创建时间 | | `paid_at` | string | 支付时间(可为空) | | `completed_at` | string | 完成时间(可为空) | | `packages` | array | 订单套餐列表 | `packages` 中每项: | 字段 | 类型 | 说明 | |------|------|------| | `package_id` | uint | 套餐 ID | | `package_name` | string | 套餐名称 | | `package_type` | string | 套餐类型:`formal`(正式套餐)/ `addon`(加油包) | | `price` | int64 | 单价(分) | | `quantity` | int | 数量 | --- ### 套餐购买流程 ```mermaid flowchart TD A[用户选择套餐] --> B["D1 POST /orders/create\n传入 identifier + package_ids + app_type"] B --> C{响应 order_type} C -->|package 套餐订单| D[调起微信支付\n使用 pay_config] C -->|recharge 充值订单| E[提示用户需要充值\n显示 linked_package_info 中的金额说明] E --> F[调起微信支付\n使用 pay_config] D --> G[支付成功] F --> G G --> H[后端支付回调处理] H -->|套餐订单| I[直接激活套餐] H -->|充值订单| J[余额到账后自动购买套餐] I --> K[套餐激活完成] J --> K ``` > **强充两阶段说明**:当用户钱包余额不足时,后端自动创建充值订单(`order_type=recharge`)。用户支付充值金额后,系统自动扣款购买套餐,前端无需再次调用购买接口。`linked_package_info` 字段包含套餐名称和金额明细,可用于向用户展示说明。 --- ### 实名(/api/c/v1/realname/) #### E1 获取实名跳转链接 ``` GET /api/c/v1/realname/link?identifier=xxx&iccid=xxx ``` **Query 参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `identifier` | string | 是 | 资产标识符,1~50 字符 | | `iccid` | string | 否 | 物联网卡 ICCID(设备场景下指定具体卡) | **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `realname_mode` | string | 实名模式:`none`(无需实名)/ `template`(模板实名)/ `gateway`(网关实名) | | `realname_url` | string | 实名跳转链接 | | `card_info` | object | 卡片简要信息 | | `expire_at` | string | 链接过期时间(可为空) | `card_info` 字段: | 字段 | 类型 | 说明 | |------|------|------| | `iccid` | string | 物联网卡 ICCID | | `msisdn` | string | 手机号 | | `virtual_no` | string | 虚拟号 | --- ### 设备(/api/c/v1/device/) #### F1 设备卡列表 ``` GET /api/c/v1/device/cards?identifier=xxx ``` **响应体:** ```json { "cards": [ { "card_id": 1, "iccid": "898600...", "msisdn": "1380000...", "carrier_name": "中国移动", "network_status": "online", "real_name_status": 1, "slot_position": 1, "is_active": true } ] } ``` | 字段 | 类型 | 说明 | |------|------|------| | `card_id` | uint | 卡 ID | | `iccid` | string | 物联网卡 ICCID | | `msisdn` | string | 手机号 | | `carrier_name` | string | 运营商名称 | | `network_status` | string | 网络状态 | | `real_name_status` | int | 实名状态:0(未实名)/ 1(已实名) | | `slot_position` | int | 插槽位置 | | `is_active` | bool | 是否当前激活卡 | --- #### F2 设备重启 ``` POST /api/c/v1/device/reboot ``` **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `identifier` | string | 是 | 资产标识符,1~50 字符 | **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `accepted` | bool | 是否已受理 | | `request_id` | string | 请求 ID | --- #### F3 恢复出厂设置 ``` POST /api/c/v1/device/factory-reset ``` **请求体**:同 F2(`identifier` 字段) **响应体**:同 F2(`accepted` / `request_id`) --- #### F4 WiFi 配置 ``` POST /api/c/v1/device/wifi ``` **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `identifier` | string | 是 | 资产标识符,1~50 字符 | | `ssid` | string | 是 | WiFi 名称,1~32 字符 | | `password` | string | 是 | WiFi 密码,1~64 字符 | | `enabled` | bool | 是 | 是否启用 WiFi | **响应体**:同 F2(`accepted` / `request_id`) --- #### F5 切卡 ``` POST /api/c/v1/device/switch-card ``` **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `identifier` | string | 是 | 资产标识符,1~50 字符 | | `target_iccid` | string | 是 | 目标 ICCID,1~30 字符 | **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `accepted` | bool | 是否已受理 | | `target_iccid` | string | 目标 ICCID | --- ### 换货(/api/c/v1/exchange/) #### G1 查询进行中的换货通知 ``` GET /api/c/v1/exchange/pending?identifier=xxx ``` **Query 参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `identifier` | string | 是 | 资产标识符,1~100 字符 | **响应体:** | 字段 | 类型 | 说明 | |------|------|------| | `id` | uint | 换货单 ID | | `exchange_no` | string | 换货单号 | | `status` | int | 换货状态(1~5) | | `status_text` | string | 换货状态文本 | | `exchange_reason` | string | 换货原因 | | `created_at` | string | 创建时间 | > 若无进行中的换货单,返回空数据(非报错)。 --- #### G2 填写收货信息 ``` POST /api/c/v1/exchange/:id/shipping-info ``` **路径参数**:`id`(换货单 ID) **请求体:** | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `recipient_name` | string | 是 | 收件人姓名,1~50 字符 | | `recipient_phone` | string | 是 | 收件人电话,1~20 字符 | | `recipient_address` | string | 是 | 收货地址,1~500 字符 | --- ## 六、认证方式说明 | 端 | 认证方式 | Header 格式 | |----|----------|-------------| | 后台(`/api/admin/`) | Bearer Token(Redis 存储) | `Authorization: Bearer ` | | C 端(`/api/c/v1/`) | JWT | `Authorization: Bearer ` | **C 端 JWT 获取方式**:通过 A2 公众号登录或 A3 小程序登录接口获取,有效期请参考接口返回。 --- ## 七、统一响应格式 所有接口均返回以下格式: ```json { "code": 0, "msg": "success", "data": { ... }, "timestamp": 1710000000 } ``` | 字段 | 类型 | 说明 | |------|------|------| | `code` | int | 业务状态码,0 表示成功 | | `msg` | string | 提示信息 | | `data` | object | 业务数据 | | `timestamp` | int64 | 服务器时间戳(秒) | **常见错误码:** | 错误码 | 说明 | |--------|------| | 1001 | 缺失认证令牌 | | 1002 | 无效或过期令牌 | | 1003 | 权限不足 | | 1200 | 换货单不存在 | | 1201 | 换货单状态不允许此操作 | | 1202 | 旧资产不存在或已停用 | | 1203 | 新资产标识符无效 | | 1204 | 换货单已取消,无法操作 | | 1205 | 数据迁移失败 | | 1206 | 收货信息填写超时 | | 4000 | 参数错误 | | 5000 | 服务器内部错误 |