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.
223 lines
6.4 KiB
223 lines
6.4 KiB
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\AdminFloor;
|
|
use App\Models\Parking;
|
|
use App\Models\ParkingChannel;
|
|
use App\Models\ParkingReservation;
|
|
use App\Models\ParkingSpace;
|
|
|
|
class ParkingReservationService extends BaseService
|
|
{
|
|
/**
|
|
* @var string[]
|
|
*/
|
|
public array $statusArr = ['undetermined', 'confirmed', 'canceled'];
|
|
|
|
/**
|
|
* @var string[]
|
|
*/
|
|
public array $licensePlateTypeArr
|
|
= [
|
|
1 => 'fuel',
|
|
2 => 'new_energy'
|
|
];
|
|
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* 返回翻译后的状态
|
|
* @param $licensePlateType
|
|
* @return string
|
|
*/
|
|
public function getLicensePlateTypeStr($licensePlateType): string
|
|
{
|
|
$value = $this->licensePlateTypeArr[$licensePlateType] ?? '';
|
|
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();
|
|
}
|
|
|
|
// 创建预约
|
|
public function createData($data)
|
|
{
|
|
$reserve_id = $this->getReserveId();
|
|
$customer_id = $this->getCustomerId();
|
|
$member_id = $this->getMemberId();
|
|
$member_type = $this->getMemberType();
|
|
$license_plate_id = (new ParkingLicensePlateService(
|
|
$this->logService
|
|
))->createLicenseId($data['license_plate']);
|
|
$create = [
|
|
'reserve_id' => $reserve_id,
|
|
'license_plate_type' => 1,
|
|
'license_plate_id' => $license_plate_id,
|
|
'is_driver' => $data['is_driver'],
|
|
'floor_id' => $data['floor_id'],
|
|
'floor_region_id' => $data['floor_region_id'],
|
|
'status' => 0,
|
|
'created_at' => get_datetime(),
|
|
'space_attr_id' => $data['space_attr_id'],
|
|
'space_type_id' => $data['space_type_id'],
|
|
'customer_id' => $customer_id,
|
|
'member_id' => $member_id,
|
|
'channel_id' => $data['channel_id'],
|
|
'member_type' => $member_type,
|
|
'parking_id' => $data['parking_id'],
|
|
'remark' => $data['remark'] ?? '',
|
|
'date' => $data['date'],
|
|
];
|
|
$model = ParkingReservation::query()->create($create);
|
|
return [
|
|
'parking' => Parking::getName($data['parking_id']),
|
|
'channel' => ParkingChannel::getName($data['channel_id']),
|
|
'floor' => AdminFloor::getName($data['floor_id']),
|
|
'date' => $data['date'],
|
|
'reserve_time' => $create['created_at'],
|
|
'id' => $reserve_id,
|
|
];
|
|
}
|
|
|
|
protected function getReserveId()
|
|
{
|
|
$id = $this->generateAppointmentNo('CPB', 9);
|
|
if (ParkingReservation::query()->where('reserve_id', $id)->exists()) {
|
|
return $this->getReserveId();
|
|
}
|
|
return $id;
|
|
}
|
|
|
|
/**
|
|
* 生成预约编号
|
|
* @param string $prefix 前缀,例如 'YY'、'BK'
|
|
* @param int $digitLength 后面随机数字的位数
|
|
* @param callable|null $isUnique 唯一性检查回调,返回 true 表示该编号未被占用
|
|
* @param int $maxAttempts 最大重试次数
|
|
* @return string
|
|
*/
|
|
protected function generateAppointmentNo(
|
|
string $prefix = '',
|
|
int $digitLength = 6,
|
|
?callable $isUnique = null,
|
|
int $maxAttempts = 100
|
|
): string {
|
|
for ($attempt = 0; $attempt < $maxAttempts; $attempt++) {
|
|
$digits = '';
|
|
|
|
// 逐位生成随机数字,支持前导 0
|
|
for ($i = 0; $i < $digitLength; $i++) {
|
|
try {
|
|
$digits .= random_int(0, 9);
|
|
} catch (\Exception $e) {
|
|
}
|
|
}
|
|
|
|
$no = $prefix . $digits;
|
|
|
|
// 如果没有传入唯一性检查,直接返回
|
|
if ($isUnique === null || $isUnique($no)) {
|
|
return $no;
|
|
}
|
|
}
|
|
return '';
|
|
}
|
|
|
|
protected function getCustomerId()
|
|
{
|
|
return $this->generateAppointmentNo('CUST');
|
|
}
|
|
|
|
protected function getMemberId()
|
|
{
|
|
return $this->generateAppointmentNo('M');
|
|
}
|
|
|
|
protected function getMemberType()
|
|
{
|
|
$arr = ParkingAdminUserService::$memberType;
|
|
$rand = rand(1, 11);
|
|
return array_search($arr[$rand], $arr);
|
|
}
|
|
|
|
// 确认预约
|
|
|
|
public function confirm($id)
|
|
{
|
|
$update = [
|
|
'confirm_at' => get_datetime(),
|
|
'status' => 1
|
|
];
|
|
$update['updated_at'] = $update['confirm_at'];
|
|
ParkingReservation::query()->where('id', $id)->update($update);
|
|
}
|
|
|
|
// 取消预约
|
|
public function cancel($id)
|
|
{
|
|
$update = [
|
|
'cancel_at' => get_datetime(),
|
|
'status' => 2
|
|
];
|
|
$update['updated_at'] = $update['cancel_at'];
|
|
ParkingReservation::query()->where('id', $id)->update($update);
|
|
}
|
|
}
|
|
|