## 套餐 (`packages`)

可售卖的基础套餐,定义流量、带宽、域名数等额度与价格。

鉴权: 仅管理员 · 文档: https://www-demo.kuxitong.com/zh/docs/api/packages

### GET `/api/v2/packages`

列出套餐 · 鉴权: 仅管理员

查询参数:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `page` | integer |  | 页码,从 1 开始。 默认: 1 |
| `page_size` | integer |  | 每页条数。 默认: 20 |
| `sort` | string |  | 排序字段,逗号分隔,前缀 `-` 表示降序,如 `-created_at,id`。 |

```sh
curl "https://panel.example.com/api/v2/packages" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/packages`

创建套餐 · 鉴权: 仅管理员

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `backup_group_id` | integer |  | 备用线路分组;null = 没有 |
| `bandwidth_mbps` | integer |  | 带宽 Mbps,-1 不限 |
| `buy_limit` | integer |  | 每租户最多持有几份,-1 不限 |
| `cname_domain_id` | integer |  | 接入根域(CNAME 域名);null = 套餐不绑线路 |
| `cname_host_suffix` | string |  | 新生成主机记录的后缀;空 = 只有 8 位随机名 |
| `cname_mode` | PackageCnameMode |  | CNAME 模式:site = 按站点生成(每个站点/四层转发各一个接入名);package = 按套餐生成(已售套餐下的站点/四层转发共用一个接入名)。 可选值: ["site","package"] |
| `connections` | integer |  | 并发连接数,-1 不限 |
| `custom_cc_rule` | boolean |  | 可自定义 CC 规则 |
| `des` | string |  | 备注说明 |
| `domains` | integer |  | 域名数(IP 站每站占 1),-1 不限 |
| `enabled` | boolean |  | 是否启用 |
| `group_ids` | integer[] |  | 所属套餐分组 |
| `http_ports` | integer |  | HTTP/HTTPS 非标端口数(80/443 之外),-1 不限 |
| `ip_num` | integer |  | 可选 IP 数(「我的 IP」),-1 不限 |
| `ip_pool_id` | integer |  | 开通 IP 站点用的 IP 池(IP 产品线);null = 不开通 |
| `ip_site_port` | integer |  | IP 站端口数:套餐下全部 IP 站点去重后的端口个数(含 80/443),-1 不限;IP 站端口不占非标端口数 |
| `l2` | boolean |  | 含分层回源(付费项 l2 的租户开关):租户还要主控授权的分层回源已开通,才能给网站打开分层回源、节点才按它回源;存量套餐为 false(升级时已开分层回源的租户,其已售套餐置 true) |
| `name` | string | 有 | 名称 |
| `node_group_id` | integer |  | 主线路分组;null = 套餐不绑线路 |
| `origin_ip_limit` | string[] |  | 允许的源站 IP/网段;空 = 不限。非空时该套餐下站点的源站须落在其中,域名源站不许 |
| `owners` | integer[] |  | 限定可购买的租户 id;空 = 不限 |
| `price_month_cents` | integer | 有 | 月价,分 |
| `price_quarter_cents` | integer | 有 | 季价,分 |
| `price_year_cents` | integer | 有 | 年价,分 |
| `region_id` | integer |  | 区域;null = 套餐不绑线路 |
| `renew_before_days` | integer |  | 到期前几天内才许续费,-1 不限 |
| `require_verified` | boolean |  | 须实名认证才能购买 |
| `sale_until` | string |  | 过了此刻不再出售;不给/null = 不限 |
| `sort` | integer |  | 排序值(小的在前)。 |
| `stream_ports` | integer |  | 四层转发端口数,-1 不限 |
| `traffic_gb` | integer |  | 每计费周期流量 GB,-1 不限 |
| `waf_enhanced` | boolean |  | 含 WAF 增强(付费项 waf_enhanced 的租户开关):租户还要主控授权的 WAF 增强未降级才能用标准/严格等级、大屏、Bot 深度、防篡改等;存量套餐为 false |
| `websocket` | boolean |  | 可开 WebSocket |

```sh
curl -X POST "https://panel.example.com/api/v2/packages" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domains":10,"group_ids":[],"http_ports":2,"name":"基础版","price_month_cents":3000,"price_quarter_cents":8000,"price_year_cents":30000}'
```

### POST `/api/v2/packages/batch-enable`

批量启用或禁用套餐 · 鉴权: 仅管理员

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `enabled` | boolean | 有 | 是否启用 |
| `ids` | integer[] | 有 | 要改的对象 id,至多 100 个。 |

```sh
curl -X POST "https://panel.example.com/api/v2/packages/batch-enable" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"enabled":false,"ids":[1,2]}'
```

### GET `/api/v2/packages/{id}`

获取套餐 · 鉴权: 仅管理员

```sh
curl "https://panel.example.com/api/v2/packages/{id}" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### PUT `/api/v2/packages/{id}`

修改套餐 · 鉴权: 仅管理员

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `backup_group_id` | integer |  | 备用线路分组;null = 没有 |
| `bandwidth_mbps` | integer |  | 带宽 Mbps,-1 不限 |
| `buy_limit` | integer |  | 每租户最多持有几份,-1 不限 |
| `cname_domain_id` | integer |  | 接入根域(CNAME 域名);null = 套餐不绑线路 |
| `cname_host_suffix` | string |  | 新生成主机记录的后缀;空 = 只有 8 位随机名 |
| `cname_mode` | PackageCnameMode |  | CNAME 模式:site = 按站点生成(每个站点/四层转发各一个接入名);package = 按套餐生成(已售套餐下的站点/四层转发共用一个接入名)。 可选值: ["site","package"] |
| `connections` | integer |  | 并发连接数,-1 不限 |
| `custom_cc_rule` | boolean |  | 可自定义 CC 规则 |
| `des` | string |  | 备注说明 |
| `domains` | integer |  | 域名数(IP 站每站占 1),-1 不限 |
| `enabled` | boolean |  | 是否启用 |
| `group_ids` | integer[] |  | 所属套餐分组 |
| `http_ports` | integer |  | HTTP/HTTPS 非标端口数(80/443 之外),-1 不限 |
| `ip_num` | integer |  | 可选 IP 数(「我的 IP」),-1 不限 |
| `ip_pool_id` | integer |  | 开通 IP 站点用的 IP 池(IP 产品线);null = 不开通 |
| `ip_site_port` | integer |  | IP 站端口数:套餐下全部 IP 站点去重后的端口个数(含 80/443),-1 不限;IP 站端口不占非标端口数 |
| `l2` | boolean |  | 含分层回源(付费项 l2 的租户开关):租户还要主控授权的分层回源已开通,才能给网站打开分层回源、节点才按它回源;存量套餐为 false(升级时已开分层回源的租户,其已售套餐置 true) |
| `name` | string | 有 | 名称 |
| `node_group_id` | integer |  | 主线路分组;null = 套餐不绑线路 |
| `origin_ip_limit` | string[] |  | 允许的源站 IP/网段;空 = 不限。非空时该套餐下站点的源站须落在其中,域名源站不许 |
| `owners` | integer[] |  | 限定可购买的租户 id;空 = 不限 |
| `price_month_cents` | integer | 有 | 月价,分 |
| `price_quarter_cents` | integer | 有 | 季价,分 |
| `price_year_cents` | integer | 有 | 年价,分 |
| `region_id` | integer |  | 区域;null = 套餐不绑线路 |
| `renew_before_days` | integer |  | 到期前几天内才许续费,-1 不限 |
| `require_verified` | boolean |  | 须实名认证才能购买 |
| `sale_until` | string |  | 过了此刻不再出售;不给/null = 不限 |
| `sort` | integer |  | 排序值(小的在前)。 |
| `stream_ports` | integer |  | 四层转发端口数,-1 不限 |
| `traffic_gb` | integer |  | 每计费周期流量 GB,-1 不限 |
| `waf_enhanced` | boolean |  | 含 WAF 增强(付费项 waf_enhanced 的租户开关):租户还要主控授权的 WAF 增强未降级才能用标准/严格等级、大屏、Bot 深度、防篡改等;存量套餐为 false |
| `websocket` | boolean |  | 可开 WebSocket |

```sh
curl -X PUT "https://panel.example.com/api/v2/packages/{id}" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domains":10,"group_ids":[],"http_ports":2,"name":"基础版","price_month_cents":3000,"price_quarter_cents":8000,"price_year_cents":30000}'
```

### DELETE `/api/v2/packages/{id}`

删除套餐 · 鉴权: 仅管理员

```sh
curl -X DELETE "https://panel.example.com/api/v2/packages/{id}" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/packages/{id}/syncs`

同步基础套餐到已购套餐 · 鉴权: 仅管理员

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `items` | PackageSyncField[] | 有 | 要同步的字段 |

```sh
curl -X POST "https://panel.example.com/api/v2/packages/{id}/syncs" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"items":["traffic_gb","price_month_cents"]}'
```

套餐对象:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `backup_group_id` | integer |  | 备用线路分组;null = 没有 |
| `bandwidth_mbps` | integer |  | 带宽 Mbps,-1 不限 |
| `buy_limit` | integer |  | 每租户最多持有几份,-1 不限 |
| `cname_domain_id` | integer |  | 接入根域(CNAME 域名);null = 套餐不绑线路 |
| `cname_host_suffix` | string |  | 新生成主机记录的后缀;空 = 只有 8 位随机名 |
| `cname_mode` | PackageCnameMode |  | CNAME 模式:site = 按站点生成(每个站点/四层转发各一个接入名);package = 按套餐生成(已售套餐下的站点/四层转发共用一个接入名)。 可选值: ["site","package"] |
| `connections` | integer |  | 并发连接数,-1 不限 |
| `created_at` | string |  | 创建时间 (只读) |
| `custom_cc_rule` | boolean |  | 可自定义 CC 规则 |
| `des` | string |  | 备注说明 |
| `domains` | integer |  | 域名数(IP 站每站占 1),-1 不限 |
| `enabled` | boolean |  | 是否启用 |
| `errors` | FieldError[] |  | 没改的逐条原因;field 为 /ids/<下标>,code 同单条修改接口(not_found、readonly 等)。 |
| `group_ids` | integer[] |  | 所属套餐分组 |
| `http_ports` | integer |  | HTTP/HTTPS 非标端口数(80/443 之外),-1 不限 |
| `id` | integer |  | 记录 ID (只读) |
| `ids` | integer[] | 有 | 要改的对象 id,至多 100 个。 |
| `ip_num` | integer |  | 可选 IP 数(「我的 IP」),-1 不限 |
| `ip_pool_id` | integer |  | 开通 IP 站点用的 IP 池(IP 产品线);null = 不开通 |
| `ip_site_port` | integer |  | IP 站端口数:套餐下全部 IP 站点去重后的端口个数(含 80/443),-1 不限;IP 站端口不占非标端口数 |
| `items` | PackageSyncField[] | 有 | 要同步的字段 |
| `l2` | boolean |  | 含分层回源(付费项 l2 的租户开关):租户还要主控授权的分层回源已开通,才能给网站打开分层回源、节点才按它回源;存量套餐为 false(升级时已开分层回源的租户,其已售套餐置 true) |
| `name` | string |  | 名称 |
| `node_group_id` | integer |  | 主线路分组;null = 套餐不绑线路 |
| `origin_ip_limit` | string[] |  | 允许的源站 IP/网段;空 = 不限。非空时该套餐下站点的源站须落在其中,域名源站不许 |
| `owners` | integer[] |  | 限定可购买的租户 id;空 = 不限 |
| `price_month_cents` | integer |  | 月价,分 |
| `price_quarter_cents` | integer |  | 季价,分 |
| `price_year_cents` | integer |  | 年价,分 |
| `region_id` | integer |  | 区域;null = 套餐不绑线路 |
| `renew_before_days` | integer |  | 到期前几天内才许续费,-1 不限 |
| `require_verified` | boolean |  | 须实名认证才能购买 |
| `sale_until` | string |  | 过了此刻不再出售;不给/null = 不限 |
| `skipped` | integer |  | 不跟随或至少一个改动字段单独改过而跳过的个数(其余字段照常同步) |
| `skipped_ids` | integer[] |  | 被跳过的已购套餐 id |
| `sort` | integer |  | 排序值(小的在前)。 |
| `stream_ports` | integer |  | 四层转发端口数,-1 不限 |
| `sync` | PackageSyncResult |  | 同步结果。 |
| `synced` | integer |  | 已同步的已购套餐数(自动同步时 = 本次改动的字段全部同步了的个数) |
| `traffic_gb` | integer |  | 每计费周期流量 GB,-1 不限 |
| `updated` | integer[] |  | 已改好的 id(含本来就是目标状态的),按请求顺序。 |
| `updated_at` | string |  | 更新时间 (只读) |
| `waf_enhanced` | boolean |  | 含 WAF 增强(付费项 waf_enhanced 的租户开关):租户还要主控授权的 WAF 增强未降级才能用标准/严格等级、大屏、Bot 深度、防篡改等;存量套餐为 false |
| `websocket` | boolean |  | 可开 WebSocket |
