feat: Docker化部署 - 單容器架構轉換

將 Tool_OCR 從 macOS conda 環境轉換為 Docker 單容器部署方案。
前後端整合於同一容器,通過 Nginx 反向代理,僅對外暴露單一端口。

## 新增功能
- Docker 單容器架構(Frontend + Backend + Nginx)
- 多階段構建優化鏡像大小
- Supervisor 進程管理
- 健康檢查機制
- 完整部署文檔

## 技術細節
- 對外端口:12015(原 12010 已被佔用)
- 內部架構:Nginx(12015) → FastAPI(8000)
- 前端靜態文件由 Nginx 直接服務
- API 請求通過 Nginx 反向代理

## 系統依賴完善
- libmagic1:文件類型檢測
- LibreOffice:Office 文檔轉換
- paddlex[ocr]:PP-StructureV3 版面分析
- 中日韓字體支援

## 配置調整
- 環境變數路徑:macOS 路徑 → 容器絕對路徑
- 前端 API URL:修正為統一端口 12015
- Pip 安裝:延長超時至 600 秒,重試 5 次
- CRLF 轉換:自動處理 Windows 換行符

## 清理
- 移除臨時文檔(API_FIX_SUMMARY.md 等 7 個文檔)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
beabigegg
2025-11-13 13:12:59 +08:00
parent 57cf91271c
commit 0f81d5e70b
26 changed files with 1166 additions and 2985 deletions

View File

@@ -264,7 +264,7 @@ export default function ExportPage() {
{t('export.options.confidenceThreshold')}
</label>
<span className="text-sm font-bold text-primary">
{(options.confidence_threshold * 100).toFixed(0)}%
{((options.confidence_threshold ?? 0.5) * 100).toFixed(0)}%
</span>
</div>
<input
@@ -348,7 +348,7 @@ export default function ExportPage() {
className="w-full px-4 py-3 border border-border rounded-lg bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary transition-colors"
>
{cssTemplates.map((template) => (
<option key={template.filename} value={template.filename}>
<option key={template.name} value={template.name}>
{template.name} - {template.description}
</option>
))}
@@ -391,7 +391,7 @@ export default function ExportPage() {
<div>
<div className="text-xs text-muted-foreground mb-1"></div>
<div className="text-sm font-medium text-foreground">
{(options.confidence_threshold * 100).toFixed(0)}%
{((options.confidence_threshold ?? 0.5) * 100).toFixed(0)}%
</div>
</div>

View File

@@ -9,7 +9,7 @@ import { Badge } from '@/components/ui/badge'
import { useToast } from '@/components/ui/toast'
import { useUploadStore } from '@/store/uploadStore'
import { apiClient } from '@/services/api'
import { Play, CheckCircle, FileText, AlertCircle, Clock, Activity, Loader2, TrendingUp } from 'lucide-react'
import { Play, CheckCircle, FileText, AlertCircle, Clock, Activity, Loader2 } from 'lucide-react'
export default function ProcessingPage() {
const { t } = useTranslation()

View File

@@ -19,7 +19,7 @@ export default function ResultsPage() {
const [selectedFileId, setSelectedFileId] = useState<number | null>(null)
// Get batch status to show results
const { data: batchStatus, isLoading } = useQuery({
const { data: batchStatus } = useQuery({
queryKey: ['batchStatus', batchId],
queryFn: () => apiClient.getBatchStatus(batchId!),
enabled: !!batchId,
@@ -28,7 +28,7 @@ export default function ResultsPage() {
// Get OCR result for selected file
const { data: ocrResult, isLoading: isLoadingResult } = useQuery({
queryKey: ['ocrResult', selectedFileId],
queryFn: () => apiClient.getOCRResult(selectedFileId!.toString()),
queryFn: () => apiClient.getOCRResult(selectedFileId!),
enabled: !!selectedFileId,
})