tien_nemo

demo

<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
<?php
namespace App\Http\Controllers;
use App\Models\DtTemplate;
use App\Models\MstTemplate;
use Illuminate\Http\Request;
class OcrController extends Controller
{
public function index()
{
return view('ocr.index');
}
public function store(Request $request)
{
$request->validate([
'customer_name_text' => 'required|string',
'customer_name_xy' => 'required|string',
'tpl_name' => 'unique:mst_template',
]);
// Lưu vào bảng mst_template
$mst = MstTemplate::create([
'tpl_name' => $request->template_name,
'tpl_text' => $request->customer_name_text,
'tpl_xy' => $request->customer_name_xy,
]);
// Lưu các field khác vào dt_template
foreach ($request->fields as $field) {
DtTemplate::create([
'tpl_id' => $mst->id,
'field_name' => $field['name'],
'field_xy' => $field['xy'],
]);
}
return response()->json(['success' => true, 'message' => 'Lưu template thành công']);
}
public function getData()
{
// Giả sử file OCR JSON & ảnh nằm trong storage/app/public/image/
$jsonPath = public_path("image/data_picking_detail_1754967679.json");
$imgPath = ("image/data_picking_detail_1754967679.jpg");
$templateName = 'nemo_4';
/// Lấy từ request hoặc mặc định
if (!file_exists($jsonPath)) {
return response()->json(['error' => 'File not found'], 404);
}
$ocrData = json_decode(file_get_contents($jsonPath), true);
$formData = [];
if ($templateName) {
$mst = MstTemplate::where('tpl_name', $templateName)->first();
if ($mst) {
// Lấy detail của template
$details = DtTemplate::where('tpl_id', $mst->id)->get();
foreach ($details as $detail) {
$coords = array_map('intval', explode(',', $detail->field_xy));
// coords = [x1, y1, x2, y2]
// Tìm text OCR nằm trong bbox này
$text = $this->findTextInBBox($ocrData, $coords);
// field_name => text
$formData[$detail->field_name] = $text;
}
} else{
$formData = [
'export_date' => "",
'order_code' => "",
'customer' => "",
'address' => "",
'staff' => "",
'customer_name' => ""
];
}
}
return response()->json([
'ocrData' => $ocrData,
'pdfImageUrl' => $imgPath,
'formData' => $formData,
'fieldOptions' => [
[ 'value' => 'template_name', 'label' => 'Tên Mẫu PDF' ],
[ 'value' => 'customer_name', 'label' => 'Tên khách hàng' ],
[ 'value' => 'export_date', 'label' => 'Ngày xuất' ],
[ 'value' => 'order_code', 'label' => 'Mã đơn hàng' ],
[ 'value' => 'customer', 'label' => 'Khách hàng' ],
[ 'value' => 'address', 'label' => 'Địa chỉ' ],
[ 'value' => 'staff', 'label' => 'Nhân viên' ],
]
]);
}
private function findTextInBBox($ocrData, $coords)
{
[$x1, $y1, $x2, $y2] = $coords;
foreach ($ocrData as $item) {
[$ix1, $iy1, $ix2, $iy2] = $item['bbox'];
// Kiểm tra nếu bbox OCR nằm trong vùng bbox template
if ($ix1 >= $x1 && $iy1 >= $y1 && $ix2 <= $x2 && $iy2 <= $y2) {
return $item['text'];
}
}
return '';
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class DtTemplate extends Model
{
public $timestamps = false;
protected $table = 'dt_template';
protected $guarded = [];
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class MstTemplate extends Model
{
public $timestamps = false;
protected $table = 'mst_template';
protected $guarded = [];
}
<?php
use Illuminate\Contracts\Http\Kernel;
use Illuminate\Http\Request;
define('LARAVEL_START', microtime(true));
/*
|--------------------------------------------------------------------------
| Check If The Application Is Under Maintenance
|--------------------------------------------------------------------------
|
| If the application is in maintenance / demo mode via the "down" command
| we will load this file so that any pre-rendered content can be shown
| instead of starting the framework, which could cause an exception.
|
*/
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
require $maintenance;
}
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| this application. We just need to utilize it! We'll simply require it
| into the script here so we don't need to manually load our classes.
|
*/
require __DIR__.'/../vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request using
| the application's HTTP kernel. Then, we will send the response back
| to this client's browser, allowing them to enjoy our application.
|
*/
$app = require_once __DIR__.'/../bootstrap/app.php';
$kernel = $app->make(Kernel::class);
$response = $kernel->handle(
$request = Request::capture()
)->send();
$kernel->terminate($request, $response);
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\OcrController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::get('/mapping', [OcrController::class, 'index']);
Route::get('/ocr/data-list', [OcrController::class, 'getData']);
Route::post('/ocr/save-template', [OcrController::class, 'store'])->name('store');