From 00ae9d306716b7be0dc7367145795fa17cc34e8e Mon Sep 17 00:00:00 2001 From: admin Date: Mon, 1 Jun 2026 09:57:50 +0700 Subject: [PATCH] 690601:0957 ADR-032-232 #03 --- .../src/modules/ai/services/ocr.service.ts | 25 ++++++++++++++++--- .../ai/services/sandbox-ocr-engine.service.ts | 25 ++++++++++++++++--- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/backend/src/modules/ai/services/ocr.service.ts b/backend/src/modules/ai/services/ocr.service.ts index c6d38a78..b4228aa2 100644 --- a/backend/src/modules/ai/services/ocr.service.ts +++ b/backend/src/modules/ai/services/ocr.service.ts @@ -197,12 +197,29 @@ export class OcrService { } } - /** แปลง local upload path เป็น path ที่ sidecar เห็นผ่าน CIFS mount */ + /** แปลง local upload path เป็น path ที่ sidecar เห็นผ่าน CIFS/Windows bind mount */ private remapPath(localPath: string): string { - if (this.localUploadBase && localPath.startsWith(this.localUploadBase)) { - return localPath.replace(this.localUploadBase, this.sidecarUploadBase); + if (!localPath) return localPath; + + // แปลง Windows backslash ให้เป็น forward slash + const normalizedPath = localPath.replace(/\\/g, '/'); + const normalizedLocalBase = this.localUploadBase.replace(/\\/g, '/'); + + // ตรวจสอบความเข้ากันได้ของ base path + if (normalizedLocalBase && normalizedPath.includes(normalizedLocalBase)) { + const relativePart = normalizedPath.substring( + normalizedPath.indexOf(normalizedLocalBase) + normalizedLocalBase.length + ); + return `${this.sidecarUploadBase.replace(/\/$/, '')}${relativePart}`; } - return localPath; + + // กรณีพิเศษ: ถ้าเป็น Windows Path และมีคำว่า /uploads/ ให้แมปเข้ากับ sidecar base + const uploadsIndex = normalizedPath.indexOf('/uploads/'); + if (uploadsIndex !== -1) { + return `${this.sidecarUploadBase.replace(/\/$/, '')}${normalizedPath.substring(uploadsIndex + 8)}`; + } + + return normalizedPath; } /** ตรวจสอบสุขภาพและ latency ของ OCR sidecar (Tesseract) ผ่าน GET /health */ diff --git a/backend/src/modules/ai/services/sandbox-ocr-engine.service.ts b/backend/src/modules/ai/services/sandbox-ocr-engine.service.ts index 26a0e5b9..4a9b9832 100644 --- a/backend/src/modules/ai/services/sandbox-ocr-engine.service.ts +++ b/backend/src/modules/ai/services/sandbox-ocr-engine.service.ts @@ -47,12 +47,29 @@ export class SandboxOcrEngineService { ); } - /** แปลง local upload path เป็น path ที่ sidecar เห็นผ่าน CIFS mount */ + /** แปลง local upload path เป็น path ที่ sidecar เห็นผ่าน CIFS/Windows bind mount */ private remapPath(localPath: string): string { - if (this.localUploadBase && localPath.startsWith(this.localUploadBase)) { - return localPath.replace(this.localUploadBase, this.sidecarUploadBase); + if (!localPath) return localPath; + + // แปลง Windows backslash ให้เป็น forward slash + const normalizedPath = localPath.replace(/\\/g, '/'); + const normalizedLocalBase = this.localUploadBase.replace(/\\/g, '/'); + + // ตรวจสอบความเข้ากันได้ของ base path + if (normalizedLocalBase && normalizedPath.includes(normalizedLocalBase)) { + const relativePart = normalizedPath.substring( + normalizedPath.indexOf(normalizedLocalBase) + normalizedLocalBase.length + ); + return `${this.sidecarUploadBase.replace(/\/$/, '')}${relativePart}`; } - return localPath; + + // กรณีพิเศษ: ถ้าเป็น Windows Path และมีคำว่า /uploads/ ให้แมปเข้ากับ sidecar base + const uploadsIndex = normalizedPath.indexOf('/uploads/'); + if (uploadsIndex !== -1) { + return `${this.sidecarUploadBase.replace(/\/$/, '')}${normalizedPath.substring(uploadsIndex + 8)}`; + } + + return normalizedPath; } /** รัน OCR ตาม engine ที่เลือก โดย fallback กลับไป Tesseract baseline เมื่อ Typhoon ล้มเหลว */