feat(web): add zone-based website management

以稳定 Zone ID 替换旧托管域名详情页:列表展示根域与域名计数,详情提供
概览/域名/路由/证书/设置 Tabs,并补齐 ZoneService 与 vitest 行为测试。
Zone 列表 API 返回 domain_count;同步 Swagger 与重构计划进度。
This commit is contained in:
ryan
2026-07-12 15:23:43 +08:00
parent d4d9bad74d
commit 350b433cc1
30 changed files with 2369 additions and 1178 deletions
+5
View File
@@ -42,6 +42,8 @@ import {
UptimeKumaService,
WafService,
WebsiteService,
ZoneDomainService,
ZoneService,
} from './openflare';
const services = {
@@ -67,6 +69,8 @@ const services = {
openflareDashboard: DashboardService,
openflareWaf: WafService,
openflareWebsite: WebsiteService,
openflareZone: ZoneService,
openflareZoneDomain: ZoneDomainService,
openflareTls: TlsCertificateService,
openflareDns: DnsAccountService,
openflarePages: PagesService,
@@ -201,6 +205,7 @@ export {
export type {
NodeItem,
ProxyRouteItem,
ProxyRouteZoneDomain,
ProxyRouteConfigSection,
ConfigVersionSummary,
ConfigVersionDetail,
+7
View File
@@ -7,6 +7,7 @@ export { ApplyLogService } from './apply-log.service';
export { DashboardService } from './dashboard.service';
export { WafService } from './waf.service';
export { WebsiteService } from './website.service';
export { ZoneDomainService, ZoneService, zoneQueryKey } from './zone.service';
export { TlsCertificateService } from './tls-certificate.service';
export { DnsAccountService } from './dns-account.service';
export { PagesService } from './pages.service';
@@ -49,6 +50,7 @@ export type {
ProxyRouteItem,
ProxyRouteMutationPayload,
ProxyRoutePoWConfig,
ProxyRouteZoneDomain,
ReleaseChannel,
SupportFile,
DashboardOverview,
@@ -105,6 +107,11 @@ export type {
ManagedDomainItem,
ManagedDomainMatchResult,
ManagedDomainMutationPayload,
ZoneDomainItem,
ZoneDomainMutationPayload,
ZoneItem,
ZoneMutationPayload,
ZoneOverview,
TlsCertificateApplyPayload,
TlsCertificateContentItem,
TlsCertificateDetailItem,
+49 -13
View File
@@ -228,13 +228,19 @@ export interface ProxyRoutePoWConfig {
blacklist: ProxyRoutePoWListConfig;
}
/** Route-bound Zone domain as returned by proxy-route APIs. */
export interface ProxyRouteZoneDomain {
id: number;
zone_id: number;
domain: string;
cert_id: number | null;
}
export interface ProxyRouteItem {
id: number;
site_name: string;
domain: string;
domains: string[];
primary_domain: string;
domain_count: number;
zone_domain_ids: number[];
zone_domains: ProxyRouteZoneDomain[];
origin_id: number | null;
origin_url: string;
origin_host: string;
@@ -242,9 +248,6 @@ export interface ProxyRouteItem {
upstream_list: string[];
enabled: boolean;
enable_https: boolean;
cert_id: number | null;
cert_ids: number[];
domain_cert_ids: number[];
redirect_http: boolean;
limit_conn_per_server: number;
limit_conn_per_ip: number;
@@ -271,8 +274,7 @@ export interface ProxyRouteItem {
export interface ProxyRouteMutationPayload {
site_name?: string;
domain: string;
domains?: string[];
zone_domain_ids: number[];
origin_id: number | null;
origin_url: string;
origin_scheme: 'http' | 'https';
@@ -283,9 +285,6 @@ export interface ProxyRouteMutationPayload {
upstreams: string[];
enabled: boolean;
enable_https: boolean;
cert_id: number | null;
cert_ids?: number[];
domain_cert_ids?: number[];
redirect_http: boolean;
limit_conn_per_server?: number;
limit_conn_per_ip?: number;
@@ -962,6 +961,43 @@ export interface DashboardOverviewCompact {
// ==================== Websites / TLS / DNS ====================
export interface ZoneItem {
id: number;
domain: string;
remark: string;
/** Present on list API; may be omitted on nested zone objects. */
domain_count?: number;
created_at: string;
updated_at: string;
}
export interface ZoneMutationPayload {
domain: string;
remark: string;
}
export interface ZoneDomainItem {
id: number;
zone_id: number;
proxy_route_id: number | null;
domain: string;
cert_id: number | null;
remark: string;
created_at: string;
updated_at: string;
}
export interface ZoneDomainMutationPayload {
domain: string;
cert_id: number | null;
remark: string;
}
export interface ZoneOverview {
zone: ZoneItem;
domains: ZoneDomainItem[];
}
export interface ManagedDomainItem {
id: number;
domain: string;
@@ -1078,4 +1114,4 @@ export interface DnsAccountMutationPayload {
name: string;
type: string;
authorization: string;
}
}
@@ -0,0 +1,22 @@
import {OpenFlareBaseService} from './base.service'
import type {ZoneDomainItem, ZoneDomainMutationPayload, ZoneItem, ZoneMutationPayload, ZoneOverview} from './types'
export const zoneQueryKey = ['openflare', 'zones'] as const
export class ZoneService extends OpenFlareBaseService {
protected static override readonly basePath = '/api/v1/d/zones'
static list(): Promise<ZoneItem[]> { return this.get<ZoneItem[]>('/') }
static getOverview(id: number): Promise<ZoneOverview> { return this.get<ZoneOverview>(`/${id}/overview`) }
static create(payload: ZoneMutationPayload): Promise<ZoneItem> { return this.post<ZoneItem>('/', payload) }
static update(id: number, payload: ZoneMutationPayload): Promise<ZoneItem> { return this.post<ZoneItem>(`/${id}/update`, payload) }
static deleteById(id: number): Promise<void> { return this.post<void>(`/${id}/delete`) }
}
export class ZoneDomainService extends OpenFlareBaseService {
protected static override readonly basePath = '/api/v1/d/zones'
static create(zoneId: number, payload: ZoneDomainMutationPayload): Promise<ZoneDomainItem> { return this.post<ZoneDomainItem>(`/${zoneId}/domains`, payload) }
static update(zoneId: number, id: number, payload: ZoneDomainMutationPayload): Promise<ZoneDomainItem> { return this.post<ZoneDomainItem>(`/${zoneId}/domains/${id}/update`, payload) }
static deleteById(zoneId: number, id: number): Promise<void> { return this.post<void>(`/${zoneId}/domains/${id}/delete`) }
}