// +---------------------------------------------------------------------- declare (strict_types = 1); namespace addon\blog\controller\backend; use addon\blog\model\BlogArticle as ArticleModel; use addon\blog\model\BlogComment as CommentModel; use ywxapp\model\MemberUser as UserModel; use addon\blog\model\BlogVisit as VisitModel; use think\facade\Db; use think\facade\Request; use think\facade\View; use ywxapp\controller\BackendBase; /** * Stat 类 * * @author ywxapp */ class Stat extends BackendBase { protected $noNeedVerify = ['*']; protected function initialize() {} /** * 今日起始时间戳 */ private function todayStart() { return strtotime(date('Y-m-d')); } /** * 统计分析首页 */ public function index() { $range = request()->get('range', 'week'); $startTime = $this->getTimeRange($range); $today = $this->todayStart(); $stats = [ 'total_visit' => VisitModel::count(), 'today_visit' => VisitModel::where('create_at', '>=', $today)->count(), 'total_article' => ArticleModel::count(), 'today_article' => ArticleModel::where('create_at', '>=', $today)->count(), 'total_user' => UserModel::count(), 'today_user' => UserModel::where('create_at', '>=', $today)->count(), 'total_comment' => CommentModel::count(), 'today_comment' => CommentModel::where('create_at', '>=', $today)->count(), ]; $visitTrend = $this->getTrendData('visit', $startTime, $range); $articleTrend = $this->getTrendData('article', $startTime, $range); $userTrend = $this->getTrendData('member', $startTime, $range); $hotPages = VisitModel::field('url, count(*) as count') ->where('create_at', '>=', $startTime) ->group('url') ->order('count', 'desc') ->limit(10) ->select(); $hotArticles = ArticleModel::with(['author']) ->where('create_at', '>=', $startTime) ->order('view_count', 'desc') ->limit(10) ->select(); return View::fetch('stat/index', [ 'stats' => $stats, 'visitTrend' => $visitTrend, 'articleTrend' => $articleTrend, 'userTrend' => $userTrend, 'hotPages' => $hotPages, 'hotArticles' => $hotArticles, 'range' => $range, ]); } /** * 获取时间范围 */ private function getTimeRange($range) { switch ($range) { case 'today': return strtotime(date('Y-m-d')); case 'week': return strtotime('-7 days'); case 'month': return strtotime('-30 days'); case 'year': return strtotime('-1 year'); default: return strtotime('-7 days'); } } /** * 获取趋势数据 */ private function getTrendData($type, $startTime, $range) { $dateFormat = $range == 'year' ? '%Y-%m' : '%Y-%m-%d'; $table = [ 'visit' => 'blog_visit', 'article' => 'blog_article', 'member' => 'member', ][$type]; $dateField = 'create_at'; $rows = Db::name($table) ->field("FROM_UNIXTIME({$dateField}, '{$dateFormat}') as date, count(*) as count") ->where($dateField, '>=', $startTime) ->group("FROM_UNIXTIME({$dateField}, '{$dateFormat}')") ->order('date', 'asc') ->select() ->toArray(); return array_column($rows, 'count', 'date'); } }