174 行
6.5 KiB
PHP
174 行
6.5 KiB
PHP
<?php
|
|
|
|
namespace app\admin\controller;
|
|
|
|
use app\admin\model\Appeal;
|
|
use app\admin\model\Master;
|
|
use app\admin\model\Merchant;
|
|
use app\admin\model\Order;
|
|
use app\admin\model\Service;
|
|
use app\admin\model\User;
|
|
use app\admin\model\Withdraw;
|
|
use app\common\controller\Backend;
|
|
use think\Db;
|
|
|
|
/**
|
|
* 优匠优服数字化运营指挥中心(数据大盘首页)
|
|
*
|
|
* @icon fa fa-tachometer
|
|
* @remark 平台核心业务数据大屏,实时监控订单履约、资金流水、运力健康度与待办预警
|
|
*/
|
|
class Home extends Backend
|
|
{
|
|
|
|
public function index()
|
|
{
|
|
try {
|
|
Db::execute("SET @@sql_mode='';");
|
|
} catch (\Exception $e) {
|
|
|
|
}
|
|
|
|
// 1. 时间范围定义
|
|
$todayStart = strtotime(date('Y-m-d 00:00:00'));
|
|
$todayEnd = strtotime(date('Y-m-d 23:59:59'));
|
|
$monthStart = strtotime(date('Y-m-01 00:00:00'));
|
|
|
|
// 2. 核心经营 KPI (真实数据聚合)
|
|
$totalOrder = Order::count();
|
|
$totalGmv = (float)(Order::sum('pay_amount') ?: 0);
|
|
$avgTicket = $totalOrder > 0 ? round($totalGmv / $totalOrder, 2) : 0;
|
|
|
|
$todayOrderCount = Order::whereBetween('createtime', [$todayStart, $todayEnd])->count();
|
|
$todayGmv = (float)(Order::whereBetween('pay_time', [$todayStart, $todayEnd])->sum('pay_amount') ?: 0);
|
|
$monthGmv = (float)(Order::whereBetween('pay_time', [$monthStart, $todayEnd])->sum('pay_amount') ?: 0);
|
|
|
|
// 运力与商户统计
|
|
$totalMaster = Master::where('verify_status', 'pass')->count();
|
|
$onlineMaster = Master::where('work_status', 'on')->count();
|
|
$totalMerchant = Merchant::where('verify_status', 'pass')->count();
|
|
$totalUser = User::count();
|
|
|
|
// 3. 订单状态分布与履约漏斗
|
|
$statusCounts = Order::field('status, count(*) as cnt')
|
|
->group('status')
|
|
->select();
|
|
$statusCountMap = [];
|
|
foreach ($statusCounts as $s) {
|
|
$statusCountMap[$s['status']] = (int)$s['cnt'];
|
|
}
|
|
|
|
$unpaidCount = $statusCountMap[0] ?? 0;
|
|
$waitDispatchCount = $statusCountMap[1] ?? 0;
|
|
$inServiceCount = ($statusCountMap[3] ?? 0) + ($statusCountMap[6] ?? 0);
|
|
$doneCount = $statusCountMap[8] ?? 0;
|
|
$afterSaleCount = $statusCountMap[10] ?? 0;
|
|
|
|
// 4. 实时待办预警与风控中心
|
|
$pendingMaster = Master::where('verify_status', 'pending')->count();
|
|
$waitingAppeal = Appeal::where('status', 'wait')->count();
|
|
$waitingWithdraw = Withdraw::where('status', 'wait')->count();
|
|
$pendingDispatch = $waitDispatchCount;
|
|
|
|
// 5. 近 7 天订单趋势与 GMV 流水 (双轴图表数据)
|
|
$dateColumns = [];
|
|
$orderCounts = [];
|
|
$orderAmounts = [];
|
|
for ($i = 6; $i >= 0; $i--) {
|
|
$date = date('Y-m-d', strtotime("-$i days"));
|
|
$dateColumns[] = date('m-d', strtotime("-$i days"));
|
|
$dayStart = strtotime($date . ' 00:00:00');
|
|
$dayEnd = strtotime($date . ' 23:59:59');
|
|
|
|
$cnt = Order::whereBetween('createtime', [$dayStart, $dayEnd])->count();
|
|
$amt = Order::whereBetween('createtime', [$dayStart, $dayEnd])->sum('pay_amount') ?: 0;
|
|
|
|
$orderCounts[] = (int)$cnt;
|
|
$orderAmounts[] = round((float)$amt, 2);
|
|
}
|
|
|
|
// 6. 服务品类与运力健康指标
|
|
$masterAvg = Db::name('master')
|
|
->where('verify_status', 'pass')
|
|
->field('ROUND(AVG(score), 1) as avg_score, ROUND(AVG(accept_rate), 1) as avg_accept, ROUND(AVG(ontime_rate), 1) as avg_ontime')
|
|
->find();
|
|
|
|
$totalService = Service::count();
|
|
$totalCategory = Db::name('service_cat')->count();
|
|
|
|
// 7. 环形状态分布数据
|
|
$statusDisplayNames = [
|
|
0 => '待支付',
|
|
1 => '待接单',
|
|
2 => '报价中',
|
|
3 => '已接单',
|
|
4 => '待上门',
|
|
5 => '已到达',
|
|
6 => '服务中',
|
|
7 => '待验收',
|
|
8 => '已完成',
|
|
9 => '已取消',
|
|
10 => '售后中',
|
|
];
|
|
$statusChartData = [];
|
|
foreach ($statusCountMap as $stKey => $val) {
|
|
$statusChartData[] = [
|
|
'name' => $statusDisplayNames[$stKey] ?? ('状态' . $stKey),
|
|
'value' => $val,
|
|
];
|
|
}
|
|
|
|
// 8. 最新动态订单
|
|
$recentOrders = Db::name('order')
|
|
->alias('o')
|
|
->join('user u', 'o.user_id = u.id', 'LEFT')
|
|
->field('o.id, o.order_no, o.service_name, o.pay_amount, o.status, o.createtime, u.nickname as user_name')
|
|
->order('o.id', 'desc')
|
|
->limit(6)
|
|
->select();
|
|
|
|
$this->view->assign([
|
|
'totalOrder' => $totalOrder,
|
|
'totalGmv' => number_format($totalGmv, 2, '.', ','),
|
|
'avgTicket' => number_format($avgTicket, 2, '.', ''),
|
|
'todayOrderCount' => $todayOrderCount,
|
|
'todayGmv' => number_format($todayGmv, 2, '.', ','),
|
|
'monthGmv' => number_format($monthGmv, 2, '.', ','),
|
|
|
|
'totalMaster' => $totalMaster,
|
|
'onlineMaster' => $onlineMaster,
|
|
'totalMerchant' => $totalMerchant,
|
|
'totalUser' => $totalUser,
|
|
|
|
'unpaidCount' => $unpaidCount,
|
|
'waitDispatchCount' => $waitDispatchCount,
|
|
'inServiceCount' => $inServiceCount,
|
|
'doneCount' => $doneCount,
|
|
'afterSaleCount' => $afterSaleCount,
|
|
|
|
'pendingMaster' => $pendingMaster,
|
|
'waitingAppeal' => $waitingAppeal,
|
|
'waitingWithdraw' => $waitingWithdraw,
|
|
'pendingDispatch' => $pendingDispatch,
|
|
|
|
'masterAvgScore' => $masterAvg['avg_score'] ?: '5.0',
|
|
'masterAvgAccept' => $masterAvg['avg_accept'] ?: '100',
|
|
'masterAvgOntime' => $masterAvg['avg_ontime'] ?: '100',
|
|
|
|
'totalService' => $totalService,
|
|
'totalCategory' => $totalCategory,
|
|
'recentOrders' => $recentOrders,
|
|
'systemClock' => date('Y-m-d H:i:s'),
|
|
]);
|
|
|
|
// ECharts 配置注入
|
|
$this->assignconfig('dateColumns', $dateColumns);
|
|
$this->assignconfig('orderCounts', $orderCounts);
|
|
$this->assignconfig('orderAmounts', $orderAmounts);
|
|
$this->assignconfig('statusChartData', $statusChartData);
|
|
$this->assignconfig('totalOrder', $totalOrder);
|
|
|
|
return $this->view->fetch();
|
|
}
|
|
}
|