diff --git a/app/Http/Controllers/Admin/LicensePlateRecognitionController.php b/app/Http/Controllers/Admin/LicensePlateRecognitionController.php new file mode 100644 index 0000000..5e4e4a4 --- /dev/null +++ b/app/Http/Controllers/Admin/LicensePlateRecognitionController.php @@ -0,0 +1,124 @@ +has('start_time') && $request->has('end_time')) { + $start_time = $request->input('start_time'); + $end_time = $request->input('end_time'); + if (strtotime($start_time) && strtotime($end_time)) { + $query->whereBetween('time_slot', [$start_time, $end_time]); + } + } + + // 分页 + $page = $request->input('page', 1); + $perPage = $request->input('per_page', 10); + + $columns = ['time_slot']; + + $total = 0; + $all = $query->groupBy('time_slot')->select($columns)->get(); + if ($all) { + $total = count($all); + } + $items = $query->groupBy(['time_slot'])->latest('time_slot') + ->forPage($page, $perPage)->get()->each(function ($item) { + $countData = $this->getCount($item['time_slot']); + $item['sum_count'] = $countData['sum_count']; + $item['high_ratio'] = $countData['high_ratio']; + $item['middle_ratio'] = $countData['middle_ratio']; + $item['manual_count'] = $countData['manual_count']; + $item['manual_ratio'] = $countData['manual_ratio']; + return $item; + }); + return $this->responseService->success([ + 'items' => $items, + 'total' => $total, + 'page' => $page, + 'per_page' => $perPage, + 'last_page' => ceil($total / $perPage), + ]); + } catch (Exception $e) { + $m_prefix = __('exception.exception_handler.resource'); + return $this->responseService->systemError( + $m_prefix . ':' . $e->getMessage() + ); + } + } + + protected function getCount($time_slot) + { + $manualWhere = $highWhere = $middleWhere = $where = [ + 'time_slot' => $time_slot + ]; + $where['manual_modification'] = 0; + $sumCount = LicensePlateRecognition::query()->where($where) + ->count(); + $highWhere['recognition'] = 5; + $highCount = LicensePlateRecognition::query()->where( + $highWhere + )->count(); + $middleWhere['recognition'] = 1; + $middleCount = LicensePlateRecognition::query()->where( + $middleWhere + )->count(); + $manualWhere['manual_modification'] = 1; + $manualCount = LicensePlateRecognition::query()->where( + $manualWhere + )->count(); + return [ + 'sum_count' => $sumCount, + 'high_count' => $highCount, + 'middle_count' => $middleCount, + 'manual_count' => $manualCount, + 'high_ratio' => get_ratio($sumCount, $highCount), + 'middle_ratio' => get_ratio($sumCount, $middleCount), + 'manual_ratio' => get_ratio($sumCount, $manualCount) + ]; + } + + public function curveGraph(Request $request): JsonResponse + { + try { + $query = LicensePlateRecognition::query(); + if ($request->has('start_time') && $request->has('end_time')) { + $start_time = $request->input('start_time'); + $end_time = $request->input('end_time'); + if (strtotime($start_time) && strtotime($end_time)) { + $query->whereBetween('time_slot', [$start_time, $end_time]); + } + } + // 分页 + $page = 1; + $perPage = 16; + $items = $query->groupBy(['time_slot'])->latest('time_slot') + ->forPage($page, $perPage)->select('time_slot')->get() + ->each(function ($item) { + $countData = $this->getCount($item['time_slot']); + $item['high_ratio'] = $countData['high_ratio']; + $item['middle_ratio'] = $countData['middle_ratio']; + $item['manual_ratio'] = $countData['manual_ratio']; + return $item; + }); + return $this->responseService->success($items); + } catch (Exception $e) { + $m_prefix = __('exception.exception_handler.resource'); + return $this->responseService->systemError( + $m_prefix . ':' . $e->getMessage() + ); + } + } +} diff --git a/app/Models/LicensePlateRecognition.php b/app/Models/LicensePlateRecognition.php new file mode 100644 index 0000000..39be81c --- /dev/null +++ b/app/Models/LicensePlateRecognition.php @@ -0,0 +1,23 @@ +logService->menuTitle = 'recognition_rate'; + } + + + /** + * @param $data + * @throws Exception + */ + public function createData($data) + { + $model = LicensePlateRecognition::query()->create([ + 'time_slot' => get_datetime('date'), + 'manual_modification' => $data['manual_modification'], + 'license_plate' => $data['license_plate'], + 'recognition' => $data['recognition'], + 'capture_images' => $data['capture_images'], + 'created_at' => get_datetime() + ]); + return $model; + } + +} diff --git a/database/migrations/2026_04_23_143449_create_license_plate_recognition_table.php b/database/migrations/2026_04_23_143449_create_license_plate_recognition_table.php new file mode 100644 index 0000000..e65df92 --- /dev/null +++ b/database/migrations/2026_04_23_143449_create_license_plate_recognition_table.php @@ -0,0 +1,34 @@ +id(); + $table->date('time_slot')->comment('时间段'); + $table->tinyInteger('manual_modification')->default(0)->comment('手动修改 0无 1有'); + $table->string('license_plate', 50)->default('')->comment('车牌号码'); + $table->tinyInteger('recognition')->default(0)->comment('识别度 0无法识别 1低 5高'); + $table->string('capture_images', 255)->default('')->comment('抓取图片'); + $table->innoDb(); + $table->timestamps(); + $table->comment('车牌识别'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('license_plate_recognition'); + } +}; diff --git a/routes/admin/api.php b/routes/admin/api.php index aa7bb67..91cdde4 100644 --- a/routes/admin/api.php +++ b/routes/admin/api.php @@ -25,6 +25,7 @@ use App\Http\Controllers\Admin\ParkingPatternController; use App\Http\Controllers\Admin\ParkingPatternSpaceController; use App\Http\Controllers\Admin\EventCalendarController; use App\Http\Controllers\Admin\NoticeController; +use App\Http\Controllers\Admin\LicensePlateRecognitionController; Route::group(['prefix' => 'admin'], function () { @@ -145,6 +146,9 @@ Route::group(['prefix' => 'admin'], function () { Route::get('/notice/search', [NoticeController::class, 'search']); Route::post('/notice/setting', [NoticeController::class, 'setting']); Route::get('/notice/show/{id}', [NoticeController::class, 'show']); + // 车牌识别率 + Route::get('/licensePlateRecognition', [LicensePlateRecognitionController::class, 'index']); + Route::get('/licensePlateRecognition/curveGraph', [LicensePlateRecognitionController::class, 'curveGraph']); // 系统日志 Route::get('/operationLog/index', [OperationLogController::class, 'index']);