Files
MBTI_wang/api/app/controller/admin/Dashboard.php
Ghost a9bedf019d 服务端-其余代码
Made-with: Cursor
2026-03-17 11:58:45 +08:00

180 lines
6.1 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\controller\admin;
use app\BaseController;
use think\facade\Db;
use think\facade\Request;
/**
* 数据概览控制器(普通管理员)
*/
class Dashboard extends BaseController
{
/**
* 获取统计数据
* @return \think\response\Json
*/
public function index()
{
$user = $this->request->user ?? null;
if (!$user) {
return error('未登录', 401);
}
// 验证是否为管理员
if (!in_array($user['role'], ['admin', 'enterprise_admin'])) {
return error('无权限访问', 403);
}
try {
// admin / enterprise_admin 均只统计本企业数据
$enterpriseId = $user['enterpriseId'] ?? null;
if (!$enterpriseId) {
$adminRow = Db::name('users')->where('id', $user['userId'] ?? 0)->find();
$enterpriseId = $adminRow['enterpriseId'] ?? null;
}
// 企业用户 ID 集合(用于后续统计个人版测试)
$enterpriseUserIds = [];
if ($enterpriseId) {
$enterpriseUserIds = Db::name('wechat_users')
->where('enterpriseId', $enterpriseId)
->column('id');
$enterpriseUserIds = array_values(array_filter($enterpriseUserIds));
}
// 总用户数wechat_users.enterpriseId = 本企业
if ($enterpriseId) {
$totalUsers = count($enterpriseUserIds);
} else {
try {
$totalUsers = (int) Db::name('wechat_users')->count('openid', true);
} catch (\Throwable $e) {
$totalUsers = (int) Db::name('wechat_users')->count();
}
}
// 已完成测试数:严格按 test_results.enterpriseId 归属企业统计
if ($enterpriseId) {
$testsCompleted = (int) Db::name('test_results')
->where('enterpriseId', $enterpriseId)
->count();
} else {
$testsCompleted = (int) Db::name('test_results')->count();
}
// 今日活跃用户数
$todayStart = strtotime(date('Y-m-d 00:00:00'));
$todayEnd = strtotime(date('Y-m-d 23:59:59'));
$activeQuery = Db::name('test_results')
->where('createdAt', '>=', $todayStart)
->where('createdAt', '<=', $todayEnd);
if ($enterpriseId) {
$activeQuery->where('enterpriseId', $enterpriseId);
$activeIds = $activeQuery->distinct(true)->column('userId');
$activeToday = count(array_filter($activeIds));
} else {
$activeIds = $activeQuery->distinct(true)->column('userId');
$activeToday = count(array_filter($activeIds));
}
// 待审核暂返回0
$pendingReviews = 0;
// 最近 14 天测试趋势
$days = 14;
$startDate = strtotime(date('Y-m-d 00:00:00', strtotime('-' . ($days - 1) . ' days')));
$trendQuery = Db::name('test_results')
->where('createdAt', '>=', $startDate)
->whereIn('testType', ['face', 'mbti', 'disc', 'pdp']);
if ($enterpriseId) {
$trendQuery->where('enterpriseId', $enterpriseId);
}
$trendRows = $trendQuery
->field("FROM_UNIXTIME(createdAt, '%Y-%m-%d') as d, testType, COUNT(*) as c")
->group('d,testType')
->order('d', 'asc')
->select()
->toArray();
// 组装为按日期汇总的数组
$trendMap = [];
foreach ($trendRows as $row) {
$d = $row['d'];
$type = $row['testType'];
$cnt = (int) ($row['c'] ?? 0);
if (!isset($trendMap[$d])) {
$trendMap[$d] = [
'date' => $d,
'face' => 0,
'mbti' => 0,
'disc' => 0,
'pdp' => 0,
'total' => 0,
];
}
if (in_array($type, ['face', 'mbti', 'disc', 'pdp'], true)) {
$trendMap[$d][$type] += $cnt;
$trendMap[$d]['total'] += $cnt;
}
}
// 补齐没有数据的日期
$trendData = [];
for ($i = 0; $i < $days; $i++) {
$d = date('Y-m-d', strtotime('-' . ($days - 1 - $i) . ' days'));
if (isset($trendMap[$d])) {
$trendData[] = $trendMap[$d];
} else {
$trendData[] = [
'date' => $d,
'face' => 0,
'mbti' => 0,
'disc' => 0,
'pdp' => 0,
'total' => 0,
];
}
}
return success([
'totalUsers' => $totalUsers,
'testsCompleted' => $testsCompleted,
'activeToday' => $activeToday,
'pendingReviews' => $pendingReviews,
'testTrends' => $trendData,
]);
} catch (\Exception $e) {
return error('获取统计数据失败:' . $e->getMessage(), 500);
}
}
/**
* 格式化时间
* @param int $timestamp
* @return string
*/
private function formatTime($timestamp)
{
if (!$timestamp) {
return '';
}
$now = time();
$diff = $now - $timestamp;
if ($diff < 60) {
return '刚刚';
} elseif ($diff < 3600) {
return floor($diff / 60) . '分钟前';
} elseif ($diff < 86400) {
return floor($diff / 3600) . '小时前';
} elseif ($diff < 604800) {
return floor($diff / 86400) . '天前';
} else {
return date('Y-m-d H:i', $timestamp);
}
}
}