From fed112656f22ef6d3b5d40b7dffeb623d6766dba Mon Sep 17 00:00:00 2001 From: beabigegg Date: Wed, 12 Nov 2025 23:55:21 +0800 Subject: [PATCH] update FRONTEND documentation --- .claude/settings.local.json | 4 +- FRONTEND_ANALYSIS.md | 511 ++++++++++++++++++++++++++++ FRONTEND_CODE_EXAMPLES.md | 652 ++++++++++++++++++++++++++++++++++++ FRONTEND_QUICK_REFERENCE.md | 397 ++++++++++++++++++++++ FRONTEND_README.md | 185 ++++++++++ 5 files changed, 1748 insertions(+), 1 deletion(-) create mode 100644 FRONTEND_ANALYSIS.md create mode 100644 FRONTEND_CODE_EXAMPLES.md create mode 100644 FRONTEND_QUICK_REFERENCE.md create mode 100644 FRONTEND_README.md diff --git a/.claude/settings.local.json b/.claude/settings.local.json index c0f1d06..d47fec9 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -51,7 +51,9 @@ "Bash(TOKEN=\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIzIiwidXNlcm5hbWUiOiJhZG1pbiIsImV4cCI6MTc2Mjk1ODUzOX0.S1JjFxVVmifdkN5F_dORt5jTRdTFN9MKJ8UJKuYacA8\")", "Bash(tree:*)", "Bash(done)", - "Bash(git add:*)" + "Bash(git add:*)", + "Bash(git commit:*)", + "Bash(git push)" ], "deny": [], "ask": [] diff --git a/FRONTEND_ANALYSIS.md b/FRONTEND_ANALYSIS.md new file mode 100644 index 0000000..2f4d2d6 --- /dev/null +++ b/FRONTEND_ANALYSIS.md @@ -0,0 +1,511 @@ +# Tool_OCR 前端項目結構分析 + +## 項目概況 + +- **項目名稱**: Tool_OCR Frontend +- **框架**: React 19.2.0 (TypeScript) +- **構建工具**: Vite 7.2.2 +- **樣式方案**: Tailwind CSS 4.1.17 +- **路由管理**: React Router v7.9.5 +- **狀態管理**: Zustand 5.0.8 +- **數據獲取**: TanStack React Query v5.90.7 +- **國際化**: i18next 25.6.2 +- **源碼行數**: ~2,700 行 +- **開發語言**: TypeScript +- **運行端口**: 12011 + +--- + +## 前端技術棧詳解 + +### 核心框架 +- **React 19.2.0**: 最新版 React,用於構建用戶界面 + - 使用函數式組件 + - React Hooks 進行狀態和副作用管理 + - 嚴格模式(StrictMode)開啟 + +### 構建與開發 +- **Vite 7.2.2**: 快速的前端構建工具 + - 配置路徑別名 `@` → `./src` + - 開發服務器代理設定(API 轉發到 localhost:12010) + - TypeScript 支持 + +- **TypeScript ~5.9.3**: 類型檢查和增強開發體驗 + +- **ESLint + TypeScript ESLint**: 代碼質量檢查 + - React Hooks 規則檢查 + - React Refresh 支持 + +### 樣式設計 + +#### Tailwind CSS 4.1.17 +- **CSS 框架**: 完全採用 Tailwind CSS +- **配置文件**: `/frontend/tailwind.config.js` + +**主題配置 (HSL 色彩系統)**: +``` +顏色變數 (CSS 自定義屬性): +- --background / --foreground (背景/前景) +- --primary / --primary-foreground (主色/主色前景) +- --secondary / --secondary-foreground (次色) +- --muted / --muted-foreground (灰色系) +- --accent / --accent-foreground (強調色) +- --destructive / --destructive-foreground (危險操作) +- --card / --card-foreground (卡片) +- --popover / --popover-foreground (彈出框) +- --border / --input (邊框/輸入框) +- --ring (焦點環) +``` + +**亮色模式**: +- 白色背景 (hsl(0 0% 100%)) +- 深色文字 (hsl(222.2 84% 4.9%)) +- 藍色主題 (hsl(221.2 83.2% 53.3%)) + +**暗色模式** (.dark class): +- 深色背景 (hsl(222.2 84% 4.9%)) +- 淺色文字 (hsl(210 40% 98%)) + +#### PostCSS +- **配置文件**: `/frontend/postcss.config.js` +- **插件**: @tailwindcss/postcss (新版本原生支持) + +#### 全局樣式 +- **入口**: `/frontend/src/index.css` + - @tailwind 指令導入 + - CSS 變數定義 + - 亮色/暗色主題切換 + +--- + +## 項目目錄結構 + +``` +frontend/ +├── src/ +│ ├── assets/ # 靜態資源 +│ ├── components/ # React 組件 +│ │ ├── ui/ # UI 基礎組件庫 +│ │ │ ├── button.tsx # 按鈕組件 (多種變體) +│ │ │ ├── card.tsx # 卡片容器 +│ │ │ ├── badge.tsx # 標籤組件 +│ │ │ ├── table.tsx # 表格組件 +│ │ │ ├── progress.tsx # 進度條 +│ │ │ └── toast.tsx # 提示通知 +│ │ ├── FileUpload.tsx # 文件上傳 (拖放支持) +│ │ ├── ResultsTable.tsx # 結果表格 +│ │ ├── MarkdownPreview.tsx # Markdown 預覽 +│ │ └── Layout.tsx # 主佈局組件 +│ │ +│ ├── pages/ # 頁面組件 +│ │ ├── LoginPage.tsx # 登錄頁面 +│ │ ├── UploadPage.tsx # 文件上傳頁面 +│ │ ├── ProcessingPage.tsx # OCR 處理頁面 +│ │ ├── ResultsPage.tsx # 結果查看頁面 +│ │ ├── ExportPage.tsx # 導出配置頁面 +│ │ └── SettingsPage.tsx # 系統設置頁面 +│ │ +│ ├── store/ # 狀態管理 (Zustand) +│ │ ├── authStore.ts # 認證狀態 +│ │ └── uploadStore.ts # 上傳狀態 +│ │ +│ ├── services/ # API 服務層 +│ │ └── api.ts # API 客戶端 (Axios) +│ │ +│ ├── types/ # TypeScript 類型定義 +│ │ └── api.ts # API 接口類型 +│ │ +│ ├── lib/ # 工具函數 +│ │ └── utils.ts # cn() 函數 (Tailwind 類名合併) +│ │ +│ ├── hooks/ # 自定義 React Hooks +│ │ └── (待擴展) +│ │ +│ ├── i18n/ # 國際化配置 +│ │ ├── index.ts # i18n 初始化 +│ │ └── locales/ +│ │ └── zh-TW.json # 繁體中文翻譯 +│ │ +│ ├── App.tsx # 應用根組件 (路由定義) +│ ├── main.tsx # 應用入口 +│ ├── index.css # 全局樣式 +│ └── App.css # 應用樣式 (可棄用) +│ +├── public/ # 公開靜態資源 +├── vite.config.ts # Vite 配置 +├── tailwind.config.js # Tailwind 配置 +├── postcss.config.js # PostCSS 配置 +├── tsconfig.json # TypeScript 配置 +├── tsconfig.app.json # 應用 TS 配置 +├── tsconfig.node.json # Node TS 配置 +├── eslint.config.js # ESLint 配置 +├── index.html # HTML 入口 +├── package.json # 依賴管理 +├── package-lock.json # 依賴鎖定 +└── .env # 環境變數 + +``` + +--- + +## 核心頁面和功能 + +### 頁面概述 + +| 頁面 | 路由 | 功能描述 | 行數 | +|------|------|--------|------| +| LoginPage | /login | 用戶認證 | 97 | +| UploadPage | /upload | 文件上傳,支持拖放 | 140 | +| ProcessingPage | /processing | 實時監控 OCR 處理進度 | 200 | +| ResultsPage | /results | 查看和下載 OCR 結果 | 157 | +| ExportPage | /export | 導出規則管理和結果導出 | 321 | +| SettingsPage | /settings | 系統配置和用戶偏好 | 325 | + +### 總 UI 頁面代碼: ~1,240 行 + +--- + +## 組件架構 + +### UI 基礎組件庫 (/src/components/ui/) + +採用現代化的無頭 UI 組件設計,配合 Tailwind CSS: + +1. **Button** + - 變體: default, destructive, outline, secondary, ghost, link + - 尺寸: default, sm, lg, icon + - 使用 cn() 實現動態類名合併 + +2. **Card** + - CardRoot, CardHeader, CardTitle, CardContent, CardFooter + - 容器組件,使用 Tailwind 樣式 + +3. **Table** + - 表格組件家族 + - Table, TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell + +4. **Badge** + - 標籤/徽章組件 + - 用於狀態指示 + +5. **Progress** + - 進度條組件 + - 百分比顯示 + +6. **Toast** + - 通知系統 + - useToast() Hook + - 支持多個變體 + +### 業務組件 + +1. **FileUpload** + - react-dropzone 整合 + - 支持拖放和點擊選擇 + - 文件驗證 (類型、大小、數量) + - 自定義 accept 配置 + +2. **ResultsTable** + - 結果列表展示 + +3. **MarkdownPreview** + - Markdown 內容預覽 + +4. **Layout** + - 主體佈局 + - 導航欄 + - 頁頭 + - 頁腳 + +--- + +## 狀態管理方案 + +### Zustand (v5.0.8) + +#### 1. authStore.ts +```typescript +interface AuthState { + user: User | null + isAuthenticated: boolean + setUser: (user: User | null) => void + logout: () => void +} +``` +- **持久化**: localStorage (auth-storage) +- **用途**: 管理登錄用戶信息和認證狀態 + +#### 2. uploadStore.ts +```typescript +interface UploadState { + batchId: number | null + files: FileInfo[] + uploadProgress: number + setBatchId: (id: number) => void + setFiles: (files: FileInfo[]) => void + setUploadProgress: (progress: number) => void + updateFileStatus: (fileId: number, status: string) => void + clearUpload: () => void +} +``` +- **持久化**: localStorage (tool-ocr-upload-store) + - 只持久化: batchId, files (不持久化進度) +- **用途**: 管理當前上傳批次和文件信息 + +--- + +## API 服務層 + +### API 客戶端 (services/api.ts) + +基於 Axios 的單例模式實現: + +**配置**: +- Base URL: http://localhost:12010 (可通過 VITE_API_BASE_URL 環境變數覆蓋) +- API 版本: /api/v1 +- 超時時間: 30 秒 +- Content-Type: application/json + +**功能模塊**: + +1. **認證模塊** + - login(username, password) + - logout() + - Token 管理 (localStorage) + +2. **文件上傳模塊** + - uploadFiles(files: File[]) + - FormData multipart 上傳 + +3. **OCR 處理模塊** + - processOCR(batchId, lang, confidenceThreshold) + - getTaskStatus(taskId) + - getOCRResult(taskId) + - getBatchStatus(batchId) + +4. **導出模塊** + - exportResults(batchId, format, options) + - exportPDF(fileId, cssTemplate) + - getExportRules() + - createExportRule(rule) + - updateExportRule(ruleId, rule) + - deleteExportRule(ruleId) + - getCSSTemplates() + +5. **翻譯模塊** (計劃功能) + - translateDocument() [501 Not Implemented] + - getTranslationConfigs() + - createTranslationConfig() + +**攔截器**: +- 請求攔截: 自動添加 Authorization Bearer token +- 響應攔截: 401 時清除 token 並重定向到登錄頁 + +--- + +## 類型定義 + +### 主要類型 (types/api.ts) + +#### 認證 +- LoginRequest, LoginResponse, User + +#### 文件上傳 +- UploadResponse, FileInfo + +#### OCR 處理 +- ProcessRequest, ProcessResponse, TaskStatus, BatchStatus, FileResult + +#### OCR 結果 +- OCRResult, OCRJsonData, TextBlock, LayoutInfo + +#### 導出 +- ExportRequest, ExportOptions, ExportRule, CSSTemplate + +#### 翻譯 (Future) +- TranslateRequest, TranslateResponse, TranslationConfig + +#### 錯誤處理 +- ApiError, ApiResponse + +--- + +## 國際化配置 + +### i18n (i18n/index.ts) + +- **庫**: react-i18next v16.3.0 +- **默認語言**: 繁體中文 (zh-TW) +- **翻譯文件**: /i18n/locales/zh-TW.json + +### 翻譯內容結構 +```json +{ + "app": { title, subtitle }, + "nav": { upload, processing, results, export, settings, logout }, + "auth": { login, username, password, loginButton, loginError, welcomeBack }, + "upload": { title, dragAndDrop, dropFilesHere, invalidFiles, ... }, + "processing": { title, status, progress, currentFile, ... }, + "results": { title, filename, status, confidence, ... }, + "export": { title, format, formats, options, rules, cssTemplates, ... }, + "settings": { ... }, + "errors": { ... }, + "common": { ... } +} +``` + +--- + +## 路由結構 + +### React Router v7.9.5 配置 (App.tsx) + +``` +/login → LoginPage (公開) +/ → Layout (受保護) +├── /upload → UploadPage +├── /processing → ProcessingPage +├── /results → ResultsPage +├── /export → ExportPage +└── /settings → SettingsPage +* → 重定向到 / +``` + +**保護機制**: ProtectedRoute 組件基於 authStore.isAuthenticated + +--- + +## 樣式設計工具 + +### Tailwind 工具函數 (lib/utils.ts) + +```typescript +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} +``` + +**功能**: +- clsx: 條件類名組合 +- tailwind-merge: 解決 Tailwind 類名衝突 +- 用於動態生成和合併 Tailwind 類 + +--- + +## 依賴概覽 + +### 主要依賴 +```json +{ + "react": "^19.2.0", + "react-dom": "^19.2.0", + "react-router-dom": "^7.9.5", + "zustand": "^5.0.8", + "@tanstack/react-query": "^5.90.7", + "axios": "^1.13.2", + "react-i18next": "^16.3.0", + "i18next": "^25.6.2", + "react-dropzone": "^14.3.8", + "tailwindcss": "^4.1.17", + "clsx": "^2.1.1", + "tailwind-merge": "^3.4.0" +} +``` + +### 開發依賴 +```json +{ + "typescript": "~5.9.3", + "vite": "^7.2.2", + "@vitejs/plugin-react": "^5.1.0", + "eslint": "^9.39.1", + "typescript-eslint": "^8.46.3", + "@tailwindcss/postcss": "^4.1.17", + "postcss": "^8.5.6", + "autoprefixer": "^10.4.22" +} +``` + +--- + +## 開發和構建 + +### 可用命令 +```bash +npm run dev # 啟動開發服務器 (localhost:12011) +npm run build # 生產構建 (TypeScript 編譯 + Vite 打包) +npm run lint # ESLint 檢查 +npm run preview # 預覽構建結果 +``` + +### 開發服務器配置 +- **端口**: 12011 +- **代理**: /api → http://localhost:12010 (後端) + +--- + +## 代碼質量 + +### ESLint 配置 + +- JavaScript ES2020 規範 +- TypeScript 類型檢查 +- React Hooks 規則 (recommended-latest) +- React Refresh 支持 +- 瀏覽器全局變數支持 + +### TypeScript 配置 + +- 目標: ES2020 +- 模塊: ESNext +- JSX: React-JSX (自動導入) +- 嚴格模式啟用 +- 路徑別名: @ → ./src + +--- + +## 文件統計 + +- **總文件數**: 28 個 +- **源碼總大小**: 152 KB +- **代碼行數**: ~2,702 行 (TS/TSX/JSON) +- **UI 組件**: 6 個基礎組件 +- **業務組件**: 4 個 +- **頁面**: 6 個 +- **工具函數**: 多個 + +--- + +## 樣式實現要點 + +1. **Tailwind CSS 優先**: 所有樣式都使用 Tailwind 工具類 +2. **CSS 變數系統**: 使用 HSL 色彩空間,支持主題切換 +3. **響應式設計**: 內置 Tailwind 響應式前綴支持 +4. **可訪問性**: 焦點環、禁用狀態等 UI 反饋 +5. **暗色模式**: 通過 .dark 類支持主題切換 +6. **組件化**: UI 組件開箱即用,無需額外 CSS + +--- + +## 總結 + +Tool_OCR 前端項目採用現代化的技術棧: + +- **框架**: React 19 + TypeScript +- **構建**: Vite (快速開發和構建) +- **樣式**: Tailwind CSS 4 (工具類優先) +- **狀態**: Zustand (輕量級狀態管理) +- **數據**: React Query (服務器狀態管理) +- **路由**: React Router v7 (應用導航) +- **國際化**: i18next (多語言支持) +- **質量**: ESLint + TypeScript (靜態檢查) + +**核心特點**: +1. 類型安全的開發環境 +2. 響應式 UI 設計 +3. 模塊化組件架構 +4. 完整的狀態管理 +5. API 層分離 +6. 國際化就位 +7. 開發友好 (HMR, 快速刷新) + diff --git a/FRONTEND_CODE_EXAMPLES.md b/FRONTEND_CODE_EXAMPLES.md new file mode 100644 index 0000000..3c588f9 --- /dev/null +++ b/FRONTEND_CODE_EXAMPLES.md @@ -0,0 +1,652 @@ +# Tool_OCR 前端代碼示例和最佳實踐 + +## 1. Tailwind CSS 樣式使用示例 + +### 佈局組件 (Layout.tsx 提取) +```typescript +// 導航欄樣式示例 +
+
+

{t('app.title')}

+ +
+
+ +{/* 導航選項卡 */} + +``` + +### 按鈕變體示例 (button.tsx) +```typescript +// 默認按鈕 + + +// 危險操作 + + +// 輪廓樣式 + + +// 幽靈按鈕 + + +// 鏈接樣式 + + +// 不同尺寸 + + + +``` + +### 響應式卡片示例 (UploadPage.tsx 提取) +```typescript +
+ + +
+ + {t('upload.selectedFiles')} ({selectedFiles.length}) + + +
+
+ +
+ {selectedFiles.map((file, index) => ( +
+
+

+ {file.name} +

+

+ {formatFileSize(file.size)} +

+
+ +
+ ))} +
+
+
+
+``` + +### 文件上傳拖放區域 (FileUpload.tsx 提取) +```typescript + +
+ + +
+ +
+ +
+ {isDragActive ? ( +

+ {isDragReject ? t('upload.invalidFiles') : t('upload.dropFilesHere')} +

+ ) : ( + <> +

+ {t('upload.dragAndDrop')} +

+

+ {t('upload.supportedFormats')} +

+ + )} +
+
+
+``` + +--- + +## 2. React Query 使用示例 + +### 批次狀態查詢 (ResultsPage.tsx 提取) +```typescript +import { useQuery } from '@tanstack/react-query' + +export default function ResultsPage() { + const { batchId } = useUploadStore() + const [selectedFileId, setSelectedFileId] = useState(null) + + // 獲取批次狀態 + const { data: batchStatus, isLoading } = useQuery({ + queryKey: ['batchStatus', batchId], + queryFn: () => apiClient.getBatchStatus(batchId!), + enabled: !!batchId, // 只在有 batchId 時查詢 + }) + + // 獲取 OCR 結果 + const { data: ocrResult, isLoading: isLoadingResult } = useQuery({ + queryKey: ['ocrResult', selectedFileId], + queryFn: () => apiClient.getOCRResult(selectedFileId!.toString()), + enabled: !!selectedFileId, + }) + + if (!batchId) { + return
Please upload files first
+ } + + return ( +
+ {isLoading ? ( +

Loading batch status...

+ ) : ( + + )} +
+ ) +} +``` + +--- + +## 3. Zustand 狀態管理示例 + +### 認證存儲 (authStore.ts) +```typescript +import { create } from 'zustand' +import { persist } from 'zustand/middleware' +import type { User } from '@/types/api' + +interface AuthState { + user: User | null + isAuthenticated: boolean + setUser: (user: User | null) => void + logout: () => void +} + +export const useAuthStore = create()( + persist( + (set) => ({ + user: null, + isAuthenticated: false, + setUser: (user) => + set({ + user, + isAuthenticated: user !== null, + }), + logout: () => + set({ + user: null, + isAuthenticated: false, + }), + }), + { + name: 'auth-storage', // localStorage 鍵名 + } + ) +) + +// 使用示例 +function LoginPage() { + const setUser = useAuthStore((state) => state.setUser) + + const handleLogin = async (username: string, password: string) => { + const response = await apiClient.login({ username, password }) + setUser({ id: 1, username }) + } +} +``` + +### 上傳狀態存儲 (uploadStore.ts) +```typescript +export const useUploadStore = create()( + persist( + (set) => ({ + batchId: null, + files: [], + uploadProgress: 0, + + setBatchId: (id) => { + set({ batchId: id }) + }, + + setFiles: (files) => set({ files }), + + setUploadProgress: (progress) => set({ uploadProgress: progress }), + + updateFileStatus: (fileId, status) => + set((state) => ({ + files: state.files.map((file) => + file.id === fileId ? { ...file, status } : file + ), + })), + + clearUpload: () => + set({ + batchId: null, + files: [], + uploadProgress: 0, + }), + }), + { + name: 'tool-ocr-upload-store', + // 只持久化 batchId 和 files,不持久化進度 + partialize: (state) => ({ + batchId: state.batchId, + files: state.files, + }), + } + ) +) + +// 使用示例 +function UploadPage() { + const { setBatchId, setFiles } = useUploadStore() + + const handleUploadSuccess = (data: UploadResponse) => { + setBatchId(data.batch_id) + setFiles(data.files) + } +} +``` + +--- + +## 4. API 客戶端使用示例 + +### API 認證流程 (api.ts) +```typescript +// 登錄 +const response = await apiClient.login({ + username: 'admin', + password: 'password' +}) +// Token 自動保存到 localStorage + +// 後續請求自動附帶 token +const status = await apiClient.getBatchStatus(123) +// 請求頭自動包含: Authorization: Bearer + +// 登出 +apiClient.logout() +// Token 自動從 localStorage 清除 +``` + +### 文件上傳示例 +```typescript +const handleUpload = async (files: File[]) => { + try { + const response = await apiClient.uploadFiles(files) + // response: { batch_id: 1, files: [...] } + setBatchId(response.batch_id) + setFiles(response.files) + } catch (error) { + // 自動處理 401 錯誤並重定向到登錄頁 + showError(error.response?.data?.detail) + } +} +``` + +### 導出功能示例 +```typescript +// 導出 PDF +const handleDownloadPDF = async (fileId: number) => { + const blob = await apiClient.exportPDF(fileId) + const url = window.URL.createObjectURL(blob) + const a = document.createElement('a') + a.href = url + a.download = `ocr-result-${fileId}.pdf` + a.click() + window.URL.revokeObjectURL(url) +} + +// 導出規則管理 +const rules = await apiClient.getExportRules() +const newRule = await apiClient.createExportRule({ + rule_name: 'My Rule', + config_json: { /* ... */ } +}) +await apiClient.updateExportRule(rule.id, { rule_name: 'Updated' }) +await apiClient.deleteExportRule(rule.id) +``` + +--- + +## 5. 國際化使用示例 + +### 在組件中使用翻譯 +```typescript +import { useTranslation } from 'react-i18next' + +export default function UploadPage() { + const { t } = useTranslation() + + return ( +
+

{t('upload.title')}

+

{t('upload.dragAndDrop')}

+ + {/* 帶插值的翻譯 */} +

{t('upload.fileCount', { count: 5 })}

+ {/* 會渲染: "已選擇 5 個檔案" */} + + +
+ ) +} +``` + +### i18n 初始化 (i18n/index.ts) +```typescript +import i18n from 'i18next' +import { initReactI18next } from 'react-i18next' +import zhTW from './locales/zh-TW.json' + +i18n.use(initReactI18next).init({ + resources: { + 'zh-TW': { + translation: zhTW, + }, + }, + lng: 'zh-TW', + fallbackLng: 'zh-TW', + interpolation: { + escapeValue: false, + }, +}) + +export default i18n +``` + +--- + +## 6. 路由和保護示例 + +### 受保護的路由 (App.tsx) +```typescript +function ProtectedRoute({ children }: { children: React.ReactNode }) { + const isAuthenticated = useAuthStore((state) => state.isAuthenticated) + + if (!isAuthenticated) { + return + } + + return <>{children} +} + +function App() { + return ( + + {/* 公開路由 */} + } /> + + {/* 受保護的路由 */} + + + + } + > + } /> + } /> + } /> + } /> + } /> + } /> + + + {/* 全部匹配 */} + } /> + + ) +} +``` + +--- + +## 7. 類型定義示例 + +### API 類型 (types/api.ts) +```typescript +// 認證 +export interface LoginRequest { + username: string + password: string +} + +export interface LoginResponse { + access_token: string + token_type: string +} + +// 文件上傳 +export interface UploadResponse { + batch_id: number + files: FileInfo[] +} + +export interface FileInfo { + id: number + filename: string + file_size: number + format: string + status: 'pending' | 'processing' | 'completed' | 'failed' +} + +// OCR 結果 +export interface OCRResult { + file_id: number + filename: string + status: string + markdown_content: string + json_data: OCRJsonData + confidence: number + processing_time: number +} + +export interface TextBlock { + text: string + confidence: number + bbox: [number, number, number, number] + position: number +} + +// 導出規則 +export interface ExportRule { + id: number + rule_name: string + config_json: Record + css_template?: string + created_at: string +} +``` + +--- + +## 8. 最佳實踐 + +### 1. 組件結構 +```typescript +// 導入順序 +import { useState } from 'react' +import { useNavigate } from 'react-router-dom' +import { useTranslation } from 'react-i18next' +import { useQuery } from '@tanstack/react-query' + +// 內部導入 +import { Button } from '@/components/ui/button' +import { Card } from '@/components/ui/card' +import { useAuthStore } from '@/store/authStore' +import { apiClient } from '@/services/api' + +// 組件定義 +export default function MyPage() { + // Hooks + const { t } = useTranslation() + const navigate = useNavigate() + const [state, setState] = useState(null) + + // 查詢 + const { data, isLoading } = useQuery({ + queryKey: ['key'], + queryFn: () => apiClient.getData(), + }) + + // 狀態更新 + const handleClick = () => { + // ... + } + + // 渲染 + return ( +
+ {/* JSX */} +
+ ) +} +``` + +### 2. 錯誤處理 +```typescript +const { toast } = useToast() + +const handleAction = async () => { + try { + const result = await apiClient.doSomething() + toast({ + title: t('success.title'), + description: t('success.message'), + variant: 'success', + }) + } catch (error: any) { + const errorMessage = error.response?.data?.detail || t('errors.generic') + toast({ + title: t('error.title'), + description: errorMessage, + variant: 'destructive', + }) + } +} +``` + +### 3. 類名合併 +```typescript +import { cn } from '@/lib/utils' + +// 條件類名 +const buttonClass = cn( + 'base-classes', + { + 'conditional-classes': isActive, + 'other-classes': isDisabled, + }, + customClassName +) + +// 動態樣式 +const cardClass = cn( + 'p-4 rounded-lg', + variant === 'outlined' && 'border border-input', + variant === 'elevated' && 'shadow-lg' +) +``` + +### 4. React Query 配置 +```typescript +// 主入口 (main.tsx) +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: 1, + refetchOnWindowFocus: false, + staleTime: 1000 * 60 * 5, // 5 分鐘 + }, + }, +}) + +// 使用示例 +const { data, isLoading, error } = useQuery({ + queryKey: ['items', id], + queryFn: () => apiClient.getItem(id), + enabled: !!id, // 條件查詢 + staleTime: 1000 * 60 * 10, // 10 分鐘不新鮮 +}) +``` + +--- + +## 9. 環境變數 + +### .env 文件 +```env +VITE_API_BASE_URL=http://localhost:12010 +``` + +### 使用環境變數 +```typescript +const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:12010' +``` + +--- + +## 10. 常見開發流程 + +### 創建新頁面 +1. 在 `/src/pages` 創建 `NewPage.tsx` +2. 在 `App.tsx` 添加路由 +3. 使用 Zustand 管理狀態 +4. 使用 React Query 獲取數據 +5. 使用 Tailwind CSS 樣式 +6. 使用 i18next 添加文字 + +### 添加新 API 接口 +1. 在 `types/api.ts` 定義類型 +2. 在 `services/api.ts` 添加方法 +3. 在需要的地方使用 `apiClient.method()` +4. 使用 React Query 或直接調用 + +### 修改樣式 +1. 優先使用 Tailwind CSS 工具類 +2. 使用 cn() 合併類名 +3. 修改 `tailwind.config.js` 自定義主題 +4. 在 `index.css` 添加全局樣式 + diff --git a/FRONTEND_QUICK_REFERENCE.md b/FRONTEND_QUICK_REFERENCE.md new file mode 100644 index 0000000..50b4760 --- /dev/null +++ b/FRONTEND_QUICK_REFERENCE.md @@ -0,0 +1,397 @@ +# Tool_OCR 前端快速參考指南 + +## 文件位置速查表 + +### 主要文件位置 +``` +/Users/egg/Projects/Tool_OCR/frontend/ +├── src/ +│ ├── App.tsx # 路由定義 +│ ├── main.tsx # 應用入口 +│ ├── index.css # 全局樣式 +│ ├── components/ +│ │ ├── ui/ # UI 組件庫 +│ │ ├── Layout.tsx # 主佈局 +│ │ ├── FileUpload.tsx # 文件上傳 +│ │ └── ... +│ ├── pages/ # 頁面 +│ ├── store/ # 狀態管理 +│ ├── services/api.ts # API 客戶端 +│ ├── types/api.ts # 類型定義 +│ ├── i18n/ # 國際化 +│ └── lib/utils.ts # 工具函數 +├── vite.config.ts # Vite 配置 +├── tailwind.config.js # Tailwind 配置 +├── tsconfig.json # TypeScript 配置 +└── package.json # 依賴管理 +``` + +--- + +## 技術棧速查 + +| 功能 | 技術 | 版本 | +|-----|------|------| +| UI 框架 | React | 19.2.0 | +| 語言 | TypeScript | 5.9.3 | +| 構建 | Vite | 7.2.2 | +| 樣式 | Tailwind CSS | 4.1.17 | +| 狀態管理 | Zustand | 5.0.8 | +| 數據獲取 | React Query | 5.90.7 | +| 路由 | React Router | 7.9.5 | +| 國際化 | i18next | 25.6.2 | +| HTTP | Axios | 1.13.2 | +| 檔案上傳 | react-dropzone | 14.3.8 | + +--- + +## 常用命令 + +```bash +# 開發 +cd frontend +npm run dev # 啟動開發服務器 (localhost:12011) +npm run lint # 代碼檢查 +npm run build # 生產構建 + +# 類型檢查 +npx tsc --noEmit # 檢查 TypeScript 錯誤 + +# 格式化 +npm install -D prettier # (如果需要) +npx prettier --write src/ # 格式化代碼 +``` + +--- + +## 路由結構 + +``` +/login → LoginPage (公開) +/upload → UploadPage (受保護) +/processing → ProcessingPage (受保護) +/results → ResultsPage (受保護) +/export → ExportPage (受保護) +/settings → SettingsPage (受保護) +``` + +### 添加新路由 +```typescript +// 在 App.tsx 中 +} /> + +// 在導航中 +{ to: '/new-page', label: t('nav.newPage') } +``` + +--- + +## 常用代碼片段 + +### 使用 i18n 翻譯 +```typescript +const { t } = useTranslation() +

{t('key.path')}

+``` + +### 使用 Zustand 狀態 +```typescript +const { batchId, setBatchId } = useUploadStore() +const { user, logout } = useAuthStore() +``` + +### 調用 API +```typescript +const data = await apiClient.uploadFiles(files) +const status = await apiClient.getBatchStatus(batchId) +``` + +### React Query 查詢 +```typescript +const { data, isLoading } = useQuery({ + queryKey: ['key', id], + queryFn: () => apiClient.getData(id), +}) +``` + +### Tailwind 樣式 +```typescript +className="flex items-center justify-between p-4 bg-card rounded-lg" +className={cn('base', { 'conditional': isActive })} +``` + +### 提示通知 +```typescript +const { toast } = useToast() +toast({ + title: 'Success', + description: 'Action completed', + variant: 'success', +}) +``` + +--- + +## 調試技巧 + +### 查看存儲在 localStorage 的狀態 +```javascript +// 在瀏覽器控制台 +console.log(JSON.parse(localStorage.getItem('auth-storage'))) +console.log(JSON.parse(localStorage.getItem('tool-ocr-upload-store'))) +``` + +### 查看 React Query 緩存 +```javascript +// 在瀏覽器控制台安裝 React Query DevTools +// npm install @tanstack/react-query-devtools +``` + +### TypeScript 錯誤 +```bash +# 運行編譯器檢查類型 +npx tsc --noEmit +``` + +--- + +## 環境變數配置 + +### 開發環境 (.env) +```env +VITE_API_BASE_URL=http://localhost:12010 +``` + +### 使用環境變數 +```typescript +const baseURL = import.meta.env.VITE_API_BASE_URL +``` + +--- + +## 常見問題 + +### Q: 如何添加新的頁面? +A: +1. 在 `/src/pages` 創建 `NewPage.tsx` +2. 在 `App.tsx` 添加路由 +3. 在 Layout.tsx 導航中添加鏈接 + +### Q: 如何修改主題顏色? +A: +1. 編輯 `src/index.css` 中的 CSS 變數 +2. 或編輯 `tailwind.config.js` + +### Q: 如何添加新的翻譯? +A: +1. 編輯 `src/i18n/locales/zh-TW.json` +2. 在組件中使用 `t('key.path')` + +### Q: 如何調試 API 請求? +A: +1. 打開瀏覽器開發者工具 (Network 標籤) +2. 檢查 `/api/v1/` 的請求 + +### Q: 上傳文件怎樣無法工作? +A: +1. 檢查後端是否在運行 (localhost:12010) +2. 檢查文件格式是否被支持 +3. 檢查文件大小是否超過 50MB + +### Q: 認證登錄失敗? +A: +1. 檢查用戶名和密碼 +2. 檢查後端認證端點 `/api/v1/auth/login` +3. 檢查 localStorage 中的 token + +--- + +## 依賴更新 + +```bash +# 檢查過期依賴 +npm outdated + +# 更新依賴 +npm update + +# 更新到最新版本 +npm install --save-latest package-name + +# 清除 node_modules 並重新安裝 +rm -rf node_modules package-lock.json +npm install +``` + +--- + +## 性能優化 + +### 代碼分割 +```typescript +import { lazy, Suspense } from 'react' + +const NewPage = lazy(() => import('./pages/NewPage')) + +// 在 Routes 中 +Loading...}> + + +``` + +### 優化 React Query +```typescript +const { data } = useQuery({ + queryKey: ['items'], + queryFn: () => apiClient.getItems(), + staleTime: 1000 * 60 * 5, // 5 分鐘內不重新獲取 + gcTime: 1000 * 60 * 10, // 10 分鐘後從緩存中移除 +}) +``` + +### 優化組件 +```typescript +// 使用 React.memo 避免不必要的重新渲染 +export default React.memo(function MyComponent(props) { + return
{props.data}
+}) +``` + +--- + +## 測試 (可選) + +```bash +# 安裝測試工具 +npm install -D vitest @testing-library/react + +# 運行測試 +npm test + +# 生成覆蓋率報告 +npm test -- --coverage +``` + +--- + +## 構建和部署 + +```bash +# 生產構建 +npm run build + +# 預覽構建 +npm run preview + +# 構建後的文件位置 +# dist/ + +# 部署 +# 將 dist/ 目錄上傳到服務器 +# 配置 Web 服務器支持 SPA (所有路由都指向 index.html) +``` + +--- + +## 貢獻指南 + +### 代碼風格 +- 使用 TypeScript 進行類型安全 +- 遵循現有的命名約定 +- 優先使用 Tailwind CSS +- 添加必要的類型定義 + +### 提交代碼 +```bash +# 檢查代碼 +npm run lint + +# 提交 +git add . +git commit -m "description of changes" +git push +``` + +--- + +## 有用的資源 + +### 文檔 +- [React 文檔](https://react.dev) +- [Tailwind CSS](https://tailwindcss.com) +- [React Router](https://reactrouter.com) +- [Zustand](https://github.com/pmndrs/zustand) +- [React Query](https://tanstack.com/query) +- [i18next](https://www.i18next.com) + +### 工具 +- [Vite 文檔](https://vitejs.dev) +- [TypeScript 文檔](https://www.typescriptlang.org) +- [ESLint 文檔](https://eslint.org) + +### IDE 擴展 (VS Code) +- Tailwind CSS IntelliSense +- Thunder Client (API 測試) +- React Developer Tools +- Redux DevTools (狀態檢查) + +--- + +## 快速開始 + +```bash +# 1. 進入前端目錄 +cd /Users/egg/Projects/Tool_OCR/frontend + +# 2. 安裝依賴 +npm install + +# 3. 啟動開發服務器 +npm run dev + +# 4. 打開瀏覽器 +# 訪問 http://localhost:12011 + +# 5. 登錄 +# 使用後端提供的帳號密碼 + +# 6. 開始使用 +# 上傳檔案 → 處理 → 查看結果 → 匯出 +``` + +--- + +## 常用快捷鍵 + +### VS Code +- `Ctrl+Shift+F` (或 `Cmd+Shift+F` 在 Mac) - 全文搜索 +- `Ctrl+K Ctrl+X` - 刪除行 +- `Alt+Up/Down` - 移動行 +- `Ctrl+/` - 註解行 + +### 瀏覽器開發者工具 +- `F12` 或 `Ctrl+Shift+I` - 打開開發者工具 +- `Ctrl+Shift+C` - 元素檢查器 +- `Ctrl+Shift+M` - 響應式設計模式 + +--- + +## 總結速記 + +**架構**:React 19 + TypeScript + Vite +**樣式**:Tailwind CSS 4 +**狀態**:Zustand (輕量) + React Query (數據) +**路由**:React Router v7 +**API**:Axios 單例客戶端 +**國際化**:i18next (繁體中文) +**開發端口**:12011 +**後端 API**:localhost:12010 + +**核心文件**: +- App.tsx (路由) +- main.tsx (入口) +- services/api.ts (API) +- store/*.ts (狀態) +- pages/ (頁面) +- components/ (組件) + diff --git a/FRONTEND_README.md b/FRONTEND_README.md new file mode 100644 index 0000000..f812705 --- /dev/null +++ b/FRONTEND_README.md @@ -0,0 +1,185 @@ +# Tool_OCR 前端文檔索引 + +歡迎查閱 Tool_OCR 前端項目的完整文檔。本頁面將幫助您快速找到所需的信息。 + +## 文檔列表 + +### 1. FRONTEND_ANALYSIS.md +**完整的技術棧和項目結構分析** + +包含內容: +- 項目概況和技術棧詳解 +- 完整的目錄結構說明 +- 核心頁面和功能概述 +- 組件架構設計 +- 狀態管理方案 (Zustand) +- API 服務層設計 +- 類型定義系統 +- 國際化配置 +- 路由結構 +- 依賴概覽 +- 代碼質量檢查 +- 樣式實現要點 + +**適合閱讀場景:** +- 全新成員了解項目整體架構 +- 深入理解技術選擇和設計決策 +- 查看完整的模塊組織結構 +- 了解樣式系統的設計方式 + +### 2. FRONTEND_CODE_EXAMPLES.md +**實際代碼示例和最佳實踐** + +包含內容: +- Tailwind CSS 使用示例 (佈局、按鈕、卡片等) +- React Query 數據獲取示例 +- Zustand 狀態管理示例 +- API 客戶端使用示例 +- 國際化集成示例 +- 路由和路由保護示例 +- TypeScript 類型定義示例 +- 最佳實踐指南 (組件結構、錯誤處理等) +- 環境變數配置 +- 常見開發流程 + +**適合閱讀場景:** +- 開發新功能時參考代碼模式 +- 尋找特定技術的使用示例 +- 學習項目內的最佳實踐 +- 複製粘貼代碼片段快速開發 + +### 3. FRONTEND_QUICK_REFERENCE.md +**快速查閱和常見問題** + +包含內容: +- 文件位置速查表 +- 技術棧版本速查 +- 常用開發命令 +- 路由結構速查 +- 常用代碼片段 +- 調試技巧 +- 常見問題解答 (FAQ) +- 依賴更新指南 +- 性能優化建議 +- 構建和部署指南 +- 有用資源鏈接 + +**適合閱讀場景:** +- 快速查找文件位置 +- 尋找常用命令 +- 解決常見問題 +- 快速參考語法 +- 了解開發工作流 + +## 快速開始路線圖 + +### 如果您是新開發者: +1. 先讀 **FRONTEND_QUICK_REFERENCE.md** 的「快速開始」部分 +2. 再讀 **FRONTEND_ANALYSIS.md** 了解整體架構 +3. 需要時查閱 **FRONTEND_CODE_EXAMPLES.md** 的相關示例 + +### 如果您需要開發新功能: +1. 查閱 **FRONTEND_QUICK_REFERENCE.md** 的「常用代碼片段」 +2. 參考 **FRONTEND_CODE_EXAMPLES.md** 的相關示例 +3. 根據功能類型選擇合適的設計模式 + +### 如果您遇到問題: +1. 查閱 **FRONTEND_QUICK_REFERENCE.md** 的「常見問題」 +2. 查閱 **FRONTEND_QUICK_REFERENCE.md** 的「調試技巧」 +3. 參考 **FRONTEND_CODE_EXAMPLES.md** 的「最佳實踐」 + +## 項目核心信息速記 + +### 技術棧 +- **UI 框架**: React 19.2.0 + TypeScript +- **構建工具**: Vite 7.2.2 +- **樣式**: Tailwind CSS 4.1.17 +- **狀態管理**: Zustand 5.0.8 + React Query 5.90.7 +- **路由**: React Router v7.9.5 +- **HTTP**: Axios +- **國際化**: i18next (繁體中文) + +### 開發環境 +- **開發端口**: 12011 +- **後端 API**: localhost:12010 +- **命令**: `npm run dev` | `npm run build` | `npm run lint` + +### 主要頁面 +- `/login` - 登錄頁面 +- `/upload` - 文件上傳 +- `/processing` - OCR 處理 +- `/results` - 結果查看 +- `/export` - 結果導出 +- `/settings` - 系統設置 + +### 核心目錄 +- `/components` - React 組件 +- `/pages` - 應用頁面 +- `/store` - 狀態管理 (Zustand) +- `/services` - API 客戶端 +- `/types` - TypeScript 類型 +- `/i18n` - 國際化配置 + +## 文檔使用建議 + +### 打開文檔 +所有文檔都保存在項目根目錄: +``` +/Users/egg/Projects/Tool_OCR/FRONTEND_*.md +``` + +推薦使用 VS Code 或任何 Markdown 編輯器打開。 + +### 導航技巧 +- 使用 Markdown 編輯器的大綱功能快速導航 +- 使用 Ctrl+F (或 Cmd+F) 搜索關鍵詞 +- 點擊標題鏈接快速跳轉 + +### 保持同步 +文檔基於以下源代碼分析: +- React 19.2.0 +- Vite 7.2.2 +- Tailwind CSS 4.1.17 +- 其他依賴均按 package.json 記錄 + +如果依賴升級或架構調整,請相應更新文檔。 + +## 常用快速鏈接 + +### 官方文檔 +- [React 官方文檔](https://react.dev) +- [Tailwind CSS](https://tailwindcss.com) +- [Vite 文檔](https://vitejs.dev) +- [React Router](https://reactrouter.com) +- [Zustand](https://github.com/pmndrs/zustand) +- [React Query](https://tanstack.com/query) +- [i18next](https://www.i18next.com) + +### IDE 推薦擴展 (VS Code) +- Tailwind CSS IntelliSense +- ES7+ React/Redux/React-Native snippets +- Thunder Client (API 測試) +- TypeScript Vue Plugin +- ESLint + +## 文檔維護 + +這些文檔是對項目當前狀態的快照。當進行以下操作時應考慮更新: + +- 升級主要依賴版本 +- 更改項目結構 +- 添加新的關鍵功能 +- 改變設計模式或最佳實踐 +- 優化或重構大型模塊 + +## 反饋和建議 + +如果發現文檔中有錯誤或遺漏,歡迎: +1. 直接編輯文檔並提交 PR +2. 創建 Issue 報告問題 +3. 聯繫專案維護者 + +--- + +最後更新: 2024年11月12日 +文檔覆蓋版本: React 19.2.0, Vite 7.2.2, Tailwind CSS 4.1.17