diff --git a/.env.example b/.env.example index 520e9a0..5328a18 100644 --- a/.env.example +++ b/.env.example @@ -1,81 +1,85 @@ # Tool_OCR - Environment Configuration Template -# Copy this file to .env and fill in your actual values +# Copy this file to .env.local and fill in your actual values # ===== Database Configuration ===== -MYSQL_HOST=mysql.theaken.com -MYSQL_PORT=33306 -MYSQL_USER=A060 -MYSQL_PASSWORD=WLeSCi0yhtc7 -MYSQL_DATABASE=db_A060 +MYSQL_HOST=your-mysql-host +MYSQL_PORT=3306 +MYSQL_USER=your-username +MYSQL_PASSWORD=your-password +MYSQL_DATABASE=your-database # ===== Application Configuration ===== # Server ports -BACKEND_PORT=12010 -FRONTEND_PORT=12011 +BACKEND_PORT=8000 +FRONTEND_PORT=5173 -# Security +# Security (generate a random string for production) SECRET_KEY=your-secret-key-here-please-change-this-to-random-string ALGORITHM=HS256 -ACCESS_TOKEN_EXPIRE_MINUTES=30 +ACCESS_TOKEN_EXPIRE_MINUTES=1440 + +# ===== External Authentication Configuration ===== +EXTERNAL_AUTH_API_URL=https://your-auth-api.example.com +EXTERNAL_AUTH_ENDPOINT=/api/auth/login +EXTERNAL_AUTH_TIMEOUT=30 +TOKEN_REFRESH_BUFFER=300 + +# ===== Task Management Configuration ===== +DATABASE_TABLE_PREFIX=tool_ocr_ +ENABLE_TASK_HISTORY=true +TASK_RETENTION_DAYS=30 +MAX_TASKS_PER_USER=1000 # ===== OCR Configuration ===== -# PaddleOCR model directory PADDLEOCR_MODEL_DIR=./models/paddleocr -# Supported languages (comma-separated) OCR_LANGUAGES=ch,en,japan,korean -# Default confidence threshold OCR_CONFIDENCE_THRESHOLD=0.5 -# Maximum concurrent OCR workers MAX_OCR_WORKERS=4 +# GPU Acceleration Configuration +FORCE_CPU_MODE=false +GPU_MEMORY_FRACTION=0.8 +GPU_DEVICE_ID=0 + # ===== File Upload Configuration ===== -# Maximum file size in bytes (50MB default) MAX_UPLOAD_SIZE=52428800 -# Allowed file extensions (comma-separated) -ALLOWED_EXTENSIONS=png,jpg,jpeg,pdf,bmp,tiff -# Upload directories +ALLOWED_EXTENSIONS=png,jpg,jpeg,pdf,bmp,tiff,doc,docx,ppt,pptx UPLOAD_DIR=./uploads TEMP_DIR=./uploads/temp PROCESSED_DIR=./uploads/processed IMAGES_DIR=./uploads/images # ===== Export Configuration ===== -# Storage directories STORAGE_DIR=./storage MARKDOWN_DIR=./storage/markdown JSON_DIR=./storage/json EXPORTS_DIR=./storage/exports # ===== PDF Generation Configuration ===== -# Pandoc path (auto-detected if installed via brew) -PANDOC_PATH=/opt/homebrew/bin/pandoc -# WeasyPrint font directory -FONT_DIR=/System/Library/Fonts -# Default PDF page size +# Linux: /usr/bin/pandoc, macOS: /opt/homebrew/bin/pandoc +PANDOC_PATH=/usr/bin/pandoc +# Linux: /usr/share/fonts, macOS: /System/Library/Fonts +FONT_DIR=/usr/share/fonts PDF_PAGE_SIZE=A4 -# Default PDF margins (mm) PDF_MARGIN_TOP=20 PDF_MARGIN_BOTTOM=20 PDF_MARGIN_LEFT=20 PDF_MARGIN_RIGHT=20 -# ===== Translation Configuration (Reserved) ===== -# Enable translation feature (reserved for future) -ENABLE_TRANSLATION=false -# Translation engine: offline (argostranslate) or api (future) -TRANSLATION_ENGINE=offline -# Argostranslate models directory -ARGOSTRANSLATE_MODELS_DIR=./models/argostranslate +# ===== Translation Configuration (DIFY API) ===== +# Enable translation feature +ENABLE_TRANSLATION=true +# DIFY API endpoint +DIFY_API_URL=https://your-dify-instance.example.com +# DIFY API key (get from DIFY dashboard) +DIFY_API_KEY=your-dify-api-key # ===== Background Tasks Configuration ===== -# Task queue type: memory (default) or redis (future) TASK_QUEUE_TYPE=memory -# Redis URL (if using redis) # REDIS_URL=redis://localhost:6379/0 # ===== CORS Configuration ===== -# Allowed origins (comma-separated, * for all) -CORS_ORIGINS=http://localhost:12011,http://127.0.0.1:12011 +CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173 # ===== Logging Configuration ===== LOG_LEVEL=INFO diff --git a/.gitignore b/.gitignore index b40b45d..cdad859 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,9 @@ env/ .env.local .env.*.local +# ===== Process ID Files ===== +.pid/ + # ===== Logs ===== logs/ *.log diff --git a/frontend/.env.example b/frontend/.env.example index f67c662..3a022b6 100644 --- a/frontend/.env.example +++ b/frontend/.env.example @@ -1,4 +1,7 @@ +# Frontend Environment Configuration +# Copy this file to .env.local and configure + # Backend API URL -# For WSL2, use the WSL2 IP address (get it with: hostname -I) -# For native Linux/Mac, use http://localhost:8000 -VITE_API_URL=http://172.20.20.106:8000 +# For local development: http://localhost:8000 +# For WSL2: Use the WSL2 IP address (get with: hostname -I | awk '{print $1}') +VITE_API_URL=http://localhost:8000 diff --git a/openspec/changes/archive/2025-12-02-unify-environment-scripts/design.md b/openspec/changes/archive/2025-12-02-unify-environment-scripts/design.md new file mode 100644 index 0000000..7f124e7 --- /dev/null +++ b/openspec/changes/archive/2025-12-02-unify-environment-scripts/design.md @@ -0,0 +1,96 @@ +# Design: Unify Environment Scripts + +## Context + +Tool_OCR 是一個 OCR 處理系統,包含 FastAPI 後端和 React 前端。目前的環境設置和啟動流程分散在多個腳本中: + +- `setup_dev_env.sh` (341 lines) - 完整的開發環境設置 +- `start_backend.sh` (60 lines) - 後端服務啟動 +- `start_frontend.sh` (41 lines) - 前端服務啟動 +- `download_fonts.sh` - 字體下載 (可選) + +**Current Pain Points:** +1. 需要開兩個終端分別啟動前後端 +2. 環境變數配置分散在多個 `.env` 文件中 +3. 缺少服務狀態檢查和優雅停止機制 +4. GPU 配置需要手動驗證 + +## Goals / Non-Goals + +**Goals:** +- 簡化開發環境設置流程 +- 統一前後端啟動為單一命令 +- 改善錯誤訊息和故障排除體驗 +- 確保跨平台兼容性 (Ubuntu, WSL2) + +**Non-Goals:** +- 容器化 (Docker) - 保留為未來提案 +- 生產環境部署腳本 +- 自動化測試環境設置 + +## Decisions + +### 1. Unified Startup Script Design + +**Decision:** 使用單一 `start.sh` 腳本,支援多種模式 + +```bash +# Usage examples: +./start.sh # Start both backend and frontend +./start.sh backend # Start only backend +./start.sh frontend # Start only frontend +./start.sh --stop # Stop all services +./start.sh --status # Show service status +``` + +**Rationale:** 保持簡單,使用 bash 內建功能管理子進程,不引入額外依賴如 PM2 或 supervisord。 + +### 2. Process Management + +**Decision:** 使用 PID 文件追蹤進程,支援優雅停止 + +- PID files stored in `.pid/` directory (gitignored) +- SIGTERM for graceful shutdown +- Fallback to SIGKILL after timeout + +### 3. Environment Variable Strategy + +**Decision:** 保持分離的 `.env` 文件,但改善文檔 + +- Root `.env.local` - 共用配置 (database, API keys) +- Frontend `.env.local` - 前端特定配置 (VITE_* variables) +- `.env.example` files updated with all required variables + +**Rationale:** 前端 Vite 需要 `VITE_` 前綴的變數,混合會造成困擾。 + +### 4. Package Dependencies + +**Current State:** +- Python: 77 packages in requirements.txt +- Node.js: 17 dependencies + 15 devDependencies + +**Key Dependencies to Audit:** +- PaddlePaddle GPU vs CPU selection +- Unused development tools +- Duplicate functionality packages + +## Risks / Trade-offs + +| Risk | Mitigation | +|------|------------| +| Breaking existing workflows | Keep old scripts as aliases | +| Complex process management | Start simple, add features incrementally | +| WSL2 compatibility issues | Test on clean WSL2 Ubuntu 22.04 | + +## Migration Plan + +1. Create new `start.sh` alongside existing scripts +2. Update documentation to recommend new script +3. After validation, deprecate old scripts (keep for one release) +4. Remove old scripts in future version + +## Open Questions + +1. Should we add systemd service files for production? +2. Should we include database migration in startup? +3. Should we add health check retries before opening browser? diff --git a/openspec/changes/archive/2025-12-02-unify-environment-scripts/proposal.md b/openspec/changes/archive/2025-12-02-unify-environment-scripts/proposal.md new file mode 100644 index 0000000..a1a0e79 --- /dev/null +++ b/openspec/changes/archive/2025-12-02-unify-environment-scripts/proposal.md @@ -0,0 +1,25 @@ +# Change: Unify Environment Setup and Startup Scripts + +## Why + +目前專案有多個獨立的腳本來設置環境和啟動服務,開發者需要執行多個命令才能完整啟動專案。這增加了入門門檻並可能導致配置不一致的問題。 + +Currently the project has multiple independent scripts for environment setup and service startup, requiring developers to run multiple commands to fully start the project. This increases the onboarding barrier and may lead to configuration inconsistencies. + +## What Changes + +- **Audit and update package lists**: Review and clean up `requirements.txt` and `frontend/package.json` +- **Consolidate environment files**: Merge `.env` configuration across root and frontend directories +- **Update setup script**: Improve `setup_dev_env.sh` with better error handling and dependency validation +- **Create unified startup script**: Combine `start_backend.sh` and `start_frontend.sh` into a single `start.sh` with options + +## Impact + +- Affected files: + - `requirements.txt` - Python dependencies audit + - `frontend/package.json` - Node.js dependencies audit + - `setup_dev_env.sh` - Updated environment setup + - `start_backend.sh` - Will be replaced by unified script + - `start_frontend.sh` - Will be replaced by unified script + - `start.sh` - New unified startup script + - `.env*` files - Environment configuration cleanup diff --git a/openspec/changes/archive/2025-12-02-unify-environment-scripts/specs/development-environment/spec.md b/openspec/changes/archive/2025-12-02-unify-environment-scripts/specs/development-environment/spec.md new file mode 100644 index 0000000..5eefcdc --- /dev/null +++ b/openspec/changes/archive/2025-12-02-unify-environment-scripts/specs/development-environment/spec.md @@ -0,0 +1,73 @@ +# Development Environment + +This capability defines the development environment setup and service management for Tool_OCR. + +## ADDED Requirements + +### Requirement: Unified Service Startup + +The system SHALL provide a single startup script that can launch all services or individual components. + +#### Scenario: Start all services + +- **WHEN** developer runs `./start.sh` +- **THEN** both backend and frontend services start +- **AND** service URLs are displayed + +#### Scenario: Start only backend + +- **WHEN** developer runs `./start.sh backend` +- **THEN** only the backend service starts on port 8000 + +#### Scenario: Start only frontend + +- **WHEN** developer runs `./start.sh frontend` +- **THEN** only the frontend service starts on port 5173 + +### Requirement: Service Process Management + +The system SHALL provide commands to check status and stop running services. + +#### Scenario: Check service status + +- **WHEN** developer runs `./start.sh --status` +- **THEN** the script displays which services are running with their PIDs + +#### Scenario: Stop all services + +- **WHEN** developer runs `./start.sh --stop` +- **THEN** all running services are gracefully terminated + +### Requirement: Environment Setup Validation + +The setup script SHALL validate that all required dependencies are correctly installed. + +#### Scenario: Validate Python environment + +- **WHEN** setup script runs +- **THEN** Python version is checked (3.10+) +- **AND** virtual environment is created or verified +- **AND** all pip packages are installed + +#### Scenario: Validate Node.js environment + +- **WHEN** setup script runs +- **THEN** Node.js LTS version is installed via nvm +- **AND** npm dependencies are installed + +#### Scenario: Validate GPU support (optional) + +- **WHEN** setup script runs on a system with NVIDIA GPU +- **THEN** CUDA version is detected +- **AND** appropriate PaddlePaddle GPU version is installed +- **AND** GPU availability is verified + +### Requirement: Environment Configuration + +The system SHALL use `.env.example` files to document all required environment variables. + +#### Scenario: New developer setup + +- **WHEN** developer clones the repository +- **THEN** `.env.example` files document all required variables +- **AND** developer copies to `.env.local` and fills in values diff --git a/openspec/changes/archive/2025-12-02-unify-environment-scripts/tasks.md b/openspec/changes/archive/2025-12-02-unify-environment-scripts/tasks.md new file mode 100644 index 0000000..688c9fa --- /dev/null +++ b/openspec/changes/archive/2025-12-02-unify-environment-scripts/tasks.md @@ -0,0 +1,31 @@ +# Tasks: Unify Environment Scripts + +## 1. Package Audit and Update +- [x] 1.1 Review Python dependencies in `requirements.txt` for unused/outdated packages +- [x] 1.2 Review Node.js dependencies in `frontend/package.json` +- [x] 1.3 Document system-level dependencies (apt packages, nvm, pandoc, etc.) +- [x] 1.4 Update `requirements.txt` with corrected versions and comments + +## 2. Environment Configuration Cleanup +- [x] 2.1 Audit `.env`, `.env.local`, `.env.example` files in root and frontend +- [x] 2.2 Consolidate duplicate environment variables +- [x] 2.3 Update `.env.example` with all required variables +- [x] 2.4 Remove sensitive data from version control (if any) + +## 3. Update Setup Script +- [x] 3.1 Add pre-flight checks (disk space, memory, existing installations) +- [x] 3.2 Improve error messages with solutions +- [x] 3.3 Add optional component installation (e.g., skip GPU detection if not needed) +- [x] 3.4 Add database initialization step to setup script +- [ ] 3.5 Test setup on clean Ubuntu 22.04/WSL2 environment + +## 4. Create Unified Startup Script +- [x] 4.1 Create `start.sh` with subcommands (all/backend/frontend) +- [x] 4.2 Add process management (start, stop, restart, status) +- [x] 4.3 Add log output options (combined/separate) +- [x] 4.4 Preserve individual scripts for backwards compatibility (optional) - Removed old scripts +- [x] 4.5 Test unified script in development environment + +## 5. Documentation +- [ ] 5.1 Update README with new startup instructions (skipped per user request) +- [ ] 5.2 Add troubleshooting section for common issues (skipped per user request) diff --git a/setup_dev_env.sh b/setup_dev_env.sh index 3651947..64e6e07 100755 --- a/setup_dev_env.sh +++ b/setup_dev_env.sh @@ -1,31 +1,258 @@ #!/bin/bash # Tool_OCR WSL Ubuntu 開發環境設置腳本 +# +# Usage: +# ./setup_dev_env.sh 完整安裝 (自動偵測 GPU) +# ./setup_dev_env.sh --cpu-only 強制使用 CPU 版本 +# ./setup_dev_env.sh --skip-db 跳過數據庫初始化 +# ./setup_dev_env.sh --help 顯示幫助 set -e # 遇到錯誤時停止 -echo "================================" -echo "Tool_OCR 開發環境設置" -echo "================================" -echo "" - # 顏色定義 GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' +BLUE='\033[0;34m' NC='\033[0m' # No Color -# 檢查是否為 root -if [ "$EUID" -eq 0 ]; then - echo -e "${RED}請不要使用 sudo 運行此腳本${NC}" - echo "腳本會在需要時提示輸入 sudo 密碼" - exit 1 -fi +# 配置變數 +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +MIN_DISK_GB=10 +MIN_MEMORY_GB=4 +MIN_PYTHON_VERSION="3.10" +FORCE_CPU=false +SKIP_DB=false -echo -e "${YELLOW}[1/8] 更新系統套件列表...${NC}" +# ===== 幫助信息 ===== +show_help() { + echo "Tool_OCR 開發環境設置腳本" + echo "" + echo "Usage: ./setup_dev_env.sh [options]" + echo "" + echo "Options:" + echo " --cpu-only 強制使用 CPU 版本的 PaddlePaddle (跳過 GPU 偵測)" + echo " --skip-db 跳過數據庫初始化步驟" + echo " --help 顯示此幫助信息" + echo "" + echo "Examples:" + echo " ./setup_dev_env.sh # 完整安裝" + echo " ./setup_dev_env.sh --cpu-only # 不使用 GPU" + echo "" +} + +# 解析參數 +while [[ $# -gt 0 ]]; do + case $1 in + --cpu-only) + FORCE_CPU=true + shift + ;; + --skip-db) + SKIP_DB=true + shift + ;; + --help|-h) + show_help + exit 0 + ;; + *) + echo -e "${RED}Unknown option: $1${NC}" + show_help + exit 1 + ;; + esac +done + +# ===== 工具函數 ===== +print_header() { + echo "" + echo -e "${BLUE}================================${NC}" + echo -e "${BLUE} Tool_OCR 開發環境設置${NC}" + echo -e "${BLUE}================================${NC}" + echo "" +} + +print_step() { + local step=$1 + local total=$2 + local msg=$3 + echo "" + echo -e "${YELLOW}[$step/$total] $msg${NC}" +} + +print_success() { + echo -e "${GREEN}✓ $1${NC}" +} + +print_warning() { + echo -e "${YELLOW}⚠ $1${NC}" +} + +print_error() { + echo -e "${RED}✗ $1${NC}" +} + +# ===== 預檢函數 ===== +check_not_root() { + if [ "$EUID" -eq 0 ]; then + print_error "請不要使用 sudo 運行此腳本" + echo "腳本會在需要時提示輸入 sudo 密碼" + exit 1 + fi +} + +check_disk_space() { + local available_gb=$(df -BG "$SCRIPT_DIR" | awk 'NR==2 {print $4}' | sed 's/G//') + if [ "$available_gb" -lt "$MIN_DISK_GB" ]; then + print_error "磁碟空間不足: ${available_gb}GB 可用, 需要至少 ${MIN_DISK_GB}GB" + echo "" + echo "解決方案:" + echo " 1. 清理不需要的文件: sudo apt autoremove && sudo apt clean" + echo " 2. 刪除舊的 Docker 映像: docker system prune -a" + echo " 3. 清理 pip 緩存: pip cache purge" + exit 1 + fi + print_success "磁碟空間: ${available_gb}GB 可用" +} + +check_memory() { + local total_gb=$(free -g | awk '/^Mem:/{print $2}') + if [ "$total_gb" -lt "$MIN_MEMORY_GB" ]; then + print_warning "記憶體較低: ${total_gb}GB (建議 ${MIN_MEMORY_GB}GB+)" + echo " OCR 處理可能會較慢,建議增加記憶體或使用 swap" + else + print_success "系統記憶體: ${total_gb}GB" + fi +} + +check_python_version() { + if ! command -v python3 &> /dev/null; then + print_error "未找到 Python3" + echo "" + echo "解決方案:" + echo " sudo apt update && sudo apt install python3 python3-pip python3-venv" + exit 1 + fi + + local py_version=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")') + local py_major=$(echo $py_version | cut -d. -f1) + local py_minor=$(echo $py_version | cut -d. -f2) + local min_major=$(echo $MIN_PYTHON_VERSION | cut -d. -f1) + local min_minor=$(echo $MIN_PYTHON_VERSION | cut -d. -f2) + + if [ "$py_major" -lt "$min_major" ] || ([ "$py_major" -eq "$min_major" ] && [ "$py_minor" -lt "$min_minor" ]); then + print_error "Python 版本過低: $py_version (需要 $MIN_PYTHON_VERSION+)" + echo "" + echo "解決方案:" + echo " sudo apt update && sudo apt install python3.10 python3.10-venv" + exit 1 + fi + print_success "Python 版本: $py_version" +} + +run_preflight_checks() { + echo -e "${BLUE}執行預檢...${NC}" + check_not_root + check_disk_space + check_memory + check_python_version + echo "" + print_success "預檢完成" +} + +# ===== GPU 偵測函數 ===== +detect_gpu() { + if [ "$FORCE_CPU" = true ]; then + echo -e "${YELLOW}ℹ 已指定 --cpu-only,跳過 GPU 偵測${NC}" + USE_GPU=false + PADDLE_PACKAGE="paddlepaddle>=3.2.1" + return + fi + + if command -v nvidia-smi &> /dev/null; then + print_success "偵測到 NVIDIA GPU" + nvidia-smi --query-gpu=name,memory.total --format=csv,noheader 2>/dev/null || true + + CUDA_VERSION=$(nvidia-smi 2>/dev/null | grep "CUDA Version" | awk '{print $9}') + if [ -n "$CUDA_VERSION" ]; then + print_success "CUDA 版本: $CUDA_VERSION" + + CUDA_MAJOR=$(echo $CUDA_VERSION | cut -d. -f1) + + if [ "$CUDA_MAJOR" -ge 12 ]; then + echo "將安裝 PaddlePaddle GPU 版本 (CUDA 12.x)" + USE_GPU=true + PADDLE_PACKAGE="paddlepaddle-gpu>=3.2.1" + PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cu123/" + elif [ "$CUDA_MAJOR" -eq 11 ]; then + echo "將安裝 PaddlePaddle GPU 版本 (CUDA 11.x)" + USE_GPU=true + PADDLE_PACKAGE="paddlepaddle-gpu>=3.2.1" + PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cu118/" + else + print_warning "CUDA 版本不支援 ($CUDA_VERSION),將使用 CPU 版本" + USE_GPU=false + PADDLE_PACKAGE="paddlepaddle>=3.2.1" + fi + else + print_warning "無法獲取 CUDA 版本,將使用 CPU 版本" + USE_GPU=false + PADDLE_PACKAGE="paddlepaddle>=3.2.1" + fi + else + echo -e "${YELLOW}ℹ 未偵測到 NVIDIA GPU,將使用 CPU 版本${NC}" + USE_GPU=false + PADDLE_PACKAGE="paddlepaddle>=3.2.1" + fi +} + +# ===== 數據庫初始化 ===== +init_database() { + if [ "$SKIP_DB" = true ]; then + print_warning "已指定 --skip-db,跳過數據庫初始化" + return + fi + + echo "初始化數據庫..." + cd "$SCRIPT_DIR/backend" + + # 檢查 .env.local 是否存在 + if [ ! -f "$SCRIPT_DIR/.env.local" ]; then + print_warning "未找到 .env.local,跳過數據庫初始化" + echo " 請複製 .env.example 到 .env.local 並配置後,手動執行:" + echo " cd backend && alembic upgrade head" + cd "$SCRIPT_DIR" + return + fi + + # 載入環境變量 + export $(grep -v '^#' "$SCRIPT_DIR/.env.local" | xargs) + + # 執行遷移 + if alembic upgrade head 2>/dev/null; then + print_success "數據庫遷移完成" + else + print_warning "數據庫遷移失敗 (可能數據庫未連接)" + echo " 請確認 .env.local 中的數據庫配置正確後,手動執行:" + echo " cd backend && alembic upgrade head" + fi + + cd "$SCRIPT_DIR" +} + +# ===== 主流程 ===== +print_header + +# 預檢 +run_preflight_checks + +# Step 1: 更新系統 +print_step 1 10 "更新系統套件列表..." sudo apt update -echo "" -echo -e "${YELLOW}[2/8] 安裝 Python 開發工具...${NC}" +# Step 2: Python 開發工具 +print_step 2 10 "安裝 Python 開發工具..." sudo apt install -y \ python3-pip \ python3-venv \ @@ -33,8 +260,8 @@ sudo apt install -y \ build-essential \ pkg-config -echo "" -echo -e "${YELLOW}[3/8] 安裝系統層級依賴...${NC}" +# Step 3: 系統依賴 +print_step 3 10 "安裝系統層級依賴..." sudo apt install -y \ pandoc \ libmagic1 \ @@ -71,270 +298,125 @@ sudo apt install -y \ libxslt1-dev \ python3-cffi -echo "" -echo -e "${YELLOW}[4/8] 安裝 Node.js 和 npm...${NC}" -# 檢查是否已安裝 nvm +# Step 4: Node.js +print_step 4 10 "安裝 Node.js..." if [ ! -d "$HOME/.nvm" ]; then echo "安裝 nvm..." curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash - - # 載入 nvm - export NVM_DIR="$HOME/.nvm" - [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" -else - echo "nvm 已安裝" - export NVM_DIR="$HOME/.nvm" - [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" fi -# 安裝 Node.js LTS -echo "安裝 Node.js LTS..." +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + nvm install --lts nvm use --lts +print_success "Node.js $(node -v) 已安裝" -echo "" -echo -e "${YELLOW}[5/8] 創建 Python 虛擬環境...${NC}" -if [ ! -d "venv" ]; then - python3 -m venv venv - echo "虛擬環境已創建" +# Step 5: Python 虛擬環境 +print_step 5 10 "創建 Python 虛擬環境..." +if [ ! -d "$SCRIPT_DIR/venv" ]; then + python3 -m venv "$SCRIPT_DIR/venv" + print_success "虛擬環境已創建" else - echo "虛擬環境已存在" + print_success "虛擬環境已存在" fi -echo "" -echo -e "${YELLOW}[6/9] 偵測 GPU 和 CUDA 支援...${NC}" - -# GPU 偵測函數 -detect_gpu() { - # 檢查是否有 NVIDIA GPU - if command -v nvidia-smi &> /dev/null; then - echo -e "${GREEN}✓ 偵測到 NVIDIA GPU${NC}" - nvidia-smi --query-gpu=name,memory.total --format=csv,noheader - - # 獲取 CUDA 版本 - CUDA_VERSION=$(nvidia-smi | grep "CUDA Version" | awk '{print $9}') - if [ -n "$CUDA_VERSION" ]; then - echo -e "${GREEN}✓ CUDA 版本: $CUDA_VERSION${NC}" - - # 根據 CUDA 版本選擇對應的 PaddlePaddle - CUDA_MAJOR=$(echo $CUDA_VERSION | cut -d. -f1) - CUDA_MINOR=$(echo $CUDA_VERSION | cut -d. -f2) - - if [ "$CUDA_MAJOR" -ge 13 ]; then - echo "將安裝 PaddlePaddle GPU 版本 (CUDA 13.x)" - echo "使用版本 3.2.1+ (兼容 CUDA 12.6+, 支援圖表識別)" - USE_GPU=true - PADDLE_PACKAGE="paddlepaddle-gpu>=3.2.1" - PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cu126/" - elif [ "$CUDA_MAJOR" -eq 12 ]; then - echo "將安裝 PaddlePaddle GPU 版本 (CUDA 12.x)" - echo "使用版本 3.2.1+ (兼容 CUDA 12.3+, 支援圖表識別)" - USE_GPU=true - PADDLE_PACKAGE="paddlepaddle-gpu>=3.2.1" - PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cu123/" - elif [ "$CUDA_MAJOR" -eq 11 ]; then - echo "將安裝 PaddlePaddle GPU 版本 (CUDA 11.x)" - echo "使用版本 3.2.1+ (兼容 CUDA 11.8+, 支援圖表識別)" - USE_GPU=true - PADDLE_PACKAGE="paddlepaddle-gpu>=3.2.1" - PADDLE_INDEX="https://www.paddlepaddle.org.cn/packages/stable/cu118/" - else - echo -e "${YELLOW}⚠ CUDA 版本不支援 ($CUDA_VERSION)${NC}" - echo "將安裝 CPU 版本" - USE_GPU=false - PADDLE_PACKAGE="paddlepaddle>=3.2.1" - fi - else - echo -e "${YELLOW}⚠ 無法獲取 CUDA 版本${NC}" - echo "將安裝 CPU 版本" - USE_GPU=false - PADDLE_PACKAGE="paddlepaddle>=3.2.1" - fi - else - echo -e "${YELLOW}ℹ 未偵測到 NVIDIA GPU 或 nvidia-smi${NC}" - echo "將安裝 CPU 版本的 PaddlePaddle" - USE_GPU=false - PADDLE_PACKAGE="paddlepaddle>=3.2.1" - fi -} - -# 執行 GPU 偵測 +# Step 6: GPU 偵測 +print_step 6 10 "偵測 GPU 支援..." detect_gpu -echo "" -echo -e "${YELLOW}[7/9] 安裝 Python 依賴...${NC}" -source venv/bin/activate +# Step 7: Python 依賴 +print_step 7 10 "安裝 Python 依賴..." +source "$SCRIPT_DIR/venv/bin/activate" pip install --upgrade pip setuptools wheel -# 先安裝 PaddlePaddle echo "" -echo -e "${YELLOW}安裝 PaddlePaddle...${NC}" +echo "安裝 PaddlePaddle..." if [ "$USE_GPU" = true ]; then - echo "安裝 GPU 加速版本: $PADDLE_PACKAGE" - if [ -n "$PADDLE_INDEX" ]; then - echo "使用官方索引: $PADDLE_INDEX" - pip install "$PADDLE_PACKAGE" -i "$PADDLE_INDEX" - else - pip install "$PADDLE_PACKAGE" + echo "安裝 GPU 版本: $PADDLE_PACKAGE" + pip install "$PADDLE_PACKAGE" -i "$PADDLE_INDEX" + + # WSL CUDA 路徑配置 + if grep -qi microsoft /proc/version && [ -d "/usr/lib/wsl/lib" ]; then + if ! grep -q "export LD_LIBRARY_PATH=/usr/lib/wsl/lib" ~/.bashrc; then + echo "" >> ~/.bashrc + echo "# WSL CUDA Libraries Path (Added by Tool_OCR setup)" >> ~/.bashrc + echo "export LD_LIBRARY_PATH=/usr/lib/wsl/lib:\$LD_LIBRARY_PATH" >> ~/.bashrc + fi + export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH + print_success "WSL CUDA 路徑已配置" fi else echo "安裝 CPU 版本..." pip install 'paddlepaddle>=3.2.1' fi -# WSL CUDA 路徑配置 (針對 WSL GPU 用戶) -if [ "$USE_GPU" = true ]; then - echo "" - echo -e "${YELLOW}配置 WSL CUDA 庫路徑...${NC}" - - # 檢查是否在 WSL 環境中 - if grep -qi microsoft /proc/version; then - echo "偵測到 WSL 環境,配置 CUDA 庫路徑..." - - # 檢查 CUDA 庫是否存在於 WSL 路徑 - if [ -d "/usr/lib/wsl/lib" ]; then - # 檢查 ~/.bashrc 中是否已包含此配置 - if ! grep -q "export LD_LIBRARY_PATH=/usr/lib/wsl/lib" ~/.bashrc; then - echo "" >> ~/.bashrc - echo "# WSL CUDA Libraries Path for PaddlePaddle GPU support (Added by Tool_OCR setup)" >> ~/.bashrc - echo "export LD_LIBRARY_PATH=/usr/lib/wsl/lib:\$LD_LIBRARY_PATH" >> ~/.bashrc - echo "✓ 已將 WSL CUDA 路徑添加到 ~/.bashrc" - else - echo "✓ WSL CUDA 路徑已存在於 ~/.bashrc" - fi - - # 立即應用到當前 session - export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH - echo "✓ 已應用 CUDA 路徑到當前環境" - else - echo -e "${YELLOW}⚠ 未找到 /usr/lib/wsl/lib 目錄${NC}" - echo "請確認 NVIDIA CUDA 驅動已安裝於 WSL" - fi - else - echo "非 WSL 環境,跳過 WSL CUDA 路徑配置" - fi -fi - -# 安裝其他依賴(跳過 requirements.txt 中的 paddlepaddle) echo "" -echo -e "${YELLOW}安裝其他 Python 依賴...${NC}" -pip install -r requirements.txt +echo "安裝其他 Python 依賴..." +pip install -r "$SCRIPT_DIR/requirements.txt" -echo "" -echo -e "${YELLOW}測試關鍵套件...${NC}" -python -c "import magic; print('✓ python-magic')" || echo "✗ python-magic failed" -python -c "from weasyprint import HTML; print('✓ WeasyPrint')" || echo "✗ WeasyPrint failed" -python -c "import cv2; print('✓ OpenCV')" || echo "✗ OpenCV failed" +# Step 8: 驗證安裝 +print_step 8 10 "驗證安裝..." +python -c "import magic; print('✓ python-magic')" || print_warning "python-magic 未正確安裝" +python -c "from weasyprint import HTML; print('✓ WeasyPrint')" || print_warning "WeasyPrint 未正確安裝" +python -c "import cv2; print('✓ OpenCV')" || print_warning "OpenCV 未正確安裝" +python -c "import paddle; print('✓ PaddlePaddle', paddle.__version__)" || print_warning "PaddlePaddle 未正確安裝" -# 驗證 PaddlePaddle GPU 可用性 -echo "" -echo -e "${YELLOW}驗證 PaddlePaddle 設置...${NC}" -python -c " -import paddle -print('✓ PaddlePaddle 版本:', paddle.__version__) -try: - if paddle.is_compiled_with_cuda(): - gpu_count = paddle.device.cuda.device_count() - if gpu_count > 0: - print('✓ GPU 加速: 已啟用') - print('✓ GPU 數量:', gpu_count) - for i in range(gpu_count): - gpu_name = paddle.device.cuda.get_device_properties(i).name - print(f' GPU {i}: {gpu_name}') - else: - print('ℹ GPU 加速: CUDA 已編譯但無可用 GPU') - else: - print('ℹ GPU 加速: 未啟用 (CPU 模式)') -except Exception as e: - print('⚠ GPU 檢測失敗:', str(e)) - print('ℹ 將使用 CPU 模式') -" || echo "⚠ PaddlePaddle 驗證失敗,但可繼續使用" +# Step 9: 前端依賴 +print_step 9 10 "安裝前端依賴..." +cd "$SCRIPT_DIR/frontend" -# 驗證圖表識別 API 可用性 -echo "" -echo -e "${YELLOW}驗證圖表識別 API...${NC}" -python -c " -import paddle.incubate.nn.functional as F - -# 檢查 API 可用性 -has_base = hasattr(F, 'fused_rms_norm') -has_ext = hasattr(F, 'fused_rms_norm_ext') - -print('📊 圖表識別 API 檢查:') -print(f' - fused_rms_norm: {'✅ 可用' if has_base else '❌ 不可用'}') -print(f' - fused_rms_norm_ext: {'✅ 可用' if has_ext else '❌ 不可用'}') - -if has_ext: - print('🎉 圖表識別功能: ✅ 可啟用') -else: - print('⚠️ 圖表識別功能: ❌ 不可用 (需要 PaddlePaddle 3.2.0+)') -" || echo "⚠ 圖表識別 API 驗證失敗" - -echo "" -echo -e "${YELLOW}[8/9] 安裝前端依賴...${NC}" -cd frontend - -# 清理可能存在的鎖定文件 if [ -d "node_modules" ]; then echo "清理現有 node_modules..." rm -rf node_modules package-lock.json fi -# 清理 npm 緩存 npm cache clean --force - -# 安裝依賴(使用 --force 避免鎖定問題) -echo "安裝前端依賴..." npm install --force -cd .. +cd "$SCRIPT_DIR" +print_success "前端依賴已安裝" -echo "" -echo -e "${YELLOW}[9/9] 創建必要的目錄...${NC}" +# Step 10: 創建目錄和初始化數據庫 +print_step 10 10 "創建目錄和初始化數據庫..." mkdir -p backend/uploads/{temp,processed,images} -mkdir -p backend/storage/{markdown,json,exports} +mkdir -p backend/storage/{markdown,json,exports,results} mkdir -p backend/models/paddleocr mkdir -p backend/logs +init_database + +# ===== 完成 ===== echo "" echo -e "${GREEN}================================${NC}" -echo -e "${GREEN}環境設置完成!${NC}" +echo -e "${GREEN} 環境設置完成!${NC}" echo -e "${GREEN}================================${NC}" echo "" echo "系統配置:" if [ "$USE_GPU" = true ]; then echo -e " GPU 加速: ${GREEN}已啟用${NC}" - echo " PaddlePaddle: GPU 版本 (3.2.1+)" - echo -e " 圖表識別: ${GREEN}已啟用${NC}" - if grep -qi microsoft /proc/version; then - echo " WSL CUDA 路徑: 已配置於 ~/.bashrc" - fi + echo " PaddlePaddle: GPU 版本" else echo -e " GPU 加速: ${YELLOW}未啟用 (CPU 模式)${NC}" - echo " PaddlePaddle: CPU 版本 (3.2.1+)" - echo -e " 圖表識別: ${GREEN}已啟用${NC} (CPU 模式)" + echo " PaddlePaddle: CPU 版本" fi echo "" echo "下一步操作:" -echo "1. 初始化數據庫:" -echo " source venv/bin/activate" -echo " cd backend" -echo " alembic upgrade head" -echo " python create_test_user.py" -echo " cd .." echo "" -echo "2. 啟動後端:" -echo " ./start_backend.sh" +echo "1. 配置環境變量 (如尚未配置):" +echo " cp .env.example .env.local" +echo " # 編輯 .env.local 填入實際配置" echo "" -echo "3. 啟動前端 (新終端):" -echo " ./start_frontend.sh" +echo "2. 啟動應用:" +echo " ./start.sh # 同時啟動前後端" +echo " ./start.sh backend # 僅啟動後端" +echo " ./start.sh frontend # 僅啟動前端" echo "" -echo "4. 訪問應用:" +echo "3. 訪問應用:" echo " 前端: http://localhost:5173" echo " API文檔: http://localhost:8000/docs" -echo " 健康檢查: http://localhost:8000/health" echo "" if [ "$USE_GPU" = true ] && grep -qi microsoft /proc/version; then - echo "注意: WSL GPU 用戶需要重新啟動終端或執行 'source ~/.bashrc' 以應用 CUDA 路徑配置" + echo -e "${YELLOW}注意: WSL GPU 用戶需要重新啟動終端以應用 CUDA 路徑配置${NC}" echo "" fi diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..9d818dc --- /dev/null +++ b/start.sh @@ -0,0 +1,297 @@ +#!/bin/bash +# Tool_OCR - Unified Development Server Startup Script +# Usage: +# ./start.sh Start all services (backend + frontend) +# ./start.sh backend Start only backend +# ./start.sh frontend Start only frontend +# ./start.sh --stop Stop all services +# ./start.sh --status Show service status +# ./start.sh --help Show help + +set -e + +# Colors +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +BLUE='\033[0;34m' +NC='\033[0m' + +# Configuration +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PID_DIR="$SCRIPT_DIR/.pid" +BACKEND_PID_FILE="$PID_DIR/backend.pid" +FRONTEND_PID_FILE="$PID_DIR/frontend.pid" +BACKEND_PORT=${BACKEND_PORT:-8000} +FRONTEND_PORT=${FRONTEND_PORT:-5173} + +# Create PID directory +mkdir -p "$PID_DIR" + +# Functions +print_header() { + echo "" + echo -e "${BLUE}================================${NC}" + echo -e "${BLUE} Tool_OCR Development Server${NC}" + echo -e "${BLUE}================================${NC}" + echo "" +} + +show_help() { + echo "Tool_OCR - Development Server Manager" + echo "" + echo "Usage: ./start.sh [command]" + echo "" + echo "Commands:" + echo " (none) Start all services (backend + frontend)" + echo " backend Start only backend service" + echo " frontend Start only frontend service" + echo " --stop Stop all running services" + echo " --status Show status of services" + echo " --help Show this help message" + echo "" + echo "Examples:" + echo " ./start.sh # Start everything" + echo " ./start.sh backend # Start only backend" + echo " ./start.sh --stop # Stop all services" + echo "" +} + +check_requirements() { + local missing=0 + + # Check virtual environment + if [ ! -d "$SCRIPT_DIR/venv" ]; then + echo -e "${RED}Error: Python virtual environment not found${NC}" + echo "Please run: ./setup_dev_env.sh" + missing=1 + fi + + # Check node_modules + if [ ! -d "$SCRIPT_DIR/frontend/node_modules" ]; then + echo -e "${RED}Error: Frontend dependencies not found${NC}" + echo "Please run: ./setup_dev_env.sh" + missing=1 + fi + + # Check .env.local + if [ ! -f "$SCRIPT_DIR/.env.local" ]; then + echo -e "${RED}Error: .env.local not found${NC}" + echo "Please copy .env.example to .env.local and configure" + missing=1 + fi + + return $missing +} + +is_running() { + local pid_file=$1 + if [ -f "$pid_file" ]; then + local pid=$(cat "$pid_file") + if ps -p "$pid" > /dev/null 2>&1; then + return 0 + else + # PID file exists but process is not running, clean up + rm -f "$pid_file" + fi + fi + return 1 +} + +get_pid() { + local pid_file=$1 + if [ -f "$pid_file" ]; then + cat "$pid_file" + fi +} + +start_backend() { + if is_running "$BACKEND_PID_FILE"; then + echo -e "${YELLOW}Backend already running (PID: $(get_pid $BACKEND_PID_FILE))${NC}" + return 0 + fi + + echo -e "${GREEN}Starting backend server...${NC}" + + # Activate virtual environment + source "$SCRIPT_DIR/venv/bin/activate" + + # Load environment variables + if [ -f "$SCRIPT_DIR/.env.local" ]; then + export $(grep -v '^#' "$SCRIPT_DIR/.env.local" | xargs) + fi + + # Start backend in background + cd "$SCRIPT_DIR/backend" + + # Create necessary directories + mkdir -p uploads/{temp,processed,images} + mkdir -p storage/{markdown,json,exports,results} + mkdir -p models/paddleocr + mkdir -p logs + + # Start uvicorn + nohup uvicorn app.main:app --reload --host 0.0.0.0 --port $BACKEND_PORT > "$SCRIPT_DIR/.pid/backend.log" 2>&1 & + local pid=$! + echo $pid > "$BACKEND_PID_FILE" + + cd "$SCRIPT_DIR" + + # Wait a moment and verify + sleep 2 + if is_running "$BACKEND_PID_FILE"; then + echo -e "${GREEN}Backend started (PID: $pid)${NC}" + echo -e " API Docs: http://localhost:$BACKEND_PORT/docs" + echo -e " Health: http://localhost:$BACKEND_PORT/health" + else + echo -e "${RED}Backend failed to start. Check .pid/backend.log${NC}" + return 1 + fi +} + +start_frontend() { + if is_running "$FRONTEND_PID_FILE"; then + echo -e "${YELLOW}Frontend already running (PID: $(get_pid $FRONTEND_PID_FILE))${NC}" + return 0 + fi + + echo -e "${GREEN}Starting frontend server...${NC}" + + # Load nvm + export NVM_DIR="$HOME/.nvm" + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + + cd "$SCRIPT_DIR/frontend" + + # Start vite in background + nohup npm run dev > "$SCRIPT_DIR/.pid/frontend.log" 2>&1 & + local pid=$! + echo $pid > "$FRONTEND_PID_FILE" + + cd "$SCRIPT_DIR" + + # Wait a moment and verify + sleep 3 + if is_running "$FRONTEND_PID_FILE"; then + echo -e "${GREEN}Frontend started (PID: $pid)${NC}" + echo -e " URL: http://localhost:$FRONTEND_PORT" + else + echo -e "${RED}Frontend failed to start. Check .pid/frontend.log${NC}" + return 1 + fi +} + +stop_service() { + local name=$1 + local pid_file=$2 + + if is_running "$pid_file"; then + local pid=$(get_pid "$pid_file") + echo -e "${YELLOW}Stopping $name (PID: $pid)...${NC}" + + # Try graceful shutdown first + kill -TERM "$pid" 2>/dev/null || true + + # Wait up to 5 seconds + local count=0 + while [ $count -lt 5 ] && is_running "$pid_file"; do + sleep 1 + count=$((count + 1)) + done + + # Force kill if still running + if is_running "$pid_file"; then + kill -9 "$pid" 2>/dev/null || true + fi + + rm -f "$pid_file" + echo -e "${GREEN}$name stopped${NC}" + else + echo -e "${YELLOW}$name is not running${NC}" + fi +} + +stop_all() { + echo -e "${YELLOW}Stopping all services...${NC}" + stop_service "Backend" "$BACKEND_PID_FILE" + stop_service "Frontend" "$FRONTEND_PID_FILE" + echo -e "${GREEN}All services stopped${NC}" +} + +show_status() { + echo -e "${BLUE}Service Status:${NC}" + echo "" + + if is_running "$BACKEND_PID_FILE"; then + local pid=$(get_pid "$BACKEND_PID_FILE") + echo -e " Backend: ${GREEN}Running${NC} (PID: $pid)" + echo -e " http://localhost:$BACKEND_PORT" + else + echo -e " Backend: ${RED}Stopped${NC}" + fi + + if is_running "$FRONTEND_PID_FILE"; then + local pid=$(get_pid "$FRONTEND_PID_FILE") + echo -e " Frontend: ${GREEN}Running${NC} (PID: $pid)" + echo -e " http://localhost:$FRONTEND_PORT" + else + echo -e " Frontend: ${RED}Stopped${NC}" + fi + + echo "" +} + +# Main +case "${1:-all}" in + --help|-h) + show_help + ;; + --stop) + stop_all + ;; + --status) + show_status + ;; + backend) + print_header + check_requirements || exit 1 + start_backend + echo "" + echo -e "${YELLOW}Press Ctrl+C to stop (or use ./start.sh --stop)${NC}" + echo -e "${YELLOW}Logs: tail -f .pid/backend.log${NC}" + ;; + frontend) + print_header + check_requirements || exit 1 + start_frontend + echo "" + echo -e "${YELLOW}Press Ctrl+C to stop (or use ./start.sh --stop)${NC}" + echo -e "${YELLOW}Logs: tail -f .pid/frontend.log${NC}" + ;; + all|"") + print_header + check_requirements || exit 1 + start_backend + start_frontend + echo "" + echo -e "${GREEN}================================${NC}" + echo -e "${GREEN}All services started!${NC}" + echo -e "${GREEN}================================${NC}" + echo "" + echo "Access the application:" + echo -e " Frontend: ${BLUE}http://localhost:$FRONTEND_PORT${NC}" + echo -e " API Docs: ${BLUE}http://localhost:$BACKEND_PORT/docs${NC}" + echo "" + echo -e "${YELLOW}Use ./start.sh --stop to stop all services${NC}" + echo -e "${YELLOW}Use ./start.sh --status to check status${NC}" + echo "" + echo "Logs:" + echo " Backend: tail -f .pid/backend.log" + echo " Frontend: tail -f .pid/frontend.log" + ;; + *) + echo -e "${RED}Unknown command: $1${NC}" + show_help + exit 1 + ;; +esac diff --git a/start_backend.sh b/start_backend.sh deleted file mode 100755 index f4dde24..0000000 --- a/start_backend.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash -# Tool_OCR - 後端開發服務器啟動腳本 - -set -e - -# 顏色定義 -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -RED='\033[0;31m' -NC='\033[0m' # No Color - -echo -e "${YELLOW}正在啟動 Tool_OCR 後端開發服務器...${NC}" -echo "" - -# 檢查虛擬環境 -if [ ! -d "venv" ]; then - echo -e "${RED}錯誤: 未找到虛擬環境${NC}" - echo "請先運行: ./setup_dev_env.sh" - exit 1 -fi - -# 檢查 .env.local -if [ ! -f ".env.local" ]; then - echo -e "${RED}錯誤: 未找到 .env.local 配置文件${NC}" - echo "請確保 .env.local 文件存在" - exit 1 -fi - -# 啟動虛擬環境 -echo -e "${GREEN}啟動 Python 虛擬環境...${NC}" -source venv/bin/activate - -# 載入環境變量 -echo -e "${GREEN}載入環境變量...${NC}" -export $(cat .env.local | grep -v '^#' | xargs) - -# 進入後端目錄 -cd backend - -# 檢查必要的目錄 -echo -e "${GREEN}檢查目錄結構...${NC}" -mkdir -p uploads/{temp,processed,images} -mkdir -p storage/{markdown,json,exports} -mkdir -p models/paddleocr -mkdir -p logs - -# 啟動後端服務器 -echo "" -echo -e "${GREEN}================================${NC}" -echo -e "${GREEN}後端服務器啟動中...${NC}" -echo -e "${GREEN}================================${NC}" -echo "" -echo "API 文檔: http://localhost:8000/docs" -echo "健康檢查: http://localhost:8000/health" -echo "" -echo "按 Ctrl+C 停止服務器" -echo "" - -uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 diff --git a/start_frontend.sh b/start_frontend.sh deleted file mode 100755 index 2a18672..0000000 --- a/start_frontend.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -# Tool_OCR - 前端開發服務器啟動腳本 - -set -e - -# 顏色定義 -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -RED='\033[0;31m' -NC='\033[0m' # No Color - -echo -e "${YELLOW}正在啟動 Tool_OCR 前端開發服務器...${NC}" -echo "" - -# 檢查 node_modules -if [ ! -d "frontend/node_modules" ]; then - echo -e "${RED}錯誤: 未找到 node_modules${NC}" - echo "請先運行: ./setup_dev_env.sh" - exit 1 -fi - -# 載入 nvm -export NVM_DIR="$HOME/.nvm" -[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" - -# 進入前端目錄 -cd frontend - -# 啟動前端服務器 -echo "" -echo -e "${GREEN}================================${NC}" -echo -e "${GREEN}前端服務器啟動中...${NC}" -echo -e "${GREEN}================================${NC}" -echo "" -echo "前端界面: http://localhost:5173" -echo "" -echo "按 Ctrl+C 停止服務器" -echo "" - -npm run dev