后台点击用户名称旁边的hello word会出现提示。

企业微信截图_17545462641024.png#B #S #R #60%

直接将该代码替换掉原本的代码即可:

<?php

namespace TypechoPlugin\HelloWorld;

use Typecho\Plugin\PluginInterface;
use Typecho\Widget\Helper\Form;
use Typecho\Widget\Helper\Form\Element\Text;
use Widget\Options;
use Widget\Stat;
use Typecho\Db;

if (!defined('__TYPECHO_ROOT_DIR__')) {
    exit;
}

/**
 * Hello World
 *
 * @package HelloWorld
 * @author 白荼
 * @version 1.0.0
 */
class Plugin implements PluginInterface
{
    /**
     * 激活插件方法,如果激活失败,直接抛出异常
     */
    public static function activate()
    {
        \Typecho\Plugin::factory('admin/menu.php')->navBar = __CLASS__ . '::render';
        // 添加CSS和JS
        \Typecho\Plugin::factory('admin/header.php')->header = __CLASS__ . '::header';
    }

    /**
     * 禁用插件方法,如果禁用失败,直接抛出异常
     */
    public static function deactivate()
    {
    }

    /**
     * 获取插件配置面板
     *
     * @param Form $form 配置面板
     */
    public static function config(Form $form)
    {
        /** 分类名称 */
        $name = new Text('word', null, 'Hello World', _t('说点什么'));
        $form->addInput($name);
    }

    /**
     * 个人用户的配置面板
     *
     * @param Form $form
     */
    public static function personalConfig(Form $form)
    {
    }

    /**
     * 在header中添加CSS和JS
     */
    public static function header($header)
    {
        $customCssJs = '
<!-- HelloWorld Plugin CSS -->
<style>
.helloworld-tooltip {
    position: absolute;
    background: #fff;
    border: 1px solid #ddd;
    border-radius: 4px;
    padding: 15px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
    z-index: 9999;
    min-width: 280px;
    display: none;
    font-size: 12px;
}
.helloworld-tooltip h4 {
    margin: 0 0 10px 0;
    padding: 0;
    color: #333;
    border-bottom: 1px solid #eee;
    padding-bottom: 8px;
    font-size: 14px;
}
.helloworld-tooltip .comparison {
    background: #f8f9fa;
    border-left: 3px solid #007cba;
    padding: 8px 12px;
    margin: 10px 0;
    border-radius: 0 4px 4px 0;
    font-size: 13px;
}
.helloworld-tooltip ul {
    list-style: none;
    padding: 0;
    margin: 0;
}
.helloworld-tooltip li {
    padding: 5px 0;
    border-bottom: 1px solid #f5f5f5;
    line-height: 1.5;
}
.helloworld-tooltip li:last-child {
    border-bottom: none;
}
.helloworld-tooltip strong {
    color: #666;
    font-weight: normal;
}
.helloworld-trigger {
    cursor: pointer;
    border-bottom: 1px dotted #BBBBBB;
}
.helloworld-trigger:hover {
    color: #666 !important;
    border-bottom-color: #666;
}
</style>
<!-- HelloWorld Plugin JS -->
<script>
(function() {
    function initHelloWorldTooltip() {
        var trigger = document.querySelector(".helloworld-trigger");
        var tooltip = document.querySelector(".helloworld-tooltip");
        
        if (trigger && tooltip) {
            trigger.addEventListener("click", function(e) {
                e.preventDefault();
                e.stopPropagation();
                
                // 计算位置
                var rect = trigger.getBoundingClientRect();
                var tooltipWidth = tooltip.offsetWidth || 280;
                var tooltipHeight = tooltip.offsetHeight || 250;
                
                // 默认位置
                var left = rect.left + window.scrollX;
                var top = rect.bottom + window.scrollY + 5;
                
                // 边界检测
                if (left + tooltipWidth > window.innerWidth + window.scrollX) {
                    left = window.innerWidth + window.scrollX - tooltipWidth - 10;
                }
                if (top + tooltipHeight > window.innerHeight + window.scrollY) {
                    top = rect.top + window.scrollY - tooltipHeight - 5;
                }
                
                tooltip.style.left = left + "px";
                tooltip.style.top = top + "px";
                tooltip.style.display = "block";
            });
            
            // 点击其他地方关闭
            document.addEventListener("click", function(e) {
                if (!tooltip.contains(e.target) && e.target !== trigger) {
                    tooltip.style.display = "none";
                }
            });
        }
    }
    
    if (document.readyState === "loading") {
        document.addEventListener("DOMContentLoaded", initHelloWorldTooltip);
    } else {
        initHelloWorldTooltip();
    }
})();
</script>';

        return $header . $customCssJs;
    }

    /**
     * 根据字数获取对应的文学著作比较
     */
    private static function getLiteraryComparison($wordCount)
    {
        // 文学著作字数对照表(字数 => 著作名称)
        $literaryWorks = [
            // 百字级
            50 => '几行诗句',
            100 => '一段朋友圈文字',
            200 => '一条微博内容',
            500 => '一篇微博长文',
            
            // 千字级
            1000 => '一页A4纸手写内容',
            1500 => '一页打印稿',
            2000 => '一篇标准作文',
            3000 => '一篇博客文章',
            5000 => '一篇短篇小说',
            8000 => '一篇中篇小说开头',
            
            // 万字级(中国现代文学)
            10000 => '《呐喊》',
            12000 => '《彷徨》',
            15000 => '《朝花夕拾》',
            20000 => '《野草》',
            25000 => '《故事新编》',
            30000 => '《热风》',
            35000 => '《坟》',
            40000 => '《而已集》',
            45000 => '《三闲集》',
            
            // 万字级(其他现代文学)
            50000 => '《沉沦》(郁达夫)',
            55000 => '《春风沉醉的晚上》',
            60000 => '《迟桂花》',
            65000 => '《茑萝集》',
            70000 => '《过去》',
            75000 => '《薄奠》',
            80000 => '《微雪的早晨》',
            
            // 万字级(长篇小说选段)
            85000 => '《骆驼祥子》前半部分',
            90000 => '《二马》',
            95000 => '《离婚》',
            100000 => '《骆驼祥子》',
            110000 => '《四世同堂》第一部分',
            120000 => '《边城》',
            130000 => '《湘行散记》',
            140000 => '《长河》',
            150000 => '《家》',
            160000 => '《憩园》',
            170000 => '《第四病室》',
            180000 => '《春》',
            190000 => '《秋》',
            200000 => '《寒夜》',
            
            // 20万字级
            210000 => '《激流三部曲》选段',
            220000 => '《爱情三部曲》选段',
            230000 => '《抗战三部曲》选段',
            240000 => '《人间词话》',
            250000 => '《人间喜剧》选段',
            260000 => '《巴黎圣母院》',
            270000 => '《悲惨世界》选段',
            280000 => '《九三年》',
            290000 => '《海上劳工》',
            300000 => '《笑面人》',
            
            // 30万字级
            310000 => '《约翰·克利斯朵夫》选段',
            320000 => '《红与黑》',
            330000 => '《巴马修道院》',
            340000 => '《吕西安·娄凡》',
            350000 => '《阿尔芒斯》',
            360000 => '《法尼娜·法尼尼》',
            370000 => '《瓦尼娜·瓦尼尼》',
            380000 => '《红屋骑士》',
            390000 => '《卡斯特罗修道院院长》',
            400000 => '《意大利遗事》',
            
            // 40万字级
            410000 => '《三个火枪手》',
            420000 => '《基督山伯爵》',
            430000 => '《黑郁金香》',
            440000 => '《二十年后》',
            450000 => '《布拉热洛纳子爵》',
            460000 => '《玛戈王后》',
            470000 => '《蒙梭罗夫人》',
            480000 => '《四十五卫士》',
            490000 => '《侠隐记》',
            500000 => '《红楼梦》(精简版)',
            
            // 50万字级
            520000 => '《水浒传》选段',
            540000 => '《西游记》选段',
            560000 => '《三国演义》选段',
            580000 => '《儒林外史》',
            600000 => '《聊斋志异》选段',
            620000 => '《阅微草堂笔记》',
            640000 => '《子不语》',
            660000 => '《夜雨秋灯录》',
            680000 => '《萤窗异草》',
            700000 => '《耳食录》',
            
            // 70万字级
            720000 => '《浮生六记》',
            740000 => '《影梅庵忆语》',
            760000 => '《秋灯琐忆》',
            780000 => '《香艳丛书》选段',
            800000 => '《太平广记》选段',
            820000 => '《夷坚志》选段',
            840000 => '《剪灯新话》',
            860000 => '《剪灯余话》',
            880000 => '《觅灯因话》',
            900000 => '《喻世明言》',
            
            // 百万字级
            920000 => '《警世通言》',
            940000 => '《醒世恒言》',
            960000 => '《初刻拍案惊奇》',
            980000 => '《二刻拍案惊奇》',
            1000000 => '《红楼梦》',
            1050000 => '《镜花缘》',
            1100000 => '《老残游记》',
            1150000 => '《孽海花》',
            1200000 => '《官场现形记》',
            1250000 => '《二十年目睹之怪现状》',
            
            // 百万字级以上
            1300000 => '《资本论》第一卷',
            1400000 => '《莎士比亚十四行诗集》',
            1500000 => '《战争与和平》',
            1600000 => '《安娜·卡列尼娜》',
            1700000 => '《复活》',
            1800000 => '《静静的顿河》',
            1900000 => '《被开垦的处女地》',
            2000000 => '《一个人的遭遇》',
            2100000 => '《静静的顿河》全本',
            2200000 => '《钢铁是怎样炼成的》',
            2300000 => '《青年近卫军》',
            2400000 => '《日瓦戈医生》',
            2500000 => '《追忆似水年华》第一卷',
            2600000 => '《约翰·克利斯朵夫》',
            2700000 => '《马丁·伊登》',
            2800000 => '《美国悲剧》',
            2900000 => '《嘉莉妹妹》',
            3000000 => '《资本论》全三卷',
            3100000 => '《莎士比亚全集》悲剧部分',
            3200000 => '《莎士比亚全集》喜剧部分',
            3300000 => '《莎士比亚全集》历史剧部分',
            3400000 => '《莎士比亚十四行诗全集》',
            3500000 => '《莎士比亚全集》',
            3600000 => '《追忆似水年华》第二卷',
            3700000 => '《追忆似水年华》第三卷',
            3800000 => '《追忆似水年华》第四卷',
            3900000 => '《追忆似水年华》第五卷',
            4000000 => '《追忆似水年华》',
            4200000 => '《堂吉诃德》',
            4400000 => '《神曲》',
            4600000 => '《荷马史诗》',
            4800000 => '《失乐园》',
            5000000 => '《大英百科全书》一卷',
            5500000 => '《大英百科全书》两卷',
            6000000 => '《牛津英语词典》一卷',
            6500000 => '《不列颠百科全书》',
            7000000 => '《中国大百科全书》一卷',
            7500000 => '《辞海》',
            8000000 => '《康熙字典》',
            9000000 => '《中华大字典》',
            10000000 => '《大英百科全书》全套',
            12000000 => '《四库全书》选段',
            15000000 => '《永乐大典》残卷',
            20000000 => '《古今图书集成》选段'
        ];
    
        // 找到最接近的著作
        $closestWork = '几行文字';
        $closestWords = 0;
        
        foreach ($literaryWorks as $words => $work) {
            if ($wordCount >= $words) {
                $closestWork = $work;
                $closestWords = $words;
            } else {
                break;
            }
        }
    
        // 计算倍数
        if ($closestWords > 0) {
            $multiple = round($wordCount / $closestWords, 1);
            if ($multiple >= 2) {
                return "约等于 {$multiple} 本 {$closestWork} 的字数";
            } else {
                return "约等于 1 本 {$closestWork} 的字数";
            }
        } else {
            return "约等于几行文字的字数";
        }
    }

    /**
     * 获取统计信息
     */
    private static function getStats()
    {
        $db = Db::get();
        $user = \Typecho\Widget::widget('Widget_User');
        
        // 最近登录时间
        $lastLogin = $user->logged;
        $lastLoginText = $lastLogin ? date('Y-m-d H:i:s', $lastLogin) : '未知';
        
        // 文章数量
        $postCount = $db->fetchObject($db->select(['COUNT(cid)' => 'num'])
            ->from('table.contents')
            ->where('type = ?', 'post')
            ->where('authorId = ?', $user->uid))->num;
        
        // 字数统计(简单统计标题和内容长度)
        $posts = $db->fetchAll($db->select('title', 'text')
            ->from('table.contents')
            ->where('type = ?', 'post')
            ->where('authorId = ?', $user->uid));
        
        $totalWords = 0;
        foreach ($posts as $post) {
            $totalWords += mb_strlen($post['title'], 'UTF-8');
            $totalWords += mb_strlen(strip_tags($post['text']), 'UTF-8');
        }
        
        // 最近文章时间
        $lastPost = $db->fetchRow($db->select('created')
            ->from('table.contents')
            ->where('type = ?', 'post')
            ->where('authorId = ?', $user->uid)
            ->order('created', Db::SORT_DESC)
            ->limit(1));
        
        $lastPostTime = $lastPost ? date('Y-m-d H:i:s', $lastPost['created']) : '暂无文章';
        
        // 获取文学著作比较
        $literaryComparison = self::getLiteraryComparison($totalWords);
        
        return [
            'lastLogin' => $lastLoginText,
            'postCount' => $postCount,
            'totalWords' => $totalWords,
            'lastPostTime' => $lastPostTime,
            'literaryComparison' => $literaryComparison
        ];
    }

    /**
     * 插件实现方法
     *
     * @access public
     * @return void
     */
    public static function render()
    {
        $stats = self::getStats();
        $word = Options::alloc()->plugin('HelloWorld')->word;
        
        // 获取当前登录用户的信息
        $user = \Typecho\Widget::widget('Widget_User');
        $userName = $user->screenName ?: $user->name; // 优先使用昵称,如果没有则使用登录名

        echo '<span class="helloworld-trigger" style="color:#BBBBBB">' . 
             htmlspecialchars($word) . 
             '</span>';
        
        echo '<div class="helloworld-tooltip">
                <h4>欢迎回来,' . htmlspecialchars($userName) . '</h4>
                <div style="margin-bottom:20px;">
                    您已经写了 ' . $stats['postCount'] . ' 篇文章,一共 ' . $stats['totalWords'] . ' 字,' . $stats['literaryComparison'] . '。
                </div>
                <ul>
                    <li><strong>最近登录:</strong>' . $stats['lastLogin'] . '</li>
                    <li><strong>最近发文:</strong>' . $stats['lastPostTime'] . '</li>
                </ul>
              </div>';
    }
}
最后修改:2025 年 08 月 07 日
如果觉得我的文章对你有用,请随意赞赏