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){ $startDay = Carbon::parse($startTime); $endDay = Carbon::parse($endTime); if($startDay->format('Y-m-d') == $endDay->format('Y-m-d')){//判断是否同一天 $day = $startDay->format('Y-m-d'); }else{ $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{ //调整截至到当前小时 $th = $startDay->format('H'); $eh = $endDay->format('H');; if($day == date('Y-m-d')){ if($eh > date('H')){ $eh = date('H'); } } for ($i = $th; $i < ($eh+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; } public function getMonitorModeDeviceData($monitorMode, $startTime, $endTime) { 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'); $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, 'xkeys'=> $xKeys ]; } } return $fieldMap; } }