mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-09 00:56:37 +08:00
migrate frontend
This commit is contained in:
@@ -27,6 +27,7 @@ import {PushService} from './push';
|
||||
import {AdminUploadService, UploadService} from './upload';
|
||||
import {UserService} from './user';
|
||||
import {
|
||||
AboutService,
|
||||
AccessLogService,
|
||||
ApplyLogService,
|
||||
ConfigVersionService,
|
||||
@@ -61,6 +62,7 @@ const services = {
|
||||
adminUpload: AdminUploadService,
|
||||
dbManage: DbManageService,
|
||||
push: PushService,
|
||||
openflareAbout: AboutService,
|
||||
openflareNode: NodeService,
|
||||
openflareProxyRoute: ProxyRouteService,
|
||||
openflareConfigVersion: ConfigVersionService,
|
||||
@@ -181,6 +183,7 @@ export type { PushEvent, PushHistory, PushChannelConfig, ListPushHistoriesReques
|
||||
// ==================== OpenFlare 业务服务导出 ====================
|
||||
|
||||
export {
|
||||
AboutService,
|
||||
LegacyOpenFlareBaseService,
|
||||
NodeService,
|
||||
ProxyRouteService,
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import {LegacyOpenFlareBaseService} from './legacy-base.service';
|
||||
|
||||
export class AboutService extends LegacyOpenFlareBaseService {
|
||||
protected static override readonly basePath = '/api';
|
||||
|
||||
static getAboutContent(): Promise<string> {
|
||||
return this.legacyGet<string>('/about');
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
export { AboutService } from './about.service';
|
||||
export { LegacyOpenFlareBaseService } from './legacy-base.service';
|
||||
export type { LegacyApiResponse } from './legacy-base.service';
|
||||
|
||||
@@ -87,6 +88,9 @@ export type {
|
||||
DatabaseCleanupTarget,
|
||||
LatestReleaseInfo,
|
||||
OpenFlarePublicStatus,
|
||||
UpgradeLogItem,
|
||||
UpgradeStreamSnapshot,
|
||||
UploadedServerBinaryInfo,
|
||||
OriginDetail,
|
||||
OriginItem,
|
||||
OriginMutationPayload,
|
||||
@@ -108,6 +112,7 @@ export type {
|
||||
TlsCertificateMutationPayload,
|
||||
} from './types';
|
||||
|
||||
import {AboutService} from './about.service';
|
||||
import {AccessLogService} from './access-log.service';
|
||||
import {ApplyLogService} from './apply-log.service';
|
||||
import {ConfigVersionService} from './config-version.service';
|
||||
@@ -126,6 +131,7 @@ import {WafService} from './waf.service';
|
||||
import {WebsiteService} from './website.service';
|
||||
|
||||
export const openflareServices = {
|
||||
about: AboutService,
|
||||
node: NodeService,
|
||||
proxyRoute: ProxyRouteService,
|
||||
configVersion: ConfigVersionService,
|
||||
|
||||
@@ -669,10 +669,28 @@ export interface LatestReleaseInfo {
|
||||
has_update: boolean;
|
||||
upgrade_supported: boolean;
|
||||
in_progress: boolean;
|
||||
upgrade_status: string;
|
||||
upgrade_status: 'idle' | 'running' | 'succeeded' | 'failed' | string;
|
||||
upgrade_logs: UpgradeLogItem[];
|
||||
}
|
||||
|
||||
export interface UpgradeStreamSnapshot {
|
||||
in_progress: boolean;
|
||||
upgrade_status: 'idle' | 'running' | 'succeeded' | 'failed' | string;
|
||||
upgrade_logs: UpgradeLogItem[];
|
||||
}
|
||||
|
||||
export interface UploadedServerBinaryInfo {
|
||||
upload_token: string;
|
||||
file_name: string;
|
||||
detected_version: string;
|
||||
current_version: string;
|
||||
has_update: boolean;
|
||||
upgrade_supported: boolean;
|
||||
ready_to_upgrade: boolean;
|
||||
comparison_message: string;
|
||||
uploaded_at: string;
|
||||
}
|
||||
|
||||
export interface WAFRuleGroup {
|
||||
id: number;
|
||||
name: string;
|
||||
|
||||
@@ -1,16 +1,135 @@
|
||||
import type {InternalAxiosRequestConfig} from 'axios';
|
||||
|
||||
import {getApiBaseUrl} from '@/lib/services/core/config';
|
||||
import {ApiErrorBase} from '@/lib/services/core/errors';
|
||||
|
||||
import type {LegacyApiResponse} from './legacy-base.service';
|
||||
import {LegacyOpenFlareBaseService} from './legacy-base.service';
|
||||
import type {LatestReleaseInfo, ReleaseChannel} from './types';
|
||||
import type {LatestReleaseInfo, ReleaseChannel, UpgradeStreamSnapshot, UploadedServerBinaryInfo,} from './types';
|
||||
|
||||
/**
|
||||
* OpenFlare 服务端升级 API(遗留 `/api/update/*`)。
|
||||
*
|
||||
* 可选集成:在顶栏或 Admin 升级入口调用 `getLatestRelease()` 展示版本与更新状态;
|
||||
* 完整升级流程(upgrade / manual-upload / logs WebSocket)可对接 Wavelet `admin/updater`。
|
||||
*/
|
||||
export class UpdateService extends LegacyOpenFlareBaseService {
|
||||
protected static override readonly basePath = '/api/update';
|
||||
|
||||
private static getLegacyApiUrl(path: string): string {
|
||||
const baseURL = getApiBaseUrl();
|
||||
const fullPath = this.getFullPath(path);
|
||||
if (!baseURL) {
|
||||
return fullPath;
|
||||
}
|
||||
return `${baseURL.replace(/\/$/, '')}${fullPath}`;
|
||||
}
|
||||
|
||||
static getLatestRelease(channel: ReleaseChannel = 'stable'): Promise<LatestReleaseInfo> {
|
||||
return this.legacyGet<LatestReleaseInfo>('/latest-release', { channel });
|
||||
}
|
||||
|
||||
static upgradeServer(channel: ReleaseChannel = 'stable'): Promise<LatestReleaseInfo> {
|
||||
return this.legacyPost<LatestReleaseInfo>('/upgrade', { channel });
|
||||
}
|
||||
|
||||
static uploadServerBinary(
|
||||
binary: File,
|
||||
onProgress?: (progress: number) => void,
|
||||
): Promise<UploadedServerBinaryInfo> {
|
||||
const formData = new FormData();
|
||||
formData.append('binary', binary);
|
||||
|
||||
if (!onProgress) {
|
||||
return this.legacyPost<UploadedServerBinaryInfo>('/manual-upload', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
} as InternalAxiosRequestConfig);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', this.getLegacyApiUrl('/manual-upload'));
|
||||
xhr.withCredentials = true;
|
||||
|
||||
xhr.upload.addEventListener('progress', (event) => {
|
||||
if (event.lengthComputable) {
|
||||
onProgress(Math.round((event.loaded / event.total) * 100));
|
||||
}
|
||||
});
|
||||
|
||||
xhr.addEventListener('load', () => {
|
||||
let payload: LegacyApiResponse<UploadedServerBinaryInfo> | null = null;
|
||||
try {
|
||||
payload = JSON.parse(
|
||||
xhr.responseText,
|
||||
) as LegacyApiResponse<UploadedServerBinaryInfo>;
|
||||
} catch {
|
||||
payload = null;
|
||||
}
|
||||
if (xhr.status < 200 || xhr.status >= 300) {
|
||||
reject(
|
||||
new ApiErrorBase(
|
||||
payload?.message || `请求失败(${xhr.status})`,
|
||||
undefined,
|
||||
xhr.status,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (!payload) {
|
||||
reject(new ApiErrorBase('响应格式无效', undefined, xhr.status));
|
||||
return;
|
||||
}
|
||||
if (!payload.success) {
|
||||
reject(new ApiErrorBase(payload.message || '请求失败', undefined, xhr.status));
|
||||
return;
|
||||
}
|
||||
resolve(payload.data);
|
||||
});
|
||||
|
||||
xhr.addEventListener('error', () => {
|
||||
reject(new ApiErrorBase('上传过程中网络连接中断,请检查网络后重试', undefined, 0));
|
||||
});
|
||||
|
||||
xhr.send(formData);
|
||||
});
|
||||
}
|
||||
|
||||
static confirmManualServerUpgrade(uploadToken: string): Promise<UploadedServerBinaryInfo> {
|
||||
return this.legacyPost<UploadedServerBinaryInfo>('/manual-upgrade', {
|
||||
upload_token: uploadToken,
|
||||
});
|
||||
}
|
||||
|
||||
static createUpgradeLogsWebSocket(): WebSocket | null {
|
||||
if (typeof window === 'undefined') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const apiUrl = this.getLegacyApiUrl('/logs/ws');
|
||||
const resolvedUrl = apiUrl.startsWith('http://')
|
||||
? `ws://${apiUrl.slice('http://'.length)}`
|
||||
: apiUrl.startsWith('https://')
|
||||
? `wss://${apiUrl.slice('https://'.length)}`
|
||||
: `${window.location.protocol === 'https:' ? 'wss:' : 'ws:'}//${window.location.host}${apiUrl}`;
|
||||
|
||||
return new WebSocket(resolvedUrl);
|
||||
}
|
||||
|
||||
static parseUpgradeStreamSnapshot(rawMessage: string): UpgradeStreamSnapshot | null {
|
||||
try {
|
||||
const parsed = JSON.parse(rawMessage) as Partial<UpgradeStreamSnapshot>;
|
||||
if (
|
||||
typeof parsed.in_progress !== 'boolean' ||
|
||||
typeof parsed.upgrade_status !== 'string' ||
|
||||
!Array.isArray(parsed.upgrade_logs)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
in_progress: parsed.in_progress,
|
||||
upgrade_status: parsed.upgrade_status,
|
||||
upgrade_logs: parsed.upgrade_logs,
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user