【XIUNOX插件】头像框 v1.0.0

管理

xnx_avatar_frame 头像框

头像框商店、购买、佩戴、过期管理插件,通过 avatar_component_frame.php hook 渲染装饰性头像框,零侵入核心头像组件代码。

功能特性

  • 头像框管理:后台新建 / 编辑 / 删除头像框,支持名称、描述、排序、上下架开关

  • 两种框类型:图片框(上传 PNG / GIF / JPG / WebP,自动校验真实 MIME)与 CSS 样式框(管理员内联 style 输出,已过滤 PHP 标签字符)

  • 头像框商店:前台 /frame-shop.htm 浏览可购买头像框,按 sort 排序,支持分页

  • 购买扣费:调用 CreditsService::sub() 扣积分(支持 credits / golds 两种货币),事务由 CreditsService 内部保证;已拥有、用户组不在白名单、余额不足均会拦截

  • 佩戴管理:同一时间只能佩戴一个头像框;前台 /frame-my.htm 查看已拥有头像框、佩戴 / 取消佩戴,自动记录佩戴日志

  • 过期管理:购买时按 duration_days(0=永久)计算 expire_time;每日 cron(model_cron_daily_end.php hook)批量清理过期佩戴 + 显示时懒检查(getWearingFrame 命中过期立即卸下并写日志)双重保障

  • 用户组限制:每个头像框可配置 allowed_gids 白名单(逗号分隔,空 = 所有组可购买)

  • 头像框渲染:通过 avatar_component_frame.php hook 注入到 avatar_component_from_data() 内部,覆盖模式 $data['frame_html'] = ...;图片框用绝对定位 <img> 叠加,CSS 框用绝对定位 <div> 叠加,均 pointer-events:none 不影响头像交互

  • 性能优化:FrameService 内置 $userWearCache / $frameCache 请求级静态缓存,帖子列表页同用户多次调用只查一次库,避免 N+1

安装说明

  1. 将插件目录放入 plugin/xnx_avatar_frame/

  2. 进入后台「插件管理」找到「头像框」点击安装,自动建 3 张表并初始化默认配置

  3. 安装后默认启用,可在后台「插件设置」→「全局设置」中关闭

与 xnx_avatar_ai 的互斥提示

本插件与 xnx_avatar_aiconf.jsonhooks_rank 第二段路由标识都是 avatar,安装时系统会弹冲突提示。两者功能完全独立(xnx_avatar_ai 负责 AI 生成头像,本插件负责头像装饰框),可共存,忽略提示即可。

使用指南

后台管理

访问 /admin/plugin-setting-xnx_avatar_frame,包含 4 个 Tab:

Tab

路径参数

用途

头像框列表

?plugin-setting-xnx_avatar_frame-list.htm

新建 / 编辑 / 删除头像框,上传图片,配置价格 / 有效期 / 用户组白名单 / 排序

购买记录

?plugin-setting-xnx_avatar_frame-log.htm

查看所有购买 / 佩戴 / 取消佩戴 / 过期日志,含用户名与花费明细

佩戴记录

?plugin-setting-xnx_avatar_frame-wear.htm

查看当前佩戴中的头像框,含过期时间

全局设置

?plugin-setting-xnx_avatar_frame-settings.htm

开关插件整体启用状态

权限:仅管理员组(gid=1,2)可访问,所有 POST 操作经 CsrfService::check() CSRF 校验。

前台页面

  • 头像框商店:/frame-shop.htm(分页 /frame-shop-{page}.htm)—— 浏览可购买头像框,点击购买扣费

  • 我的头像框:/frame-my.htm —— 查看已拥有头像框列表、剩余有效天数、佩戴 / 取消佩戴

  • 个人中心侧边栏:通过 my_sidebar_nav_threads_before.htm / my_sidebar_nav_threads_before_mobile.htm hook 注入「我的头像框」入口(PC + 移动端双模板)

技术细节

渲染机制

通过 avatar_component_frame.php hook 注入到核心 avatar_component_from_data() 渲染流程。hook 文件读取 $data['uid'],调用 FrameService::getWearingFrame($uid) 获取当前佩戴的头像框,再调 FrameService::renderFrameHtml() 生成 HTML 片段,以覆盖模式 $data['frame_html'] = ... 回传。核心代码零硬编码插件名,插件禁用后 hook 自动不执行,头像恢复正常显示。

框类型实现

  • 图片框(frame_type=0):输出 <img class="avatar-frame-img"> 绝对定位铺满头像容器,z-index:2 叠在头像本体之上

  • CSS 框(frame_type=1):输出 <div class="avatar-frame-css"> 绝对定位铺满,管理员填写的 frame_css 作为内联 style 拼接到 style 属性末尾(已过滤 <?php / ?> 等 PHP 标签字符)

积分扣费

购买流程调用 CreditsService::sub($uid, $price_type, $price_value, '购买头像框: xxx', 0, true),扣费成功后才写入拥有记录;若写入拥有记录失败,扣分不回滚(已在返回信息中提示)。CreditsService::sub 内部已包含事务,无需外层包裹。

过期双重保障

  • 每日 cron:model_cron_daily_end.php hook 触发 FrameService::cleanExpired(),扫描所有 is_wearing=1expire_time>0 的记录,过期的批量卸下并写 expire 日志

  • 显示时懒检查:FrameService::getWearingFrame() 命中过期记录时立即 db_update 卸下、写日志、清缓存,避免 cron 未执行时用户仍看到过期头像框

性能优化

FrameService 内置两个请求级静态缓存:

  • $userWearCache:uid → 佩戴头像框数据(或 null),帖子列表页同一用户多次渲染头像只查一次库

  • $frameCache:frame_id → 头像框定义,避免购买 / 佩戴 / 日志等流程重复查 frame 表

数据表

表名

用途

关键字段

xnx_avatar_frame

头像框定义

id, name, frame_type, frame_image, frame_css, price_type, price_value, duration_days, allowed_gids, sort, enabled

xnx_avatar_frame_own

用户拥有 + 佩戴记录

uid, frame_id, source(buy/gift/admin), cost_type, cost_value, buy_time, expire_time(0=永久), is_wearing;UNIQUE KEY (uid, frame_id)

xnx_avatar_frame_log

操作日志

uid, frame_id, frame_name(冗余), action(buy/wear/unwear/expire), cost_type, cost_value, create_time

所有表使用 utf8mb4 字符集支持 emoji。上传的头像框图片存放在 upload/avatar_frame/ 目录。

兼容性

  • Xiuno X 1.0+

  • PHP 8.x(全局数组访问已加 isset 兜底)

  • Bootstrap 5

  • 无 jQuery 依赖(前台交互使用原生 JS)

  • 通过 avatar_component_frame.php hook 与核心头像组件解耦,核心代码无硬编码插件名

版本历史

  • 1.0.0:首版发布,包含头像框 CRUD、商店购买、佩戴管理、过期清理、用户组白名单、图片框 / CSS 框双类型渲染



头像框 截图

头像框 截图

头像框 截图

头像框 截图



版本:v1.0.0
适用版本:1.1
开发者:贰先生

请登录后查看此内容
最新回复

请先登录后再回复 登录