• one
    勋章管理插件
    ID medal版本 1.6.3插件制作者 one售价 20 积分2701 行 / 160.2 KBHook / 路由 / 后台页
    创建勋章、设置自动发放规则并按条件授予用户,支持手动发放回收、有效期与持有统计,可自定义勋章底色、渐变底色、边框颜色与边框圆角,并可配置帖子与列表页勋章的展示形态、位置及头像角标佩戴。
    收费插件安装说明购买后点击“授权码”获取一次性授权码;在后台 > 插件广场点击在线安装或更新,并填写该授权码。已购买用户更新免费:每次在线安装或更新前,重新点击“授权码”获取新的一次性授权码即可,无需再次购买;也可直接下载新版后用后台“插件上传”更新。尊重并感谢他人劳动,请勿传播代码。
    app/plugins/medal/plugin.php
    开发日志已有 7 条

    个人独立维护项目。

    • bbs1org
      bbs1org
      版本 1.6.3 1d038a4b2d67 更新:采用个人设置新hookrelease
    • one
      one
      版本 1.6.2 2c1c2ba9808e 更新:### Added - 勋章渐变底色:勋章编辑表单新增「渐变底色」颜色项(`gradient_color`,含于 install 建表语句),启用后徽章底色沿对角线(135°)向渐变色过渡(CSS 变量 `--medal-gradient`);未设置时保持原纯色底观感。后台勋章列表胶囊与编辑表单实时预览同步生效。 ### Changed - 渐变底色改为显式开关(`gradient_enabled
    • bbs1org
      bbs1org
      版本 1.6.1 1c534d7dd9db 更新:优化细节
    • bbs1org
      bbs1org
      版本 1.6.0 f6dcf1bfc461 更新:优化移动端UI
    • bbs1org
      bbs1org
      版本 1.6.0 0c25a5b50c19 更新:一、性能优化(核心:缓存 + 批量查询) ### 1. 勋章定义写入「插件持久缓存」 - 新增 medal_meta(),借助核心 settings_rows_cache() 将启用勋章的定义(名称/图标/说明/底色/圆角/边框色/文字色/排序)缓存在 app_settings 。 - 勋章定义只有缓存为空时才查一次勋章表,跨请求复用;同一请求内二次命中直接走内存 $GLOBALS['__meda
    • one
      one
      版本 1.2.2 003f4303bc16 更新:### Fixed - 规则引擎在 MySQL 下报 SQLSTATE 42000(插件被自动停用):`medal_user_metrics()` / `medal_user_metric_single()` 使用 `CAST(... AS INTEGER)`,MySQL 仅支持 `SIGNED/UNSIGNED`;新增 `medal_cast_int()` 按驱动生成 `SIGNED`(MySQ
    • one
      one
      版本 1.2.1 531516958238 更新:强大的勋章管理系统。这个插件做好了有一段时间了今天修复适配论坛8.8版本并首次发布 1.2.1。 主要功能:论坛勋章系统——勋章定义、自动发放规则、手动发放回收、持有统计与多种展示形态设置。 在使用过程遇到问题,欢迎在本贴交流。(附上具体怎么复现,和错误代码)
    主楼
  • one

    版本 1.2.1 更新:
    强大的勋章管理系统。这个插件做好了有一段时间了今天修复适配论坛8.8版本并首次发布 1.2.1。

    主要功能:论坛勋章系统——勋章定义、自动发放规则、手动发放回收、持有统计与多种展示形态设置。

    在使用过程遇到问题,欢迎在本贴交流。(附上具体怎么复现,和错误代码)

    #1
  • 质量报告

    插件质量报告

    插件:medal

    Hook功能范围循环使用频率文件读写修改系统表读写系统表读写自己的表
    app.boot全站请求启动否5----
    page.before_render全站页面输出前回调内5---读 plugin_medal_user_medals, plugin_medal_medals, plugin_medal_user_prefs 修正❗️
    reply.after_render主题查看页/回帖列表逐条渲染是5---读 plugin_medal_medals, plugin_medal_user_medals, plugin_medal_user_prefs 修正❗️
    topic.after_render首页/版块列表/主题查看逐条渲染是5---读 plugin_medal_medals, plugin_medal_user_medals, plugin_medal_user_prefs 修正❗️
    reply.after_save回帖保存后回调内3--app_users, app_topics, app_replies写 plugin_medal_logs, plugin_medal_rules;读 plugin_medal_medals, plugin_medal_user_medals 修正❗️
    topic.after_save主题保存后回调内3--app_users, app_topics, app_replies写 plugin_medal_logs, plugin_medal_rules;读 plugin_medal_medals, plugin_medal_user_medals 修正❗️
    user.after_save用户注册/资料保存后回调内3--app_users, app_topics, app_replies写 plugin_medal_logs, plugin_medal_rules;读 plugin_medal_medals, plugin_medal_user_medals 修正❗️
    user.points_changed用户积分变动后回调内3--app_users, app_topics, app_replies写 plugin_medal_logs, plugin_medal_rules;读 plugin_medal_medals, plugin_medal_user_medals 修正❗️
    profile.settings_tab_content非系统hook否1---读 plugin_medal_user_medals, plugin_medal_medals, plugin_medal_user_prefs
    profile.settings_tabs非系统hook否1----

    颜色说明:黄色表示有数据读写,红色表示 Hook 在系统循环中执行,浅蓝色表示有文件写入。“列表跳过”表示回调在列表路径会提前返回,“回调内”表示操作位于回调自身或其帮助函数的循环体内。“文件批处理”表示逐个处理用户一次提交的文件,属于必要操作,不标记修正。只有操作实际处于需要优化的循环路径时,才会标记“修正❗️”。

    数据字典

    plugin_medal_medals

    字段类型可空默认值约束
    idid否-主键、自增
    namestring否--
    iconstring否''-
    textstring否''-
    colorstring否'#6c8cff'-
    radiusuint否999-
    border_colorstring否''-
    text_colorstring否''-
    gradient_enableduint否0-
    gradient_colorstring否''-
    bg_alphauint否16-
    enableduint否1-
    sortuint否0-
    duration_daysuint否0-
    expire_atuint否0-
    created_atuint否--

    plugin_medal_user_medals

    字段类型可空默认值约束
    medal_iduint否-主键
    user_iduint否-主键
    sourcestring否'manual'-
    rule_iduint否0-
    created_atuint否--
    expires_atuint否0-

    plugin_medal_rules

    字段类型可空默认值约束
    idid否-主键、自增
    medal_iduint否--
    namestring否''-
    conditionstext否--
    logicstring否'and'-
    enableduint否1-
    last_run_atuint否0-
    granted_totaluint否0-
    created_atuint否--

    plugin_medal_logs

    字段类型可空默认值约束
    idid否-主键、自增
    medal_iduint否--
    user_iduint否--
    actionstring否--
    sourcestring否'manual'-
    rule_iduint否0-
    operator_iduint否0-
    created_atuint否--

    plugin_medal_user_prefs

    字段类型可空默认值约束
    user_iduint否-主键
    avatar_medal_iduint否0-
    #2
  • zaiwai

    可以不错的哦。

    #3
  • one

    过奖啦😀

    #4
  • code

    自动停用原因
    2026-08-30 02:56:50 PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INTEGER) AS reg_days,COALESCE(t.cnt,0) AS topics,COALESCE(r.cnt,0) AS replies FR' at line 1 (index.php:285)

    #5
  • one

    小问题,我一会儿修复它(。之前就修复了,对齐版本号的时候对数据库进行优化导致的)

    #7
  • code

    paste-20260830-030003.png

    点击立即执行就出错了!

    paste-20260830-030034.png

    #6
  • one

    已修复,请重新下载,有问题请反馈。

    #9
  • one

    版本 1.2.2 更新:

    Fixed

    • 规则引擎在 MySQL 下报 SQLSTATE 42000(插件被自动停用):medal_user_metrics() / medal_user_metric_single() 使用 CAST(... AS INTEGER),MySQL 仅支持 SIGNED/UNSIGNED;新增 medal_cast_int() 按驱动生成 SIGNED(MySQL)或 INTEGER(SQLite/PG)。同时将内部 LIMIT 参数由占位符改为 int 内联,规避 PDO 绑定差异。
    • 勋章本体绝对有效期(expire_at)已过但仍启用时,自动规则每次运行都会生成「即刻到期」的持有记录,随后被 cron 回收、下一轮又再发放,形成发放/回收日志死循环;现于 medal_grant()、medal_batch_insert_held() 及规则评估的勋章有效性查询(expire_at=0 OR expire_at>?)三处拒绝发放已过期的勋章。

    Changed

    • 手动发放的跳过提示补充「勋章已过期」原因。
    • UI微调
    #8
  • bbs1org

    后台界面,缺少个padding
    paste-20260830-103414.png

    #10
  • one

    不要在意细节,先跑通所有功能,再同意搞UI

    #11
  • bbs1org

    最好统一到用户名下面那一行
    paste-20260830-103607.png

    #12
  • one

    你是没认真看后台吧,可设置展示位置的。

    #14
  • bbs1org

    可以了。再完善设置,可以显示最前面或者最后面

    #16
  • one

    可以显示最前面或者最后面?这个我没太理解。
    是多勋章时的显示位置?可以通过排序调整

    #17
  • bbs1org

    整体思路非常棒!加油

    #13
  • one

    给我也加一个😀

    #15
  • x

    这个金牌🏅️,你是值得的

    #18
  • one

    哈哈哈。没毛病,打磨了至少有20个版本+。应该是从v8.6.0开始开发的
    如果有逻辑上的问题,欢迎大家交流。功能基本就是这样了(个人觉得已经牛逼不得强了)

    #19
  • x

    慢慢优化,越来越好

    #20
  • bbs1org

    版本 1.6.0 更新:
    一、性能优化(核心:缓存 + 批量查询)

    1. 勋章定义写入「插件持久缓存」

    • 新增 medal_meta(),借助核心 settings_rows_cache() 将启用勋章的定义(名称/图标/说明/底色/圆角/边框色/文字色/排序)缓存在 app_settings

    。

    • 勋章定义只有缓存为空时才查一次勋章表,跨请求复用;同一请求内二次命中直接走内存 $GLOBALS['__medal_meta'],逐条渲染零重复构建。
    • 每次勋章写操作(新增/编辑/删除/单切/批量启停/批量删除/卸载)都会 medal_cache_clear() 失效缓存,改动即时生效。

    2. 用户持有记录:由「全表扫描」改为「整页一次 IN 查询」

    • 彻底删除了原先每次任何列表/看帖请求都在启动时全表拉整站持有记录 + 全站排序的重活。
    • 官网钩子(topic.after_render/reply.after_render)是逐条触发、无法预知整页作者,因此创新采用「唯一占位符 + 整页回填」方案:
    • 渲染时只在精确锚点埋入 <!--medal-{随机token}-{uid}-->(自带作者 id,防正文伪造);
    • 在核心 page.before_render(整页最终 hooks)里,用一条 WHERE user_id IN (…) 查询批量取回本页所有作者持有记录,内存里与缓存勋章定

    义 join 后一次性回填所有占位符;

    • 无勋章作者 → 占位符替换为空(原地消失),无占位符页面 → 零开销直接返回。
    • 每页只发一条持有查询(不再按作者 N 条),复杂度从 O(整站持有量) 降至 O(每页作者 ∪ 一次)。
    • AJAX 内联发帖/回帖(走 json_response 绕开 page())单独走 medal_inject_post_badges_inline() 单作者直连,避免"新回帖占位符滞留"。

    3. 附带修掉一个隐藏 bug

    公开页徽章原先只透传了 color,新版勋章定义完整进入渲染,radius / border_color / text_color 现在在帖子与列表徽章上都能如实显示。

    ────────────────────────────────────────────────────────────────────────────────

    二、功能增强:勋章「文字颜色」

    • 新增 text_color 列(建表 + app_db_ensure_columns 双保险,幂等升级旧库);
    • 所有读取(medal_meta / 管理列表 / 个人资料页)均带上该列;
    • medal_style() 输出 --medal-text-color,留空时回退主题色;.medal-badge 与 .medal-medal-check 均消费该变量;
    • 后台表单新增「文字颜色」取色器,实时预览 JS 同步联动,#RRGGBB 校验后入库。

    ────────────────────────────────────────────────────────────────────────────────

    三、UI / 细节修正

    • 修复 medal_field_label 误写导致的 Call to undefined function medal_field() 崩溃;
    • 修复文字颜色在管理页不生效——给 .medal-medal-check 补上 color:var(--medal-text-color,var(--text));
    • 依据你的要求,勋章徽章样式彻底去除 font-weight(.medal-badge、帖子行内、纯文字形态、管理页勋章胶囊四类)。
    #21
  • one

    不错啊,展示为头像右下角时,对于除了ICO外空白的部分做50%遮罩更漂亮了。

    #23
  • bbs1org

    做完插件,记得跟ai说一句:优化性能,不要在循环中查询数据库。这一条非常重要。

    #24
  • one

    好吧,我忘记了。(请你写入到开发者文档)

    #25
  • bbs1org

    版本 1.6.0 更新:
    优化移动端UI

    #22
  • bbs1org

    版本 1.6.1 更新:
    优化细节

    #26
  • demius

    bbs老大发积分了,有积分任性买了!😚

    #27
  • one

    真值这个价,物超所值👍
    使用过程中有问题随时反馈😊

    #28
  • one

    版本 1.6.2 更新:

    Added

    • 勋章渐变底色:勋章编辑表单新增「渐变底色」颜色项(gradient_color,含于 install 建表语句),启用后徽章底色沿对角线(135°)向渐变色过渡(CSS 变量 --medal-gradient);未设置时保持原纯色底观感。后台勋章列表胶囊与编辑表单实时预览同步生效。

    Changed

    • 渐变底色改为显式开关(gradient_enabled,默认关闭):关闭时勋章只显示底色(单色),开启后底色沿对角线(135°)向渐变色过渡;关闭时渐变色选择器原生禁用(disabled)不可选色,保存时清空渐变色;实时预览同步跟随开关。
    • 勋章新增「底色透明度」自定义(bg_alpha,0-100%,默认 16%,即原固定着色浓度):底色与渐变色共用该浓度,后台表单与实时预览同步生效。
    • 重构后台「新增/编辑勋章」表单布局:拆分为「基础信息 / 外观样式 / 有效期与状态」三个分区卡片,同类字段网格排布;实时预览移至「基础信息」与「外观样式」之间;基础信息长度提示并入输入框 placeholder;渐变底色说明改为开关悬停气泡以省空间;表单解除核心 .plugin-settings-form 520px 宽度限制铺满 plugin-panel-body,「保存勋章」按钮改为左对齐。
    • 个人资料页「获得的勋章」及后台规则列表等处勋章悬停说明由浏览器原生 title 统一改为主题化 CSS 悬停气泡(data-medal-tip,复用核心设计令牌,明暗主题自适应)。

    Fixed

    • 列表页「头像右下角」角标改为纯图标呈现:去除勋章自带边框、圆角与底色透明度(bg_alpha)对角标的影响,角标始终为圆形无边框;背景层(勋章底色→渐变色过渡)独立于 ::before,着色浓度由新增设置「头像角标底色透明度」(0-100%,默认 50%,仅 avatar 模式下可编辑)控制,磨砂随透明度联动(0% 时关闭磨砂呈现纯图标,其余值轻度磨砂 2px),Emoji 图标本体始终 100% 不受任何透明度影响。
    • 个人资料页「头像角标佩戴」保存按钮由 .btn alt 次级胶囊样式改为核心全局官方提交按钮样式,与前台表单主题一致。
    • 后台勋章管理悬停勋章显示的说明文字由浏览器原生 title 改为主题化 CSS 悬停气泡(data-medal-tip,复用核心设计令牌,明暗主题自适应)。

    用GLM5.3 打磨了一上午,消耗积分700+,非重大问题不再处理,收工。

    #29
  • bbs1org

    版本 1.6.3 更新:
    启用新的个人设置页面hook

    #30
  • bbs1org

    版本 1.6.3 更新:
    采用个人设置新hook

    #31
  • Moo

    🌹🌹

    #32

发表回复

登录后回复