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

208 lines
6.2 KiB

<?php
namespace App\Console\Commands;
use App\Models\ParkingAccessRecord;
use App\Models\ParkingSpace;
use App\Models\ParkingSpaceType;
use App\Models\ParkingUtilizationRate;
use App\Services\ParkingOccupancyRateService;
use Exception;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class CreateParkingUtilizationRate extends Command
{
/**
* The name and signature of the console command.
* @var string
*/
protected $signature = 'run:create-parking-utilization-rate';
/**
* The console command description.
* @var string
*/
protected $description = 'Command description';
/**
* Execute the console command.
*/
public function handle()
{
//
try {
DB::beginTransaction();
// 每小时统计一次使用率
$start_time = date("Y-m-d H:00:00", strtotime('-1 hours'));
$end_time = date("Y-m-d H:00:00", time());
// 每天统计一次使用率
$now_hours = date('H');
$day_start_time = date("Y-m-d 00:00:00", strtotime('-1 day'));
$day_end_time = date("Y-m-d 00:00:00", time());
$ParkingSpaceIds = ParkingSpace::query()->pluck('id');
if ($ParkingSpaceIds) {
foreach ($ParkingSpaceIds as $space_id) {
// 小时
$this->createRate($start_time, $end_time, $space_id);
// 天
if ($now_hours == '01') {
$this->createRate(
$day_start_time,
$day_end_time,
$space_id,
2
);
}
}
}
$ParkingSpaceTypeIds = ParkingSpaceType::query()->pluck('id');
foreach ($ParkingSpaceTypeIds as $space_type_id) {
$this->createOccupancyRate(
$start_time,
$end_time,
$space_type_id
);
if ($now_hours == '01') {
$this->createOccupancyRate(
$day_start_time,
$day_end_time,
$space_type_id,
2
);
}
}
DB::commit();
} catch (Exception $e) {
DB::rollBack();
dd($e);
}
}
private function createRate(
$start_time,
$end_time,
$space_id,
$date_type = 1
) {
$where = [
'start_time' => $start_time,
'end_time' => $end_time,
'space_id' => $space_id,
'date_type' => $date_type
];
if (!ParkingUtilizationRate::query()->where($where)->exists()
) {
$create = $where;
$create['rate'] = $this->getRate(
$start_time,
$end_time,
$space_id,
$date_type
);
$create['created_at'] = date("Y-m-d H:i:s", time());
ParkingUtilizationRate::query()->create($create);
}
}
private function getRate(
$start_time,
$end_time,
$space_id,
$date_type
): string {
$rate = 0;
$sumSecond = 3600;
if ($date_type == 2) {
$sumSecond = 3600 * 24;
}
$start_times = strtotime($start_time);
$end_times = strtotime($end_time);
$model = ParkingAccessRecord::query()->where('space_id', $space_id)
->where(
function ($query) use ($start_times, $end_times) {
$query->whereRaw(
" enter_time < {$end_times}"
.
" AND (leave_time IS NULL OR leave_time > {$start_times})"
);
}
)->select(['enter_time', 'leave_time'])->get();
if ($model) {
$list = $model->toArray();
foreach ($list as $item) {
$enter_time = strtotime($item['enter_time']);
$leave_time = $item['leave_time'] ? strtotime(
$item['leave_time']
) : $end_times;
if ($enter_time < $start_times) {
$enter_time = $start_times;
}
if ($leave_time > $end_times) {
$leave_time = $end_times;
}
$second = $leave_time - $enter_time;
if ($second > 0) {
$rate = round($second / $sumSecond, 4);
}
}
}
return $rate * 100;
}
private function createOccupancyRate(
$start_time,
$end_time,
$space_type_id,
$time_type = 1
) {
$start_times = strtotime($start_time);
$end_times = strtotime($end_time);
$list = ParkingSpace::query()->where(
'space_type_id',
$space_type_id
)->select(['floor_id', 'id'])->get()->toArray();
$floor_data = [];
foreach ($list as $item) {
$floor_data[$item['floor_id']][] = $item['id'];
}
foreach ($floor_data as $floor_id => $space_ids) {
$sum_count = count($space_ids);
$occupy_space_ids = ParkingAccessRecord::query()->whereIn(
'space_id',
$space_ids
)->where(
function ($query) use ($start_times, $end_times) {
$query->whereRaw(
" enter_time < {$end_times}"
.
" AND (leave_time IS NULL OR leave_time > {$start_times})"
);
}
)->pluck('space_id')->toArray();
$unique_space_ids = array_unique($occupy_space_ids);
$occupy_count = count($unique_space_ids);
ParkingOccupancyRateService::createData(
$space_type_id,
$floor_id,
$start_time,
$sum_count,
$occupy_count,
$time_type
);
}
}
}