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
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
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|