From 0fa6b741b288dd88a0c5a8e43f694fb4393dbc9a Mon Sep 17 00:00:00 2001 From: LTbinglingfeng Date: Thu, 21 May 2026 01:29:27 +0800 Subject: [PATCH] chore: remove unused hooks and utils --- src/hooks/index.ts | 3 -- src/hooks/useApi.ts | 66 -------------------------------- src/hooks/useDebounce.ts | 21 ----------- src/hooks/usePagination.ts | 59 ----------------------------- src/utils/constants.ts | 38 ------------------- src/utils/format.ts | 47 ----------------------- src/utils/helpers.ts | 77 -------------------------------------- src/utils/validation.ts | 53 -------------------------- 8 files changed, 364 deletions(-) delete mode 100644 src/hooks/useApi.ts delete mode 100644 src/hooks/useDebounce.ts delete mode 100644 src/hooks/usePagination.ts diff --git a/src/hooks/index.ts b/src/hooks/index.ts index ee756c7..67f867a 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -2,10 +2,7 @@ * Hooks 统一导出 */ -export { useApi } from './useApi'; -export { useDebounce } from './useDebounce'; export { useLocalStorage } from './useLocalStorage'; export { useInterval } from './useInterval'; export { useMediaQuery } from './useMediaQuery'; -export { usePagination } from './usePagination'; export { useHeaderRefresh } from './useHeaderRefresh'; diff --git a/src/hooks/useApi.ts b/src/hooks/useApi.ts deleted file mode 100644 index 8d5565f..0000000 --- a/src/hooks/useApi.ts +++ /dev/null @@ -1,66 +0,0 @@ -/** - * 通用 API 调用 Hook - */ - -import { useState, useCallback } from 'react'; -import { useNotificationStore } from '@/stores'; - -interface UseApiOptions { - onSuccess?: (data: T) => void; - onError?: (error: Error) => void; - showSuccessNotification?: boolean; - showErrorNotification?: boolean; - successMessage?: string; -} - -export function useApi( - apiFunction: (...args: Args) => Promise, - options: UseApiOptions = {} -) { - const [data, setData] = useState(null); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - - const { showNotification } = useNotificationStore(); - - const execute = useCallback( - async (...args: Args) => { - setLoading(true); - setError(null); - - try { - const result = await apiFunction(...args); - setData(result); - - if (options.showSuccessNotification && options.successMessage) { - showNotification(options.successMessage, 'success'); - } - - options.onSuccess?.(result); - return result; - } catch (err: unknown) { - const errorObj = - err instanceof Error ? err : new Error(typeof err === 'string' ? err : 'Unknown error'); - setError(errorObj); - - if (options.showErrorNotification !== false) { - showNotification(errorObj.message, 'error'); - } - - options.onError?.(errorObj); - throw errorObj; - } finally { - setLoading(false); - } - }, - [apiFunction, options, showNotification] - ); - - const reset = useCallback(() => { - setData(null); - setError(null); - setLoading(false); - }, []); - - return { data, loading, error, execute, reset }; -} diff --git a/src/hooks/useDebounce.ts b/src/hooks/useDebounce.ts deleted file mode 100644 index 24e3d20..0000000 --- a/src/hooks/useDebounce.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * 防抖 Hook - */ - -import { useEffect, useState } from 'react'; - -export function useDebounce(value: T, delay: number = 500): T { - const [debouncedValue, setDebouncedValue] = useState(value); - - useEffect(() => { - const handler = setTimeout(() => { - setDebouncedValue(value); - }, delay); - - return () => { - clearTimeout(handler); - }; - }, [value, delay]); - - return debouncedValue; -} diff --git a/src/hooks/usePagination.ts b/src/hooks/usePagination.ts deleted file mode 100644 index f2b7bf4..0000000 --- a/src/hooks/usePagination.ts +++ /dev/null @@ -1,59 +0,0 @@ -/** - * 分页 Hook - */ - -import { useState, useMemo } from 'react'; -import type { PaginationState } from '@/types'; - -export function usePagination( - items: T[], - initialPageSize: number = 20 -): PaginationState & { - currentItems: T[]; - goToPage: (page: number) => void; - nextPage: () => void; - prevPage: () => void; - setPageSize: (size: number) => void; -} { - const [currentPage, setCurrentPage] = useState(1); - const [pageSize, setPageSize] = useState(initialPageSize); - - const totalItems = items.length; - const totalPages = Math.ceil(totalItems / pageSize) || 1; - - const currentItems = useMemo(() => { - const start = (currentPage - 1) * pageSize; - const end = start + pageSize; - return items.slice(start, end); - }, [items, currentPage, pageSize]); - - const goToPage = (page: number) => { - const validPage = Math.max(1, Math.min(page, totalPages)); - setCurrentPage(validPage); - }; - - const nextPage = () => { - goToPage(currentPage + 1); - }; - - const prevPage = () => { - goToPage(currentPage - 1); - }; - - const handleSetPageSize = (size: number) => { - setPageSize(size); - setCurrentPage(1); // 重置到第一页 - }; - - return { - currentPage, - pageSize, - totalPages, - totalItems, - currentItems, - goToPage, - nextPage, - prevPage, - setPageSize: handleSetPageSize - }; -} diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 39b77f9..bf6c133 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -18,26 +18,17 @@ export const MANAGEMENT_API_PREFIX = '/v0/management'; export const REQUEST_TIMEOUT_MS = 30 * 1000; export const VERSION_HEADER_KEYS = ['x-cpa-version', 'x-server-version']; export const BUILD_DATE_HEADER_KEYS = ['x-cpa-build-date', 'x-server-build-date']; -export const STATUS_UPDATE_INTERVAL_MS = 1000; -export const LOG_REFRESH_DELAY_MS = 500; // 日志相关 -export const MAX_LOG_LINES = 2000; -export const LOG_FETCH_LIMIT = 2500; export const LOGS_TIMEOUT_MS = 60 * 1000; // 认证文件分页 -export const DEFAULT_AUTH_FILES_PAGE_SIZE = 20; -export const MIN_AUTH_FILES_PAGE_SIZE = 10; -export const MAX_AUTH_FILES_PAGE_SIZE = 100; export const MAX_AUTH_FILE_SIZE = 10 * 1024 * 1024; // 本地存储键名 export const STORAGE_KEY_AUTH = 'cli-proxy-auth'; export const STORAGE_KEY_THEME = 'cli-proxy-theme'; export const STORAGE_KEY_LANGUAGE = 'cli-proxy-language'; -export const STORAGE_KEY_SIDEBAR = 'cli-proxy-sidebar-collapsed'; -export const STORAGE_KEY_AUTH_FILES_PAGE_SIZE = 'cli-proxy-auth-files-page-size'; // 语言配置 export const LANGUAGE_ORDER = defineLanguageOrder(['zh-CN', 'zh-TW', 'en', 'ru'] as const); @@ -51,32 +42,3 @@ export const SUPPORTED_LANGUAGES = LANGUAGE_ORDER; // 通知持续时间 export const NOTIFICATION_DURATION_MS = 3000; - -// OAuth 卡片 ID 列表 -export const OAUTH_CARD_IDS = [ - 'codex-oauth-card', - 'anthropic-oauth-card', - 'antigravity-oauth-card', - 'gemini-cli-oauth-card', - 'kimi-oauth-card', - 'xai-oauth-card' -]; -export const OAUTH_PROVIDERS = { - CODEX: 'codex', - ANTHROPIC: 'anthropic', - ANTIGRAVITY: 'antigravity', - GEMINI_CLI: 'gemini-cli', - KIMI: 'kimi', - XAI: 'xai' -} as const; - -// API 端点 -export const API_ENDPOINTS = { - CONFIG: '/config', - LOGIN: '/login', - API_KEYS: '/api-keys', - PROVIDERS: '/providers', - AUTH_FILES: '/auth-files', - OAUTH: '/oauth', - LOGS: '/logs' -} as const; diff --git a/src/utils/format.ts b/src/utils/format.ts index ba80460..ee6b82e 100644 --- a/src/utils/format.ts +++ b/src/utils/format.ts @@ -5,14 +5,6 @@ import { parseTimestamp } from './timestamp'; * 从原项目 src/utils/string.js 迁移 */ -const resolveDefaultLocale = (): string | undefined => { - const fromDocument = - typeof document !== 'undefined' ? document.documentElement?.lang?.trim() : ''; - if (fromDocument) return fromDocument; - const fromNavigator = typeof navigator !== 'undefined' ? navigator.language?.trim() : ''; - return fromNavigator || undefined; -}; - /** * 隐藏 API Key 中间部分,仅保留前后两位 */ @@ -45,27 +37,6 @@ export function formatFileSize(bytes: number): string { return `${(bytes / Math.pow(k, i)).toFixed(2)} ${units[i]}`; } -/** - * 格式化日期时间 - */ -export function formatDateTime(date: string | Date, locale?: string): string { - const d = typeof date === 'string' ? parseTimestamp(date) ?? new Date(date) : date; - - if (isNaN(d.getTime())) { - return 'Invalid Date'; - } - - const resolvedLocale = locale?.trim() || resolveDefaultLocale(); - return d.toLocaleString(resolvedLocale, { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', - minute: '2-digit', - second: '2-digit' - }); -} - /** * 将 Unix 时间戳(秒/毫秒/微秒/纳秒)格式化为本地时间字符串 */ @@ -96,21 +67,3 @@ export function formatUnixTimestamp(value: unknown, locale?: string): string { if (Number.isNaN(date.getTime())) return ''; return locale ? date.toLocaleString(locale) : date.toLocaleString(); } - -/** - * 格式化数字(添加千位分隔符) - */ -export function formatNumber(num: number, locale?: string): string { - const resolvedLocale = locale?.trim() || resolveDefaultLocale(); - return num.toLocaleString(resolvedLocale); -} - -/** - * 截断长文本 - */ -export function truncateText(text: string, maxLength: number): string { - if (text.length <= maxLength) { - return text; - } - return text.slice(0, maxLength) + '...'; -} diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index 2b90768..947b4fa 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -3,86 +3,9 @@ * 从原项目 src/utils/array.js, dom.js, html.js 迁移 */ -/** - * 规范化数组响应(处理后端可能返回非数组的情况) - */ -export function normalizeArrayResponse(data: T | T[] | null | undefined): T[] { - if (!data) return []; - if (Array.isArray(data)) return data; - return [data]; -} - -/** - * 防抖函数 - */ -export function debounce( - func: (this: This, ...args: Args) => Return, - delay: number -): (this: This, ...args: Args) => void { - let timeoutId: ReturnType; - - return function (this: This, ...args: Args) { - clearTimeout(timeoutId); - timeoutId = setTimeout(() => func.apply(this, args), delay); - }; -} - -/** - * 节流函数 - */ -export function throttle( - func: (this: This, ...args: Args) => Return, - limit: number -): (this: This, ...args: Args) => void { - let inThrottle: boolean; - - return function (this: This, ...args: Args) { - if (!inThrottle) { - func.apply(this, args); - inThrottle = true; - setTimeout(() => (inThrottle = false), limit); - } - }; -} - -/** - * HTML 转义(防 XSS) - */ -export function escapeHtml(text: string): string { - const div = document.createElement('div'); - div.textContent = text; - return div.innerHTML; -} - /** * 生成唯一 ID */ export function generateId(): string { return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; } - -/** - * 深拷贝对象 - */ -export function deepClone(obj: T): T { - if (obj === null || typeof obj !== 'object') return obj; - - if (obj instanceof Date) return new Date(obj.getTime()) as unknown as T; - if (Array.isArray(obj)) return obj.map((item) => deepClone(item)) as unknown as T; - - const source = obj as Record; - const cloned: Record = {}; - for (const key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - cloned[key] = deepClone(source[key]); - } - } - return cloned as unknown as T; -} - -/** - * 延迟函数 - */ -export function sleep(ms: number): Promise { - return new Promise((resolve) => setTimeout(resolve, ms)); -} diff --git a/src/utils/validation.ts b/src/utils/validation.ts index e1cf66f..935f81e 100644 --- a/src/utils/validation.ts +++ b/src/utils/validation.ts @@ -2,39 +2,6 @@ * 验证工具函数 */ -/** - * 验证 URL 格式 - */ -export function isValidUrl(url: string): boolean { - try { - new URL(url); - return true; - } catch { - return false; - } -} - -/** - * 验证 API Base URL - */ -export function isValidApiBase(apiBase: string): boolean { - if (!apiBase) return false; - - // 允许 http/https 协议 - const urlPattern = /^https?:\/\/.+/i; - return urlPattern.test(apiBase); -} - -/** - * 验证 API Key 格式 - */ -export function isValidApiKey(key: string): boolean { - if (!key || key.length < 8) return false; - - // 基础验证:不包含空格 - return !/\s/.test(key); -} - /** * 验证 API Key 字符集(仅允许 ASCII 可见字符) */ @@ -42,23 +9,3 @@ export function isValidApiKeyCharset(key: string): boolean { if (!key) return false; return /^[\x21-\x7E]+$/.test(key); } - -/** - * 验证 JSON 格式 - */ -export function isValidJson(str: string): boolean { - try { - JSON.parse(str); - return true; - } catch { - return false; - } -} - -/** - * 验证 Email 格式 - */ -export function isValidEmail(email: string): boolean { - const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; - return emailPattern.test(email); -}