停车场管理系统
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.
 
 

481 lines
14 KiB

<?php
namespace App\Services;
use App\Models\AdminFloor;
use App\Models\ParkingLicensePlate;
use App\Models\ParkingSpace;
use App\Models\ParkingSpaceAttributes;
use App\Models\ParkingSpaceType;
use App\Models\ParkingSpaceTypeAttr;
use Exception;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class ParkingSpaceService extends BaseService
{
protected int $recognition = 80;
/**
* @var string[]
*/
protected array $statusArr = ['vacant', 'occupy','repair'];
protected array $operationType
= [
'',
'no_cars',
'yes_cars',
'number_update'
];
public function __construct(OperationLogService $logService)
{
parent::__construct($logService);
$this->logService->menuTitle = 'cat_list';
}
/**
* 返回翻译后的状态
* @param $status
* @return string
*/
public function getStatusStr($status): string
{
$value = $this->statusArr[$status] ?? '';
if ($value) {
return __('service.parking_space.' . $value);
}
return $value;
}
public function getRecognition($recognition): string
{
if ($recognition) {
$str = $recognition >= $this->recognition ? 'high' : 'land';
return __('service.parking_space.' . $str);
}
return '-';
}
public function getOperationType($operation_type): string
{
$value = $this->operationType[$operation_type] ?? '';
if ($value) {
return __('service.parking_space.' . $value);
}
return '-';
}
public function getStatusArr($is_child = false): array
{
$arr = [];
foreach ($this->statusArr as $key => $value) {
$arr[$key] = __('service.parking_space.' . $value);
if ($value == 'occupy' && $is_child) {
$arr['children'] = [
$key => [
3 => __('service.parking_space.yes_license'),
4 => __('service.parking_space.no_license')
]
];
}
}
return $arr;
}
public function getStatusArrKey(): array
{
return array_keys($this->statusArr);
}
public function optionItems($item)
{
$item['floor'] = AdminFloor::getName($item['floor_id']);
$item['space_attr'] = ParkingSpaceAttributes::getAttr(
$item['space_attr_id']
);
$item['space_type'] = ParkingSpaceType::getName(
$item['space_type_id']
);
$license_plate = ParkingLicensePlate::getNumber(
$item['license_plate_id']
);
$item['license_plate'] = $license_plate ?: '-';
$item['berthing_time'] = is_null($item['berthing_time'])
? '-' : $item['berthing_time'];
$item['recognition'] = $this->getRecognition(
$item['recognition']
);
$item['status'] = $this->getStatusStr(
$item['status']
);
$item['operation_type'] = $this->getOperationType(
$item['operation_type']
);
unset(
$item['floor_id'], $item['space_attr_id'],
$item['space_type_id'], $item['license_plate_id']
);
return $item;
}
/**
* 更新车位数据
* @param array $data
* @param string $key
* @return Builder
* @throws Exception
*/
public function updateData(
array $data,
string $key = 'space_type_id'
): Builder {
try {
DB::beginTransaction();
$ids = $data['space_ids'];
$data_id = $data[$key];
$model = ParkingSpace::query()->whereIn('id', $ids)->select();
$oldValues = $model->get()->toArray();
$updateData = [
$key => $data_id,
'updated_at' => get_datetime()
];
$model->update($updateData);
// 同步更新模式 类型、属性、附属类型
if ($key == 'space_type_id') {
foreach ($ids as $space_id) {
$tar_mode_id = EventCalendarService::getTargetModeId();
$this->syncUpdateSpaceData($space_id, $data_id, $tar_mode_id, false);
}
}
$newValue = $oldValues;
$newValue[$key] = $data_id;
$newValue['updated_at'] = $updateData['updated_at'];
$this->logService->logUpdatedData(
new ParkingSpace(),
$oldValues,
$this->getLogDescription($key),
$newValue
);
DB::commit();
return $model;
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
}
private function getLogDescription($key): string
{
$str = '';
if ($key == 'space_type_id') {
$str = 'space_type.update';
} elseif ($key == 'space_attr_id') {
$str = 'space_attributes.update';
} elseif ($key == 'auxiliary_space_type') {
$str = 'parking_space.auxiliary_space_type';
}
return $str;
}
/**
* @param $data
* @return Builder|Model
* @throws Exception
*/
public function createModel($data): Builder|Model
{
try {
DB::beginTransaction();
if (ParkingSpace::query()->where('number', $data['number'])
->exists()
) {
throw new Exception(__('service.parking_space.number_exists'));
}
if (empty($data['space_type_id'])) {
$res = ParkingSpaceType::getDefaultData();
if ($res) {
$data['space_type_id'] = $res['id'];
}
}
$model = $this->createData($data);
DB::commit();
return $model;
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
}
public function createData($data): Builder|Model
{
$model = ParkingSpace::query()->create([
'floor_id' => $data['floor_id'],
'region_id' => $data['region_id'],
'number' => $data['number'],
'space_attr_id' => $data['space_attr_id'],
'license_plate_id' => $data['license_plate_id'] ?? 0,
'status' => $data['status'] ?? 0,
'space_type_id' => $data['space_type_id'] ?? 0,
'operation_type' => $data['operation_type'] ?? 0,
'created_at' => get_datetime()
]);
$this->logService->logCreated($model, 'parking_space.create');
return $model;
}
// 更新车位属性
public function updateAttr($id, $space_attr_id)
{
$model = ParkingSpace::query()->findOrFail($id);
$oldValues = $model->toArray();
if ($space_attr_id != $oldValues['space_attr_id']) {
$model->update([
'space_attr_id' => $space_attr_id,
'updated_at' => get_datetime()
]);
$this->logService->logUpdated(
$model,
$oldValues,
'space_attributes.update'
);
}
}
// 获取车位列表
public static function getSelectList($floor_id): array
{
$columns = ['id as parking_space_id', 'number as parking_space_number'];
return ParkingSpace::query()->where('floor_id', $floor_id)->select(
$columns
)->get()->toArray();
}
// 更新状态和车牌
public function updateStatus($id, $status, $license_plate)
{
try {
DB::beginTransaction();
$model = ParkingSpace::query()->findOrFail($id);
$oldValues = $model->toArray();
$update = [
'status' => $status,
'updated_at' => get_datetime()
];
if (!empty($license_plate) && $status == 1) {
$number_id = ParkingLicensePlate::getValueId($license_plate);
if (!$number_id) {
$licensePlateService = new ParkingLicensePlateService($this->logService);
$create = [
'number' => $license_plate,
'space_type_id' => $oldValues['space_type_id']
];
$licensePlateModel = $licensePlateService->createData($create);
$number_id = $licensePlateModel->id;
}
if ($number_id) {
$update['license_plate_id'] = $number_id;
$update['berthing_time'] = get_datetime();
$update['recognition'] = 'high';
}
} else if (!$status) {
$update['license_plate_id'] = 0;
$update['berthing_time'] = null;
$update['recognition'] = '';
}
$model->update($update);
$this->logService->logUpdated(
$model,
$oldValues,
'parking_space.update_status'
);
DB::commit();
return $model;
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
}
/**
* 根据不同模式 更新车位类型
* @param $id
* @param $type_id
* @param $pattern_id
* @param bool $is_target_mode // 是否判断是不是当前模式
* @return void
*/
public function syncUpdateSpaceData(
$id,
$type_id,
$pattern_id,
bool $is_target_mode = true
) {
// 跳过判断
if ($is_target_mode) {
// 非当前模式不更新
$targetPatternId = EventCalendarService::getTargetModeId();
if ($pattern_id != $targetPatternId) {
return;
}
}
$model = ParkingSpace::query()->findOrFail($id);
$oldValues = $model->toArray();
// 相同不更新
if ($oldValues['space_type_id'] == $type_id) {
return;
}
$updateData = [
'space_type_id' => $type_id,
'updated_at' => date("Y-m-d H:i:s", time())
];
$model->update($updateData);
// 记录日志
$this->logService->logUpdated(
$model,
$oldValues,
$this->getLogDescription('space_type_id')
);
// 切换车位类型,同步切换车位灯颜色
if ($oldValues['status'] != 2) {
$this->changeSpaceCameraColor($oldValues['number'], $type_id, $oldValues['space_attr_id']);
}
}
// 切换模式更改车位类型 后 更改车位灯颜色
public function changeSpaceCameraColor($number, $space_type_id, $space_attr, $is_repair = false)
{
if ($number == '1-1') {
$SpaceType = ParkingSpaceType::query()->find($space_type_id);
$SpaceTypeAttr = ParkingSpaceTypeAttr::getSpaceTypeAttrInfo($space_type_id, $space_attr);
$color_occupy = $SpaceType['default_color_occupy'];
$color_vacant = $SpaceType['default_color_vacant'];
$is_flicker = $SpaceType['default_is_warning'];
if ($SpaceTypeAttr) {
$color_occupy = $SpaceTypeAttr['color_occupy'];
$color_vacant = $SpaceTypeAttr['color_vacant'];
$is_flicker = $SpaceTypeAttr['is_warning'];
}
// 维修灯
if ($is_repair) {
$color_occupy = $SpaceType['repair_light'];
$color_vacant = $SpaceType['repair_light'];
$is_flicker = false;
}
$HikParkingCameraService = new HikParkingCameraService($this->logService);
$body = $HikParkingCameraService->getBody($color_occupy, $color_vacant, $is_flicker);
$HikParkingCameraService->updatelight($body);
}
}
/**
* @param array $data
* @param int $id
* @throws Exception
*/
public function updateModel(array $data, int $id)
{
try {
DB::beginTransaction();
// 验证
$existsWhere = [
['number', '=', $data['number']],
['id', '<>', $id]
];
if (ParkingSpace::query()->where($existsWhere)->exists()) {
throw new Exception(__service('parking_space.number_exists'));
}
$space_type_id = 0;
$res = ParkingSpaceType::getDefaultData();
if ($res) {
$space_type_id = $res['id'];
}
// 更新
$model = ParkingSpace::query()->findOrFail($id);
$oldValues = $model->toArray();
$model->update([
'floor_id' => $data['floor_id'],
'region_id' => $data['region_id'],
'number' => $data['number'],
'space_attr_id' => $data['space_attr_id'],
'space_type_id' => $space_type_id,
'updated_at' => get_datetime()
]);
$this->logService->logUpdated(
$model,
$oldValues,
'parking_space.update'
);
DB::commit();
return $model;
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
}
/**
* @param $id
* @return bool
* @throws Exception
*/
public function deleteModel($id): bool
{
try {
DB::beginTransaction();
$model = ParkingSpace::query()->findOrFail($id);
$this->logService->logDeleted($model, 'parking_space.delete');
$model->delete();
DB::commit();
return true;
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
}
/**
* @param $ids
* @return bool
* @throws Exception
*/
public function batchDeleteModel($ids): bool
{
try {
DB::beginTransaction();
foreach ($ids as $id) {
$model = ParkingSpace::query()->findOrFail($id);
$this->logService->logDeleted(
$model,
'parking_space.delete'
);
$model->delete();
}
DB::commit();
return true;
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
}
}