为什么要做这个插件
客户用的是子比主题做资源站,主题本身带积分系统,但有两个需求满足不了:
- 浏览文章给积分 — 用户看文章也能攒积分,鼓励用户多逛网站
- 积分兑换余额 — 积分能换成站内余额,用来购买付费内容
子比主题自带的积分主要靠签到、评论、消费获取,浏览不给;而且积分和余额是两套独立的体系,不能互转。客户想把这两个点打通。
插件都做了啥 1. 浏览积分功能
用户打开文章页面,停留一段时间就能获得积分。具体规则后台可以配:
- 每分钟给多少积分(默认1分)
- 多久结算一次(默认60秒)
- 普通用户每日上限
- VIP用户每日上限(VIP拿得多一点,鼓励充会员)
前端有个小计时器,右下角飘着,显示倒计时和今日已获得多少积分。到点了会飘个"+X分"的动画,用户能看到自己在攒积分,挺有成就感的。


这里有几个细节是做的时候才想到的:
页面可见性检测 :用户切到别的标签页就暂停计时,回来继续。不然挂着页面不看也给积分,太亏了。
防刷机制 :加了请求节流,两次请求间隔不能少于10秒,防止有人刷接口。
VIP判断 :调用子比的 zib_get_user_vip_level() 函数拿等级,大于0就算VIP。做了多层 fallback,函数不存在就从 user_meta 里读,尽量兼容各种情况。
- 积分兑换余额
用户积分够了可以换成站内余额,兑换比例后台能设,比如100积分换1块钱。
兑换入口放在用户中心的积分页面里,点了弹个模态框,输积分数,实时显示能换多少钱,确认后直接兑换。
这个功能做的时候最折腾,主要是和子比主题的API对接:
- 扣积分用 zibpay_update_user_points ,传负数就是扣
- 加余额用 zibpay_update_user_balance ,类型写 "Points Exchange"
- 两边都有日志记录,能追溯 3. 后台管理
后台加了个设置页面,能调: - 浏览积分开关、每分钟积分、结算间隔、普通/VIP每日上限
- 积分兑换开关、兑换比例
- 前端通知开关
还有兑换日志列表,能看谁什么时候兑换了多少积分换了多少钱,成功还是失败。出问题了方便排查。

踩过的坑
坑1:子比主题的检测
最开始用 function_exists('zibpay_get_user_points') 检测主题装没装,后来发现有时候主题激活了但函数还没加载到(插件加载顺序的问题)。后来改成了双重检测:先看当前主题是不是 zibll,再检查函数存不存在,这样更靠谱一点。
坑2:兑换按钮渲染时机
最开始想通过 WordPress 的 action 钩子把按钮插到积分页面里,结果子比主题的用户中心是前端渲染的(tab切换那种),PHP 钩子根本没地方挂。
后来改成了前端 JS 注入的方式:
- 页面加载完延迟1秒,检测当前是不是积分tab
- 监听 tab 切换事件和 URL hash 变化
- 检测到在积分页面就把兑换按钮 append 进去
虽然有点"野路子",但确实能用,而且不用改主题文件,插件禁用了按钮也就没了,比较干净。
坑3:Nonce 验证失败
有段时间兑换功能时不时报安全验证失败,查了半天发现是因为页面缓存或者用户停留太久,nonce 过期了。后来加了个获取新 nonce 的 AJAX 接口,提交前如果 nonce 不对就先刷新一下,问题就解决了。
坑4:积分扣除和余额添加的原子性
最怕的就是积分扣了但余额没加上,或者反过来。处理的时候做了个简单的事务逻辑:先扣积分,再加余额;如果余额加失败了,就把积分回滚回去。虽然不是数据库级别的事务,但至少能避免大部分问题。
坑5:夜间模式兼容
子比主题有夜间模式,最开始兑换模块的背景色在夜间模式下特别刺眼。后来加了 .theme-dark 的样式覆盖,夜间模式下自动换成深色背景,就和谐多了。
技术结构
插件用的单例模式,分了几个类:
- Fantuan_Zibll_Points — 主类,负责加载依赖和初始化
- Fantuan_Zibll_Points_Core — 积分核心,封装子比的积分API
- Fantuan_Zibll_Browsing_Points — 浏览积分功能
- Fantuan_Zibll_Points_Exchange — 积分兑换功能
- Fantuan_Zibll_Points_Frontend — 前端显示
- Fantuan_Zibll_Points_Admin — 后台管理
所有和子比主题交互的地方都封装在 Core 类里,以后主题API变了改一个地方就行。
总结
这个插件本身功能不复杂,但因为是深度集成到第三方主题里,很多地方得跟着主题的节奏走。最大的体会是: 做主题增强插件,一定要多留 fallback,不能假设主题的某个函数一定存在、某个钩子一定能挂得上 。
评论