修复内容
This commit is contained in:
@@ -6,6 +6,7 @@ use app\admin\model\OrderRecharge;
|
||||
use app\admin\model\OrderYearcard;
|
||||
use app\admin\model\User;
|
||||
use app\common\server\UrlServer;
|
||||
use think\Db;
|
||||
use think\facade\Url;
|
||||
use app\admin\model\Order;
|
||||
|
||||
@@ -15,6 +16,14 @@ class BulletinBoard extends AdminBase
|
||||
//看板统计
|
||||
public function index()
|
||||
{
|
||||
// 本月与上月时间范围
|
||||
$monthStart = date('Y-m-01 00:00:00');
|
||||
$monthEnd = date('Y-m-t 23:59:59');
|
||||
$lastMonthStart = date('Y-m-01 00:00:00', strtotime('-1 month'));
|
||||
$lastMonthEnd = date('Y-m-t 23:59:59', strtotime('-1 month'));
|
||||
$monthStartTs = strtotime($monthStart);
|
||||
$monthEndTs = strtotime($monthEnd);
|
||||
|
||||
//查询商品订单
|
||||
$orderMoney = Order::where('status','<>', 0)->sum('order_amount');
|
||||
//年卡订单
|
||||
@@ -104,6 +113,243 @@ class BulletinBoard extends AdminBase
|
||||
// 本月注册但没下过单的(新客户)
|
||||
$newCustomerCount = count($monthUsers) - $oldCustomerCount;
|
||||
}
|
||||
|
||||
// ========== 目标完成率与客服进度 ==========
|
||||
// 销售目标(可以后续做成后台可配置,这里先写死为 100000)
|
||||
$monthlyTarget = 100000;
|
||||
$overallCompletion = $monthlyTarget > 0 ? round(($monthlySales / $monthlyTarget) * 100, 2) : 0;
|
||||
|
||||
// 按客服统计本月与上月销售额
|
||||
$staffCurrent = Db::name('order')
|
||||
->alias('o')
|
||||
->join('admin a', 'o.admin_id = a.id', 'LEFT')
|
||||
->where('o.status', '<>', 0)
|
||||
->whereTime('o.create_time', 'between', [$monthStart, $monthEnd])
|
||||
->field('o.admin_id,a.name as staff_name,SUM(o.order_amount) as total')
|
||||
->group('o.admin_id')
|
||||
->select();
|
||||
|
||||
$staffLast = Db::name('order')
|
||||
->alias('o')
|
||||
->join('admin a', 'o.admin_id = a.id', 'LEFT')
|
||||
->where('o.status', '<>', 0)
|
||||
->whereTime('o.create_time', 'between', [$lastMonthStart, $lastMonthEnd])
|
||||
->field('o.admin_id,SUM(o.order_amount) as total')
|
||||
->group('o.admin_id')
|
||||
->select();
|
||||
|
||||
$staffLastMap = [];
|
||||
foreach ($staffLast as $row) {
|
||||
$staffLastMap[$row['admin_id']] = $row['total'];
|
||||
}
|
||||
|
||||
$staffProgress = [];
|
||||
foreach ($staffCurrent as $row) {
|
||||
$adminId = $row['admin_id'];
|
||||
$staffSales = (float)$row['total'];
|
||||
$lastSales = isset($staffLastMap[$adminId]) ? (float)$staffLastMap[$adminId] : 0;
|
||||
$percent = $monthlySales > 0 ? round(($staffSales / $monthlySales) * 100, 2) : 0;
|
||||
$yoy = $lastSales > 0 ? round((($staffSales - $lastSales) / $lastSales) * 100, 2) : 0;
|
||||
|
||||
$staffProgress[] = [
|
||||
'name' => $row['staff_name'] ?: '未分配',
|
||||
'sales' => $staffSales,
|
||||
'percent' => $percent,
|
||||
'yoy' => $yoy,
|
||||
];
|
||||
}
|
||||
|
||||
// ========== 渠道分析(当月订单数按渠道) ==========
|
||||
$channelRows = Db::name('order')
|
||||
->alias('o')
|
||||
->join('orderchannel c', 'o.channel_id = c.id', 'LEFT')
|
||||
->where('o.status', '<>', 0)
|
||||
->whereTime('o.create_time', 'month')
|
||||
->field('c.name as channel_name, COUNT(*) as total')
|
||||
->group('o.channel_id')
|
||||
->select();
|
||||
|
||||
$channelPie = [];
|
||||
foreach ($channelRows as $row) {
|
||||
$name = $row['channel_name'] ?: '其他';
|
||||
$value = (int)$row['total'];
|
||||
$channelPie[] = [
|
||||
'name' => $name,
|
||||
'value' => $value,
|
||||
];
|
||||
}
|
||||
|
||||
// ========== 每日销售趋势(仅商品订单,按天汇总) ==========
|
||||
$trendRows = Db::name('order')
|
||||
->where('status', '<>', 0)
|
||||
->whereTime('create_time', 'between', [$monthStart, $monthEnd])
|
||||
->field("FROM_UNIXTIME(create_time,'%Y-%m-%d') as day, SUM(order_amount) as total")
|
||||
->group('day')
|
||||
->order('day asc')
|
||||
->select();
|
||||
|
||||
$trendDates = [];
|
||||
$trendValues = [];
|
||||
$trendTotal = 0;
|
||||
foreach ($trendRows as $row) {
|
||||
$trendDates[] = $row['day'];
|
||||
$amount = (float)$row['total'];
|
||||
$trendValues[] = $amount;
|
||||
$trendTotal += $amount;
|
||||
}
|
||||
|
||||
// 上月总销售额(用于计算趋势图上的“上月同比”)
|
||||
$lastTrendTotal = Db::name('order')
|
||||
->where('status', '<>', 0)
|
||||
->whereTime('create_time', 'between', [$lastMonthStart, $lastMonthEnd])
|
||||
->sum('order_amount');
|
||||
|
||||
$trendCompare = $lastTrendTotal > 0 ? round((($trendTotal - $lastTrendTotal) / $lastTrendTotal) * 100, 2) : 0;
|
||||
|
||||
// ========== 区域月销售额(通过地址模糊匹配简单统计) ==========
|
||||
$regions = ['南明区', '云岩区', '白云区', '乌当区', '花溪区', '龙里'];
|
||||
$regionTotals = [];
|
||||
foreach ($regions as $regionName) {
|
||||
$total = Db::name('order')
|
||||
->where('status', '<>', 0)
|
||||
->whereTime('create_time', 'month')
|
||||
->whereLike('address', '%' . $regionName . '%')
|
||||
->sum('order_amount');
|
||||
$regionTotals[] = (float)$total;
|
||||
}
|
||||
|
||||
// ========== 本月销售情况(单次/年卡/次卡/其它服务) ==========
|
||||
// 复用统计图表控制器中的规则:根据 number 字段区分不同卡类型
|
||||
$salesSituation = [
|
||||
['value' => 0, 'name' => '单次服务'],
|
||||
['value' => 0, 'name' => '年卡销量'],
|
||||
['value' => 0, 'name' => '次卡销量'],
|
||||
['value' => 0, 'name' => '其它服务'],
|
||||
];
|
||||
$kaWhere = [
|
||||
['del', '=', 0],
|
||||
['create_time', '>=', $monthStartTs],
|
||||
['create_time', '<=', $monthEndTs],
|
||||
];
|
||||
// 单次服务:number = 1
|
||||
$salesSituation[0]['value'] = Db::name('order')
|
||||
->where($kaWhere)
|
||||
->where('number', '=', 1)
|
||||
->sum('total_amount');
|
||||
// 年卡:number > 6
|
||||
$salesSituation[1]['value'] = Db::name('order')
|
||||
->where($kaWhere)
|
||||
->where('number', '>', 6)
|
||||
->sum('total_amount');
|
||||
// 次卡:2 <= number <= 6
|
||||
$salesSituation[2]['value'] = Db::name('order')
|
||||
->where($kaWhere)
|
||||
->where('number', '>=', 2)
|
||||
->where('number', '<=', 6)
|
||||
->sum('total_amount');
|
||||
// 其它服务:number = 0
|
||||
$salesSituation[3]['value'] = Db::name('order')
|
||||
->where($kaWhere)
|
||||
->where('number', '=', 0)
|
||||
->sum('total_amount');
|
||||
|
||||
// ========== 渠道 & 区域详细拆分(总额 / 年卡 / 次卡 / 单次 / 其它) ==========
|
||||
$serviceTypes = [
|
||||
'total' => [],
|
||||
'year' => [['number', '>', 6]],
|
||||
'times' => [['number', '>=', 2], ['number', '<=', 6]],
|
||||
'single'=> [['number', '=', 1]],
|
||||
'other' => [['number', '=', 0]],
|
||||
];
|
||||
|
||||
// 渠道关键字到列 key 的映射
|
||||
$channelBuckets = [
|
||||
'meituan' => '美团',
|
||||
'gzh' => '公众号',
|
||||
'douyin' => '抖音',
|
||||
'staff' => '员工',
|
||||
'yeye' => '异业',
|
||||
'other' => '渠道',
|
||||
];
|
||||
|
||||
$channelDetail = [];
|
||||
foreach ($serviceTypes as $typeKey => $extraWhere) {
|
||||
$totals = [
|
||||
'meituan' => 0,
|
||||
'gzh' => 0,
|
||||
'douyin' => 0,
|
||||
'staff' => 0,
|
||||
'yeye' => 0,
|
||||
'other' => 0,
|
||||
];
|
||||
|
||||
$query = Db::name('order')
|
||||
->alias('o')
|
||||
->join('orderchannel c', 'o.channel_id = c.id', 'LEFT')
|
||||
->where('o.status', '<>', 0)
|
||||
->whereBetween('o.create_time', [$monthStartTs, $monthEndTs]);
|
||||
|
||||
if (!empty($extraWhere)) {
|
||||
$query->where($extraWhere);
|
||||
}
|
||||
|
||||
$rows = $query
|
||||
->field('c.name as channel_name, SUM(o.order_amount) as total')
|
||||
->group('o.channel_id')
|
||||
->select();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$name = $row['channel_name'] ?? '';
|
||||
$value = (float)($row['total'] ?? 0);
|
||||
$bucket = 'other';
|
||||
if (mb_strpos($name, '美团') !== false) {
|
||||
$bucket = 'meituan';
|
||||
} elseif (mb_strpos($name, '公众号') !== false || mb_strpos($name, '公') !== false) {
|
||||
$bucket = 'gzh';
|
||||
} elseif (mb_strpos($name, '抖音') !== false) {
|
||||
$bucket = 'douyin';
|
||||
} elseif (mb_strpos($name, '员工') !== false) {
|
||||
$bucket = 'staff';
|
||||
} elseif (mb_strpos($name, '异业') !== false) {
|
||||
$bucket = 'yeye';
|
||||
}
|
||||
$totals[$bucket] += $value;
|
||||
}
|
||||
|
||||
$channelDetail[$typeKey] = $totals;
|
||||
}
|
||||
|
||||
// 区域明细:每种服务类型在各区域的销售额
|
||||
$regionDetail = [];
|
||||
foreach ($serviceTypes as $typeKey => $extraWhere) {
|
||||
$regionDetail[$typeKey] = [];
|
||||
foreach ($regions as $regionName) {
|
||||
$q = Db::name('order')
|
||||
->where('status', '<>', 0)
|
||||
->whereBetween('create_time', [$monthStartTs, $monthEndTs])
|
||||
->whereLike('address', '%' . $regionName . '%');
|
||||
if (!empty($extraWhere)) {
|
||||
$q->where($extraWhere);
|
||||
}
|
||||
$regionDetail[$typeKey][$regionName] = (float)$q->sum('order_amount');
|
||||
}
|
||||
}
|
||||
|
||||
// 汇总仪表盘数据供前端使用
|
||||
$dashboardData = [
|
||||
'monthlyTarget' => $monthlyTarget,
|
||||
'overallCompletion' => $overallCompletion,
|
||||
'staffProgress' => $staffProgress,
|
||||
'channelPie' => $channelPie,
|
||||
'trendDates' => $trendDates,
|
||||
'trendValues' => $trendValues,
|
||||
'trendCompare' => $trendCompare,
|
||||
'regions' => $regions,
|
||||
'regionTotals' => $regionTotals,
|
||||
'salesSituation' => $salesSituation,
|
||||
'channelDetail' => $channelDetail,
|
||||
'regionDetail' => $regionDetail,
|
||||
];
|
||||
|
||||
// 传递数据到视图
|
||||
$this->assign([
|
||||
@@ -115,6 +361,7 @@ class BulletinBoard extends AdminBase
|
||||
'customersCompare' => $customersCompare,
|
||||
'oldCustomers' => $oldCustomerCount, // 老客户数量(本月注册且下过单的)
|
||||
'newCustomers' => $newCustomerCount, // 新客户数量(本月注册但没下过单的)
|
||||
'dashboardData' => json_encode($dashboardData, JSON_UNESCAPED_UNICODE),
|
||||
]);
|
||||
|
||||
return $this->fetch();
|
||||
|
||||
Reference in New Issue
Block a user