mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-08 08:36:37 +08:00
prettier
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
import {BaseService} from '@/lib/services/core';
|
||||
import type {AuthSource, AuthSourceRequest, ToggleAuthSourceRequest} from './types';
|
||||
import { BaseService } from '@/lib/services/core';
|
||||
import type {
|
||||
AuthSource,
|
||||
AuthSourceRequest,
|
||||
ToggleAuthSourceRequest,
|
||||
} from './types';
|
||||
|
||||
export class AdminAuthSourceService extends BaseService {
|
||||
protected static readonly basePath = '/api/v1/admin';
|
||||
@@ -8,19 +12,27 @@ export class AdminAuthSourceService extends BaseService {
|
||||
return this.get<AuthSource[]>('/auth-sources');
|
||||
}
|
||||
|
||||
static async createAuthSource(request: AuthSourceRequest): Promise<AuthSource> {
|
||||
static async createAuthSource(
|
||||
request: AuthSourceRequest,
|
||||
): Promise<AuthSource> {
|
||||
return this.post<AuthSource>('/auth-sources', request);
|
||||
}
|
||||
|
||||
static async updateAuthSource(id: string, request: AuthSourceRequest): Promise<AuthSource> {
|
||||
static async updateAuthSource(
|
||||
id: string,
|
||||
request: AuthSourceRequest,
|
||||
): Promise<AuthSource> {
|
||||
return this.put<AuthSource>(`/auth-sources/${id}`, request);
|
||||
}
|
||||
|
||||
static async toggleAuthSource(id: string, request: ToggleAuthSourceRequest): Promise<void> {
|
||||
static async toggleAuthSource(
|
||||
id: string,
|
||||
request: ToggleAuthSourceRequest,
|
||||
): Promise<void> {
|
||||
return this.put<void>(`/auth-sources/${id}/toggle`, request);
|
||||
}
|
||||
|
||||
static async deleteAuthSource(id: string): Promise<void> {
|
||||
return this.delete<void>(`/auth-sources/${id}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {BaseService} from '@/lib/services/core';
|
||||
import type {CacheConfig, CacheStatus} from './types';
|
||||
import { BaseService } from '@/lib/services/core';
|
||||
import type { CacheConfig, CacheStatus } from './types';
|
||||
|
||||
export class AdminCacheService extends BaseService {
|
||||
protected static readonly basePath = '/api/v1/admin';
|
||||
@@ -15,4 +15,4 @@ export class AdminCacheService extends BaseService {
|
||||
static async clearCache(): Promise<void> {
|
||||
return this.post<void>('/cache/clear');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,4 +41,4 @@ export type {
|
||||
StorageDriver,
|
||||
StorageConfig,
|
||||
ObjectStorageConfig,
|
||||
} from './types';
|
||||
} from './types';
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import {BaseService} from '@/lib/services/core';
|
||||
import { BaseService } from '@/lib/services/core';
|
||||
|
||||
export class AdminLogService extends BaseService {
|
||||
protected static readonly basePath = '/api/v1/admin';
|
||||
|
||||
static async getLogs(cursor: number = 0, limit: number = 200): Promise<{
|
||||
static async getLogs(
|
||||
cursor: number = 0,
|
||||
limit: number = 200,
|
||||
): Promise<{
|
||||
lines: Array<{ index: number; data: string }>;
|
||||
has_more: boolean;
|
||||
next_cursor: number;
|
||||
@@ -50,4 +53,4 @@ export class AdminLogService extends BaseService {
|
||||
}> {
|
||||
return this.get('/logs/analytics');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {BaseService} from '@/lib/services/core';
|
||||
import type {AppUpdateStatus, SystemStatus} from './types';
|
||||
import { BaseService } from '@/lib/services/core';
|
||||
import type { AppUpdateStatus, SystemStatus } from './types';
|
||||
|
||||
export class AdminStatusService extends BaseService {
|
||||
protected static readonly basePath = '/api/v1/admin';
|
||||
@@ -15,4 +15,4 @@ export class AdminStatusService extends BaseService {
|
||||
static async applyUpdate(): Promise<void> {
|
||||
return this.post<void>('/update/apply');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {BaseService} from '@/lib/services/core';
|
||||
import { BaseService } from '@/lib/services/core';
|
||||
import type {
|
||||
CreateSystemConfigRequest,
|
||||
SystemConfig,
|
||||
@@ -8,11 +8,15 @@ import type {
|
||||
export class AdminSystemConfigService extends BaseService {
|
||||
protected static readonly basePath = '/api/v1/admin';
|
||||
|
||||
static async createSystemConfig(request: CreateSystemConfigRequest): Promise<void> {
|
||||
static async createSystemConfig(
|
||||
request: CreateSystemConfigRequest,
|
||||
): Promise<void> {
|
||||
return this.post<void>('/system-configs', request);
|
||||
}
|
||||
|
||||
static async listSystemConfigs(type?: 'system' | 'business'): Promise<SystemConfig[]> {
|
||||
static async listSystemConfigs(
|
||||
type?: 'system' | 'business',
|
||||
): Promise<SystemConfig[]> {
|
||||
const query = type ? `?type=${type}` : '';
|
||||
return this.get<SystemConfig[]>(`/system-configs${query}`);
|
||||
}
|
||||
@@ -21,7 +25,10 @@ export class AdminSystemConfigService extends BaseService {
|
||||
return this.get<SystemConfig>(`/system-configs/${key}`);
|
||||
}
|
||||
|
||||
static async updateSystemConfig(key: string, request: UpdateSystemConfigRequest): Promise<void> {
|
||||
static async updateSystemConfig(
|
||||
key: string,
|
||||
request: UpdateSystemConfigRequest,
|
||||
): Promise<void> {
|
||||
return this.put<void>(`/system-configs/${key}`, request);
|
||||
}
|
||||
|
||||
@@ -41,4 +48,4 @@ export class AdminSystemConfigService extends BaseService {
|
||||
static async listUploadTypes(): Promise<string[]> {
|
||||
return this.get<string[]>('/uploads/types');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {BaseService} from '@/lib/services/core';
|
||||
import { BaseService } from '@/lib/services/core';
|
||||
import type {
|
||||
CreateScheduleRequest,
|
||||
DispatchTaskRequest,
|
||||
@@ -61,15 +61,20 @@ export class AdminTaskService extends BaseService {
|
||||
return this.get<Schedule[]>('/tasks/schedules');
|
||||
}
|
||||
|
||||
static async createSchedule(request: CreateScheduleRequest): Promise<Schedule> {
|
||||
static async createSchedule(
|
||||
request: CreateScheduleRequest,
|
||||
): Promise<Schedule> {
|
||||
return this.post<Schedule>('/tasks/schedules', request);
|
||||
}
|
||||
|
||||
static async updateSchedule(id: string, request: UpdateScheduleRequest): Promise<Schedule> {
|
||||
static async updateSchedule(
|
||||
id: string,
|
||||
request: UpdateScheduleRequest,
|
||||
): Promise<Schedule> {
|
||||
return this.put<Schedule>(`/tasks/schedules/${id}`, request);
|
||||
}
|
||||
|
||||
static async deleteSchedule(id: string): Promise<void> {
|
||||
return this.delete<void>(`/tasks/schedules/${id}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import {BaseService} from '@/lib/services/core';
|
||||
import type {CreateTemplateRequest, Template, UpdateTemplateRequest} from './types';
|
||||
import { BaseService } from '@/lib/services/core';
|
||||
import type {
|
||||
CreateTemplateRequest,
|
||||
Template,
|
||||
UpdateTemplateRequest,
|
||||
} from './types';
|
||||
|
||||
export class AdminTemplateService extends BaseService {
|
||||
protected static readonly basePath = '/api/v1/admin';
|
||||
@@ -12,15 +16,20 @@ export class AdminTemplateService extends BaseService {
|
||||
return this.get<Template>(`/templates/${key}`);
|
||||
}
|
||||
|
||||
static async createTemplate(request: CreateTemplateRequest): Promise<Template> {
|
||||
static async createTemplate(
|
||||
request: CreateTemplateRequest,
|
||||
): Promise<Template> {
|
||||
return this.post<Template>('/templates', request);
|
||||
}
|
||||
|
||||
static async updateTemplate(key: string, request: UpdateTemplateRequest): Promise<Template> {
|
||||
static async updateTemplate(
|
||||
key: string,
|
||||
request: UpdateTemplateRequest,
|
||||
): Promise<Template> {
|
||||
return this.put<Template>(`/templates/${key}`, request);
|
||||
}
|
||||
|
||||
static async deleteTemplate(key: string): Promise<void> {
|
||||
return this.delete<void>(`/templates/${key}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
/**
|
||||
* 系统配置信息
|
||||
*/
|
||||
@@ -178,7 +176,8 @@ export interface DispatchTaskRequest {
|
||||
payload?: string;
|
||||
}
|
||||
|
||||
export type TaskExecutionStatus = 'pending' | 'running' | 'succeeded' | 'failed';
|
||||
export type TaskExecutionStatus =
|
||||
'pending' | 'running' | 'succeeded' | 'failed';
|
||||
|
||||
/**
|
||||
* 任务执行记录
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {BaseService} from '@/lib/services/core';
|
||||
import { BaseService } from '@/lib/services/core';
|
||||
import type {
|
||||
AdminUser,
|
||||
CreateUserRequest,
|
||||
@@ -11,15 +11,23 @@ import type {
|
||||
export class AdminUserService extends BaseService {
|
||||
protected static readonly basePath = '/api/v1/admin';
|
||||
|
||||
static async listUsers(request: ListUsersRequest): Promise<ListUsersResponse> {
|
||||
return this.get<ListUsersResponse>('/users', request as unknown as Record<string, unknown>);
|
||||
static async listUsers(
|
||||
request: ListUsersRequest,
|
||||
): Promise<ListUsersResponse> {
|
||||
return this.get<ListUsersResponse>(
|
||||
'/users',
|
||||
request as unknown as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
|
||||
static async getUser(id: string): Promise<AdminUser> {
|
||||
return this.get<AdminUser>(`/users/${id}`);
|
||||
}
|
||||
|
||||
static async updateUserStatus(id: string, request: UpdateUserStatusRequest): Promise<void> {
|
||||
static async updateUserStatus(
|
||||
id: string,
|
||||
request: UpdateUserStatusRequest,
|
||||
): Promise<void> {
|
||||
return this.put<void>(`/users/${id}/status`, request);
|
||||
}
|
||||
|
||||
@@ -31,7 +39,10 @@ export class AdminUserService extends BaseService {
|
||||
return this.delete<void>(`/users/${id}`);
|
||||
}
|
||||
|
||||
static async updateUser(id: string, request: UpdateUserRequest): Promise<void> {
|
||||
static async updateUser(
|
||||
id: string,
|
||||
request: UpdateUserRequest,
|
||||
): Promise<void> {
|
||||
return this.put<void>(`/users/${id}`, request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type {InternalAxiosRequestConfig} from 'axios';
|
||||
import {BaseService} from '@/lib/services/core';
|
||||
import type { InternalAxiosRequestConfig } from 'axios';
|
||||
import { BaseService } from '@/lib/services/core';
|
||||
import type {
|
||||
AuthSource,
|
||||
ChangePasswordRequest,
|
||||
@@ -40,8 +40,13 @@ export class AuthService extends BaseService {
|
||||
return this.get<AuthSource[]>('/oauth/sources');
|
||||
}
|
||||
|
||||
static async getAuthorizeUrl(source: string, purpose: 'login' | 'bind' = 'login'): Promise<OAuthAuthorizeResponse> {
|
||||
return this.get<OAuthAuthorizeResponse>(`/oauth/${encodeURIComponent(source)}/authorize?purpose=${purpose}`);
|
||||
static async getAuthorizeUrl(
|
||||
source: string,
|
||||
purpose: 'login' | 'bind' = 'login',
|
||||
): Promise<OAuthAuthorizeResponse> {
|
||||
return this.get<OAuthAuthorizeResponse>(
|
||||
`/oauth/${encodeURIComponent(source)}/authorize?purpose=${purpose}`,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,7 +69,9 @@ export class AuthService extends BaseService {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
static async handleCallback(request: OAuthCallbackRequest): Promise<OAuthCallbackResult> {
|
||||
static async handleCallback(
|
||||
request: OAuthCallbackRequest,
|
||||
): Promise<OAuthCallbackResult> {
|
||||
return this.post<OAuthCallbackResult>('/oauth/callback', request);
|
||||
}
|
||||
|
||||
@@ -105,16 +112,44 @@ export class AuthService extends BaseService {
|
||||
await this.get<void>('/oauth/logout');
|
||||
}
|
||||
|
||||
static async login(request: LoginRequest, headers?: Record<string, string>): Promise<User> {
|
||||
return this.post<User>('/user/login', request, headers ? ({ headers } as unknown as InternalAxiosRequestConfig) : undefined);
|
||||
static async login(
|
||||
request: LoginRequest,
|
||||
headers?: Record<string, string>,
|
||||
): Promise<User> {
|
||||
return this.post<User>(
|
||||
'/user/login',
|
||||
request,
|
||||
headers
|
||||
? ({ headers } as unknown as InternalAxiosRequestConfig)
|
||||
: undefined,
|
||||
);
|
||||
}
|
||||
|
||||
static async register(request: RegisterRequest, headers?: Record<string, string>): Promise<User> {
|
||||
return this.post<User>('/user/register', request, headers ? ({ headers } as unknown as InternalAxiosRequestConfig) : undefined);
|
||||
static async register(
|
||||
request: RegisterRequest,
|
||||
headers?: Record<string, string>,
|
||||
): Promise<User> {
|
||||
return this.post<User>(
|
||||
'/user/register',
|
||||
request,
|
||||
headers
|
||||
? ({ headers } as unknown as InternalAxiosRequestConfig)
|
||||
: undefined,
|
||||
);
|
||||
}
|
||||
|
||||
static async sendEmailCode(email: string, scene: 'register' | 'login', headers?: Record<string, string>): Promise<void> {
|
||||
return this.post<void>('/user/send-email-code', { email, scene }, headers ? ({ headers } as unknown as InternalAxiosRequestConfig) : undefined);
|
||||
static async sendEmailCode(
|
||||
email: string,
|
||||
scene: 'register' | 'login',
|
||||
headers?: Record<string, string>,
|
||||
): Promise<void> {
|
||||
return this.post<void>(
|
||||
'/user/send-email-code',
|
||||
{ email, scene },
|
||||
headers
|
||||
? ({ headers } as unknown as InternalAxiosRequestConfig)
|
||||
: undefined,
|
||||
);
|
||||
}
|
||||
|
||||
static async changePassword(request: ChangePasswordRequest): Promise<void> {
|
||||
@@ -130,6 +165,8 @@ export class AuthService extends BaseService {
|
||||
}
|
||||
|
||||
static async deleteExternalAccountBinding(id: string): Promise<void> {
|
||||
return this.post<void>(`/oauth/external-accounts/${encodeURIComponent(id)}/delete`);
|
||||
return this.post<void>(
|
||||
`/oauth/external-accounts/${encodeURIComponent(id)}/delete`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* 认证服务模块
|
||||
*
|
||||
*
|
||||
* @description
|
||||
* 提供 OAuth 认证相关的功能,包括:
|
||||
* - 获取登录 URL
|
||||
@@ -8,18 +8,18 @@
|
||||
* - 获取用户信息
|
||||
* - 用户登出
|
||||
* - 发起登录流程
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { AuthService } from '@/lib/services';
|
||||
*
|
||||
*
|
||||
* // 发起登录
|
||||
* await AuthService.initiateLogin();
|
||||
*
|
||||
*
|
||||
* // 获取用户信息
|
||||
* const user = await AuthService.getUserInfo();
|
||||
* console.log('当前用户:', user.username);
|
||||
*
|
||||
*
|
||||
* // 登出
|
||||
* await AuthService.logout();
|
||||
* ```
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {BaseService} from '@/lib/services/core';
|
||||
import type {PublicConfigResponse} from './types';
|
||||
import { BaseService } from '@/lib/services/core';
|
||||
import type { PublicConfigResponse } from './types';
|
||||
|
||||
/**
|
||||
* 配置服务
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
/**
|
||||
* 配置服务模块
|
||||
*
|
||||
*
|
||||
* @description
|
||||
* 提供系统公共配置相关的功能,包括:
|
||||
* - 获取公共配置(争议时间窗口等)
|
||||
* - 获取用户平台等级配置(公开接口)
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* import { ConfigService } from '@/lib/services';
|
||||
*
|
||||
*
|
||||
* // 获取公共配置
|
||||
* const config = await ConfigService.getPublicConfig();
|
||||
* console.log('争议时间窗口:', config.dispute_time_window_hours, '小时');
|
||||
*
|
||||
*
|
||||
* // 获取用户平台等级配置
|
||||
* const payConfigs = await ConfigService.getUserPayConfigs();
|
||||
* console.log('平台等级列表:', payConfigs);
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import axios, {AxiosError, AxiosResponse, CancelTokenSource, InternalAxiosRequestConfig} from 'axios';
|
||||
import {toast} from 'sonner';
|
||||
import {apiConfig} from './config';
|
||||
import axios, {
|
||||
AxiosError,
|
||||
AxiosResponse,
|
||||
CancelTokenSource,
|
||||
InternalAxiosRequestConfig,
|
||||
} from 'axios';
|
||||
import { toast } from 'sonner';
|
||||
import { apiConfig } from './config';
|
||||
import {
|
||||
ApiErrorBase,
|
||||
ForbiddenError,
|
||||
@@ -11,7 +16,7 @@ import {
|
||||
UnauthorizedError,
|
||||
ValidationError,
|
||||
} from './errors';
|
||||
import {ApiError, ApiResponse} from './types';
|
||||
import { ApiError, ApiResponse } from './types';
|
||||
|
||||
/**
|
||||
* API 客户端实例
|
||||
@@ -37,20 +42,22 @@ const cancelTokens = new Map<string, CancelTokenSource>();
|
||||
*/
|
||||
const pendingRequests = new Map<string, Promise<AxiosResponse<ApiResponse>>>();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 生成请求的唯一键
|
||||
* 包含方法、URL 和请求数据的哈希,确保不同参数的请求不会被误取消
|
||||
*/
|
||||
function getRequestKey(config: { method?: string; url?: string; data?: unknown }): string {
|
||||
const baseKey = `${ config.method?.toUpperCase() }_${ config.url }`;
|
||||
function getRequestKey(config: {
|
||||
method?: string;
|
||||
url?: string;
|
||||
data?: unknown;
|
||||
}): string {
|
||||
const baseKey = `${config.method?.toUpperCase()}_${config.url}`;
|
||||
|
||||
/* 序列化加入键中 */
|
||||
if (config.data) {
|
||||
try {
|
||||
const dataHash = JSON.stringify(config.data);
|
||||
return `${ baseKey }_${ dataHash }`;
|
||||
return `${baseKey}_${dataHash}`;
|
||||
} catch {
|
||||
// 失败使用基础键
|
||||
return baseKey;
|
||||
@@ -92,7 +99,7 @@ function initiateLogin(currentPath: string): Promise<never> {
|
||||
window.location.href = loginUrl.toString();
|
||||
}
|
||||
|
||||
return new Promise<never>(() => { });
|
||||
return new Promise<never>(() => {});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,7 +128,9 @@ apiClient.interceptors.response.use(
|
||||
|
||||
/* 请求被取消时静默处理 */
|
||||
if (axios.isCancel(error)) {
|
||||
const cancelError = new Error(error.message || '请求已被取消') as Error & { __CANCEL__?: boolean };
|
||||
const cancelError = new Error(
|
||||
error.message || '请求已被取消',
|
||||
) as Error & { __CANCEL__?: boolean };
|
||||
cancelError.__CANCEL__ = true;
|
||||
return Promise.reject(cancelError);
|
||||
}
|
||||
@@ -134,7 +143,11 @@ apiClient.interceptors.response.use(
|
||||
/* 403 权限不足错误 */
|
||||
if (error.response?.status === 403) {
|
||||
return Promise.reject(
|
||||
new ForbiddenError(error.response.data?.error_msg || '权限不足,请过盾后重试', error.response.data?.error_code, error.response.data?.details),
|
||||
new ForbiddenError(
|
||||
error.response.data?.error_msg || '权限不足,请过盾后重试',
|
||||
error.response.data?.error_code,
|
||||
error.response.data?.details,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -158,17 +171,16 @@ apiClient.interceptors.response.use(
|
||||
/* 429 速率限制错误 */
|
||||
if (error.response?.status === 429) {
|
||||
const retryAfter = error.response.headers?.['retry-after'];
|
||||
const message = error.response.data?.error_msg ||
|
||||
`请求过于频繁,请 ${ retryAfter || '稍后' } 秒后重试`;
|
||||
const message =
|
||||
error.response.data?.error_msg ||
|
||||
`请求过于频繁,请 ${retryAfter || '稍后'} 秒后重试`;
|
||||
|
||||
toast.error('请求频率限制', {
|
||||
description: message,
|
||||
id: 'rate-limit-error',
|
||||
});
|
||||
|
||||
return Promise.reject(
|
||||
new ApiErrorBase(message, 'RATE_LIMITED', 429),
|
||||
);
|
||||
return Promise.reject(new ApiErrorBase(message, 'RATE_LIMITED', 429));
|
||||
}
|
||||
|
||||
/* 5xx 服务器错误 */
|
||||
@@ -212,9 +224,7 @@ apiClient.interceptors.response.use(
|
||||
}
|
||||
|
||||
/* 兜底错误 */
|
||||
return Promise.reject(
|
||||
new ApiErrorBase(error.message || '网络请求失败'),
|
||||
);
|
||||
return Promise.reject(new ApiErrorBase(error.message || '网络请求失败'));
|
||||
},
|
||||
);
|
||||
|
||||
@@ -224,7 +234,7 @@ apiClient.interceptors.response.use(
|
||||
* @param url - 请求 URL
|
||||
*/
|
||||
export function cancelRequest(method: string, url: string): void {
|
||||
const requestKey = `${ method.toUpperCase() }_${ url }`;
|
||||
const requestKey = `${method.toUpperCase()}_${url}`;
|
||||
const source = cancelTokens.get(requestKey);
|
||||
if (source) {
|
||||
source.cancel('请求已被手动取消');
|
||||
@@ -249,18 +259,29 @@ export function cancelAllRequests(): void {
|
||||
*/
|
||||
function createRequestMethod(
|
||||
method: 'get' | 'post' | 'put' | 'patch' | 'delete',
|
||||
hasBody: boolean
|
||||
hasBody: boolean,
|
||||
) {
|
||||
if (hasBody) {
|
||||
return <T = ApiResponse>(url: string, data?: unknown, config?: InternalAxiosRequestConfig) => {
|
||||
const requestKey = getRequestKey({ method: method.toUpperCase(), url, data });
|
||||
return <T = ApiResponse>(
|
||||
url: string,
|
||||
data?: unknown,
|
||||
config?: InternalAxiosRequestConfig,
|
||||
) => {
|
||||
const requestKey = getRequestKey({
|
||||
method: method.toUpperCase(),
|
||||
url,
|
||||
data,
|
||||
});
|
||||
|
||||
if (pendingRequests.has(requestKey)) {
|
||||
return pendingRequests.get(requestKey) as Promise<AxiosResponse<T>>;
|
||||
}
|
||||
|
||||
const promise = apiClient[method]<T>(url, data, config);
|
||||
pendingRequests.set(requestKey, promise as Promise<AxiosResponse<ApiResponse>>);
|
||||
pendingRequests.set(
|
||||
requestKey,
|
||||
promise as Promise<AxiosResponse<ApiResponse>>,
|
||||
);
|
||||
|
||||
promise.then(
|
||||
() => pendingRequests.delete(requestKey),
|
||||
@@ -271,15 +292,25 @@ function createRequestMethod(
|
||||
};
|
||||
}
|
||||
|
||||
return <T = ApiResponse>(url: string, config?: InternalAxiosRequestConfig) => {
|
||||
const requestKey = getRequestKey({ method: method.toUpperCase(), url, data: config?.params });
|
||||
return <T = ApiResponse>(
|
||||
url: string,
|
||||
config?: InternalAxiosRequestConfig,
|
||||
) => {
|
||||
const requestKey = getRequestKey({
|
||||
method: method.toUpperCase(),
|
||||
url,
|
||||
data: config?.params,
|
||||
});
|
||||
|
||||
if (pendingRequests.has(requestKey)) {
|
||||
return pendingRequests.get(requestKey) as Promise<AxiosResponse<T>>;
|
||||
}
|
||||
|
||||
const promise = apiClient[method]<T>(url, config);
|
||||
pendingRequests.set(requestKey, promise as Promise<AxiosResponse<ApiResponse>>);
|
||||
pendingRequests.set(
|
||||
requestKey,
|
||||
promise as Promise<AxiosResponse<ApiResponse>>,
|
||||
);
|
||||
|
||||
promise.then(
|
||||
() => pendingRequests.delete(requestKey),
|
||||
@@ -295,11 +326,29 @@ function createRequestMethod(
|
||||
* 在原有 axios 实例基础上添加请求缓存功能
|
||||
*/
|
||||
const wrappedApiClient = {
|
||||
get: createRequestMethod('get', false) as <T = ApiResponse>(url: string, config?: InternalAxiosRequestConfig) => Promise<AxiosResponse<T>>,
|
||||
post: createRequestMethod('post', true) as <T = ApiResponse>(url: string, data?: unknown, config?: InternalAxiosRequestConfig) => Promise<AxiosResponse<T>>,
|
||||
put: createRequestMethod('put', true) as <T = ApiResponse>(url: string, data?: unknown, config?: InternalAxiosRequestConfig) => Promise<AxiosResponse<T>>,
|
||||
patch: createRequestMethod('patch', true) as <T = ApiResponse>(url: string, data?: unknown, config?: InternalAxiosRequestConfig) => Promise<AxiosResponse<T>>,
|
||||
delete: createRequestMethod('delete', false) as <T = ApiResponse>(url: string, config?: InternalAxiosRequestConfig) => Promise<AxiosResponse<T>>,
|
||||
get: createRequestMethod('get', false) as <T = ApiResponse>(
|
||||
url: string,
|
||||
config?: InternalAxiosRequestConfig,
|
||||
) => Promise<AxiosResponse<T>>,
|
||||
post: createRequestMethod('post', true) as <T = ApiResponse>(
|
||||
url: string,
|
||||
data?: unknown,
|
||||
config?: InternalAxiosRequestConfig,
|
||||
) => Promise<AxiosResponse<T>>,
|
||||
put: createRequestMethod('put', true) as <T = ApiResponse>(
|
||||
url: string,
|
||||
data?: unknown,
|
||||
config?: InternalAxiosRequestConfig,
|
||||
) => Promise<AxiosResponse<T>>,
|
||||
patch: createRequestMethod('patch', true) as <T = ApiResponse>(
|
||||
url: string,
|
||||
data?: unknown,
|
||||
config?: InternalAxiosRequestConfig,
|
||||
) => Promise<AxiosResponse<T>>,
|
||||
delete: createRequestMethod('delete', false) as <T = ApiResponse>(
|
||||
url: string,
|
||||
config?: InternalAxiosRequestConfig,
|
||||
) => Promise<AxiosResponse<T>>,
|
||||
};
|
||||
|
||||
export default wrappedApiClient;
|
||||
|
||||
@@ -5,12 +5,12 @@ import { InternalAxiosRequestConfig } from 'axios';
|
||||
/**
|
||||
* 服务基类
|
||||
* 提供通用的 HTTP 方法封装
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* class UserService extends BaseService {
|
||||
* protected static readonly basePath = '/api/v1/users';
|
||||
*
|
||||
*
|
||||
* static async getAll() {
|
||||
* return this.get<User[]>('/');
|
||||
* }
|
||||
@@ -30,7 +30,7 @@ export class BaseService {
|
||||
* @returns 完整路径
|
||||
*/
|
||||
protected static getFullPath(path: string): string {
|
||||
return `${ this.basePath }${ path }`;
|
||||
return `${this.basePath}${path}`;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,18 +150,14 @@ export class BaseService {
|
||||
* @param url - 完整 URL
|
||||
* @param params - 查询参数
|
||||
* @returns 响应数据(不经过 response.data.data 解包)
|
||||
*
|
||||
*
|
||||
* @remarks
|
||||
* 仅用于不遵循标准响应格式的特殊端点(如 /api.php)
|
||||
*/
|
||||
protected static async rawGet<T>(
|
||||
url: string,
|
||||
params?: unknown,
|
||||
): Promise<T> {
|
||||
const response = await apiClient.get<T>(
|
||||
url,
|
||||
{ params } as InternalAxiosRequestConfig,
|
||||
);
|
||||
protected static async rawGet<T>(url: string, params?: unknown): Promise<T> {
|
||||
const response = await apiClient.get<T>(url, {
|
||||
params,
|
||||
} as InternalAxiosRequestConfig);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
@@ -172,7 +168,7 @@ export class BaseService {
|
||||
* @param data - 请求数据
|
||||
* @param config - 额外的请求配置
|
||||
* @returns 响应数据(不经过 response.data.data 解包)
|
||||
*
|
||||
*
|
||||
* @remarks
|
||||
* 仅用于不遵循标准响应格式的特殊端点(如 /api.php)
|
||||
*/
|
||||
@@ -185,4 +181,3 @@ export class BaseService {
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
*/
|
||||
export function getApiBaseUrl(): string {
|
||||
if (typeof window === 'undefined') {
|
||||
return process.env.WAVELET_BACKEND_URL || process.env.NEXT_PUBLIC_WAVELET_BACKEND_URL || 'http://localhost:8000';
|
||||
return (
|
||||
process.env.WAVELET_BACKEND_URL ||
|
||||
process.env.NEXT_PUBLIC_WAVELET_BACKEND_URL ||
|
||||
'http://localhost:8000'
|
||||
);
|
||||
}
|
||||
return process.env.NEXT_PUBLIC_WAVELET_BACKEND_URL || '';
|
||||
}
|
||||
@@ -24,4 +28,3 @@ export const apiConfig = {
|
||||
/** 携带凭证 */
|
||||
withCredentials: true,
|
||||
} as const;
|
||||
|
||||
|
||||
@@ -101,5 +101,12 @@ export class ValidationError extends ApiErrorBase {
|
||||
* @returns 是否为取消错误
|
||||
*/
|
||||
export function isCancelError(error: unknown): boolean {
|
||||
return error !== null && typeof error === 'object' && ('__CANCEL__' in error && (error as { __CANCEL__?: boolean }).__CANCEL__ === true || ('message' in error && (error as { message?: string }).message === '请求已被取消'));
|
||||
return (
|
||||
error !== null &&
|
||||
typeof error === 'object' &&
|
||||
(('__CANCEL__' in error &&
|
||||
(error as { __CANCEL__?: boolean }).__CANCEL__ === true) ||
|
||||
('message' in error &&
|
||||
(error as { message?: string }).message === '请求已被取消'))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
* 提供 API 请求的基础设施
|
||||
*/
|
||||
|
||||
export { default as apiClient, cancelRequest, cancelAllRequests } from './api-client';
|
||||
export {
|
||||
default as apiClient,
|
||||
cancelRequest,
|
||||
cancelAllRequests,
|
||||
} from './api-client';
|
||||
export { BaseService } from './base.service';
|
||||
export { apiConfig } from './config';
|
||||
export {
|
||||
@@ -24,4 +28,3 @@ export type {
|
||||
PaginationResponse,
|
||||
RequestConfig,
|
||||
} from './types';
|
||||
|
||||
|
||||
@@ -61,4 +61,3 @@ export interface RequestConfig {
|
||||
/** 是否携带凭证 */
|
||||
withCredentials?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import type {InternalAxiosRequestConfig} from 'axios';
|
||||
import type { InternalAxiosRequestConfig } from 'axios';
|
||||
|
||||
import apiClient from '@/lib/services/core/api-client';
|
||||
import {BaseService} from '@/lib/services/core';
|
||||
import type {DBOverview, ExecuteSQLResponse, TableDataResponse} from './types';
|
||||
import { BaseService } from '@/lib/services/core';
|
||||
import type {
|
||||
DBOverview,
|
||||
ExecuteSQLResponse,
|
||||
TableDataResponse,
|
||||
} from './types';
|
||||
|
||||
/**
|
||||
* 数据库管理服务类
|
||||
@@ -32,7 +36,10 @@ export class DbManageService extends BaseService {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
}): Promise<TableDataResponse> {
|
||||
return this.get<TableDataResponse>('/table-data', params as unknown as Record<string, unknown>);
|
||||
return this.get<TableDataResponse>(
|
||||
'/table-data',
|
||||
params as unknown as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,7 +58,8 @@ export class DbManageService extends BaseService {
|
||||
responseType: 'blob',
|
||||
} as InternalAxiosRequestConfig);
|
||||
|
||||
const disposition = response.headers['content-disposition'] as string | undefined;
|
||||
const disposition = response.headers['content-disposition'] as
|
||||
string | undefined;
|
||||
let filename = 'wavelet_export';
|
||||
if (disposition) {
|
||||
const match = disposition.match(/filename="?([^";]+)"?/);
|
||||
|
||||
@@ -1,2 +1,6 @@
|
||||
export { DbManageService } from './db-manage.service';
|
||||
export type { DBOverview, TableDataResponse, ExecuteSQLResponse } from './types';
|
||||
export type {
|
||||
DBOverview,
|
||||
TableDataResponse,
|
||||
ExecuteSQLResponse,
|
||||
} from './types';
|
||||
|
||||
@@ -23,7 +23,7 @@ export interface TableDataResponse {
|
||||
* 执行自定义 SQL 的响应
|
||||
*/
|
||||
export interface ExecuteSQLResponse {
|
||||
type: "select" | "exec";
|
||||
type: 'select' | 'exec';
|
||||
columns?: string[];
|
||||
results?: Record<string, unknown>[];
|
||||
affected_rows: number;
|
||||
|
||||
@@ -20,12 +20,12 @@ import {
|
||||
AdminTemplateService,
|
||||
AdminUserService,
|
||||
} from './admin';
|
||||
import {AuthService} from './auth';
|
||||
import {ConfigService} from './config';
|
||||
import {DbManageService} from './db-manage';
|
||||
import {PushService} from './push';
|
||||
import {AdminUploadService, UploadService} from './upload';
|
||||
import {UserService} from './user';
|
||||
import { AuthService } from './auth';
|
||||
import { ConfigService } from './config';
|
||||
import { DbManageService } from './db-manage';
|
||||
import { PushService } from './push';
|
||||
import { AdminUploadService, UploadService } from './upload';
|
||||
import { UserService } from './user';
|
||||
|
||||
const services = {
|
||||
auth: AuthService,
|
||||
@@ -81,7 +81,15 @@ export type {
|
||||
// ==================== 业务服务导出 ====================
|
||||
|
||||
export { AuthService } from './auth';
|
||||
export type { User, OAuthLoginUrlResponse, OAuthCallbackRequest, AuthSource, ExternalAccountBinding, ChangePasswordRequest, UpdateProfileRequest } from './auth';
|
||||
export type {
|
||||
User,
|
||||
OAuthLoginUrlResponse,
|
||||
OAuthCallbackRequest,
|
||||
AuthSource,
|
||||
ExternalAccountBinding,
|
||||
ChangePasswordRequest,
|
||||
UpdateProfileRequest,
|
||||
} from './auth';
|
||||
|
||||
export { ConfigService } from './config';
|
||||
export type { PublicConfigResponse } from './config';
|
||||
@@ -136,11 +144,34 @@ export type {
|
||||
export { UserService } from './user';
|
||||
export type { AccessToken, CreateTokenResponse } from './user';
|
||||
|
||||
export { UploadService, AdminUploadService, formatFileSize, getFileUrl } from './upload';
|
||||
export type { UploadImageResponse, Upload, ListUploadsResponse, FileStatsResponse, ImageQuality } from './upload';
|
||||
export {
|
||||
UploadService,
|
||||
AdminUploadService,
|
||||
formatFileSize,
|
||||
getFileUrl,
|
||||
} from './upload';
|
||||
export type {
|
||||
UploadImageResponse,
|
||||
Upload,
|
||||
ListUploadsResponse,
|
||||
FileStatsResponse,
|
||||
ImageQuality,
|
||||
} from './upload';
|
||||
|
||||
export { DbManageService } from './db-manage';
|
||||
export type { DBOverview, TableDataResponse, ExecuteSQLResponse } from './db-manage';
|
||||
export type {
|
||||
DBOverview,
|
||||
TableDataResponse,
|
||||
ExecuteSQLResponse,
|
||||
} from './db-manage';
|
||||
|
||||
export { PushService } from './push';
|
||||
export type { PushEvent, PushHistory, PushChannelConfig, ListPushHistoriesRequest, ListPushHistoriesResponse, UpdatePushEventRequest, TestPushRequest } from './push';
|
||||
export type {
|
||||
PushEvent,
|
||||
PushHistory,
|
||||
PushChannelConfig,
|
||||
ListPushHistoriesRequest,
|
||||
ListPushHistoriesResponse,
|
||||
UpdatePushEventRequest,
|
||||
TestPushRequest,
|
||||
} from './push';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2026 Arctel.net
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import {BaseService} from '@/lib/services/core';
|
||||
import { BaseService } from '@/lib/services/core';
|
||||
import type {
|
||||
ChannelDefinition,
|
||||
CreateChannelRequest,
|
||||
@@ -14,7 +14,7 @@ import type {
|
||||
TestChannelRequest,
|
||||
TestPushRequest,
|
||||
UpdateChannelRequest,
|
||||
UpdatePushEventRequest
|
||||
UpdatePushEventRequest,
|
||||
} from './types';
|
||||
|
||||
/**
|
||||
@@ -41,14 +41,23 @@ export class PushService extends BaseService {
|
||||
* 创建通知事件配置
|
||||
*/
|
||||
static async createEvent(data: CreatePushEventRequest): Promise<PushEvent> {
|
||||
return this.post<PushEvent>('/events', data as unknown as Record<string, unknown>);
|
||||
return this.post<PushEvent>(
|
||||
'/events',
|
||||
data as unknown as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新指定通知事件配置
|
||||
*/
|
||||
static async updateEvent(id: number, data: UpdatePushEventRequest): Promise<void> {
|
||||
return this.put<void>(`/events/${id}`, data as unknown as Record<string, unknown>);
|
||||
static async updateEvent(
|
||||
id: number,
|
||||
data: UpdatePushEventRequest,
|
||||
): Promise<void> {
|
||||
return this.put<void>(
|
||||
`/events/${id}`,
|
||||
data as unknown as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -68,8 +77,13 @@ export class PushService extends BaseService {
|
||||
/**
|
||||
* 分页查询通知推送历史
|
||||
*/
|
||||
static async listHistories(params: ListPushHistoriesRequest): Promise<ListPushHistoriesResponse> {
|
||||
return this.get<ListPushHistoriesResponse>('/histories', params as unknown as Record<string, unknown>);
|
||||
static async listHistories(
|
||||
params: ListPushHistoriesRequest,
|
||||
): Promise<ListPushHistoriesResponse> {
|
||||
return this.get<ListPushHistoriesResponse>(
|
||||
'/histories',
|
||||
params as unknown as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,14 +104,23 @@ export class PushService extends BaseService {
|
||||
* 创建新的消息通道
|
||||
*/
|
||||
static async createChannel(data: CreateChannelRequest): Promise<PushChannel> {
|
||||
return this.post<PushChannel>('/channels', data as unknown as Record<string, unknown>);
|
||||
return this.post<PushChannel>(
|
||||
'/channels',
|
||||
data as unknown as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新指定消息通道
|
||||
*/
|
||||
static async updateChannel(id: number, data: UpdateChannelRequest): Promise<PushChannel> {
|
||||
return this.put<PushChannel>(`/channels/${id}`, data as unknown as Record<string, unknown>);
|
||||
static async updateChannel(
|
||||
id: number,
|
||||
data: UpdateChannelRequest,
|
||||
): Promise<PushChannel> {
|
||||
return this.put<PushChannel>(
|
||||
`/channels/${id}`,
|
||||
data as unknown as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,7 +134,10 @@ export class PushService extends BaseService {
|
||||
* 测试消息通道连通性
|
||||
*/
|
||||
static async testChannel(data: TestChannelRequest): Promise<void> {
|
||||
return this.post<void>('/channels/test', data as unknown as Record<string, unknown>);
|
||||
return this.post<void>(
|
||||
'/channels/test',
|
||||
data as unknown as Record<string, unknown>,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -135,4 +135,3 @@ export interface ChannelDefinition {
|
||||
description: string;
|
||||
fields: ChannelFieldDef[];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type {InternalAxiosRequestConfig} from 'axios';
|
||||
import type { InternalAxiosRequestConfig } from 'axios';
|
||||
|
||||
import {BaseService} from '../core/base.service';
|
||||
import type {FileStatsResponse, ListUploadsResponse} from './types';
|
||||
import { BaseService } from '../core/base.service';
|
||||
import type { FileStatsResponse, ListUploadsResponse } from './types';
|
||||
|
||||
export class AdminUploadService extends BaseService {
|
||||
protected static readonly basePath = '/api/v1/admin/uploads';
|
||||
@@ -13,7 +13,10 @@ export class AdminUploadService extends BaseService {
|
||||
type?: string,
|
||||
extension?: string,
|
||||
): Promise<ListUploadsResponse> {
|
||||
const params: Record<string, string | number> = { page, page_size: pageSize };
|
||||
const params: Record<string, string | number> = {
|
||||
page,
|
||||
page_size: pageSize,
|
||||
};
|
||||
if (keyword) params.keyword = keyword;
|
||||
if (type) params.type = type;
|
||||
if (extension) params.extension = extension;
|
||||
@@ -37,4 +40,4 @@ export class AdminUploadService extends BaseService {
|
||||
responseType: 'blob',
|
||||
} as InternalAxiosRequestConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,9 @@ export { UploadService } from './upload.service';
|
||||
export { AdminUploadService } from './admin-upload.service';
|
||||
export { formatFileSize, getFileUrl } from './utils';
|
||||
export type { ImageQuality } from './utils';
|
||||
export type { UploadImageResponse, Upload, ListUploadsResponse, FileStatsResponse } from './types';
|
||||
export type {
|
||||
UploadImageResponse,
|
||||
Upload,
|
||||
ListUploadsResponse,
|
||||
FileStatsResponse,
|
||||
} from './types';
|
||||
|
||||
@@ -2,34 +2,34 @@
|
||||
* 文件上传元数据
|
||||
*/
|
||||
export interface UploadMetadata {
|
||||
width?: number
|
||||
height?: number
|
||||
duration?: number
|
||||
original_mime?: string
|
||||
user_agent?: string
|
||||
client_ip?: string
|
||||
bucket?: string
|
||||
extra?: Record<string, unknown>
|
||||
width?: number;
|
||||
height?: number;
|
||||
duration?: number;
|
||||
original_mime?: string;
|
||||
user_agent?: string;
|
||||
client_ip?: string;
|
||||
bucket?: string;
|
||||
extra?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传记录
|
||||
*/
|
||||
export interface Upload {
|
||||
id: string
|
||||
user_id: string
|
||||
file_name: string
|
||||
file_path: string
|
||||
file_size: number
|
||||
mime_type: string
|
||||
extension: string
|
||||
hash: string
|
||||
type: string
|
||||
status: string
|
||||
access_mode: number
|
||||
metadata: UploadMetadata
|
||||
created_at: string
|
||||
updated_at: string
|
||||
id: string;
|
||||
user_id: string;
|
||||
file_name: string;
|
||||
file_path: string;
|
||||
file_size: number;
|
||||
mime_type: string;
|
||||
extension: string;
|
||||
hash: string;
|
||||
type: string;
|
||||
status: string;
|
||||
access_mode: number;
|
||||
metadata: UploadMetadata;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,55 +37,55 @@ export interface Upload {
|
||||
*/
|
||||
export interface UploadImageResponse {
|
||||
/** 上传记录 ID */
|
||||
id: string
|
||||
id: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件列表查询参数
|
||||
*/
|
||||
export interface ListUploadsQuery {
|
||||
page?: number
|
||||
page_size?: number
|
||||
type?: string
|
||||
extension?: string
|
||||
keyword?: string
|
||||
page?: number;
|
||||
page_size?: number;
|
||||
type?: string;
|
||||
extension?: string;
|
||||
keyword?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件列表分页响应
|
||||
*/
|
||||
export interface ListUploadsResponse {
|
||||
total: number
|
||||
page: number
|
||||
page_size: number
|
||||
items: Upload[]
|
||||
total: number;
|
||||
page: number;
|
||||
page_size: number;
|
||||
items: Upload[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 近 7 天新增文件趋势项
|
||||
*/
|
||||
export interface TrendItem {
|
||||
date: string
|
||||
count: number
|
||||
size: number
|
||||
date: string;
|
||||
count: number;
|
||||
size: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件分类/类型统计项
|
||||
*/
|
||||
export interface DistributionItem {
|
||||
name: string
|
||||
count: number
|
||||
size: number
|
||||
name: string;
|
||||
count: number;
|
||||
size: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件统计信息响应
|
||||
*/
|
||||
export interface FileStatsResponse {
|
||||
total_count: number
|
||||
total_size: number
|
||||
trend: TrendItem[]
|
||||
categories: DistributionItem[]
|
||||
types: DistributionItem[]
|
||||
}
|
||||
total_count: number;
|
||||
total_size: number;
|
||||
trend: TrendItem[];
|
||||
categories: DistributionItem[];
|
||||
types: DistributionItem[];
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type {InternalAxiosRequestConfig} from 'axios';
|
||||
import type { InternalAxiosRequestConfig } from 'axios';
|
||||
|
||||
import {BaseService} from '../core/base.service';
|
||||
import type {ListUploadsResponse, Upload, UploadImageResponse} from './types';
|
||||
import { BaseService } from '../core/base.service';
|
||||
import type { ListUploadsResponse, Upload, UploadImageResponse } from './types';
|
||||
|
||||
export class UploadService extends BaseService {
|
||||
protected static readonly basePath = '/api/v1/upload';
|
||||
@@ -48,7 +48,10 @@ export class UploadService extends BaseService {
|
||||
type?: string,
|
||||
extension?: string,
|
||||
): Promise<ListUploadsResponse> {
|
||||
const params: Record<string, string | number> = { page, page_size: pageSize };
|
||||
const params: Record<string, string | number> = {
|
||||
page,
|
||||
page_size: pageSize,
|
||||
};
|
||||
if (keyword) params.keyword = keyword;
|
||||
if (type) params.type = type;
|
||||
if (extension) params.extension = extension;
|
||||
@@ -59,7 +62,11 @@ export class UploadService extends BaseService {
|
||||
return this.delete<void>(`/${id}`);
|
||||
}
|
||||
|
||||
static async updateMyFile(id: string, fileName: string, accessMode?: number): Promise<Upload> {
|
||||
static async updateMyFile(
|
||||
id: string,
|
||||
fileName: string,
|
||||
accessMode?: number,
|
||||
): Promise<Upload> {
|
||||
return this.put<Upload>(`/${id}`, {
|
||||
file_name: fileName,
|
||||
access_mode: accessMode,
|
||||
@@ -75,4 +82,4 @@ export class UploadService extends BaseService {
|
||||
static getDownloadUrl(id: string): string {
|
||||
return `${this.basePath}/download/${id}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,4 +15,4 @@ export function formatFileSize(bytes: number): string {
|
||||
const sizes = ['B', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* 用户服务模块
|
||||
*
|
||||
*
|
||||
* @description
|
||||
* 提供用户个人设置相关的功能
|
||||
*/
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {BaseService} from '../core/base.service';
|
||||
import { BaseService } from '../core/base.service';
|
||||
|
||||
export interface AccessToken {
|
||||
id: number;
|
||||
@@ -34,8 +34,14 @@ export class UserService extends BaseService {
|
||||
* @param name - 令牌名称
|
||||
* @param isAdmin - 是否赋予管理员权限(默认 false)
|
||||
*/
|
||||
static async createAccessToken(name: string, isAdmin = false): Promise<CreateTokenResponse> {
|
||||
return this.post<CreateTokenResponse>('/access-tokens', { name, is_admin: isAdmin });
|
||||
static async createAccessToken(
|
||||
name: string,
|
||||
isAdmin = false,
|
||||
): Promise<CreateTokenResponse> {
|
||||
return this.post<CreateTokenResponse>('/access-tokens', {
|
||||
name,
|
||||
is_admin: isAdmin,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user