From 091f3518a5469b6ce9cdb2c6735290b68caa3165 Mon Sep 17 00:00:00 2001 From: XIGE <710062962@qq.com> Date: Mon, 23 Feb 2026 20:04:21 +0800 Subject: [PATCH] 1.0 --- Plugin.php | 1061 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1061 insertions(+) create mode 100644 Plugin.php diff --git a/Plugin.php b/Plugin.php new file mode 100644 index 0000000..fafbac9 --- /dev/null +++ b/Plugin.php @@ -0,0 +1,1061 @@ +header = array('TimeProgressStats_Plugin', 'header'); + Typecho_Plugin::factory('Widget_Archive')->footer = array('TimeProgressStats_Plugin', 'footer'); + return '插件已激活'; + } + + /** + * 禁用插件 + */ + public static function deactivate() + { + return '插件已禁用'; + } + + /** + * 插件配置 + */ + public static function config(Typecho_Widget_Helper_Form $form) + { + // 是否开启插件 + $enable = new Typecho_Widget_Helper_Form_Element_Radio('enable', array( + '1' => '开启', + '0' => '关闭' + ), '1', '是否开启插件', '启用或禁用时间进度统计功能'); + $form->addInput($enable); + + // 博客建立日期 + $blog_start_date = new Typecho_Widget_Helper_Form_Element_Text('blog_start_date', null, date('Y-m-d'), + _t('博客建立日期'), _t('设置博客建立的日期,用于计算运行天数,格式:YYYY-MM-DD')); + $form->addInput($blog_start_date); + + // 显示样式设置 + $style = new Typecho_Widget_Helper_Form_Element_Radio('style', array( + 'card' => '卡片样式', + 'simple' => '简洁样式', + 'modern' => '现代样式' + ), 'card', '显示样式', '选择统计信息的显示样式'); + $form->addInput($style); + + // 更新速度设置 + $updateSpeed = new Typecho_Widget_Helper_Form_Element_Select('update_speed', array( + '100' => '0.1秒(非常流畅)', + '200' => '0.2秒(流畅)', + '500' => '0.5秒(标准)', + '1000' => '1秒(节能)' + ), '200', '更新速度', '设置实时更新的速度'); + $form->addInput($updateSpeed); + + // 显示实时时钟 + $showClock = new Typecho_Widget_Helper_Form_Element_Radio('show_clock', array( + '1' => '显示', + '0' => '隐藏' + ), '1', '实时时钟', '是否显示实时时钟'); + $form->addInput($showClock); + + // 今年文章目标 + $postGoal = new Typecho_Widget_Helper_Form_Element_Text('post_goal', null, '50', + _t('今年文章目标'), _t('设置今年计划写的文章数量')); + $form->addInput($postGoal); + + // 今年字数目标 + $charGoal = new Typecho_Widget_Helper_Form_Element_Text('char_goal', null, '100000', + _t('今年字数目标'), _t('设置今年计划写的总字数')); + $form->addInput($charGoal); + } + + /** + * 个人配置 + */ + public static function personalConfig(Typecho_Widget_Helper_Form $form) {} + + /** + * 获取统计数据 + */ + public static function getStats() + { + $db = Typecho_Db::get(); + $currentYear = date('Y'); + $currentMonth = date('n'); + + // 今年文章 + $yearPosts = $db->fetchRow($db->select('COUNT(*) as total') + ->from('table.contents') + ->where('type = ?', 'post') + ->where('status = ?', 'publish') + ->where('YEAR(FROM_UNIXTIME(created)) = ?', $currentYear)); + + // 本月文章 + $monthPosts = $db->fetchRow($db->select('COUNT(*) as total') + ->from('table.contents') + ->where('type = ?', 'post') + ->where('status = ?', 'publish') + ->where('YEAR(FROM_UNIXTIME(created)) = ?', $currentYear) + ->where('MONTH(FROM_UNIXTIME(created)) = ?', $currentMonth)); + + // 本月字数 + $monthChars = $db->fetchRow($db->select('SUM(LENGTH(text)) as total') + ->from('table.contents') + ->where('type = ?', 'post') + ->where('status = ?', 'publish') + ->where('YEAR(FROM_UNIXTIME(created)) = ?', $currentYear) + ->where('MONTH(FROM_UNIXTIME(created)) = ?', $currentMonth)); + + // 标签总数 + $tags = $db->fetchRow($db->select('COUNT(*) as total') + ->from('table.metas') + ->where('type = ?', 'tag')); + + // 分类总数 + $categories = $db->fetchRow($db->select('COUNT(*) as total') + ->from('table.metas') + ->where('type = ?', 'category')); + + // 评论总数(已审核) + $comments = $db->fetchRow($db->select('COUNT(*) as total') + ->from('table.comments') + ->where('status = ?', 'approved')); + + // 文章总数 + $totalPosts = $db->fetchRow($db->select('COUNT(*) as total') + ->from('table.contents') + ->where('type = ?', 'post') + ->where('status = ?', 'publish')); + + // 累计字数(全部) + $totalChars = $db->fetchRow($db->select('SUM(LENGTH(text)) as total') + ->from('table.contents') + ->where('type = ?', 'post') + ->where('status = ?', 'publish')); + + // 今年字数 + $yearChars = $db->fetchRow($db->select('SUM(LENGTH(text)) as total') + ->from('table.contents') + ->where('type = ?', 'post') + ->where('status = ?', 'publish') + ->where('YEAR(FROM_UNIXTIME(created)) = ?', $currentYear)); + + return array( + 'year_posts' => isset($yearPosts['total']) ? intval($yearPosts['total']) : 0, + 'month_posts' => isset($monthPosts['total']) ? intval($monthPosts['total']) : 0, + 'month_chars' => isset($monthChars['total']) ? intval($monthChars['total']) : 0, + 'total_tags' => isset($tags['total']) ? intval($tags['total']) : 0, + 'total_categories' => isset($categories['total']) ? intval($categories['total']) : 0, + 'total_comments' => isset($comments['total']) ? intval($comments['total']) : 0, + 'total_posts' => isset($totalPosts['total']) ? intval($totalPosts['total']) : 0, + 'total_chars' => isset($totalChars['total']) ? intval($totalChars['total']) : 0, + 'year_chars' => isset($yearChars['total']) ? intval($yearChars['total']) : 0 + ); + } + + /** + * 获取运行天数 + */ + private static function getRunningDays($blogStartDate) + { + try { + $startDate = new DateTime($blogStartDate); + $today = new DateTime(); + $interval = $startDate->diff($today); + return $interval->days + 1; // +1 包含今天 + } catch (Exception $e) { + // 如果日期格式错误,使用默认值 + return 0; + } + } + + /** + * 格式化数字 + */ + private static function formatNumber($number) + { + $number = intval($number); + if ($number >= 100000000) { + return round($number / 100000000, 2) . '亿'; + } elseif ($number >= 10000) { + return round($number / 10000, 1) . '万'; + } + return number_format($number); + } + + /** + * 渲染统计数据 + */ + public static function renderStats($config = null) + { + if (!$config) { + $options = Typecho_Widget::widget('Widget_Options'); + $config = $options->plugin('TimeProgressStats'); + } + + // 检查插件是否开启 + if (isset($config->enable) && $config->enable == '0') { + return ''; + } + + $stats = self::getStats(); + $year = date('Y'); + $hour = date('H'); + $minute = date('i'); + $second = date('s'); + + // 获取运行天数 + $runningDays = 0; + if (isset($config->blog_start_date) && !empty($config->blog_start_date)) { + $runningDays = self::getRunningDays($config->blog_start_date); + } + + // 时间计算 + $isLeapYear = (($year % 400 == 0) || ($year % 4 == 0 && $year % 100 != 0)); + $totalDays = $isLeapYear ? 366 : 365; + $dayOfYear = date('z') + 1; + $remainingDays = $totalDays - $dayOfYear; + + // 进度计算 + $yearProgress = ($dayOfYear / $totalDays) * 100; + $totalSecondsToday = $hour * 3600 + $minute * 60 + $second; + $dayProgress = ($totalSecondsToday / 86400) * 100; + + // 年度目标计算 + $postGoal = isset($config->post_goal) ? intval($config->post_goal) : 50; + $charGoal = isset($config->char_goal) ? intval($config->char_goal) : 100000; + + // 月度目标计算(年度目标除以12) + $monthPostGoal = ceil($postGoal / 12); + $monthCharGoal = ceil($charGoal / 12); + + // 进度计算 + $postGoalProgress = $postGoal > 0 ? ($stats['year_posts'] / $postGoal) * 100 : 0; + $charGoalProgress = $charGoal > 0 ? ($stats['year_chars'] / $charGoal) * 100 : 0; + $monthPostGoalProgress = $monthPostGoal > 0 ? ($stats['month_posts'] / $monthPostGoal) * 100 : 0; + $monthCharGoalProgress = $monthCharGoal > 0 ? ($stats['month_chars'] / $monthCharGoal) * 100 : 0; + + // 格式化显示 + $charsFormatted = self::formatNumber($stats['total_chars']); + $yearCharsFormatted = self::formatNumber($stats['year_chars']); + $monthCharsFormatted = self::formatNumber($stats['month_chars']); + + $styleClass = 'tps-card'; + if ($config && $config->style) { + $styleClass = 'tps-' . $config->style; + } + + $showClockClass = ''; + if ($config && isset($config->show_clock) && $config->show_clock == '1') { + $showClockClass = 'tps-has-clock'; + } + + ob_start(); + ?> +
+ +
+

🎯 实时数据

+
+ + + 仅剩 + show_clock) && $config->show_clock == '1'): ?> + + +
+
+ +
+ +
+
+
+
运行天数
+
+
+
+
分类数量
+
+
+
+
标签总数
+
+
+
+
文章总数
+
+
+ +
+
评论总数
+
+
+
+
累计字数
+
+
+
+
+ + +
+
+
+ 今年进度 + % +
+
+
+
+
+ +
+
+ 今日进度 + % +
+
+
+
+
+
+ + +
+
+
+ 今年文章 + 篇 / + % +
+
+
+
+
+ +
+
+ 今年字数 + / + % +
+
+
+
+
+
+ + +
+
+
+ 本月文章 + 篇 / + % +
+
+
+
+
+ +
+
+ 本月字数 + / + % +
+
+
+
+
+
+
+
+ + + + +