Files
cunkebao_v3/Server/application/cunkebao/controller/StatsController.php
wong 639d7d3cb6 1
2025-08-15 18:30:03 +08:00

387 lines
14 KiB
PHP
Raw 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\cunkebao\controller;
use think\Db;
use think\Controller;
class StatsController extends Controller
{
const WEEK = [
0 => '周日',
1 => '周一',
2 => '周二',
3 => '周三',
4 => '周四',
5 => '周五',
6 => '周六',
];
/**
* 基础信息
* @return \think\response\Json
*/
public function baseInfoStats()
{
$deviceNum = Db::name('device')->where(['companyId' => $this->request->userInfo['companyId'], 'deleteTime' => 0])->count();
$wechatNum = Db::name('wechat_customer')->where(['companyId' => $this->request->userInfo['companyId']])->count();
$aliveWechatNum = Db::name('wechat_customer')->alias('wc')
->join('device_wechat_login dwl', 'wc.wechatId = dwl.wechatId')
->where(['wc.companyId' => $this->request->userInfo['companyId'], 'dwl.alive' => 1])
->group('wc.wechatId')
->count();
$data = [
'deviceNum' => $deviceNum,
'wechatNum' => $wechatNum,
'aliveWechatNum' => $aliveWechatNum,
];
return successJson($data, '获取成功');
}
/**
* 场景获客统计
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function planStats()
{
$num = $this->request->param('num', 4);
$planScene = Db::name('plan_scene')
->field('id,name,image')
->where(['status' => 1])
->order('sort DESC')
->page(1, $num)
->select();
foreach ($planScene as &$v) {
$allNum = Db::name('customer_acquisition_task')->alias('ac')
->join('task_customer tc', 'tc.task_id = ac.id')
->where(['ac.sceneId' => $v['id'], 'ac.companyId' => $this->request->userInfo['companyId'], 'ac.deleteTime' => 0])
->count();
$addNum = Db::name('customer_acquisition_task')->alias('ac')
->join('task_customer tc', 'tc.task_id = ac.id')
->where(['ac.sceneId' => $v['id'], 'ac.companyId' => $this->request->userInfo['companyId'], 'ac.deleteTime' => 0])
->whereIn('tc.status', [1, 2, 3, 4])
->count();
$passNum = Db::name('customer_acquisition_task')->alias('ac')
->join('task_customer tc', 'tc.task_id = ac.id')
->where(['ac.sceneId' => $v['id'], 'ac.companyId' => $this->request->userInfo['companyId'], 'ac.deleteTime' => 0])
->whereIn('tc.status', [4])
->count();
$v['allNum'] = $allNum;
$v['addNum'] = $addNum;
$v['passNum'] = $passNum;
}
unset($v);
return successJson($planScene, '获取成功');
}
public function todayStats()
{
$date = date('Y-m-d',time());
$start = strtotime($date . ' 00:00:00');
$end = strtotime($date . ' 23:59:59');
$companyId = $this->request->userInfo['companyId'];
$momentsNum = Db::name('workbench')->alias('w')
->join('workbench_moments_sync_item wi', 'w.id = wi.workbenchId')
->where(['w.companyId' => $companyId])
->where('wi.createTime', 'between', [$start, $end])
->count();
$groupPushNum = Db::name('workbench')->alias('w')
->join('workbench_group_push_item wi', 'w.id = wi.workbenchId')
->where(['w.companyId' => $companyId])
->where('wi.createTime', 'between', [$start, $end])
->count();
$addNum = Db::name('customer_acquisition_task')->alias('ac')
->join('task_customer tc', 'tc.task_id = ac.id')
->where(['ac.companyId' => $companyId, 'ac.deleteTime' => 0])
->where('tc.updateTime', 'between', [$start, $end])
->whereIn('tc.status', [1, 2, 3, 4])
->count();
// 通过量
$passNum = Db::name('customer_acquisition_task')->alias('ac')
->join('task_customer tc', 'tc.task_id = ac.id')
->where(['ac.companyId' => $companyId, 'ac.deleteTime' => 0])
->where('tc.updateTime', 'between', [$start, $end])
->whereIn('tc.status', [4])
->count();
if (!empty($passNum)){
$passRate = number_format(($addNum / $passNum) * 100,2) ;
}else{
$passRate = '0%';
}
$sysActive = '90%';
$data = [
'momentsNum' => $momentsNum,
'groupPushNum' => $groupPushNum,
'addNum' => $addNum,
'passNum' => $passNum,
'passRate' => $passRate,
'sysActive' => $sysActive,
];
return successJson($data, '获取成功');
}
/**
* 近7天获客统计
* @return \think\response\Json
*/
public function customerAcquisitionStats7Days()
{
$companyId = $this->request->userInfo['companyId'];
$days = 7;
$dates = [];
$allNum = [];
$addNum = [];
$passNum = [];
for ($i = $days - 1; $i >= 0; $i--) {
$date = date('Y-m-d', strtotime("-$i day"));
$start = strtotime($date . ' 00:00:00');
$end = strtotime($date . ' 23:59:59');
// 获客总量
$allNum[] = Db::name('customer_acquisition_task')->alias('ac')
->join('task_customer tc', 'tc.task_id = ac.id')
->where(['ac.companyId' => $companyId, 'ac.deleteTime' => 0])
->where('tc.createTime', 'between', [$start, $end])
->count();
// 添加量
$addNum[] = Db::name('customer_acquisition_task')->alias('ac')
->join('task_customer tc', 'tc.task_id = ac.id')
->where(['ac.companyId' => $companyId, 'ac.deleteTime' => 0])
->where('tc.updateTime', 'between', [$start, $end])
->whereIn('tc.status', [1, 2, 3, 4])
->count();
// 通过量
$passNum[] = Db::name('customer_acquisition_task')->alias('ac')
->join('task_customer tc', 'tc.task_id = ac.id')
->where(['ac.companyId' => $companyId, 'ac.deleteTime' => 0])
->where('tc.updateTime', 'between', [$start, $end])
->whereIn('tc.status', [4])
->count();
$week = date("w", strtotime($date));
$dates[] = self::WEEK[$week];
}
$data = [
'date' => $dates,
'allNum' => $allNum,
'addNum' => $addNum,
'passNum' => $passNum,
];
return successJson($data, '获取成功');
}
/**
* 场景获客数据统计
* @return \think\response\Json
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function getFriendRequestTaskStats()
{
$companyId = $this->request->userInfo['companyId'];
$taskId = $this->request->param('taskId', '');
if(empty($taskId)){
return errorJson('任务id不能为空');
}
$task = Db::name('customer_acquisition_task')->where(['id' => $taskId, 'companyId' => $companyId,'deleteTime' => 0])->find();
if(empty($task)){
return errorJson('任务不存在或已删除');
}
// 1. 获取startTime和endTime格式是日期
$startTime = $this->request->param('startTime', '');
$endTime = $this->request->param('endTime', '');
// 如果获取不到则默认为7天的跨度
if (empty($startTime)) {
$startTime = date('Y-m-d', time() - 86400 * 6);
}
if (empty($endTime)) {
$endTime = date('Y-m-d', time());
}
// 转换成时间戳格式
$startTimestamp = strtotime($startTime . ' 00:00:00');
$endTimestamp = strtotime($endTime . ' 23:59:59');
// 同时生成日期数组和时间戳二维数组
$dateArray = [];
$timestampArray = [];
$currentTimestamp = $startTimestamp;
while ($currentTimestamp <= $endTimestamp) {
// 生成日期格式数组
$dateArray[] = date('m-d', $currentTimestamp);
// 生成时间戳二维数组
$dayStart = $currentTimestamp;
$dayEnd = strtotime('+1 day', $currentTimestamp) - 1; // 23:59:59
$timestampArray[] = [$dayStart, $dayEnd];
$currentTimestamp = strtotime('+1 day', $currentTimestamp);
}
// 使用分组聚合统计,减少 SQL 次数
$allRows = Db::name('task_customer')
->field("FROM_UNIXTIME(createTime, '%m-%d') AS d, COUNT(*) AS c")
->where(['task_id' => $taskId])
->where('createTime', 'between', [$startTimestamp, $endTimestamp])
->group('d')
->select();
$successRows = Db::name('task_customer')
->field("FROM_UNIXTIME(addTime, '%m-%d') AS d, COUNT(*) AS c")
->where(['task_id' => $taskId])
->where('addTime', 'between', [$startTimestamp, $endTimestamp])
->whereIn('status', [1, 2, 4])
->group('d')
->select();
$passRows = Db::name('task_customer')
->field("FROM_UNIXTIME(passTime, '%m-%d') AS d, COUNT(*) AS c")
->where(['task_id' => $taskId])
->where('passTime', 'between', [$startTimestamp, $endTimestamp])
->group('d')
->select();
$errorRows = Db::name('task_customer')
->field("FROM_UNIXTIME(updateTime, '%m-%d') AS d, COUNT(*) AS c")
->where(['task_id' => $taskId, 'status' => 3])
->where('updateTime', 'between', [$startTimestamp, $endTimestamp])
->group('d')
->select();
// 将分组结果映射到连续日期数组
$mapToSeries = function(array $rows) use ($dateArray) {
$dict = [];
foreach ($rows as $row) {
// 兼容对象/数组两种返回
$d = is_array($row) ? ($row['d'] ?? '') : ($row->d ?? '');
$c = (int)(is_array($row) ? ($row['c'] ?? 0) : ($row->c ?? 0));
if ($d !== '') {
$dict[$d] = $c;
}
}
$series = [];
foreach ($dateArray as $d) {
$series[] = $dict[$d] ?? 0;
}
return $series;
};
$allNumArray = $mapToSeries($allRows);
$successNumArray = $mapToSeries($successRows);
$passNumArray = $mapToSeries($passRows);
$errorNumArray = $mapToSeries($errorRows);
// 计算通过率和成功率
$passRateArray = [];
$successRateArray = [];
for ($i = 0; $i < count($dateArray); $i++) {
// 通过率 = 通过数 / 总数
$passRate = ($allNumArray[$i] > 0) ? round(($passNumArray[$i] / $allNumArray[$i]) * 100, 2) : 0;
$passRateArray[] = $passRate;
// 成功率 = 成功数 / 总数
$successRate = ($allNumArray[$i] > 0) ? round(($successNumArray[$i] / $allNumArray[$i]) * 100, 2) : 0;
$successRateArray[] = $successRate;
}
// 计算总体统计
$totalAll = array_sum($allNumArray);
$totalSuccess = array_sum($successNumArray);
$totalPass = array_sum($passNumArray);
$totalError = array_sum($errorNumArray);
$totalPassRate = ($totalAll > 0) ? round(($totalPass / $totalAll) * 100, 2) : 0;
$totalSuccessRate = ($totalAll > 0) ? round(($totalSuccess / $totalAll) * 100, 2) : 0;
// 返回结果
$result = [
'startTime' => $startTime,
'endTime' => $endTime,
'dateArray' => $dateArray,
'allNumArray' => $allNumArray,
'successNumArray' => $successNumArray,
'passNumArray' => $passNumArray,
'errorNumArray' => $errorNumArray,
'passRateArray' => $passRateArray,
'successRateArray' => $successRateArray,
'totalStats' => [
'totalAll' => $totalAll,
'totalSuccess' => $totalSuccess,
'totalPass' => $totalPass,
'totalError' => $totalError,
'totalPassRate' => $totalPassRate,
'totalSuccessRate' => $totalSuccessRate
]
];
return successJson($result, '获取成功');
}
public function userInfoStats()
{
$companyId = $this->request->userInfo['companyId'];
$userId = $this->request->userInfo['id'];
$isAdmin = $this->request->userInfo['isAdmin'];
$device = Db::name('device')->where(['companyId' => $companyId,'deleteTime' => 0]);
$wechat = Db::name('wechat_customer')->where(['companyId' => $companyId]);
$contentLibrary = Db::name('content_library')->where(['companyId' => $companyId,'isDel' => 0]);
$user = Db::name('wechat_friendship')->where(['companyId' => $companyId,'deleteTime' => 0]);
if(empty($isAdmin)){
$contentLibrary = $contentLibrary->where(['userId' => $userId]);
}
$deviceNum = $device->count();
$wechatNum = $wechat->count();
$contentLibraryNum = $contentLibrary->count();
$userNum = $user->count();
$data = [
'deviceNum' => $deviceNum,
'wechatNum' => $wechatNum,
'contentLibraryNum' => $contentLibraryNum,
'userNum' => $userNum,
];
return successJson($data, '获取成功');
}
}