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

直接将该代码替换掉原本的代码即可:
<?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>';
}
}