modify('-30 days')->format('Y-m-d'); $end_at = now()->format('Y-m-d'); $default_daterange = $start . ' - ' . $end_at; $this->view->assign('default_daterange', $default_daterange); return $this->view->fetch(); } public function getData() { $start = now()->modify('-30 days')->format('Y-m-d'); $end_at = now()->format('Y-m-d 23:29:59'); $filter = request()->get('range', ''); if (!empty($filter)) { $arr = explode(' - ', $filter); if (trim($arr[0])) { $start = trim($arr[0]) . ' 00:00:00'; } if (trim($arr[1])) { $end_at = trim($arr[1]) . ' 23:29:59'; } } $top = $this->getTopTotal($start, $end_at); $lines = $this->getLines($start, $end_at); $this->success(data: [ 'top' => $top, 'lines' => $lines ]); } private function prepareEchartsBarData(array $data, string $startDate, string $endDate): array { // 将原始数据用日期作为键索引 $indexed = []; foreach ($data as $item) { $indexed[$item['day']] = $item; } $start = strtotime($startDate); $end = strtotime($endDate); $xAxis = []; $series_total = []; $series_count = []; $new_count_array = []; $old_count_array = []; $rent_count_array = []; $new_total_array = []; $old_total_array = []; $rent_total_array = []; for ($date = $start; $date <= $end; $date += 86400) { $day = date('Y-m-d', $date); $xAxis[] = $day; $total = $indexed[$day]['total'] ?? 0; $count = $indexed[$day]['count'] ?? 0; $new_count = $indexed[$day]['new_count'] ?? 0; $old_count = $indexed[$day]['old_count'] ?? 0; $rent_count = $indexed[$day]['rent_count'] ?? 0; $new_total = $indexed[$day]['new_total'] ?? 0; $old_total = $indexed[$day]['old_total'] ?? 0; $rent_total = $indexed[$day]['rent_total'] ?? 0; $series_total[] = $total; $series_count[] = $count; $new_count_array[] = $new_count; $old_count_array[] = $old_count; $rent_count_array[] = $rent_count; $new_total_array[] = $new_total; $old_total_array[] = $old_total; $rent_total_array[] = $rent_total; } $data = [ 'xAxis' => $xAxis, 'series' => [ 'total' => $series_total, 'count' => $series_count, 'new_count' => $new_count_array, 'old_count' => $old_count_array, 'rent_count' => $rent_count_array, 'new_total' => $new_total_array, 'old_total' => $old_total_array, 'rent_total' => $rent_total_array, ], ]; // 判断是否需要按月归档 if (count($data['xAxis']) > 31) { $monthly = []; foreach ($data['xAxis'] as $i => $date) { $month = date('Y-m', strtotime($date)); if (!isset($monthly[$month])) { $monthly[$month] = [ 'total' => 0, 'count' => 0, 'performance' => 0, 'rate_sum' => 0, 'rate_count' => 0, ]; } $monthly[$month]['total'] += $data['series']['total'][$i]; $monthly[$month]['count'] += $data['series']['count'][$i]; $monthly[$month]['performance'] += $data['series']['performance'][$i]; // 处理 rate(字符串,转换为 float) $rate = (float)$data['series']['rate'][$i]; $monthly[$month]['rate_sum'] += $rate; $monthly[$month]['rate_count'] += 1; } // 重新生成 xAxis 和 series $data['xAxis'] = array_keys($monthly); $data['series'] = [ 'total' => [], 'count' => [], 'performance' => [], 'rate' => [] ]; foreach ($monthly as $month => $values) { $data['series']['total'][] = $values['total']; $data['series']['count'][] = $values['count']; $data['series']['performance'][] = $values['performance']; // 平均 rate,保留 2 位小数 $averageRate = $values['rate_count'] > 0 ? $values['rate_sum'] / $values['rate_count'] : 0; $data['series']['rate'][] = number_format($averageRate, 2); } } return $data; } private function getTopTotal($start, $end_at) { $car_num = Db::query('SELECT COUNT(IF(car_type = 1,1,null)) new_car, COUNT(IF(car_type = 3,1,null)) rent_car, COUNT(IF(car_type = 2,1,null)) old_car FROM cars;')[0]; $start = now()->modify('-30 days')->format('Y-m-d'); $end_at = now()->format('Y-m-d 23:29:59'); $filter = request()->get('range', ''); if (!empty($filter)) { $arr = explode(' - ', $filter); if (trim($arr[0])) { $start = trim($arr[0]) . ' 00:00:00'; } if (trim($arr[1])) { $end_at = trim($arr[1]) . ' 23:29:59'; } } $build = new Sales(); $build->whereBetween('finish_at', [$start, $end_at]); $group = \model('auth_group_access')->where('uid', $this->auth->id)->find()->group_id ?? 0; if (!in_array($group, [1, 2])) { $build->where('saler_id', $this->auth->id); } $sale = $build->field([ "count(if(type=1,1,null)) new_count", "count(if(type=2,1,null)) old_count", "count(if(type=3,1,null)) rent_count", "sum(if(type=1,total_price,0)) new_sum", "sum(if(type=2,total_price,0)) old_sum", "sum(if(type=3,total_price,0)) rent_sum", "sum(total_price) total_price", ])->select()[0]->toArray(); return [ ...$car_num, ...$sale ]; } private function getLines($start, $end_at) { $build = new Sales(); $build->whereBetween('finish_at', [$start, $end_at]); $res = $build->field([ 'DATE(finish_at) day', "count(if(type=1,1,null)) new_count", "count(if(type=2,1,null)) old_count", "count(if(type=3,1,null)) rent_count", "sum(if(type=1,total_price,0)) new_total", "sum(if(type=2,total_price,0)) old_total", "sum(if(type=3,total_price,0)) rent_total", 'sum(total_price) total', 'count(id) count', ])->group('DATE(finish_at)') ->select(); $data = []; foreach ($res as $re) { $re = $re->getData(); $data [] = $re; } return $this->prepareEchartsBarData($data, $start, $end_at); } }