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

222 lines
7.4 KiB

<?php
namespace App\Http\Controllers\Reserve;
use App\Models\AdminFloor;
use App\Models\EventCalendar;
use App\Models\ParkingChannel;
use App\Models\ParkingPattern;
use App\Models\ParkingPatternSpace;
use App\Models\ParkingReservation;
use App\Models\ParkingSpace;
use App\Models\ParkingSpaceAttributes;
use App\Services\ApiResponseService;
use App\Services\OperationLogService;
use App\Services\ParkingLicensePlateService;
use App\Services\ParkingReservationService;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use JetBrains\PhpStorm\ArrayShape;
class ReservationController
{
/**
* @var ApiResponseService
*/
protected ApiResponseService $responseService;
protected ParkingReservationService $service;
/**
* 构造函数
*/
public function __construct()
{
$this->responseService = new ApiResponseService();
$this->service = new ParkingReservationService(new OperationLogService());
}
public function query(Request $request): JsonResponse
{
try {
$date = $request->get('date');
if (!$date) {
throw new Exception('预约日期不能为空');
}
$infoData = $this->getDatePatternInfo($date);
$pattern_id = $infoData['pattern_id'];
$sum_quantity = $infoData['sum_quantity'];
$count = $infoData['count'];
$remaining_quantity = $sum_quantity - $count;
$data = [
'sum_quantity' => $sum_quantity,
'remaining_quantity' => $remaining_quantity,
'pattern_id' => $pattern_id,
'space_attr_list' => ParkingSpaceAttributes::getData()
];
return $this->responseService->success($data);
} catch (Exception $e) {
return $this->responseService->systemError($e->getMessage());
}
}
public function submit(Request $request): JsonResponse
{
try {
$param = $request->all();
$license_plate = $param['license_plate'] ?? '';
$space_attr_id = $param['space_attr_id'] ?? '';
$date = $param['date'] ?? '';
$is_driver = $param['is_driver'] ?? 0;
$pattern_id = $param['pattern_id'] ?? 0;
if (empty($license_plate)) {
throw new Exception('车牌号码不能为空');
}
if (empty($space_attr_id)) {
throw new Exception('车位属性不能为空');
}
if (empty($date)) {
throw new Exception('预约日期不能为空');
}
$infoData = $this->getDatePatternInfo($date);
if ($pattern_id != $infoData['pattern_id']) {
throw new Exception('活动失效');
}
if (!in_array($is_driver, [0, 1])) {
throw new Exception('信息错误');
}
$error = (new ParkingLicensePlateService(
new OperationLogService()
))->validateLicensePlate($license_plate);
if ($error) {
throw new Exception($error);
}
$param = $this->randParkingSpaceData($param);
$data = $this->service->createData($param);
return $this->responseService->success($data);
} catch (Exception $e) {
return $this->responseService->systemError($e->getMessage());
}
}
public function confirm(Request $request): JsonResponse
{
try {
$reserve_id = $request->post('id', '');
if (empty($reserve_id)) {
throw new Exception('数据缺失');
}
$id = ParkingReservation::query()->where(
['reserve_id' => $reserve_id, 'status' => 0]
)->value('id');
if (!$id) {
throw new Exception('确认失败');
}
$this->service->confirm($id);
return $this->responseService->success();
} catch (Exception $e) {
return $this->responseService->systemError($e->getMessage());
}
}
public function cancel(Request $request): JsonResponse
{
try {
$reserve_id = $request->post('id', '');
if (empty($reserve_id)) {
throw new Exception('数据缺失');
}
$id = ParkingReservation::query()->where('reserve_id', $reserve_id)->whereIn(
'status',
[0, 1]
)->value('id');
if (!$id) {
throw new Exception('取消失败');
}
$this->service->cancel($id);
return $this->responseService->success();
} catch (Exception $e) {
return $this->responseService->systemError($e->getMessage());
}
}
protected function randParkingSpaceData($data)
{
$pattern_id = $data['pattern_id'];
$date = $data['date'];
$space_attr_id = $data['space_attr_id'];
$space_ids = ParkingPatternSpace::query()->where(
'pattern_id',
$pattern_id
)->pluck('space_id');
$count = ParkingSpace::query()->whereIn('id', $space_ids)->where(
'space_attr_id',
$space_attr_id
)->count();
$reserveCount = ParkingReservation::query()->where('date', $date)
->whereIn(
'status',
[0, 1]
)->where('space_attr_id', $space_attr_id)->count();
if ($reserveCount == $count) {
throw new Exception('当前属性车位已预约满');
}
$res = ParkingSpace::query()->whereIn('id', $space_ids)->where(
'space_attr_id',
$space_attr_id
)->first()->toArray();
$data['floor_id'] = $res['floor_id'];
$data['floor_region_id'] = $res['region_id'];
$data['space_type_id'] = $res['space_type_id'];
$data['parking_id'] = AdminFloor::getParkingId($res['floor_id']) ?? 0;
$data['channel_id'] = ParkingChannel::query()->where(
'parking_id',
$data['parking_id']
)->value('id') ?? 0;
return $data;
}
/**
* @param $date
* @return array
* @throws Exception
*/
#[ArrayShape([
'count' => "int",
'sum_quantity' => "int",
'pattern_id' => "mixed"
])] protected function getDatePatternInfo($date): array
{
$date_time = get_datetime('datetime', strtotime($date));
$pattern_id = EventCalendar::query()->where('status', 1)->where(
'end_time',
'>',
$date_time
)->whereRaw("DATE_FORMAT(start_time, '%Y-%m-%d') <= {$date}")
->value('pattern_id');
if (!$pattern_id) {
$pattern_id = ParkingPattern::query()->where('is_default', 1)
->value('id');
// throw new Exception('没有活动,不可预约');
}
$spaceIds = ParkingPatternSpace::getParkingSpaceIds($pattern_id);
$sum_quantity = count($spaceIds);
$count = ParkingReservation::query()->where('date', $date)->whereIn(
'status',
[0, 1]
)->count();
if ($count == $sum_quantity) {
throw new Exception('车位已预约满');
}
return [
'count' => $count,
'sum_quantity' => $sum_quantity,
'pattern_id' => $pattern_id
];
}
}