停车场管理系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

303 lines
10 KiB

<?php
namespace App\Services;
use App\Models\AdminFloor;
use App\Models\ParkingAccessRecord;
use App\Models\ParkingCamera;
use App\Models\ParkingLicensePlate;
use App\Models\ParkingSpace;
use App\Models\ParkingSpaceAttributes;
use App\Models\ParkingSpaceCamera;
use App\Models\ParkingSpaceType;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
class ParkingAccessRecordService extends BaseService
{
protected string $menuTitle = 'access_record';
protected array $statusArr = ['leave', 'enter'];
// 进入车位
public function enterData($data)
{
$data = [
'floor_id' => $data['floor_id'],
'license_plate_id' => $data['license_plate_id'],
'space_id' => $data['space_id'],
'status' => 1,
'enter_time' => $data['enter_time'],
'scene_image' => $data['scene_image'] ?? '',
'created_at' => date("Y-m-d H:i:s", time())
];
$model = ParkingAccessRecord::query()->create($data);
$this->logService->logCreated($model, $this->menuTitle . '.create');
$data = $model->toArray();
return $data['id'] ?? 0;
}
/**
* @return ParkingAccessRecordService
*/
public static function query(): ParkingAccessRecordService
{
return new self(new OperationLogService());
}
// 离开车位
public function leaveData($id, $data)
{
$key = 'leave:'. $id . ':data';
$count = Redis::get($key);
if (!$count) {
Redis::set($key, 1);
return false;
} else {
Redis::del($key);
}
$model = ParkingAccessRecord::query()->findOrFail($id);
$oldValues = $model->toArray();
$data = [
'status' => 0,
'leave_time' => $data['leave_time'],
'updated_at' => date("Y-m-d H:i:s", time())
];
$model->update($data);
$this->logService->logUpdated(
$model,
$oldValues,
$this->menuTitle . '.update'
);
return true;
}
// 车辆进入车位
public function enterOrLeave(
$camera_ip,
$space_number,
$license_plate,
$now_time,
$image_data = '',
$confidenceLevel = 0
)
{
$camera_id = ParkingCamera::query()->where('camera_ip', $camera_ip)
->value('id');
$ParkingSpace = ParkingSpace::query()->where('number', $space_number)
->first();
$exists = false;
$space_id = 0;
$spaceData = [];
if ($ParkingSpace) {
$spaceData = $ParkingSpace->toArray();
$space_id = $spaceData['id'];
$exists = ParkingSpaceCamera::query()->where([
'camera_id' => $camera_id,
'space_id' => $space_id
])->exists();
}
if (!$exists) {
return;
}
$where = $data = [
'space_id' => $space_id,
'floor_id' => $spaceData['floor_id'],
];
// 记录车牌信息
if ($license_plate) {
$licensePlateService = new ParkingLicensePlateService(
$this->logService
);
$license_plate = str_replace('蓝', '', $license_plate);
$license_plate = str_replace('黄', '', $license_plate);
$license_plate = str_replace('绿', '', $license_plate);
$license_plate = trim($license_plate);
$license_plate_id = $licensePlateService->saveNumber($license_plate);
$data['license_plate_id'] = $license_plate_id;
}
// 查询车位记录
$oldQuery = ParkingAccessRecord::query()->where($where)->where('status', 1)
->first(['id', 'license_plate_id']);
$ParkingSpaceService = new ParkingSpaceService($this->logService);
$old_license_plate_id = '';
$id = '';
if ($oldQuery) {
$id = $oldQuery['id'];
$old_license_plate_id = $oldQuery['license_plate_id'];
$data['leave_time'] = strtotime($now_time);
// 有记录 无车牌 离场
if (!isset($data['license_plate_id'])) {
$leaveRes = $this->leaveData($id, $data);
if (!$leaveRes) {
return;
}
// 同步车位车辆进入
$ParkingSpaceService->updateEnterLeave($space_id, 0, $now_time);
// VIP车辆离场
ParkingVipListService::leave($id, $now_time);
return;
} elseif ($data['license_plate_id'] == $old_license_plate_id) {
// 车牌相同不做操作
return;
}
}
// 无车牌不添加
if (!isset($data['license_plate_id'])) {
return;
}
// 有记录 车牌不同
if ($old_license_plate_id) {
// 原车牌离场
$leaveRes = $this->leaveData($id, $data);
if (!$leaveRes) {
return;
}
// VIP车辆离场
ParkingVipListService::leave($id, $now_time);
}
$where['license_plate_id'] = $data['license_plate_id'];
$oldExists = ParkingAccessRecord::query()->where($where)->where(
'status',
1
)->exists();
if ($oldExists) {
return;
}
// 有车牌 无停车记录,可以进入
$data['enter_time'] = strtotime($now_time);
$data['scene_image'] = $this->saveSceneImage($image_data);
$access_record_id = $this->enterData($data);
// 同步车位车辆进入
$ParkingSpaceService->updateEnterLeave(
$space_id,
1,
$now_time,
$data['license_plate_id'],
$data['scene_image'],
empty($id),
$confidenceLevel
);
// 判断是否为VIP 并添加入场 判断是否违停
ParkingVipListService::enter(
$space_id,
$spaceData['space_type_id'],
$access_record_id,
$now_time,
$data['license_plate_id'],
$spaceData['floor_id']
);
$RecognitionService = new LicensePlateRecognitionService($this->logService);
$RecognitionService->createData([
'time_slot' => date("Y-m-d", strtotime($now_time)),
'manual_modification' => 0,
'recognition' => $confidenceLevel,
'license_plate' => $license_plate,
'capture_images' => ''
]);
}
// 手动添加车辆进出记录
public function syncSpaceStatusRecord(
$floor_id,
$license_plate_id,
$space_id,
$datetime,
$status = 0,
$space_type_id = 0
) {
$data = [
'space_id' => $space_id,
'floor_id' => $floor_id,
];
$where = [
['space_id', '=', $space_id],
['floor_id', '=', $floor_id]
];
$date_times = strtotime($datetime);
// 车辆进入创建记录
if ($status == 1 && $license_plate_id) {
$data['license_plate_id'] = $license_plate_id;
$data['enter_time'] = $date_times;
$access_record_id = $this->enterData($data);
// 查询当前车位是否存在其他未离开车辆,当不包含刚进入车辆
$where[] = ['license_plate_id', '<>', $license_plate_id];
// 判断是否为VIP 判断是否违停
ParkingVipListService::enter(
$space_id,
$space_type_id,
$access_record_id,
$datetime,
$license_plate_id,
$floor_id
);
}
// 查询车位进入车辆记录
$id = ParkingAccessRecord::query()->where($where)->where('status', 1)
->value('id');
if ($id) {
$data['leave_time'] = $date_times;
$this->leaveData($id, $data);
ParkingVipListService::leave($id, $datetime);
}
}
// 保存场景图
public function saveSceneImage($imageData): string
{
$scene_image = '';
if ($imageData) {
$filename = time() . '_' . md5(Str::random(6)) . '.jpg';
$save_file_path = 'public/images/scene/' . date("Ymd") . '/' . $filename;
$deBaseData = base64_decode($imageData);
Storage::put($save_file_path, $deBaseData);
$scene_image = Storage::url($save_file_path);
}
return $scene_image;
}
/**
* @return array|string[]
*/
public function getStatus(): array
{
$statusArr = $this->statusArr;
foreach ($statusArr as $key => $value) {
$statusArr[$key] = __('admin.' . $value);
}
return $statusArr;
}
public function getOptionItem($item)
{
$leave_time = $item['leave_time'] ?? time();
$enter_times = strtotime($item['enter_time']);
$leave_times = strtotime($leave_time);
$item['duration'] = get_diff_in_minutes($enter_times, $leave_times);
$item['license_plate'] = ParkingLicensePlate::getNumber(
$item['license_plate_id']
);
$item['floor'] = AdminFloor::getName($item['floor_id']);
$ParkingSpace = ParkingSpace::query()->find($item['space_id']);
$item['parking_space_number'] = '';
$item['parking_space_type'] = '';
$item['parking_space_attr'] = '';
if ($ParkingSpace) {
$item['parking_space_number'] = $ParkingSpace['number'];
$item['parking_space_type'] = ParkingSpaceType::getName(
$ParkingSpace['space_type_id']
);
$item['parking_space_attr'] = ParkingSpaceAttributes::getAttr(
$ParkingSpace['space_attr_id']
);
}
$statusArr = $this->getStatus();
$item['status_str'] = $statusArr[$item['status']] ?? '';
unset($item['license_plate_id'], $item['floor_id'], $item['space_id']);
return $item;
}
}