Showing
1 changed file
with
114 additions
and
14 deletions
| ... | @@ -20,9 +20,13 @@ class OcrController extends Controller | ... | @@ -20,9 +20,13 @@ class OcrController extends Controller |
| 20 | $request->validate([ | 20 | $request->validate([ |
| 21 | 'customer_name_text' => 'required|string', | 21 | 'customer_name_text' => 'required|string', |
| 22 | 'customer_name_xy' => 'required|string', | 22 | 'customer_name_xy' => 'required|string', |
| 23 | - 'template_name' => 'unique:mst_template,tpl_name', | 23 | + 'template_name' => 'required|string|unique:mst_template,tpl_name', |
| 24 | + 'fields' => 'required|array', | ||
| 25 | + 'fields.*.name' => 'required|string', | ||
| 26 | + 'fields.*.xy' => 'required|string', | ||
| 24 | ]); | 27 | ]); |
| 25 | 28 | ||
| 29 | + try { | ||
| 26 | // Lưu vào bảng mst_template | 30 | // Lưu vào bảng mst_template |
| 27 | $mst = MstTemplate::create([ | 31 | $mst = MstTemplate::create([ |
| 28 | 'tpl_name' => $request->template_name, | 32 | 'tpl_name' => $request->template_name, |
| ... | @@ -39,26 +43,39 @@ class OcrController extends Controller | ... | @@ -39,26 +43,39 @@ class OcrController extends Controller |
| 39 | ]); | 43 | ]); |
| 40 | } | 44 | } |
| 41 | 45 | ||
| 42 | - return response()->json(['success' => true, 'message' => 'Lưu template thành công']); | 46 | + return response()->json([ |
| 47 | + 'success' => true, | ||
| 48 | + 'message' => 'Lưu template thành công', | ||
| 49 | + 'template_id' => $mst->id | ||
| 50 | + ]); | ||
| 51 | + } catch (\Exception $e) { | ||
| 52 | + return response()->json([ | ||
| 53 | + 'success' => false, | ||
| 54 | + 'message' => 'Lỗi khi lưu template: ' . $e->getMessage() | ||
| 55 | + ], 500); | ||
| 56 | + } | ||
| 43 | } | 57 | } |
| 44 | 58 | ||
| 45 | 59 | ||
| 46 | - public function getData() | 60 | + public function getData(Request $request) |
| 47 | { | 61 | { |
| 62 | + try { | ||
| 63 | + // Lấy template name từ request hoặc mặc định | ||
| 64 | + $templateName = $request->get('template_name', 'nemo'); | ||
| 65 | + | ||
| 48 | // Giả sử file OCR JSON & ảnh nằm trong storage/app/public/image/ | 66 | // Giả sử file OCR JSON & ảnh nằm trong storage/app/public/image/ |
| 49 | $jsonPath = public_path("image/data_picking_detail_1754967679.json"); | 67 | $jsonPath = public_path("image/data_picking_detail_1754967679.json"); |
| 50 | $imgPath = ("image/data_picking_detail_1754967679.jpg"); | 68 | $imgPath = ("image/data_picking_detail_1754967679.jpg"); |
| 51 | 69 | ||
| 52 | - | ||
| 53 | - $templateName = 'nemo'; | ||
| 54 | - /// Lấy từ request hoặc mặc định | ||
| 55 | - | ||
| 56 | - | ||
| 57 | if (!file_exists($jsonPath)) { | 70 | if (!file_exists($jsonPath)) { |
| 58 | - return response()->json(['error' => 'File not found'], 404); | 71 | + return response()->json(['error' => 'File OCR JSON không tìm thấy'], 404); |
| 59 | } | 72 | } |
| 60 | 73 | ||
| 61 | $ocrData = json_decode(file_get_contents($jsonPath), true); | 74 | $ocrData = json_decode(file_get_contents($jsonPath), true); |
| 75 | + if (json_last_error() !== JSON_ERROR_NONE) { | ||
| 76 | + return response()->json(['error' => 'File OCR JSON không hợp lệ'], 400); | ||
| 77 | + } | ||
| 78 | + | ||
| 62 | $formData = []; | 79 | $formData = []; |
| 63 | 80 | ||
| 64 | if ($templateName) { | 81 | if ($templateName) { |
| ... | @@ -72,13 +89,13 @@ class OcrController extends Controller | ... | @@ -72,13 +89,13 @@ class OcrController extends Controller |
| 72 | $coords = array_map('intval', explode(',', $detail->field_xy)); | 89 | $coords = array_map('intval', explode(',', $detail->field_xy)); |
| 73 | // coords = [x1, y1, x2, y2] | 90 | // coords = [x1, y1, x2, y2] |
| 74 | 91 | ||
| 75 | - // Tìm text OCR nằm trong bbox này | 92 | + // Tìm text OCR nằm trong bbox này (cải thiện để gộp text) |
| 76 | $text = $this->findTextInBBox($ocrData, $coords); | 93 | $text = $this->findTextInBBox($ocrData, $coords); |
| 77 | 94 | ||
| 78 | // field_name => text | 95 | // field_name => text |
| 79 | $formData[$detail->field_name] = $text; | 96 | $formData[$detail->field_name] = $text; |
| 80 | } | 97 | } |
| 81 | - } else{ | 98 | + } else { |
| 82 | $formData = [ | 99 | $formData = [ |
| 83 | 'export_date' => "", | 100 | 'export_date' => "", |
| 84 | 'order_code' => "", | 101 | 'order_code' => "", |
| ... | @@ -89,7 +106,9 @@ class OcrController extends Controller | ... | @@ -89,7 +106,9 @@ class OcrController extends Controller |
| 89 | ]; | 106 | ]; |
| 90 | } | 107 | } |
| 91 | } | 108 | } |
| 109 | + | ||
| 92 | return response()->json([ | 110 | return response()->json([ |
| 111 | + 'success' => true, | ||
| 93 | 'ocrData' => $ocrData, | 112 | 'ocrData' => $ocrData, |
| 94 | 'pdfImageUrl' => $imgPath, | 113 | 'pdfImageUrl' => $imgPath, |
| 95 | 'formData' => $formData, | 114 | 'formData' => $formData, |
| ... | @@ -101,22 +120,103 @@ class OcrController extends Controller | ... | @@ -101,22 +120,103 @@ class OcrController extends Controller |
| 101 | [ 'value' => 'customer', 'label' => 'Khách hàng' ], | 120 | [ 'value' => 'customer', 'label' => 'Khách hàng' ], |
| 102 | [ 'value' => 'address', 'label' => 'Địa chỉ' ], | 121 | [ 'value' => 'address', 'label' => 'Địa chỉ' ], |
| 103 | [ 'value' => 'staff', 'label' => 'Nhân viên' ], | 122 | [ 'value' => 'staff', 'label' => 'Nhân viên' ], |
| 104 | - ] | 123 | + ], |
| 124 | + 'template_name' => $templateName | ||
| 105 | ]); | 125 | ]); |
| 126 | + } catch (\Exception $e) { | ||
| 127 | + return response()->json([ | ||
| 128 | + 'success' => false, | ||
| 129 | + 'error' => 'Lỗi khi load data: ' . $e->getMessage() | ||
| 130 | + ], 500); | ||
| 131 | + } | ||
| 106 | } | 132 | } |
| 107 | 133 | ||
| 108 | private function findTextInBBox($ocrData, $coords) | 134 | private function findTextInBBox($ocrData, $coords) |
| 109 | { | 135 | { |
| 110 | [$x1, $y1, $x2, $y2] = $coords; | 136 | [$x1, $y1, $x2, $y2] = $coords; |
| 137 | + $foundItems = []; | ||
| 138 | + | ||
| 111 | foreach ($ocrData as $item) { | 139 | foreach ($ocrData as $item) { |
| 112 | [$ix1, $iy1, $ix2, $iy2] = $item['bbox']; | 140 | [$ix1, $iy1, $ix2, $iy2] = $item['bbox']; |
| 113 | - // Kiểm tra nếu bbox OCR nằm trong vùng bbox template | 141 | + |
| 142 | + // Kiểm tra xem box OCR có nằm trong vùng bbox template không | ||
| 114 | if ($ix1 >= $x1 && $iy1 >= $y1 && $ix2 <= $x2 && $iy2 <= $y2) { | 143 | if ($ix1 >= $x1 && $iy1 >= $y1 && $ix2 <= $x2 && $iy2 <= $y2) { |
| 115 | - return $item['text']; | 144 | + $foundItems[] = [ |
| 145 | + 'text' => $item['text'], | ||
| 146 | + 'bbox' => $item['bbox'], | ||
| 147 | + 'x' => $ix1, | ||
| 148 | + 'y' => $iy1 | ||
| 149 | + ]; | ||
| 116 | } | 150 | } |
| 117 | } | 151 | } |
| 152 | + | ||
| 153 | + if (empty($foundItems)) { | ||
| 118 | return ''; | 154 | return ''; |
| 119 | } | 155 | } |
| 120 | 156 | ||
| 157 | + // Sắp xếp các item theo vị trí (từ trái sang phải, từ trên xuống dưới) | ||
| 158 | + usort($foundItems, function($a, $b) { | ||
| 159 | + // Ưu tiên theo Y trước (hàng), sau đó theo X (cột) | ||
| 160 | + if (abs($a['y'] - $b['y']) < 20) { // Cùng hàng (toler$foundItems = {array[2]} ance 20px) | ||
| 161 | + return $a['x'] - $b['x']; // Sắp xếp theo X | ||
| 162 | + } | ||
| 163 | + return $a['y'] - $b['y']; // Sắp xếp theo Y | ||
| 164 | + }); | ||
| 165 | + | ||
| 166 | + // Gộp text theo thứ tự đã sắp xếp | ||
| 167 | + $combinedText = []; | ||
| 168 | + foreach ($foundItems as $item) { | ||
| 169 | + $combinedText[] = trim($item['text']); | ||
| 170 | + } | ||
| 121 | 171 | ||
| 172 | + return implode(' ', $combinedText); | ||
| 173 | + } | ||
| 174 | + | ||
| 175 | + /** | ||
| 176 | + * Lấy danh sách template | ||
| 177 | + */ | ||
| 178 | + public function getTemplateList() | ||
| 179 | + { | ||
| 180 | + try { | ||
| 181 | + $templates = MstTemplate::select('id', 'tpl_name', 'tpl_text', 'in_date') | ||
| 182 | + ->orderBy('created_at', 'desc') | ||
| 183 | + ->get(); | ||
| 184 | + | ||
| 185 | + return response()->json([ | ||
| 186 | + 'success' => true, | ||
| 187 | + 'templates' => $templates | ||
| 188 | + ]); | ||
| 189 | + } catch (\Exception $e) { | ||
| 190 | + return response()->json([ | ||
| 191 | + 'success' => false, | ||
| 192 | + 'error' => 'Lỗi khi lấy danh sách template: ' . $e->getMessage() | ||
| 193 | + ], 500); | ||
| 194 | + } | ||
| 195 | + } | ||
| 196 | + | ||
| 197 | + /** | ||
| 198 | + * Xóa template | ||
| 199 | + */ | ||
| 200 | + public function deleteTemplate($id) | ||
| 201 | + { | ||
| 202 | + try { | ||
| 203 | + $template = MstTemplate::findOrFail($id); | ||
| 204 | + | ||
| 205 | + // Xóa các field detail trước | ||
| 206 | + DtTemplate::where('tpl_id', $id)->delete(); | ||
| 207 | + | ||
| 208 | + // Xóa template chính | ||
| 209 | + $template->delete(); | ||
| 210 | + | ||
| 211 | + return response()->json([ | ||
| 212 | + 'success' => true, | ||
| 213 | + 'message' => 'Xóa template thành công' | ||
| 214 | + ]); | ||
| 215 | + } catch (\Exception $e) { | ||
| 216 | + return response()->json([ | ||
| 217 | + 'success' => false, | ||
| 218 | + 'error' => 'Lỗi khi xóa template: ' . $e->getMessage() | ||
| 219 | + ], 500); | ||
| 220 | + } | ||
| 221 | + } | ||
| 122 | } | 222 | } | ... | ... |
-
Please register or sign in to post a comment