Browse Source

车牌修正记录

master
wanghongjun 5 days ago
parent
commit
7bfe45470f
  1. 62
      app/Exports/ParkingManualCorrectionExport.php
  2. 81
      app/Http/Controllers/Admin/ParkingManualCorrectionController.php
  3. 35
      app/Models/ParkingManualCorrection.php
  4. 3
      app/Services/ParkingLicensePlateService.php
  5. 121
      app/Services/ParkingManualCorrectionService.php
  6. 11
      app/Services/ParkingSpaceService.php
  7. 33
      database/migrations/2026_09_09_143449_create_parking_manual_correction_table.php
  8. 9
      resources/lang/en/exports.php
  9. 3
      resources/lang/en/log.php
  10. 9
      resources/lang/zh-CN/exports.php
  11. 3
      resources/lang/zh-CN/log.php
  12. 9
      resources/lang/zh-TW/exports.php
  13. 3
      resources/lang/zh-TW/log.php
  14. 6
      routes/admin/api.php

62
app/Exports/ParkingManualCorrectionExport.php

@ -0,0 +1,62 @@
<?php
namespace App\Exports;
use App\Services\OperationLogService;
use App\Services\ParkingManualCorrectionService;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\WithHeadings;
class ParkingManualCorrectionExport implements FromArray, WithHeadings
{
public array $parents = [];
public ParkingManualCorrectionService $service;
public function __construct($parents)
{
$this->parents = $parents;
$this->service = new ParkingManualCorrectionService(
new OperationLogService()
);
}
public function array(): array
{
$data = [];
$index = 1;
$query = $this->service->indexQuery($this->parents);
$query->select()->get()->each(
function ($item) use (&$data, &$index) {
$oldItem = $this->service->getItem($item);
$data[] = [
'id' => $index,
'enter_time' => $oldItem['enter_time'],
'space_number' => $oldItem['space_number'],
'old_license_place' => $oldItem['old_license_place'],
'updated_at' => $oldItem['update_time'],
'username' => $oldItem['username'],
'new_license_place' => $oldItem['new_license_place']
];
$index += 1;
}
);
return $data;
}
/**
* @return array
*/
public function headings(): array
{
return [
__('exports.global.index'),
__('exports.parking_space.enter_time'),
__('exports.parking_space.space_number'),
__('exports.parking_space.old_license_place'),
__('exports.parking_space.updated_at'),
__('exports.parking_space.username'),
__('exports.parking_space.new_license_place')
];
}
}

81
app/Http/Controllers/Admin/ParkingManualCorrectionController.php

@ -0,0 +1,81 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Exports\ParkingManualCorrectionExport;
use App\Services\ApiResponseService;
use App\Services\ParkingManualCorrectionService;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
class ParkingManualCorrectionController extends BaseController
{
protected string $menuUri = 'manualCorrection';
protected ParkingManualCorrectionService $service;
/**
* 构造函数
* @param ApiResponseService $responseService
* @param ParkingManualCorrectionService $service
*/
public function __construct(
ApiResponseService $responseService,
ParkingManualCorrectionService $service
) {
parent::__construct($responseService);
$this->service = $service;
}
/**
* Display a listing of the resource.
*/
public function index(Request $request): JsonResponse
{
try {
$query = $this->service->indexQuery($request->all());
// 分页
$page = $request->input('page', 1);
$perPage = $request->input('per_page', 10);
$total = $query->count();
$_this = $this;
$items = $query->latest()->forPage($page, $perPage)->get()->each(
function ($item) use ($_this) {
return $_this->service->getItem($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()
);
}
}
/**
* @param Request $request
* @return BinaryFileResponse
*/
public function export(Request $request): BinaryFileResponse
{
return Excel::download(
new ParkingManualCorrectionExport($request->all()),
set_space_underline(__('exports.manual_correction.list'))
. get_datetime('date_')
. '.xlsx'
);
}
}

35
app/Models/ParkingManualCorrection.php

@ -0,0 +1,35 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ParkingManualCorrection extends Model
{
use HasFactory;
protected $table = 'parking_manual_correction';
protected $fillable = [
'enter_time',
'space_id',
'old_license_id',
'admin_user_id',
'new_license_id'
];
protected $hidden = [
'updated_at'
];
public function getEnterTimeAttribute($value): string
{
return $value ? date("Y-m-d H:i:s", strtotime($value)) : $value;
}
public function getCreatedAtAttribute($value): string
{
return $value ? date("Y-m-d H:i:s", strtotime($value)) : $value;
}
}

3
app/Services/ParkingLicensePlateService.php

@ -223,8 +223,7 @@ class ParkingLicensePlateService
// 2. 根据车牌类型选择正则 // 2. 根据车牌类型选择正则
if ($this->isMainlandChinaPlate($plate)) { if ($this->isMainlandChinaPlate($plate)) {
// 中国大陆车牌校验(禁止 I、O) // 中国大陆车牌校验(禁止 I、O)
$pattern $pattern = '/^[\x{4e00}-\x{9fa5}][A-Z](?:[A-HJ-NP-Z0-9]{6}|(?:[A-HJ-NP-Z0-9][0-9]{4}|[A-HJ-NP-Z0-9]{5}))$/u';
= '/^[\x{4e00}-\x{9fa5}][A-Z](?:[A-HJ-NP-Z0-9]{6}|(?:[A-HJ-NP-Z0-9][0-9]{4}|[0-9]{5}))$/u';
if (!preg_match($pattern, $plate)) { if (!preg_match($pattern, $plate)) {
return __validation('parking_space.zh_plate'); return __validation('parking_space.zh_plate');
} }

121
app/Services/ParkingManualCorrectionService.php

@ -0,0 +1,121 @@
<?php
namespace App\Services;
use App\Models\AdminUsers;
use App\Models\ParkingLicensePlate;
use App\Models\ParkingManualCorrection;
use App\Models\ParkingSpace;
class ParkingManualCorrectionService extends BaseService
{
protected string $menuTitle = 'manual_correction';
public function createData($data, $user_id)
{
$data = [
'enter_time' => $data['enter_time'],
'space_id' => $data['space_id'],
'old_license_id' => $data['old_license_id'],
'admin_user_id' => $user_id,
'new_license_id' => $data['new_license_id'],
'created_at' => date("Y-m-d H:i:s", time())
];
$model = ParkingManualCorrection::query()->create($data);
$this->logService->logCreated($model, $this->menuTitle . '.create');
$data = $model->toArray();
return $data['id'] ?? 0;
}
public function indexQuery($param)
{
$query = ParkingManualCorrection::query();
if (isset($param['space_number']) && !empty($param['space_number'])) {
$space_ids = ParkingSpace::getId($param['space_number']);
if ($space_ids) {
$query->whereIn('space_id', $space_ids);
} else {
$query->where('id', 0);
}
}
if (isset($param['old_license_place'])
&& !empty($param['old_license_place'])
) {
$old_id_arr = ParkingLicensePlate::getId(
$param['old_license_place']
);
$old_id_arr ? $query->whereIn(
'old_license_id',
$old_id_arr
) : $query->where('id', 0);
}
if (isset($param['start_date'])
&& !empty($param['start_date'])
&& strtotime($param['start_date'])
) {
$start_date = date(
"Y-m-d 00:00:00",
strtotime($param['start_date'])
);
if ($start_date) {
$query->where('created_at', '>=', $start_date);
}
}
if (isset($param['end_date'])
&& !empty($param['end_date'])
&& strtotime($param['end_date'])
) {
$end_date = date(
"Y-m-d 00:00:00",
strtotime($param['end_date'])
);
if ($end_date) {
$query->where('created_at', '<', $end_date);
}
}
if (isset($param['username']) && !empty($param['username'])) {
$ids = AdminUsers::getIds($param['username']);
if ($ids) {
$query->whereIn('admin_user_id', $ids);
} else {
$query->where('id', 0);
}
}
if (isset($param['new_license_place'])
&& !empty($param['new_license_place'])
) {
$new_id_arr = ParkingLicensePlate::getId(
$param['new_license_place']
);
$new_id_arr ? $query->whereIn(
'new_license_id',
$new_id_arr
) : $query->where('id', 0);
}
$query->orderBy('id', 'desc');
return $query;
}
public function getItem($item)
{
$item['space_number'] = ParkingSpace::getNumber($item['space_id']);
$item['old_license_place'] = ParkingLicensePlate::getNumber(
$item['old_license_id']
);
$item['new_license_place'] = ParkingLicensePlate::getNumber(
$item['new_license_id']
);
$item['username'] = AdminUsers::getUsername($item['admin_user_id']);
$item['update_time'] = $item['created_at'];
unset($item['space_id'], $item['old_license_id'], $item['new_license_id'], $item['admin_user_id'], $item['created_at']);
return $item;
}
}

11
app/Services/ParkingSpaceService.php

@ -362,6 +362,17 @@ class ParkingSpaceService extends BaseService
$oldValues['space_attr_id'], $oldValues['space_attr_id'],
1 1
); );
if ($number_id && $oldValues['license_plate_id']) {
$manualService = new ParkingManualCorrectionService(
$this->logService
);
$manualService->createData([
'enter_time' => $oldValues['berthing_time'],
'space_id' => $oldValues['id'],
'old_license_id' => $oldValues['license_plate_id'],
'new_license_id' => $number_id
], $this->adminUserId);
}
} else if ($status == 4) { } else if ($status == 4) {
// 占用无车牌 // 占用无车牌
$update['license_plate_id'] = 0; $update['license_plate_id'] = 0;

33
database/migrations/2026_09_09_143449_create_parking_manual_correction_table.php

@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('parking_manual_correction', function (Blueprint $table) {
$table->id();
$table->dateTime('enter_time')->comment('进入车位时间');
$table->integer('space_id')->comment('车位id');
$table->integer('old_license_id')->comment('原本车牌号码');
$table->integer('admin_user_id')->comment('操作员');
$table->integer('new_license_id')->comment('现时车牌号码');
$table->index('space_id', 'space_id');
$table->comment('车位车牌修正记录');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('parking_manual_correction');
}
};

9
resources/lang/en/exports.php

@ -125,5 +125,14 @@ return [
], ],
'utilization_rate' => [ 'utilization_rate' => [
'rate' => 'Usage Rate' 'rate' => 'Usage Rate'
],
'manual_correction' => [
'list' => 'License Plate Correction Record',
'enter_time' => 'Entry Time',
'space_number' => 'Parking Space Number',
'old_license_place' => 'Original License Plate Number',
'updated_at' => 'Modification Time',
'username' => 'Operator',
'new_license_place' => 'Current License Plate Number',
] ]
]; ];

3
resources/lang/en/log.php

@ -157,5 +157,8 @@ return [
'access_record' => [ 'access_record' => [
'create' => 'Set up vehicle entry and exit for parking spaces.', 'create' => 'Set up vehicle entry and exit for parking spaces.',
'update' => 'Update vehicle entry and exit records for parking spaces.' 'update' => 'Update vehicle entry and exit records for parking spaces.'
],
'manual_correction' => [
'create' => 'Create license plate correction record'
] ]
]; ];

9
resources/lang/zh-CN/exports.php

@ -125,5 +125,14 @@ return [
], ],
'utilization_rate' => [ 'utilization_rate' => [
'rate' => '使用率' 'rate' => '使用率'
],
'manual_correction' => [
'list' => '车牌修正记录',
'enter_time' => '进入车位时间',
'space_number' => '车位号码',
'old_license_place' => '原本车牌号码',
'updated_at' => '修改时间',
'username' => '操作员',
'new_license_place' => '现时车牌号码',
] ]
]; ];

3
resources/lang/zh-CN/log.php

@ -157,5 +157,8 @@ return [
'access_record' => [ 'access_record' => [
'create' => '创建车位车辆进出', 'create' => '创建车位车辆进出',
'update' => '更新车位车辆进出' 'update' => '更新车位车辆进出'
],
'manual_correction' => [
'create' => '创建车牌修正记录'
] ]
]; ];

9
resources/lang/zh-TW/exports.php

@ -125,5 +125,14 @@ return [
], ],
'utilization_rate' => [ 'utilization_rate' => [
'rate' => '使用率' 'rate' => '使用率'
],
'manual_correction' => [
'list' => '車牌修正記錄',
'enter_time' => '進入車位時間',
'space_number' => '車位號碼',
'old_license_place' => '原本車牌號碼',
'updated_at' => '修改時間',
'username' => '操作員',
'new_license_place' => '現時車牌號碼',
] ]
]; ];

3
resources/lang/zh-TW/log.php

@ -157,5 +157,8 @@ return [
'access_record' => [ 'access_record' => [
'create' => '創建車位車輛進出', 'create' => '創建車位車輛進出',
'update' => '更新車位車輛進出' 'update' => '更新車位車輛進出'
],
'manual_correction' => [
'create' => '創建車牌修正記錄'
] ]
]; ];

6
routes/admin/api.php

@ -44,7 +44,7 @@ use App\Http\Controllers\Admin\ParkingGateControlController;
use App\Http\Controllers\Admin\ProhibitedPassageController; use App\Http\Controllers\Admin\ProhibitedPassageController;
use App\Http\Controllers\Admin\ParkingAccessRecordController; use App\Http\Controllers\Admin\ParkingAccessRecordController;
use App\Http\Controllers\Admin\UtilizationRateController; use App\Http\Controllers\Admin\UtilizationRateController;
use App\Http\Controllers\Admin\ParkingManualCorrectionController;
Route::group(['prefix' => 'admin'], function () { Route::group(['prefix' => 'admin'], function () {
// 认证相关接口 // 认证相关接口
@ -264,6 +264,10 @@ Route::group(['prefix' => 'admin'], function () {
Route::get('/utilizationRate/search', [UtilizationRateController::class, 'search']); Route::get('/utilizationRate/search', [UtilizationRateController::class, 'search']);
Route::get('/utilizationRate/rule', [UtilizationRateController::class, 'rule']); Route::get('/utilizationRate/rule', [UtilizationRateController::class, 'rule']);
Route::get('/utilizationRate/export', [UtilizationRateController::class, 'export']); Route::get('/utilizationRate/export', [UtilizationRateController::class, 'export']);
// 车牌修正记录
Route::get('/manualCorrection', [ParkingManualCorrectionController::class, 'index']);
Route::get('/manualCorrection/rule', [ParkingManualCorrectionController::class, 'rule']);
Route::get('/manualCorrection/export', [ParkingManualCorrectionController::class, 'export']);
// 系统日志 // 系统日志
Route::get('/operationLog/index', [OperationLogController::class, 'index']); Route::get('/operationLog/index', [OperationLogController::class, 'index']);

Loading…
Cancel
Save