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
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;
|
|
}
|
|
}
|
|
|