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'); |
|||
} |
|||
}; |
|||
@ -1,15 +1,28 @@ |
|||
<?php |
|||
return [ |
|||
'vip_list' => [ |
|||
'license' => '车牌号码', |
|||
'vip_list' => [ |
|||
'license' => '车牌号码', |
|||
'import_template' => 'VIP名单导入模板', |
|||
'list' => 'VIP名单' |
|||
'list' => 'VIP名单' |
|||
], |
|||
'global' => [ |
|||
'global' => [ |
|||
'index' => '序号', |
|||
'admin' => '操作员' |
|||
], |
|||
'license_plate' => [ |
|||
'import_template' => '车牌管理导入模板' |
|||
], |
|||
'parking_space' => [ |
|||
'list' => '车位列表', |
|||
'floor' => '楼层', |
|||
'number' => '车位号码', |
|||
'space_attr' => '车位属性', |
|||
'license_plate' => '车牌号码', |
|||
'berthing_time' => '停泊时间', |
|||
'recognition' => '车牌识别度', |
|||
'status' => '状态', |
|||
'space_type' => '车位类型', |
|||
'operation_type' => '操作类型', |
|||
'updated_at' => '最后更新时间', |
|||
] |
|||
]; |
|||
|
|||
Loading…
Reference in new issue