car/application/admin/controller/Dashboard.php
2025-08-29 16:56:03 +08:00

246 lines
7.5 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\admin\controller;
use app\admin\model\Admin;
use app\admin\model\car\Sales;
use app\admin\model\User;
use app\common\controller\Backend;
use app\common\model\Attachment;
use fast\Date;
use think\Db;
use function Symfony\Component\Clock\now;
/**
* 控制台
*
* @icon fa fa-dashboard
* @remark 用于展示当前系统中的统计数据、统计报表及重要实时数据
*/
class Dashboard extends Backend
{
/**
* 查看
*/
public function index()
{
$start = now()->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);
}
}