## 全局黑白名单 (`global-ip-lists`)

平台级 IP 黑名单与白名单(全网生效),条目可带到期时间、原因与来源,支持批量导入导出;仅管理员可改。

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

### GET `/api/v2/global-ip-lists`

获取全局黑白名单 · 鉴权: 仅管理员

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

### PUT `/api/v2/global-ip-lists`

设置全局黑白名单 · 鉴权: 仅管理员

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `black` | string[] |  | 黑名单的 IP/CIDR(未过期的全部条目)。 |
| `black_items` | IpListItem[] |  | 黑名单条目(含到期时间、原因、来源)。 |
| `expected_updated_at` | string |  | 乐观锁:调用方读到的 updated_at(读到为空 = 还没设置过,用 1970-01-01T00:00:00Z)。与库里当前值不等则回 409 stale_version、不保存;不带则不检查。 |
| `white` | string[] |  | 白名单的 IP/CIDR(未过期的全部条目)。 |
| `white_items` | IpListItem[] |  | 白名单条目(含到期时间、原因、来源)。 |

```sh
curl -X PUT "https://panel.example.com/api/v2/global-ip-lists" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"black_items":[{"expires_at":"2030-01-01T00:00:00Z","ip":"198.51.100.0/24","reason":"scanner"}]}'
```

### GET `/api/v2/global-ip-lists/export`

导出全局黑白名单 · 鉴权: 仅管理员

查询参数:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `list` | string | 有 | 导出哪张名单。 可选值: ["black","white"] |
| `source` | IpListSource |  | 只导出该来源的条目;不带为全部。 可选值: ["manual","import","ip_detail","api"] |
| `format` | string |  | txt(缺省,纯文本每行一条)或 csv(带表头与来源列、UTF-8 BOM)。 可选值: ["txt","csv"] 默认: "txt" |

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

### POST `/api/v2/global-ip-lists/import`

批量导入全局黑白名单 · 鉴权: 仅管理员

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `dry_run` | boolean |  | true 只预检,不保存。 默认: false |
| `expected_updated_at` | string |  | 乐观锁:调用方读到的 updated_at(读到为空 = 还没设置过,用 1970-01-01T00:00:00Z)。与库里当前值不等则回 409 stale_version、不保存;不带则不检查。 |
| `list` | string | 有 | 导入到哪张名单。 可选值: ["black","white"] |
| `mode` | string |  | merge 并进现有名单(同 IP 以导入行为准);replace 用导入行替换整张名单。 可选值: ["merge","replace"] 默认: "merge" |
| `text` | string | 有 | 文件内容(txt/csv),每行 IP/CIDR[,到期时间][,原因]。 |

```sh
curl -X POST "https://panel.example.com/api/v2/global-ip-lists/import" \
  -H "X-API-Key: $GOCDN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dry_run":true,"list":"black","mode":"merge","text":"198.51.100.0/24,2030-01-01T00:00:00Z,scanner\n"}'
```

全局黑白名单对象:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `added` | integer |  | 新增条数。 |
| `applied` | boolean |  | 是否已保存(dry_run 或有挡导入的问题时为 false)。 |
| `black` | string[] |  | 黑名单的 IP/CIDR(未过期的全部条目)。 |
| `black_items` | IpListItem[] |  | 黑名单条目(含到期时间、原因、来源)。 |
| `dry_run` | boolean |  | true 只预检,不保存。 默认: false |
| `expected_updated_at` | string |  | 乐观锁:调用方读到的 updated_at(读到为空 = 还没设置过,用 1970-01-01T00:00:00Z)。与库里当前值不等则回 409 stale_version、不保存;不带则不检查。 |
| `issues` | IpListImportIssue[] |  | 逐行问题(最多 1000 条,按行号升序)。 |
| `lines` | integer |  | 有效条目数(去重后)。 |
| `list` | string | 有 | 导入到哪张名单。 可选值: ["black","white"] |
| `mode` | string |  | merge 并进现有名单(同 IP 以导入行为准);replace 用导入行替换整张名单。 可选值: ["merge","replace"] 默认: "merge" |
| `removed` | integer |  | replace 模式下原有、新名单里没有的条数(同 IP 的算「更新」,不算在内)。 |
| `text` | string | 有 | 文件内容(txt/csv),每行 IP/CIDR[,到期时间][,原因]。 |
| `updated` | integer |  | 已在名单里、被导入行更新的条数。 |
| `updated_at` | string |  | 更新时间 (只读) |
| `white` | string[] |  | 白名单的 IP/CIDR(未过期的全部条目)。 |
| `white_items` | IpListItem[] |  | 白名单条目(含到期时间、原因、来源)。 |
