24 changed files with 1092 additions and 28 deletions
@ -0,0 +1,16 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Exports; |
||||
|
|
||||
|
use Maatwebsite\Excel\Concerns\FromArray; |
||||
|
|
||||
|
class ParkingLicensePlateImportTemplateExport implements FromArray |
||||
|
{ |
||||
|
public function array(): array |
||||
|
{ |
||||
|
return [ |
||||
|
[__('exports.global.index'), __('exports.vip_list.license')], |
||||
|
['1', '测A88888'] |
||||
|
]; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,59 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Exports; |
||||
|
|
||||
|
use App\Models\ParkingSpace; |
||||
|
use App\Services\OperationLogService; |
||||
|
use App\Services\ParkingSpaceService; |
||||
|
use Maatwebsite\Excel\Concerns\FromArray; |
||||
|
use Maatwebsite\Excel\Concerns\WithHeadings; |
||||
|
|
||||
|
class ParkingSpaceExport implements FromArray, WithHeadings |
||||
|
{ |
||||
|
|
||||
|
public function array(): array |
||||
|
{ |
||||
|
$data = []; |
||||
|
ParkingSpace::all()->each( |
||||
|
function ($item) use (&$data) { |
||||
|
$oldItem = (new ParkingSpaceService( |
||||
|
new OperationLogService() |
||||
|
))->optionItems($item); |
||||
|
$data[] = [ |
||||
|
'id' => $oldItem['id'], |
||||
|
'floor' => $oldItem['floor'], |
||||
|
'number' => $oldItem['number'], |
||||
|
'space_attr' => $oldItem['space_attr'], |
||||
|
'license_plate' => $oldItem['license_plate'], |
||||
|
'berthing_time' => $oldItem['berthing_time'], |
||||
|
'recognition' => $oldItem['recognition'], |
||||
|
'status' => $oldItem['status'], |
||||
|
'space_type' => $oldItem['space_type'], |
||||
|
'operation_type' => $oldItem['operation_type'], |
||||
|
'updated_at' => $oldItem['updated_at'] |
||||
|
]; |
||||
|
} |
||||
|
); |
||||
|
return $data; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function headings(): array |
||||
|
{ |
||||
|
return [ |
||||
|
__('exports.global.index'), |
||||
|
__('exports.parking_space.floor'), |
||||
|
__('exports.parking_space.number'), |
||||
|
__('exports.parking_space.space_attr'), |
||||
|
__('exports.parking_space.license_plate'), |
||||
|
__('exports.parking_space.berthing_time'), |
||||
|
__('exports.parking_space.recognition'), |
||||
|
__('exports.parking_space.status'), |
||||
|
__('exports.parking_space.space_type'), |
||||
|
__('exports.parking_space.operation_type'), |
||||
|
__('exports.parking_space.updated_at') |
||||
|
]; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,205 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Http\Controllers\Admin; |
||||
|
|
||||
|
use App\Http\Controllers\Controller; |
||||
|
use App\Models\AdminFloor; |
||||
|
use App\Models\AdminFloorRegion; |
||||
|
use App\Models\ParkingLicensePlate; |
||||
|
use App\Models\ParkingReservation; |
||||
|
use App\Models\ParkingSpace; |
||||
|
use App\Models\ParkingSpaceAttributes; |
||||
|
use App\Models\ParkingSpaceType; |
||||
|
use App\Services\ApiResponseService; |
||||
|
use App\Services\ParkingReservationService; |
||||
|
use Exception; |
||||
|
use Illuminate\Http\JsonResponse; |
||||
|
use Illuminate\Http\Request; |
||||
|
|
||||
|
class ParkingReservationController extends Controller |
||||
|
{ |
||||
|
/** |
||||
|
* @var ApiResponseService |
||||
|
*/ |
||||
|
protected ApiResponseService $responseService; |
||||
|
|
||||
|
/** |
||||
|
* @var ParkingReservationService |
||||
|
*/ |
||||
|
protected ParkingReservationService $service; |
||||
|
|
||||
|
/** |
||||
|
* @param ApiResponseService $responseService |
||||
|
* @param ParkingReservationService $service |
||||
|
*/ |
||||
|
public function __construct( |
||||
|
ApiResponseService $responseService, |
||||
|
ParkingReservationService $service |
||||
|
) { |
||||
|
$this->responseService = $responseService; |
||||
|
$this->service = $service; |
||||
|
} |
||||
|
|
||||
|
public function index(Request $request): JsonResponse |
||||
|
{ |
||||
|
try { |
||||
|
$query = ParkingReservation::query(); |
||||
|
|
||||
|
// 车牌号码搜索 |
||||
|
if ($request->has('license_plate')) { |
||||
|
$license_plate = $request->input('license_plate'); |
||||
|
if (!empty($license_plate)) { |
||||
|
$license_plate_id_arr = ParkingLicensePlate::query()->where( |
||||
|
'number', |
||||
|
'like', |
||||
|
"%{$license_plate}%" |
||||
|
)->pluck('id'); |
||||
|
$license_plate_id_arr ? $query->whereIn( |
||||
|
'license_plate_id', |
||||
|
$license_plate_id_arr |
||||
|
) : $query->where('id', 0); |
||||
|
} |
||||
|
} |
||||
|
// 楼层 |
||||
|
if ($request->has('floor_id')) { |
||||
|
$floor_id = $request->input('floor_id'); |
||||
|
if (!empty($floor_id)) { |
||||
|
$query->where('floor_id', $floor_id); |
||||
|
} |
||||
|
} |
||||
|
if ($request->has('space_number')) { |
||||
|
$space_number = $request->input('space_number'); |
||||
|
if (!empty($space_number)) { |
||||
|
$license_plate_id_arr = ParkingSpace::query()->where( |
||||
|
'number', |
||||
|
$space_number |
||||
|
)->pluck('license_plate_id'); |
||||
|
$license_plate_id_arr ? $query->whereIn( |
||||
|
'license_plate_id', |
||||
|
$license_plate_id_arr |
||||
|
) : $query->where('id', 0); |
||||
|
} |
||||
|
} |
||||
|
if ($request->has('space_type_id')) { |
||||
|
$space_type_id = $request->input('space_type_id'); |
||||
|
if (!empty($space_type_id)) { |
||||
|
$query->where('space_type_id', $space_type_id); |
||||
|
} |
||||
|
} |
||||
|
if ($request->has('space_attr_id')) { |
||||
|
$space_attr_id = $request->input('space_attr_id'); |
||||
|
if (!empty($space_attr_id)) { |
||||
|
} |
||||
|
} |
||||
|
if ($request->has('status')) { |
||||
|
$status = $request->input('status'); |
||||
|
if (!empty($status)) { |
||||
|
$query->where('status', $status); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 分页 |
||||
|
$page = $request->input('page', 1); |
||||
|
$perPage = $request->input('per_page', 10); |
||||
|
|
||||
|
$total = $query->count(); |
||||
|
$items = $query->latest()->forPage($page, $perPage)->get()->each( |
||||
|
function ($item) { |
||||
|
$item['status'] = $this->service->getStatusStr( |
||||
|
$item['status'] |
||||
|
); |
||||
|
$item['space_type'] = ParkingSpaceType::getName( |
||||
|
$item['space_type_id'] |
||||
|
); |
||||
|
$item['license_plate'] = ParkingLicensePlate::getNumber( |
||||
|
$item['license_plate_id'] |
||||
|
); |
||||
|
$item['is_driver'] = $this->service->getIsDriver( |
||||
|
$item['is_driver'] |
||||
|
); |
||||
|
$item['floor'] = AdminFloor::getName($item['floor_id']); |
||||
|
$item['floor_region'] = AdminFloorRegion::getName($item['floor_region_id']); |
||||
|
unset( |
||||
|
$item['space_type_id'], |
||||
|
$item['license_plate_id'], |
||||
|
$item['floor_id'], |
||||
|
$item['floor_region_id'] |
||||
|
); |
||||
|
return $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() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public function search(): JsonResponse |
||||
|
{ |
||||
|
try { |
||||
|
$data = [ |
||||
|
'floor_data' => AdminFloor::getData(), |
||||
|
'space_type_data' => ParkingSpaceType::getData(), |
||||
|
'space_attr_data' => ParkingSpaceAttributes::getData(), |
||||
|
'status_data' => get_select_data( |
||||
|
$this->service->getStatusArr() |
||||
|
) |
||||
|
]; |
||||
|
return $this->responseService->success($data); |
||||
|
} catch (Exception $e) { |
||||
|
$m_prefix = __('exception.exception_handler.resource'); |
||||
|
return $this->responseService->systemError( |
||||
|
$m_prefix . ':' . $e->getMessage() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public function statistics(Request $request): JsonResponse |
||||
|
{ |
||||
|
try { |
||||
|
$start_at = date("Y-m-d 00:00:00"); |
||||
|
$end_at = date("Y-m-d 23:59:59"); |
||||
|
if ($request->has('appointment_date')) { |
||||
|
$appointment_date = $request->input('appointment_date'); |
||||
|
if (!empty($appointment_date)) { |
||||
|
$start_at = date( |
||||
|
"Y-m-d 00:00:00", |
||||
|
strtotime($appointment_date) |
||||
|
); |
||||
|
$end_at = date( |
||||
|
"Y-m-d 23:59:59", |
||||
|
strtotime($appointment_date) |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
$today_count = $this->service->getCount($start_at, $end_at); |
||||
|
$present_count = $this->service->getBePresentCount( |
||||
|
$start_at, |
||||
|
$end_at |
||||
|
); |
||||
|
$absent_count = $today_count - $present_count; |
||||
|
$data = [ |
||||
|
'today_count' => $today_count, |
||||
|
'present_count' => $present_count, |
||||
|
'absent_count' => max($absent_count, 0) |
||||
|
]; |
||||
|
return $this->responseService->success($data); |
||||
|
} catch (Exception $e) { |
||||
|
$m_prefix = __('exception.exception_handler.resource'); |
||||
|
return $this->responseService->systemError( |
||||
|
$m_prefix . ':' . $e->getMessage() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,247 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Http\Controllers\Admin; |
||||
|
|
||||
|
use App\Exports\ParkingSpaceExport; |
||||
|
use App\Http\Controllers\Controller; |
||||
|
use App\Models\AdminFloor; |
||||
|
use App\Models\ParkingLicensePlate; |
||||
|
use App\Models\ParkingSpace; |
||||
|
use App\Models\ParkingSpaceAttributes; |
||||
|
use App\Models\ParkingSpaceType; |
||||
|
use App\Services\ApiResponseService; |
||||
|
use App\Services\ParkingSpaceService; |
||||
|
use Exception; |
||||
|
use Illuminate\Http\JsonResponse; |
||||
|
use Illuminate\Http\Request; |
||||
|
use Illuminate\Support\Facades\Validator; |
||||
|
use Illuminate\Validation\ValidationException; |
||||
|
use Maatwebsite\Excel\Facades\Excel; |
||||
|
use Symfony\Component\HttpFoundation\BinaryFileResponse; |
||||
|
|
||||
|
class ParkingSpaceController extends Controller |
||||
|
{ |
||||
|
/** |
||||
|
* @var ApiResponseService |
||||
|
*/ |
||||
|
protected ApiResponseService $responseService; |
||||
|
|
||||
|
/** |
||||
|
* @var ParkingSpaceService |
||||
|
*/ |
||||
|
protected ParkingSpaceService $service; |
||||
|
|
||||
|
/** |
||||
|
* @param ApiResponseService $responseService |
||||
|
* @param ParkingSpaceService $service |
||||
|
*/ |
||||
|
public function __construct( |
||||
|
ApiResponseService $responseService, |
||||
|
ParkingSpaceService $service |
||||
|
) { |
||||
|
$this->responseService = $responseService; |
||||
|
$this->service = $service; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Display a listing of the resource. |
||||
|
*/ |
||||
|
public function index(Request $request): JsonResponse |
||||
|
{ |
||||
|
try { |
||||
|
$query = ParkingSpace::query(); |
||||
|
|
||||
|
if ($request->has('license_plate')) { |
||||
|
$license_plate = $request->input('license_plate'); |
||||
|
if (!empty($license_plate)) { |
||||
|
$license_plate_id_arr = ParkingLicensePlate::query()->where( |
||||
|
'number', |
||||
|
'like', |
||||
|
"%{$license_plate}%" |
||||
|
)->pluck('id'); |
||||
|
$license_plate_id_arr ? $query->whereIn( |
||||
|
'license_plate_id', |
||||
|
$license_plate_id_arr |
||||
|
) : $query->where('id', 0); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if ($request->has('floor')) { |
||||
|
$floor = $request->input('floor'); |
||||
|
if (!empty($floor)) { |
||||
|
$query->where('floor_id', $floor); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if ($request->has('number')) { |
||||
|
$number = $request->input('number'); |
||||
|
if (!empty($number)) { |
||||
|
$query->where('number', 'like', "%{$number}%"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if ($request->has('space_type')) { |
||||
|
$space_type = $request->input('space_type'); |
||||
|
if (!empty($space_type)) { |
||||
|
$query->where('space_type_id', $space_type); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if ($request->has('space_attr')) { |
||||
|
$space_attr = $request->input('space_attr'); |
||||
|
if (!empty($space_attr)) { |
||||
|
$query->where('space_attr_id', $space_attr); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if ($request->has('status')) { |
||||
|
$status = $request->input('status'); |
||||
|
if (!empty($status)) { |
||||
|
$query->where('status', $status); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 分页 |
||||
|
$page = $request->input('page', 1); |
||||
|
$perPage = $request->input('per_page', 10); |
||||
|
$query->orderBy('id'); |
||||
|
$total = $query->count(); |
||||
|
$_this = $this; |
||||
|
$items = $query->latest()->forPage($page, $perPage)->get()->each( |
||||
|
function ($item) use ($_this) { |
||||
|
return $_this->service->optionItems($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() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return JsonResponse |
||||
|
*/ |
||||
|
public function search(): JsonResponse |
||||
|
{ |
||||
|
try { |
||||
|
$data = [ |
||||
|
'floor_data' => AdminFloor::query()->select(['id', 'name']) |
||||
|
->get()->toArray(), |
||||
|
'space_type_data' => ParkingSpaceType::query()->select( |
||||
|
['id', 'name'] |
||||
|
)->get()->toArray(), |
||||
|
'space_attr_data' => ParkingSpaceAttributes::query()->select( |
||||
|
['id', 'attributes'] |
||||
|
)->get()->toArray(), |
||||
|
'status_data' => get_select_data( |
||||
|
$this->service->getStatusArr() |
||||
|
) |
||||
|
]; |
||||
|
return $this->responseService->success($data); |
||||
|
} catch (Exception $e) { |
||||
|
$m_prefix = __('exception.exception_handler.resource'); |
||||
|
return $this->responseService->systemError( |
||||
|
$m_prefix . ':' . $e->getMessage() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public function updateType(Request $request): JsonResponse |
||||
|
{ |
||||
|
try { |
||||
|
$rules = [ |
||||
|
'space_type_id' => 'required|numeric', |
||||
|
'space_ids' => 'required|array' |
||||
|
]; |
||||
|
$messages = [ |
||||
|
'space_type_id.required' => __( |
||||
|
'validation.parking_space.type_id_empty' |
||||
|
), |
||||
|
'space_type_id.numeric' => __( |
||||
|
'validation.parking_space.type_id_numeric' |
||||
|
), |
||||
|
'space_ids.required' => __( |
||||
|
'validation.parking_space.ids_empty' |
||||
|
), |
||||
|
'space_ids.array' => __( |
||||
|
'validation.parking_space.ids_array' |
||||
|
) |
||||
|
]; |
||||
|
$validator = Validator::make($request->all(), $rules, $messages); |
||||
|
|
||||
|
if ($validator->fails()) { |
||||
|
throw new ValidationException($validator); |
||||
|
} |
||||
|
$this->service->updateData($request->all()); |
||||
|
return $this->responseService->success( |
||||
|
null, |
||||
|
__('admin.update_succeeded') |
||||
|
); |
||||
|
} catch (Exception $e) { |
||||
|
return $this->responseService->systemError( |
||||
|
__('exception.parking_space.update_type_failed') . ':' |
||||
|
. $e->getMessage() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public function updateAttr(Request $request): JsonResponse |
||||
|
{ |
||||
|
try { |
||||
|
$rules = [ |
||||
|
'space_attr_id' => 'required|numeric', |
||||
|
'space_ids' => 'required|array' |
||||
|
]; |
||||
|
$messages = [ |
||||
|
'space_attr_id.required' => __( |
||||
|
'validation.parking_space.attr_id_empty' |
||||
|
), |
||||
|
'space_attr_id.numeric' => __( |
||||
|
'validation.parking_space.attr_id_numeric' |
||||
|
), |
||||
|
'space_ids.required' => __( |
||||
|
'validation.parking_space.ids_empty' |
||||
|
), |
||||
|
'space_ids.array' => __( |
||||
|
'validation.parking_space.ids_array' |
||||
|
) |
||||
|
]; |
||||
|
$validator = Validator::make($request->all(), $rules, $messages); |
||||
|
|
||||
|
if ($validator->fails()) { |
||||
|
throw new ValidationException($validator); |
||||
|
} |
||||
|
$this->service->updateData($request->all(), 'space_attr_id'); |
||||
|
return $this->responseService->success( |
||||
|
null, |
||||
|
__('admin.update_succeeded') |
||||
|
); |
||||
|
} catch (Exception $e) { |
||||
|
return $this->responseService->systemError( |
||||
|
__('exception.parking_space.update_attr_failed') . ':' |
||||
|
. $e->getMessage() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return BinaryFileResponse |
||||
|
*/ |
||||
|
public function export(): BinaryFileResponse |
||||
|
{ |
||||
|
return Excel::download( |
||||
|
new ParkingSpaceExport(), |
||||
|
__('exports.parking_space.list') . time() . '.xlsx' |
||||
|
); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,50 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Imports; |
||||
|
|
||||
|
use App\Models\ParkingLicensePlate; |
||||
|
use App\Services\OperationLogService; |
||||
|
use Maatwebsite\Excel\Concerns\ToModel; |
||||
|
use Maatwebsite\Excel\Concerns\WithHeadingRow; |
||||
|
|
||||
|
class ParkingLicensePlateImport implements ToModel, WithHeadingRow |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* @var OperationLogService |
||||
|
*/ |
||||
|
private OperationLogService $logService; |
||||
|
|
||||
|
public function __construct() |
||||
|
{ |
||||
|
$this->logService = new OperationLogService(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param array $row |
||||
|
* @return ParkingLicensePlate |
||||
|
*/ |
||||
|
public function model(array $row): ParkingLicensePlate |
||||
|
{ |
||||
|
$data = []; |
||||
|
foreach ($row as $value) { |
||||
|
$data[] = $value; |
||||
|
} |
||||
|
$where = [ |
||||
|
'number' => $data[0], |
||||
|
'space_type_id' => $data[1] |
||||
|
]; |
||||
|
if (!ParkingLicensePlate::query()->where($where) |
||||
|
->exists() |
||||
|
) { |
||||
|
$model = new ParkingLicensePlate([ |
||||
|
'number' => $data[0], |
||||
|
'space_type_id' => $data[1], |
||||
|
'created_at' => get_datetime() |
||||
|
]); |
||||
|
$this->logService->logCreated($model, '创建车牌号码'); |
||||
|
return $model; |
||||
|
} |
||||
|
return new ParkingLicensePlate(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Models; |
||||
|
|
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
|
class ParkingReservation extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
|
||||
|
protected $table = 'parking_reservation'; |
||||
|
|
||||
|
protected $fillable |
||||
|
= [ |
||||
|
'reserve_id', |
||||
|
'space_type_id', |
||||
|
'license_plate_type', |
||||
|
'license_plate_id', |
||||
|
'is_driver', |
||||
|
'floor_id', |
||||
|
'floor_region_id', |
||||
|
'status', |
||||
|
'confirm_at' |
||||
|
]; |
||||
|
|
||||
|
protected $hidden |
||||
|
= [ |
||||
|
'updated_at' |
||||
|
]; |
||||
|
|
||||
|
public function getCreatedAtAttribute($value): string |
||||
|
{ |
||||
|
return get_datetime('date_time', strtotime($value)); |
||||
|
} |
||||
|
|
||||
|
public function getConfirmAtAttribute($value): string |
||||
|
{ |
||||
|
return is_null($value) |
||||
|
? '' |
||||
|
: get_datetime('date_time', strtotime($value)); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Models; |
||||
|
|
||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory; |
||||
|
use Illuminate\Database\Eloquent\Model; |
||||
|
|
||||
|
class ParkingSpace extends Model |
||||
|
{ |
||||
|
use HasFactory; |
||||
|
|
||||
|
protected $table = 'parking_space'; |
||||
|
|
||||
|
protected $fillable |
||||
|
= [ |
||||
|
'floor_id', |
||||
|
'number', |
||||
|
'space_attr_id', |
||||
|
'license_plate_id', |
||||
|
'berthing_time', |
||||
|
'recognition', |
||||
|
'status', |
||||
|
'space_type_id', |
||||
|
'operation_type' |
||||
|
]; |
||||
|
|
||||
|
protected $hidden |
||||
|
= [ |
||||
|
'created_at' |
||||
|
]; |
||||
|
|
||||
|
|
||||
|
public function getUpdatedAtAttribute($value): string |
||||
|
{ |
||||
|
return is_null($value) |
||||
|
? '' |
||||
|
: get_datetime( |
||||
|
'date_time', |
||||
|
strtotime($value) |
||||
|
); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Services; |
||||
|
|
||||
|
class BaseService |
||||
|
{ |
||||
|
/** |
||||
|
* @var OperationLogService |
||||
|
*/ |
||||
|
protected OperationLogService $logService; |
||||
|
|
||||
|
/** |
||||
|
* 构造函数 |
||||
|
* @param OperationLogService $logService |
||||
|
*/ |
||||
|
public function __construct(OperationLogService $logService) |
||||
|
{ |
||||
|
$this->logService = $logService; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,73 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Services; |
||||
|
|
||||
|
use App\Models\ParkingReservation; |
||||
|
use App\Models\ParkingSpace; |
||||
|
|
||||
|
class ParkingReservationService extends BaseService |
||||
|
{ |
||||
|
/** |
||||
|
* @var string[] |
||||
|
*/ |
||||
|
public array $statusArr = ['undetermined', 'confirmed', 'canceled']; |
||||
|
|
||||
|
public array $isDriver = ['no', 'yes']; |
||||
|
|
||||
|
/** |
||||
|
* 返回翻译后的状态 |
||||
|
* @param $status |
||||
|
* @return string |
||||
|
*/ |
||||
|
public function getStatusStr($status): string |
||||
|
{ |
||||
|
$value = $this->statusArr[$status] ?? ''; |
||||
|
if ($value) { |
||||
|
return __('service.reservation.' . $value); |
||||
|
} |
||||
|
return $value; |
||||
|
} |
||||
|
|
||||
|
public function getStatusArr(): array |
||||
|
{ |
||||
|
$arr = []; |
||||
|
foreach ($this->statusArr as $key => $value) { |
||||
|
$arr[$key] = __('service.reservation.' . $value); |
||||
|
} |
||||
|
return $arr; |
||||
|
} |
||||
|
|
||||
|
public function getIsDriver($is_driver): string |
||||
|
{ |
||||
|
$value = $this->isDriver[$is_driver] ?? ''; |
||||
|
if ($value) { |
||||
|
return __('service.reservation.' . $value); |
||||
|
} |
||||
|
return $value; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $start |
||||
|
* @param string $end |
||||
|
* @return int |
||||
|
*/ |
||||
|
public function getCount(string $start, string $end): int |
||||
|
{ |
||||
|
return ParkingReservation::query()->whereBetween( |
||||
|
'confirm_at', |
||||
|
[$start, $end] |
||||
|
)->where('status', 1)->count(); |
||||
|
} |
||||
|
|
||||
|
public function getBePresentCount(string $start, string $end): int |
||||
|
{ |
||||
|
$license_plate_id_arr = ParkingReservation::query()->whereBetween( |
||||
|
'confirm_at', |
||||
|
[$start, $end] |
||||
|
)->where('status', 1)->pluck('license_plate_id'); |
||||
|
return ParkingSpace::query()->whereIn( |
||||
|
'license_plate_id', |
||||
|
$license_plate_id_arr |
||||
|
)->count(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,150 @@ |
|||||
|
<?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 Exception; |
||||
|
use Illuminate\Database\Eloquent\Builder; |
||||
|
use Illuminate\Support\Facades\DB; |
||||
|
|
||||
|
class ParkingSpaceService extends BaseService |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* @var string[] |
||||
|
*/ |
||||
|
protected array $statusArr = ['vacant', 'occupy']; |
||||
|
protected array $operationType |
||||
|
= [ |
||||
|
'', |
||||
|
'no_cars', |
||||
|
'yes_cars', |
||||
|
'number_update' |
||||
|
]; |
||||
|
|
||||
|
public function __construct(OperationLogService $logService) |
||||
|
{ |
||||
|
parent::__construct($logService); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 返回翻译后的状态 |
||||
|
* @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) { |
||||
|
return __('service.parking_space.' . $recognition); |
||||
|
} |
||||
|
return '-'; |
||||
|
} |
||||
|
|
||||
|
public function getOperationType($operation_type): string |
||||
|
{ |
||||
|
$value = $this->operationType[$operation_type] ?? ''; |
||||
|
if ($value) { |
||||
|
return __('service.parking_space.' . $value); |
||||
|
} |
||||
|
return '-'; |
||||
|
} |
||||
|
|
||||
|
public function getStatusArr(): array |
||||
|
{ |
||||
|
$arr = []; |
||||
|
foreach ($this->statusArr as $key => $value) { |
||||
|
$arr[$key] = __('service.parking_space.' . $value); |
||||
|
} |
||||
|
return $arr; |
||||
|
} |
||||
|
|
||||
|
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); |
||||
|
|
||||
|
$str = $key == 'space_type_id' ? '类型' : '属性'; |
||||
|
|
||||
|
$newValue = $oldValues; |
||||
|
$newValue[$key] = $data_id; |
||||
|
$newValue['updated_at'] = $updateData['updated_at']; |
||||
|
|
||||
|
$this->logService->logUpdatedData( |
||||
|
new ParkingSpace(), |
||||
|
$oldValues, |
||||
|
"更新车位" . $str, |
||||
|
$newValue |
||||
|
); |
||||
|
DB::commit(); |
||||
|
return $model; |
||||
|
} catch (Exception $e) { |
||||
|
DB::rollBack(); |
||||
|
throw $e; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
<?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_reservation', function (Blueprint $table) { |
||||
|
$table->id(); |
||||
|
$table->string('reserve_id', 12)->comment('预定编号'); |
||||
|
$table->integer('space_type_id')->comment('车位类型'); |
||||
|
$table->integer('license_plate_type')->comment('车牌类型'); |
||||
|
$table->integer('license_plate_id')->comment('车牌号码ID'); |
||||
|
$table->tinyInteger('is_driver')->default(0)->comment('是否登记司机'); |
||||
|
$table->integer('floor_id')->nullable()->comment('楼层ID'); |
||||
|
$table->integer('floor_region_id')->nullable()->comment('楼层区域ID'); |
||||
|
$table->tinyInteger('status')->default(0)->comment('状态 0待确定 1已确定 2已取消'); |
||||
|
$table->timestamp('confirm_at')->nullable()->comment('确定时间'); |
||||
|
$table->timestamps(); |
||||
|
$table->comment('车位预定列表'); |
||||
|
$table->innoDb(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Reverse the migrations. |
||||
|
*/ |
||||
|
public function down(): void |
||||
|
{ |
||||
|
Schema::dropIfExists('parking_reservation'); |
||||
|
} |
||||
|
}; |
||||
@ -0,0 +1,36 @@ |
|||||
|
<?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_space', function (Blueprint $table) { |
||||
|
$table->id(); |
||||
|
$table->integer('floor_id')->comment('楼层id'); |
||||
|
$table->string('number', 50)->default('')->comment('车位号码'); |
||||
|
$table->integer('space_attr_id')->comment('车位属性id'); |
||||
|
$table->integer('license_plate_id')->nullable()->comment('车牌号码'); |
||||
|
$table->timestamp('berthing_time')->nullable()->comment('停泊时间'); |
||||
|
$table->string('recognition', 50)->default('')->nullable()->comment('车牌识别度'); |
||||
|
$table->tinyInteger('status')->default(0)->comment('状态 0空置 1占用'); |
||||
|
$table->integer('space_type_id')->comment('车位类型id'); |
||||
|
$table->tinyInteger('operation_type')->default(0)->comment('操作类型'); |
||||
|
$table->timestamps(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Reverse the migrations. |
||||
|
*/ |
||||
|
public function down(): void |
||||
|
{ |
||||
|
Schema::dropIfExists('parking_space'); |
||||
|
} |
||||
|
}; |
||||
Loading…
Reference in new issue