feat(zone): add Cloudflare-style traffic overview charts

Expose Zone stats API with multi-host access-log aggregates and time
series, and render unique visitors, requests and data served on the
Zone overview with 24h/7d/30d range controls.
This commit is contained in:
ryan
2026-07-12 16:38:35 +08:00
parent efcf61e32d
commit 31b4886a14
20 changed files with 1026 additions and 32 deletions
+1
View File
@@ -23,6 +23,7 @@ sidebar: false
### 新增
- Zone 概览页新增 Cloudflare 风格流量图:支持 24 小时 / 7 天 / 30 天,展示唯一访问者、请求总数与已提供数据趋势。
- 新增第一阶段 Zone 与正规化 Zone 域名数据库表及路由绑定模型,为后续以稳定 ID 管理网站与域名关联提供基础。
- 新增 Zone 管理 API 与显式历史域名导入命令,使用公共后缀列表验证注册根域和域名归属。
- 管理端网站入口改为 Zone 列表与 `/websites/:zoneId` 详情(概览 / 域名 / 路由 / 证书 / 设置),反代路由通过 Zone 域名选择器绑定。
+114
View File
@@ -11225,6 +11225,70 @@ const docTemplate = `{
}
}
},
"/api/v1/d/zones/{id}/stats": {
"get": {
"security": [
{
"SessionCookie": []
}
],
"description": "按 Zone 下全部域名聚合访问日志:唯一访问者、请求总数、已提供数据(字节)。range 支持 24h/7d/30d。",
"produces": [
"application/json"
],
"tags": [
"openflare-zone"
],
"summary": "获取 Zone 流量统计",
"parameters": [
{
"type": "integer",
"description": "Zone ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "时间范围:24h(默认)、7d、30d",
"name": "range",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.Any"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/zone.Stats"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.Any"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.Any"
}
}
}
}
},
"/api/v1/d/zones/{id}/update": {
"post": {
"security": [
@@ -18954,6 +19018,56 @@ const docTemplate = `{
"$ref": "#/definitions/model.Zone"
}
}
},
"zone.Stats": {
"type": "object",
"properties": {
"available": {
"description": "Available is false when analytics storage is unavailable (e.g. ClickHouse off).",
"type": "boolean"
},
"bytes_sent": {
"description": "BytesSent is total response bytes. Currently always 0 until access logs store body_bytes_sent.",
"type": "integer"
},
"domain_count": {
"description": "DomainCount is the number of explicit Zone domains used to scope hosts.",
"type": "integer"
},
"range": {
"$ref": "#/definitions/zone.StatsRange"
},
"range_hours": {
"type": "integer"
},
"request_count": {
"description": "RequestCount is total access-log requests for Zone domains.",
"type": "integer"
},
"unique_visitors": {
"description": "UniqueVisitors is distinct client IPs (remote_addr) over the window.",
"type": "integer"
},
"window_ended_at": {
"type": "string"
},
"window_started_at": {
"type": "string"
}
}
},
"zone.StatsRange": {
"type": "string",
"enum": [
"24h",
"7d",
"30d"
],
"x-enum-varnames": [
"StatsRange24h",
"StatsRange7d",
"StatsRange30d"
]
}
},
"securityDefinitions": {
+114
View File
@@ -11218,6 +11218,70 @@
}
}
},
"/api/v1/d/zones/{id}/stats": {
"get": {
"security": [
{
"SessionCookie": []
}
],
"description": "按 Zone 下全部域名聚合访问日志:唯一访问者、请求总数、已提供数据(字节)。range 支持 24h/7d/30d。",
"produces": [
"application/json"
],
"tags": [
"openflare-zone"
],
"summary": "获取 Zone 流量统计",
"parameters": [
{
"type": "integer",
"description": "Zone ID",
"name": "id",
"in": "path",
"required": true
},
{
"type": "string",
"description": "时间范围:24h(默认)、7d、30d",
"name": "range",
"in": "query"
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/response.Any"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/zone.Stats"
}
}
}
]
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/response.Any"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/response.Any"
}
}
}
}
},
"/api/v1/d/zones/{id}/update": {
"post": {
"security": [
@@ -18947,6 +19011,56 @@
"$ref": "#/definitions/model.Zone"
}
}
},
"zone.Stats": {
"type": "object",
"properties": {
"available": {
"description": "Available is false when analytics storage is unavailable (e.g. ClickHouse off).",
"type": "boolean"
},
"bytes_sent": {
"description": "BytesSent is total response bytes. Currently always 0 until access logs store body_bytes_sent.",
"type": "integer"
},
"domain_count": {
"description": "DomainCount is the number of explicit Zone domains used to scope hosts.",
"type": "integer"
},
"range": {
"$ref": "#/definitions/zone.StatsRange"
},
"range_hours": {
"type": "integer"
},
"request_count": {
"description": "RequestCount is total access-log requests for Zone domains.",
"type": "integer"
},
"unique_visitors": {
"description": "UniqueVisitors is distinct client IPs (remote_addr) over the window.",
"type": "integer"
},
"window_ended_at": {
"type": "string"
},
"window_started_at": {
"type": "string"
}
}
},
"zone.StatsRange": {
"type": "string",
"enum": [
"24h",
"7d",
"30d"
],
"x-enum-varnames": [
"StatsRange24h",
"StatsRange7d",
"StatsRange30d"
]
}
},
"securityDefinitions": {
+78
View File
@@ -3961,6 +3961,46 @@ definitions:
zone:
$ref: '#/definitions/model.Zone'
type: object
zone.Stats:
properties:
available:
description: Available is false when analytics storage is unavailable (e.g.
ClickHouse off).
type: boolean
bytes_sent:
description: BytesSent is total response bytes. Currently always 0 until access
logs store body_bytes_sent.
type: integer
domain_count:
description: DomainCount is the number of explicit Zone domains used to scope
hosts.
type: integer
range:
$ref: '#/definitions/zone.StatsRange'
range_hours:
type: integer
request_count:
description: RequestCount is total access-log requests for Zone domains.
type: integer
unique_visitors:
description: UniqueVisitors is distinct client IPs (remote_addr) over the
window.
type: integer
window_ended_at:
type: string
window_started_at:
type: string
type: object
zone.StatsRange:
enum:
- 24h
- 7d
- 30d
type: string
x-enum-varnames:
- StatsRange24h
- StatsRange7d
- StatsRange30d
info:
contact:
name: OpenFlare
@@ -10709,6 +10749,44 @@ paths:
summary: 获取 Zone 概览
tags:
- openflare-zone
/api/v1/d/zones/{id}/stats:
get:
description: 按 Zone 下全部域名聚合访问日志:唯一访问者、请求总数、已提供数据(字节)。range 支持 24h/7d/30d。
parameters:
- description: Zone ID
in: path
name: id
required: true
type: integer
- description: 时间范围:24h(默认)、7d、30d
in: query
name: range
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
allOf:
- $ref: '#/definitions/response.Any'
- properties:
data:
$ref: '#/definitions/zone.Stats'
type: object
"400":
description: Bad Request
schema:
$ref: '#/definitions/response.Any'
"404":
description: Not Found
schema:
$ref: '#/definitions/response.Any'
security:
- SessionCookie: []
summary: 获取 Zone 流量统计
tags:
- openflare-zone
/api/v1/d/zones/{id}/update:
post:
consumes: