217 lines
8.0 KiB
PHP
217 lines
8.0 KiB
PHP
<?php
|
||
|
||
namespace App\Services\Admin;
|
||
|
||
use App\Models\Device;
|
||
use App\Models\MonitorMode;
|
||
use App\Models\{MeteorologicalDailyReport, MeteorologicalReport, SoilDailyReport, SoilReport};
|
||
use App\Filters\Admin\DeviceFilter;
|
||
use Carbon\Carbon;
|
||
use App\Admin\Components;
|
||
/**
|
||
* @method Device getModel()
|
||
* @method Device|\Illuminate\Database\Query\Builder query()
|
||
*/
|
||
class DeviceService extends BaseService
|
||
{
|
||
protected string $modelName = Device::class;
|
||
|
||
protected array $withRelationships = ['factory'];
|
||
|
||
protected string $modelFilterName = DeviceFilter::class;
|
||
|
||
public function list()
|
||
{
|
||
$query = $this->listQuery();
|
||
|
||
$items = (clone $query)->paginate(request()->input('perPage', 20))->items();
|
||
$base = settings()->get('rtsp_url');
|
||
if (request('_type') == Device::TYPE_MONITOR) {
|
||
$history = request('_mode') === 'history';
|
||
$date = explode(',', request('date'));
|
||
$start = data_get($date, 0);
|
||
$end = data_get($date, 1);
|
||
foreach ($items as &$item) {
|
||
$url = data_get($item->extends, $history ? 'rtsp_history' : 'rtsp_url');
|
||
$src = null;
|
||
if ($base && $url) {
|
||
// 查看历史监控
|
||
if ($history && $start && $end) {
|
||
$url .= '?start=' . date('Y-m-d', $start) . '&end=' . data('Y-m-d', $end);
|
||
}
|
||
$src = $base . base64_encode($url);
|
||
}
|
||
$item->src = $src;
|
||
}
|
||
}
|
||
$total = (clone $query)->count();
|
||
|
||
return compact('items', 'total');
|
||
}
|
||
|
||
/**
|
||
* 根据时间,处理X轴横坐标
|
||
*/
|
||
public function makeChartXkeys($startTime = null, $endTime = null){
|
||
$diffDays = 0;
|
||
$day = date('Y-m-d');
|
||
$xKeys = [];
|
||
if($startTime && $endTime){
|
||
if($startTime == $endTime){//查询某一天
|
||
$day = $startTime;
|
||
}else{
|
||
$startDay = Carbon::parse($startTime);
|
||
$endDay = Carbon::parse($endTime);
|
||
$diffDays = $startDay->diffInDays($endDay, false);
|
||
}
|
||
}
|
||
|
||
$xKeys = [];
|
||
if($diffDays){
|
||
for ($i = 0; $i<=$diffDays; $i++) {
|
||
$xKeys[] =(clone $startDay)->addDays($i)->startOfDay()->format('Y-m-d');
|
||
}
|
||
}else{
|
||
//调整截至到当前小时
|
||
$h = 23;
|
||
if($day == date('Y-m-d')){
|
||
$h = date('H');
|
||
}
|
||
for ($i = 0; $i < ($h+1); $i++) {
|
||
$xKeys[] = str_pad($i, 2, '0', STR_PAD_LEFT).':00';
|
||
}
|
||
}
|
||
|
||
return array($day, $diffDays, $xKeys);
|
||
}
|
||
|
||
public function getMonitorModeDeviceChartConfig($monitorMode, $startTime, $endTime, $columnNum = 3)
|
||
{
|
||
list($day, $diffDays, $xKeys) = $this->makeChartXkeys($startTime, $endTime);
|
||
switch($monitorMode->type){
|
||
case MonitorMode::TYPE_METEOROLOGICAL:
|
||
$dayliyReportQuery = MeteorologicalDailyReport::query();
|
||
$reportQuery = MeteorologicalReport::query();
|
||
$fieldNameMap = MonitorMode::fieldMap(MonitorMode::TYPE_METEOROLOGICAL);
|
||
$fieldUnitMap = MonitorMode::fieldUnitMap(MonitorMode::TYPE_METEOROLOGICAL);
|
||
break;
|
||
case MonitorMode::TYPE_SOIL:
|
||
$dayliyReportQuery = SoilDailyReport::query();
|
||
$reportQuery = SoilReport::query();
|
||
$fieldNameMap = MonitorMode::fieldMap(MonitorMode::TYPE_SOIL);
|
||
$fieldUnitMap = MonitorMode::fieldUnitMap(MonitorMode::TYPE_SOIL);
|
||
break;
|
||
}
|
||
$monitorMode->load('devices');
|
||
$configData = $fieldMap = [];
|
||
|
||
foreach($monitorMode->devices as $device){
|
||
$_fields = explode(',', $device->pivot->fields);
|
||
|
||
if($diffDays) {
|
||
$modelQuery = $dayliyReportQuery->whereBetween('reported_at', [$startTime, $endTime]);
|
||
}else{
|
||
$modelQuery = $reportQuery->whereDate('reported_at', $day);
|
||
}
|
||
if($modelQuery){
|
||
$datalist = $modelQuery->where('device_id', $device->id)->get()->keyBy('reported_at')->toArray();
|
||
}
|
||
|
||
//组装数据;
|
||
foreach($_fields as $field){
|
||
$_data = [];
|
||
foreach($xKeys as $key){
|
||
if(!$diffDays) {
|
||
$key = date('Y-m-d').' '. $key.':00';
|
||
}else{
|
||
$key .= ' 00:00:00';
|
||
}
|
||
$_data[] = $datalist[$key][$field] ?? 0;
|
||
}
|
||
$fieldMap[$field] = [
|
||
'name' => $fieldNameMap[$field],
|
||
'unit' => $fieldUnitMap[$field],
|
||
'data' => $_data
|
||
];
|
||
}
|
||
}
|
||
|
||
$k = 0;
|
||
$chartArr = [];
|
||
foreach($fieldMap as $key => $field){
|
||
$k++;
|
||
|
||
//特殊字段,特殊统计图;
|
||
switch($key){
|
||
//点状图;
|
||
case 'wind_direction':
|
||
$yData = ['北风','东北风','东风','东南风','南风','西南风','西风','西北风'];
|
||
$_chartCard = amisMake()->Card()->body(
|
||
amisMake()->Chart()->config(
|
||
Components::make()->chartScatterConfig($field['name'], $xKeys,
|
||
[
|
||
'name'=> $field['name'],
|
||
'type' => 'scatter',
|
||
'symbolSize' => 15,
|
||
'data' => array_map(function($item)use($yData){
|
||
return $yData[$item];
|
||
},$field['data']),
|
||
'color' => '#91CC75',
|
||
], $yData
|
||
)
|
||
)
|
||
);
|
||
break;
|
||
//柱状图;
|
||
case 'box_noise':
|
||
case 'pm10':
|
||
case 'pm25':
|
||
case 'box_co2':
|
||
$_chartCard = amisMake()->Card()->body(
|
||
amisMake()->Chart()->config(
|
||
Components::make()->chartLineBarConfig($field['name'], $xKeys, [
|
||
[
|
||
'name'=> $field['name'],
|
||
'type' => 'bar',
|
||
'data' => $field['data'],
|
||
'color' => '#91CC75',
|
||
'unit' => $field['unit']
|
||
]
|
||
])
|
||
)
|
||
);
|
||
break;
|
||
default://折线图
|
||
$_chartCard = amisMake()->Card()->body(
|
||
amisMake()->Chart()->config(
|
||
Components::make()->chartLineBarConfig($field['name'], $xKeys, [
|
||
[
|
||
'name'=> $field['name'],
|
||
'type' => 'line',
|
||
'data' => $field['data'],
|
||
'color' => '#91CC75',
|
||
'unit' => $field['unit']
|
||
]
|
||
])
|
||
)
|
||
);
|
||
break;
|
||
}
|
||
|
||
if($k%$columnNum != 0){
|
||
$_chartCard->className('m-r');
|
||
}
|
||
$chartArr[] = $_chartCard;
|
||
}
|
||
$i = 0;
|
||
$len = round(count($chartArr)/$columnNum);
|
||
for($i; $i<=$len; $i++){
|
||
$configData[] = \amisMake()->grid()->columns([
|
||
amisMake()->Flex()->items(array_splice($chartArr, 0, $columnNum)),
|
||
]);
|
||
}
|
||
|
||
return $configData;
|
||
}
|
||
}
|