Showing
7 changed files
with
242 additions
and
0 deletions
app/Http/Controllers/Controller.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace App\Http\Controllers; | ||
| 4 | + | ||
| 5 | +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; | ||
| 6 | +use Illuminate\Foundation\Bus\DispatchesJobs; | ||
| 7 | +use Illuminate\Foundation\Validation\ValidatesRequests; | ||
| 8 | +use Illuminate\Routing\Controller as BaseController; | ||
| 9 | + | ||
| 10 | +class Controller extends BaseController | ||
| 11 | +{ | ||
| 12 | + use AuthorizesRequests, DispatchesJobs, ValidatesRequests; | ||
| 13 | +} |
app/Http/Controllers/OcrController.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace App\Http\Controllers; | ||
| 4 | + | ||
| 5 | +use App\Models\DtTemplate; | ||
| 6 | +use App\Models\MstTemplate; | ||
| 7 | +use Illuminate\Http\Request; | ||
| 8 | + | ||
| 9 | +class OcrController extends Controller | ||
| 10 | +{ | ||
| 11 | + public function index() | ||
| 12 | + { | ||
| 13 | + return view('ocr.index'); | ||
| 14 | + } | ||
| 15 | + | ||
| 16 | + | ||
| 17 | + public function store(Request $request) | ||
| 18 | + { | ||
| 19 | + | ||
| 20 | + $request->validate([ | ||
| 21 | + 'customer_name_text' => 'required|string', | ||
| 22 | + 'customer_name_xy' => 'required|string', | ||
| 23 | + 'tpl_name' => 'unique:mst_template', | ||
| 24 | + ]); | ||
| 25 | + | ||
| 26 | + // Lưu vào bảng mst_template | ||
| 27 | + $mst = MstTemplate::create([ | ||
| 28 | + 'tpl_name' => $request->template_name, | ||
| 29 | + 'tpl_text' => $request->customer_name_text, | ||
| 30 | + 'tpl_xy' => $request->customer_name_xy, | ||
| 31 | + ]); | ||
| 32 | + | ||
| 33 | + // Lưu các field khác vào dt_template | ||
| 34 | + foreach ($request->fields as $field) { | ||
| 35 | + DtTemplate::create([ | ||
| 36 | + 'tpl_id' => $mst->id, | ||
| 37 | + 'field_name' => $field['name'], | ||
| 38 | + 'field_xy' => $field['xy'], | ||
| 39 | + ]); | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + return response()->json(['success' => true, 'message' => 'Lưu template thành công']); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + | ||
| 46 | + public function getData() | ||
| 47 | + { | ||
| 48 | + // Giả sử file OCR JSON & ảnh nằm trong storage/app/public/image/ | ||
| 49 | + $jsonPath = public_path("image/data_picking_detail_1754967679.json"); | ||
| 50 | + $imgPath = ("image/data_picking_detail_1754967679.jpg"); | ||
| 51 | + | ||
| 52 | + | ||
| 53 | + $templateName = 'nemo_4'; | ||
| 54 | + /// Lấy từ request hoặc mặc định | ||
| 55 | + | ||
| 56 | + | ||
| 57 | + if (!file_exists($jsonPath)) { | ||
| 58 | + return response()->json(['error' => 'File not found'], 404); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + $ocrData = json_decode(file_get_contents($jsonPath), true); | ||
| 62 | + $formData = []; | ||
| 63 | + | ||
| 64 | + if ($templateName) { | ||
| 65 | + $mst = MstTemplate::where('tpl_name', $templateName)->first(); | ||
| 66 | + | ||
| 67 | + if ($mst) { | ||
| 68 | + // Lấy detail của template | ||
| 69 | + $details = DtTemplate::where('tpl_id', $mst->id)->get(); | ||
| 70 | + | ||
| 71 | + foreach ($details as $detail) { | ||
| 72 | + $coords = array_map('intval', explode(',', $detail->field_xy)); | ||
| 73 | + // coords = [x1, y1, x2, y2] | ||
| 74 | + | ||
| 75 | + // Tìm text OCR nằm trong bbox này | ||
| 76 | + $text = $this->findTextInBBox($ocrData, $coords); | ||
| 77 | + | ||
| 78 | + // field_name => text | ||
| 79 | + $formData[$detail->field_name] = $text; | ||
| 80 | + } | ||
| 81 | + } else{ | ||
| 82 | + $formData = [ | ||
| 83 | + 'export_date' => "", | ||
| 84 | + 'order_code' => "", | ||
| 85 | + 'customer' => "", | ||
| 86 | + 'address' => "", | ||
| 87 | + 'staff' => "", | ||
| 88 | + 'customer_name' => "" | ||
| 89 | + ]; | ||
| 90 | + } | ||
| 91 | + } | ||
| 92 | + return response()->json([ | ||
| 93 | + 'ocrData' => $ocrData, | ||
| 94 | + 'pdfImageUrl' => $imgPath, | ||
| 95 | + 'formData' => $formData, | ||
| 96 | + 'fieldOptions' => [ | ||
| 97 | + [ 'value' => 'template_name', 'label' => 'Tên Mẫu PDF' ], | ||
| 98 | + [ 'value' => 'customer_name', 'label' => 'Tên khách hàng' ], | ||
| 99 | + [ 'value' => 'export_date', 'label' => 'Ngày xuất' ], | ||
| 100 | + [ 'value' => 'order_code', 'label' => 'Mã đơn hàng' ], | ||
| 101 | + [ 'value' => 'customer', 'label' => 'Khách hàng' ], | ||
| 102 | + [ 'value' => 'address', 'label' => 'Địa chỉ' ], | ||
| 103 | + [ 'value' => 'staff', 'label' => 'Nhân viên' ], | ||
| 104 | + ] | ||
| 105 | + ]); | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + private function findTextInBBox($ocrData, $coords) | ||
| 109 | + { | ||
| 110 | + [$x1, $y1, $x2, $y2] = $coords; | ||
| 111 | + foreach ($ocrData as $item) { | ||
| 112 | + [$ix1, $iy1, $ix2, $iy2] = $item['bbox']; | ||
| 113 | + // Kiểm tra nếu bbox OCR nằm trong vùng bbox template | ||
| 114 | + if ($ix1 >= $x1 && $iy1 >= $y1 && $ix2 <= $x2 && $iy2 <= $y2) { | ||
| 115 | + return $item['text']; | ||
| 116 | + } | ||
| 117 | + } | ||
| 118 | + return ''; | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + | ||
| 122 | +} |
app/Models/DtTemplate.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace App\Models; | ||
| 4 | + | ||
| 5 | +use Illuminate\Database\Eloquent\Factories\HasFactory; | ||
| 6 | +use Illuminate\Database\Eloquent\Model; | ||
| 7 | + | ||
| 8 | +class DtTemplate extends Model | ||
| 9 | +{ | ||
| 10 | + public $timestamps = false; | ||
| 11 | + | ||
| 12 | + protected $table = 'dt_template'; | ||
| 13 | + protected $guarded = []; | ||
| 14 | + | ||
| 15 | + | ||
| 16 | +} |
app/Models/MstTemplate.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +namespace App\Models; | ||
| 4 | + | ||
| 5 | +use Illuminate\Database\Eloquent\Factories\HasFactory; | ||
| 6 | +use Illuminate\Database\Eloquent\Model; | ||
| 7 | + | ||
| 8 | +class MstTemplate extends Model | ||
| 9 | +{ | ||
| 10 | + public $timestamps = false; | ||
| 11 | + | ||
| 12 | + protected $table = 'mst_template'; | ||
| 13 | + | ||
| 14 | + protected $guarded = []; | ||
| 15 | +} |
public/index.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use Illuminate\Contracts\Http\Kernel; | ||
| 4 | +use Illuminate\Http\Request; | ||
| 5 | + | ||
| 6 | +define('LARAVEL_START', microtime(true)); | ||
| 7 | + | ||
| 8 | +/* | ||
| 9 | +|-------------------------------------------------------------------------- | ||
| 10 | +| Check If The Application Is Under Maintenance | ||
| 11 | +|-------------------------------------------------------------------------- | ||
| 12 | +| | ||
| 13 | +| If the application is in maintenance / demo mode via the "down" command | ||
| 14 | +| we will load this file so that any pre-rendered content can be shown | ||
| 15 | +| instead of starting the framework, which could cause an exception. | ||
| 16 | +| | ||
| 17 | +*/ | ||
| 18 | + | ||
| 19 | +if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) { | ||
| 20 | + require $maintenance; | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +/* | ||
| 24 | +|-------------------------------------------------------------------------- | ||
| 25 | +| Register The Auto Loader | ||
| 26 | +|-------------------------------------------------------------------------- | ||
| 27 | +| | ||
| 28 | +| Composer provides a convenient, automatically generated class loader for | ||
| 29 | +| this application. We just need to utilize it! We'll simply require it | ||
| 30 | +| into the script here so we don't need to manually load our classes. | ||
| 31 | +| | ||
| 32 | +*/ | ||
| 33 | + | ||
| 34 | +require __DIR__.'/../vendor/autoload.php'; | ||
| 35 | + | ||
| 36 | +/* | ||
| 37 | +|-------------------------------------------------------------------------- | ||
| 38 | +| Run The Application | ||
| 39 | +|-------------------------------------------------------------------------- | ||
| 40 | +| | ||
| 41 | +| Once we have the application, we can handle the incoming request using | ||
| 42 | +| the application's HTTP kernel. Then, we will send the response back | ||
| 43 | +| to this client's browser, allowing them to enjoy our application. | ||
| 44 | +| | ||
| 45 | +*/ | ||
| 46 | + | ||
| 47 | +$app = require_once __DIR__.'/../bootstrap/app.php'; | ||
| 48 | + | ||
| 49 | +$kernel = $app->make(Kernel::class); | ||
| 50 | + | ||
| 51 | +$response = $kernel->handle( | ||
| 52 | + $request = Request::capture() | ||
| 53 | +)->send(); | ||
| 54 | + | ||
| 55 | +$kernel->terminate($request, $response); |
resources/views/ocr/index.blade.php
0 → 100644
This diff is collapsed.
Click to expand it.
routes/web.php
0 → 100644
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use Illuminate\Support\Facades\Route; | ||
| 4 | +use App\Http\Controllers\OcrController; | ||
| 5 | +/* | ||
| 6 | +|-------------------------------------------------------------------------- | ||
| 7 | +| Web Routes | ||
| 8 | +|-------------------------------------------------------------------------- | ||
| 9 | +| | ||
| 10 | +| Here is where you can register web routes for your application. These | ||
| 11 | +| routes are loaded by the RouteServiceProvider within a group which | ||
| 12 | +| contains the "web" middleware group. Now create something great! | ||
| 13 | +| | ||
| 14 | +*/ | ||
| 15 | + | ||
| 16 | +Route::get('/', function () { | ||
| 17 | + return view('welcome'); | ||
| 18 | +}); | ||
| 19 | +Route::get('/mapping', [OcrController::class, 'index']); | ||
| 20 | +Route::get('/ocr/data-list', [OcrController::class, 'getData']); | ||
| 21 | +Route::post('/ocr/save-template', [OcrController::class, 'store'])->name('store'); |
-
Please register or sign in to post a comment