246 lines
7.5 KiB
PHP
246 lines
7.5 KiB
PHP
<?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);
|
||
}
|
||
|
||
}
|