- 多维评分与编辑精选ID rate_pick版本 2.2.0插件制作者 cxk123售价 30 积分3347 行 / 204.5 KBHook / 路由 / 后台页把点赞升级成打分:每个主题可以按有用、清晰、深度等多个维度打 1 到 5 分,一人一维只算一条、随时能改,收费插件安装说明购买后点击“授权码”获取一次性授权码;在后台 > 插件广场点击在线安装或更新,并填写该授权码。已购买用户更新免费:每次在线安装或更新前,重新点击“授权码”获取新的一次性授权码即可,无需再次购买;也可直接下载新版后用后台“插件上传”更新。尊重并感谢他人劳动,请勿传播代码。app/plugins/rate_pick/plugin.php插件预览5 张开发日志已有 5 条
此项目接受所有登录用户协助维护和提交更新。
主楼 版本 1.0.0 更新:
rate_pick 1.0.0 首次上架 · 多维评分与编辑精选
把「点赞 / 顶踩」升级成一条完整链路:同一人 × 同一主题 × 多维打分 → 加权总分 → 依分排序 → 精选留档。
四项能力
- 多维评分与加权总分:维度是版块级的(默认 有用 / 清晰 / 深度,权重 1–9 可调、可停用、可整条覆盖),
每人每维 1–5 分,一人一维一条、可改不可重复(改了就是更新那一行,永远不会出现第二条);
总分 = Σ(分×权重) / Σ权重 归一化到 0–100,再做贝叶斯收缩 (n·avg + m·C)/(n+m)(m / C 后台可调),
挡住「1 个人打 5 星就登顶」。主题页给逐维评分条(含权重与人数)+ 总分 + 原始加权分 + 评分人数 + 可信度档。- 防刷:硬门槛(积分 ≥20 / 注册 ≥7 天 / 非楼主 / 非封禁,全部可调),不满足就不落库并给出点名到数字的提示;
账号按时长与积分分档;聚集识别——同一主题、同一维度、同一个分数,72 小时内出现 ≥4 个低档账号时
整组标记可疑:不计入总分、绝不删数据、逐条留痕,后台可以复核恢复(两个方向都可反复)。- 按评分排序 + 高分徽章:独立评分榜(收缩分排序,支持时间窗与版块筛选,另带编辑精选页签);
列表页支持 ?rate_sort=1 的页内浮动(只重排本页、不动分页,因此后台默认关闭、显式打开才生效);
总分 ≥80 且评分人数 ≥5 自动获得「高分」徽章。不写核心置顶列表、不改核心表结构。- 编辑精选与理由留档:设精选必须填理由(默认 ≥8 字),可带标签、可设到期、可置顶;
设为 / 改理由 / 取消 / 到期下架逐条 append-only 留档,后台可查、可导出 CSV(公式注入已中和);
到期由计划任务以 CAS 幂等下架,重叠运行也不会重复留档。工程口径(实测)
- 首页 / 版块列表 +1 条批查(行数翻倍不变);站上一条评分都没有时 +0 且页面字节与未装一致;
- 主题页 +2;评分榜 4;后台 3;提交固定 4 条(与维度数、行数无关);
- 汇总永不增量累加:每次提交用一条 GROUP BY 从票表整体重算,另提供后台分块重建;
- 匿名区(anon_board)已装时,精选条与榜单先整批遮蔽再渲染,匿名主题不会因为进了精选而露出真身。
插件质量报告
插件:
rate_pickHook 功能范围 循环 使用频率 文件读写 修改系统表 读写系统表 读写自己的表 sidebar.feature_links 首页/侧栏快捷功能 否 5 - - - - top.bar.actions 顶部栏插件入口,同一请求只执行一次(展示位置:版块导航与搜索框前后) 否 5 - - - - topic.after_render 首页/版块列表/主题查看逐条渲染 是 5 - - - - topic.index_data.loaded 首页/版块/用户主题列表查询后 否 5 - - app_topics, app_users 写 plugin_rate_pick_votes, plugin_rate_pick_totals, plugin_rate_pick_picks, plugin_rate_pick_dims, plugin_rate_pick_log topic.title_suffix 首页/版块主题列表逐条标题 是 5 - - - - diy_layout.components 非系统hook 否 1 - - - - topic.index_template 非系统hook 否 1 - - app_topics, app_users 读 plugin_rate_pick_picks topic.template 非系统hook 否 1 - - app_topics 写 plugin_rate_pick_votes, plugin_rate_pick_picks, plugin_rate_pick_dims, plugin_rate_pick_log, plugin_rate_pick_totals 颜色说明:黄色表示有数据读写,红色表示 Hook 在系统循环中执行,浅蓝色表示有文件写入。“列表跳过”表示回调在列表路径会提前返回,“回调内”表示操作位于回调自身或其帮助函数的循环体内。“文件批处理”表示逐个处理用户一次提交的文件,属于必要操作,不标记修正。只有操作实际处于需要优化的循环路径时,才会标记“修正❗️”。
数据字典
plugin_rate_pick_dims字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_rate_pick_votes字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_rate_pick_totals字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_rate_pick_picks字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_rate_pick_log字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 不知道这个是搞大众点评吗
版本 1.0.1 更新:
rate_pick 1.0.1- 新增给「页面组件 DIY」的原生只读组件「高分与精选」(rate_pick:picks):高分主题(收缩后总分 + 评分人数)与编辑精选(推荐理由、置顶标记),声明成本 6 条。
- 隐私口径:高分榜与精选条先整批过匿名区遮蔽契约(anon_board.mask_rows),再判可见性;匿名行渲染成「匿名用户」且不给主页链接,实名行照常带链接。
- 降级与隔离:无数据 / 开关关闭时零查询返回空块;遮蔽契约抛异常按「遮不了就不显示」处理(整块降级,绝不输出未遮蔽的行);渲染回调不抛异常。
- 参数:条数 2-10(只改 LIMIT 绑定值,查询条数不变)与两个分段开关。
- 未装 / 未启用 layout_diy 时行为、查询数、页面字节逐字节不变(套件有 A/B 对照)。
- 兼容性修复:维度种子改用三驱动通用的「插入忽略」SQL(原先手写 ON CONFLICT 方言,MySQL 上 install 会语法错)。
版本 2.0.0 更新:
rate_pick 2.0.0
四条新能力
- 评分分布与分歧度:主题页的每个维度除了均分,还给 1–5 分分布条(各分数各多少人)与该维度的
加权标准差 σ;面板头给出总体分歧档「一致 / 略有分歧 / 分歧较大」。
「2 人打 1 分 + 2 人打 5 分」与「4 人全打 3 分」均分几乎一样,现在一眼能分开。
评分榜新增 按分歧排序(?sort=spread),列表行与「高分与精选」组件同步显示分歧徽章。
查询数 +0:分布与 σ 出自主题页原有的那一条汇总查询(分组键由「维度」扩成「维度 × 分数」),
分歧度在 SQL 侧只攒一个整数和(Σ 权重×分²),开方与开档在 PHP 里做。- 汇总口径自愈:改维度 / 改权重 / 改高分阈值之后,专题页(实时口径)与榜单页(快照口径)
不再各说一个分数 —— 写路径当场把汇总标脏并推进一块重建,计划任务每轮继续追平,后台显示同步状态与游标。
- 「我的评分」中心(
?a=rate_pick_mine):登录用户能看到自己评过哪些主题、各自给了几分、
主题当前总分与分歧档,并可逐条撤回(POST + token;撤回只删自己那一组行,会立刻重算汇总)。
- 编辑精选闭环:主题页也有了精选徽章 + 推荐理由 + 标签 + 入选/到期时间;
到期在读取时立刻失效(不再依赖计划任务先跑),后台把这种状态标成「已过期(读路径已下架)」。
修掉的缺陷
- 改维度权重 / 增删维度后,
_totals快照不同步 → 同一主题在主题页与榜单页显示两个分数(实测 70.8 vs 67.3)。 - 后台重建 / 计划任务把
_totals.updated_at刷成当前时间 → 「近 7/30/90 天」把 100 天前的主题也算进来。
现在时间窗读
last_vote_at(票表最近一次投票时间),重建不再改它。- 聚集识别误伤资深账号:第 4 票由
weight_tier=3的账号投出时,它自己那一票也被标成可疑、不计入总分。
现在「是否跨过阈值」与「自己是否低档」是两个判定。
- 聚集前置计数把自己上一次的旧票算进「已有 N 个低档同分账号」→ 3 个账号也能凑出「≥4」的假聚集。
计数现在排除提交者自己。
- 精选过期后仍展示(首页精选条 / 榜单精选页签 / 列表徽章 / 后台状态都还算「生效中」)→ 读路径统一带时间判定。
- 精选主题点进主题页看不到推荐理由(只在列表与精选条有)→ 主题页补上精选块。
兼容
- 未装
layout_diy时行为与此前完全一致(组件注册惰性,A/B 逐字节+逐页 SQL 数对照)。 - 未装/停用匿名区时,精选条与榜单行原样渲染(零查询);装上后匿名行先遮蔽再判定可见性,匿名的行不给主页链接。
- 数据表自动补列(
sum_w_sq/last_vote_at)与时间窗过渡口径都已处理:老库升级后第一次进后台或下一轮
计划任务会自动把汇总追平,不需要手工重建。
版本 2.1.0 更新:
rate_pick 2.1.0
新能力:评分口径的版本化与历史对照
- 口径版本号:决定分数怎么算的那一组东西(维度与权重 + 高分阈值 + 贝叶斯参数 + 分歧阈值)每次真的发生变化,
都会抬一个
rev、写一份完整快照(逐维度权重与启用状态 + 四个阈值 + 操作人 + 时间 + 来源)。- 逐项 diff 留档:每次变更向 append-only 留档追加一条人话记录,例如
改维度:默认 useful 权重 3→9、改评分设置:高分阈值 80→85—— 后台可直接查历史。- 每行汇总记住自己的口径:
_totals.caliber_rev记下这行是哪个版本算的;后台给出「待同步主题数」。 - 变更前后对照:
prev_score100留着本轮变更前的分数 → 后台直接给出「本轮有多少主题分数变了 / 上升 / 下降 / 最大变化多少」。 - 前台:主题页与榜单页标出当前口径版本(零额外查询);后台口径面板与口径历史都并进原有语句,后台查询数仍是 3。
修的缺陷(真并发 + 升级路径交叉面)
- 并发首请求下,表结构自愈会把整个插件打下线:老库覆盖新文件后,两个 worker 同时补列 → 后到的那条抛
duplicate column name,异常冒到核心 → 核心按规矩自动停用整插件(实测enabled=0 / status=error,而数据其实完好)。
现在整个自愈过程不抛异常、竞态也算成功、结构没补齐就不写标记(下次请求重试)。
同一场景实测:2.0.0 → 插件被停用;2.1.0 → 6 个并发首请求全 200、插件正常、12 列与 9 枚索引齐备、老数据完整、口径自动追平。- 口径留档刚写就被孤儿清理删掉:留档表的口径行是全局行(
topic_id=0),而孤儿清理按「主题是否还存在」删行 ——
于是 rev 一直在涨、留档却永远是 0 条。现在孤儿清理只针对
topic_id>0。- 脏标记清不掉 / 展示口径与判定口径不一致:落后行的判定与执行器覆盖的集合不一致(无票空壳卡住收敛),
且后台显示的「待同步数」与清脏标记用的判据一度不是同一段 SQL。现在两者共用唯一实现,且只数「带票主题」。
- 顺带把「走完一圈」的收口判据从启发式(本块没取满)换成数据驱动(数落后行,为 0 才清)。
兼容
- 老库(1.0.x 结构)覆盖新文件后一发请求自愈,不需要停用/启用插件,也不需要手工重建:自动补列补索引、补记口径快照、标脏并由分块重建追平。
- 未装
layout_diy时行为与此前一致(组件注册惰性,逐字节 + 逐页 SQL 数对照);未装/停用匿名区时精选条与榜单行原样渲染(零查询)。 - 预算不变:两标记都 0 时首页 0;live/picks 打开时首页 +1/+2/+3、主题页 2/3、榜页 3/4、我的评分 2、后台 3、提交 4。
版本 2.2.0 更新:
2.2.0 · 榜单口径与可见性- 修复(用户可见):
?days=时间窗的条件写成「表达式与绑定参数比较」,在本站使用的 SQLite 上恒为假 ⇒ 「近 7 / 30 / 90 天榜」一直是空榜。已改为内联整数(语句与参数个数不变)。 - 修复:无筛选时
voters>0守卫被拼进了LEFT JOIN的ON子句、不再是过滤条件 ⇒ 撤回评分产生的 0 票「壳行」会按贝叶斯先验显示成「70.0 分 · 0 人」并压过真实评分主题;计数 SQL 与列表口径也不一致。已改为单源WHERE(计数与行集合由构造保证一致),并给分歧度排序的分母加除零兜底(在 PostgreSQL 上除零会抛错并导致插件被自动停用)。 - 修复:口径版本化的「本轮变化」对照张冠李戴 —— 重算会刷口径版本号却不更新基线,后台把新旧基线直接相减出现幽灵数字。现在「分数算在哪一版」与「基线取自哪一版」分开记录。
- 修复(越权):榜单、筛选条与「高分榜」DIY 组件此前没有任何版块可见性判定 ⇒ 「仅指定用户组可见」版块的主题标题会出现在公开榜单里。已与核心同一口径过滤(站内没有受限版块时 SQL 文本逐字节不变)。
- 附带:卸载补删一枚索引(口径补齐)。
升级:覆盖文件即自愈(含新增列),无手工步骤。
- 修复(用户可见):