[event_rsvp]活动报名热
- 活动报名ID event_rsvp版本 12.3.0插件制作者 cxk123售价 30 积分9211 行 / 555.3 KBHook / 路由 / 后台页12.3.0:**运行期结构自愈**(把新版文件覆盖进插件目录、没跑 install 时,老库缺表缺列不再收费插件安装说明购买后点击“授权码”获取一次性授权码;在后台 > 插件广场点击在线安装或更新,并填写该授权码。已购买用户更新免费:每次在线安装或更新前,重新点击“授权码”获取新的一次性授权码即可,无需再次购买;也可直接下载新版后用后台“插件上传”更新。尊重并感谢他人劳动,请勿传播代码。app/plugins/event_rsvp/plugin.php插件预览4 张开发日志最新 10 条
此项目接受所有登录用户协助维护和提交更新。
主楼 版本 1.0.0 更新:
1.0.0- 发布活动:标题、时间(开始/结束/报名截止)、地点、人数上限、可选报名费用(积分)。
- 在线报名:名额未满直接报名,满员自动进入候补队列;有人取消时按顺序自动补位并通知本人。
- 签到核销:活动开始前可自助签到,发起人与管理员可在名单里代签到或撤销签到。
- 站内提醒:活动开始前按后台配置的小时数自动提醒报名者,每个活动只提醒一次。
- 后台管理:活动概览、最近活动与报名/签到人数、立即结束过期活动、8 项站点设置。
- 入口:顶部栏「活动」、首页侧栏「活动报名」、个人卡片「我的活动」。
插件质量报告
插件:
event_rsvpHook 功能范围 循环 使用频率 文件读写 修改系统表 读写系统表 读写自己的表 page.footer 全站页面页脚 否 5 - - - - sidebar.feature_links 首页/侧栏快捷功能 否 5 - - - - top.bar.actions 顶部栏插件入口,同一请求只执行一次(展示位置:版块导航与搜索框前后) 否 5 - - - - user.menu_links 个人卡片/移动端我的菜单(展示位置:个人卡片) 否 4 - - - - topic.after_save 主题保存后 否 3 - - app_users 写 plugin_event_rsvp_events, plugin_event_rsvp_signups, plugin_event_rsvp_credit, plugin_event_rsvp_slots, plugin_event_rsvp_audit, plugin_event_rsvp_reviews, plugin_event_rsvp_subs, plugin_event_rsvp_templates, plugin_event_rsvp_series, plugin_event_rsvp_helpers, plugin_event_rsvp_template_shares, plugin_event_rsvp_notices, plugin_event_rsvp_refunds, plugin_event_rsvp_changes, plugin_event_rsvp_acks topic.before_delete 主题删除操作 否 2 - - app_users 写 plugin_event_rsvp_events, plugin_event_rsvp_signups, plugin_event_rsvp_credit, plugin_event_rsvp_slots, plugin_event_rsvp_audit, plugin_event_rsvp_reviews, plugin_event_rsvp_subs, plugin_event_rsvp_templates, plugin_event_rsvp_series, plugin_event_rsvp_helpers, plugin_event_rsvp_template_shares, plugin_event_rsvp_notices, plugin_event_rsvp_refunds, plugin_event_rsvp_changes, plugin_event_rsvp_acks diy_layout.components 非系统hook 否 1 - - - - 颜色说明:黄色表示有数据读写,红色表示 Hook 在系统循环中执行,浅蓝色表示有文件写入。“列表跳过”表示回调在列表路径会提前返回,“回调内”表示操作位于回调自身或其帮助函数的循环体内。“文件批处理”表示逐个处理用户一次提交的文件,属于必要操作,不标记修正。只有操作实际处于需要优化的循环路径时,才会标记“修正❗️”。
数据字典
plugin_event_rsvp_subs字段 类型 可空 默认值 约束 id id 否 - 主键、自增 user_id uint 否 - 唯一 category key 否 - 唯一 created_at uint 否 - - plugin_event_rsvp_events字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_event_rsvp_signups字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_event_rsvp_reviews字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_event_rsvp_slots字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_event_rsvp_templates字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_event_rsvp_series字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_event_rsvp_helpers字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_event_rsvp_audit字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_event_rsvp_template_shares字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_event_rsvp_notices字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_event_rsvp_refunds字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_event_rsvp_credit字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_event_rsvp_changes字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 plugin_event_rsvp_acks字段 类型 可空 默认值 约束 - 动态定义 - - 无法静态解析 - bbs1org2026-09-29
这个很实用👏
- huaxiaoji6天前
- bbs1org6天前
版本 2.0.0 更新:
2.0.0(大更新)- 报名审核:活动可开启「报名需审核」,报名先进入待审核,发起人一键通过/拒绝;通过时才占用名额,满员自动转候补。
- 签到口令:可切换为「现场口令签到」,报名者需输入你公布的 6 位口令才能签到,口令可随时重置。
- 报名提问与留言:活动可设置一个报名问题(如饮食禁忌),答案在名单与导出文件里可见。
- 候补上限:可为候补队列单独设上限,候补满了就不再收人。
- 活动分类与草稿:后台维护分类,列表可按分类筛选;发布前可先存草稿,草稿仅自己可见,随时一键发布。
- 取消截止:可设置活动开始前多少小时起禁止取消报名,避免临时放鸽子(管理团队不受限)。
- 导出与日历:发起人可导出报名名单 CSV(含留言),任何访客都能把活动加入自己的日历(.ics)。
- 论坛打通:活动可一键发到论坛讨论帖,活动页自动回链该主题。
- 结束小结:活动结束后自动给发起人发送报名/候补/实到人数小结。
- 增强联动:发布活动会通知你的粉丝(需启用「关注与动态」插件,安装则生效、未装则静默跳过)。
版本 3.0.0 更新:
3.0.0 更新
· 报名表单:可自定义最多 6 道题(单行文本、多行文本、数字、电话、下拉选择、单选按钮、勾选确认),支持必填与选项校验,名单与导出按题展示
· 扫码签到:活动页直接生成签到二维码,可投屏或一键打印;参与者手机扫码即可自助签到,原有的口令签到照常可用
· 自动讨论帖:发布活动时可在指定版块自动创建讨论帖,之后改标题或介绍会同步更新,帖子被删除时自动断开回链
· 活动评价:活动结束后,报名参与者可以打星、写感受、晒现场照片,页面显示平均分;发起人可删除不当评价
· 细节打磨:报名记录签到时间、名单可见签到时间;后台新增「自动建帖版块」与「允许评价」设置;「活动发布后通知我的粉丝」开关现在真正生效这个插件不错
版本 4.0.0 更新:
4.0.0 更新
· 多场次报名:一场活动可以拆成多个场次(最多 12 场),每场有自己的时间和名额;报名时先选场次,名额按场次单独计算,候补也会按场次自动补位
· 封面与图集:可以给活动设一张封面(列表里显示缩略图,详情页显示大图)和最多 6 张现场图片
· 数据面板:活动详情页给发起人一块面板,一眼看到报名/待审/候补/签到/评价/积分收入,以及每个场次的报名进度条
· 二次提醒:除了提前几小时提醒,还能设置「开始前 N 分钟再提醒一次」(默认 60 分钟),改活动时间会自动重新计时
· 导出升级:报名名单多出「场次」一列;加入日历时,多场次活动会生成每个场次各自的日程版本 4.0.0 更新:
4.0.0 更新
· 多场次报名:一场活动可以拆成多个场次(最多 12 场),每场有自己的时间和名额;报名时先选场次,名额按场次单独计算,候补也会按场次自动补位
· 封面与图集:可以给活动设一张封面(列表里显示缩略图,详情页显示大图)和最多 6 张现场图片
· 数据面板:活动详情页给发起人一块面板,一眼看到报名/待审/候补/签到/评价/积分收入,以及每个场次的报名进度条
· 二次提醒:除了提前几小时提醒,还能设置「开始前 N 分钟再提醒一次」(默认 60 分钟),改活动时间会自动重新计时
· 导出升级:报名名单多出「场次」一列;加入日历时,多场次活动会生成每个场次各自的日程版本 4.0.0 更新:
4.0.0 更新
· 多场次报名:一场活动可以拆成多个场次(最多 12 场),每场有自己的时间和名额;报名时先选场次,名额按场次单独计算,候补也会按场次自动补位
· 封面与图集:可以给活动设一张封面(列表里显示缩略图,详情页显示大图)和最多 6 张现场图片
· 数据面板:活动详情页给发起人一块面板,一眼看到报名/待审/候补/签到/评价/积分收入,以及每个场次的报名进度条
· 二次提醒:除了提前几小时提醒,还能设置「开始前 N 分钟再提醒一次」(默认 60 分钟),改活动时间会自动重新计时
· 导出升级:报名名单多出「场次」一列;加入日历时,多场次活动会生成每个场次各自的日程版本 5.0.0 更新:
5.0.0 更新
· 座位/分组分配:发起人可以在报名名单里直接给每位参与者填写座位或分组(例如「A 区 3 排 5 号」「第 2 组」),对方会收到变更提醒,导出名单里也带上这一列
· 分类订阅:可以订阅感兴趣的活动分类,之后该分类有新活动时会在站内提醒你(由计划任务统一广播,不会影响发布速度)
· 模板复用:活动页新增「以此活动为模板新建」,标题、介绍、名额、报名表单、封面图集与场次都会带过来,时间按原来的间隔整体后移
· 评价晒图直传:写评价时可以直接上传现场照片(复用站点已有的附件上传),不用再手动复制图片链接版本 6.0.0 更新:
6.0.0 更新(先修缺陷,再加功能)新增
① 签到统计面板:按场次看签到率、迟到与未签到名单,可一键复制或导出 CSV,面板内可直接代签到
② 候补空位通知:有人取消释放名额时,同场次候补前 3 位收到提醒(后台可关)
③ 活动模板库:把办过的活动存成模板(含场次/报名表单/封面图集),一键新建且时间按原间隔后移修复
④ 修复 8 处问题:日历文件头缺失导致部分客户端无法导入;名单里场次名显示错误;取消释放的名额被别的场次抢走;审核通过可能超出场次名额;座位可分给未报名或已取消者;评价重复提交与图片链接校验不严;分类订阅通知可能重复或补发陈旧活动;删除场次后报名记录悬空版本 7.0.0 更新:
7.0.0 更新(活动系列 + 现场核销 + 积分账单 + 到点自动递补)新增
① 活动系列:把同一主题的系列活动归成一条「系列」,系列页聚合展示每一场(报名数 / 下一场时间),可一键订阅整个系列,新活动一发布自动通知订阅者(复用既有的分类订阅广播,不新增定时任务)
② 现场连续核销台:发起人/管理团队输入订单号(报名记录 #N)或用户名,或直接从「待签到名单」点选,回车即签;页面实时显示「已签到 / 总人数 + 完成度」与最近 5 条核销记录,可连续投递不打断
③ 积分账单:每场活动的收费/退款明细页 + CSV 导出,逐笔列「应收 / 已扣 / 已退 / 净额」并标注原因(已扣费 / 已取消报名积分已退回 / 未签到名额已释放给候补 / 候补未扣费),账目与积分变动一一对应
④ 到点自动递补:开启后,活动开始前 X 分钟先给「已报名但未签到」的人发提前告警;活动开始且告警送达满 X 分钟后,把未签到者的名额释放给候补队列并原路退回积分。三道防误伤:只动已开始的活动、只动正式报名且未签到的人、候补为空时一个人也不动修复
⑤ 修复「发起人事后改价导致退款金额漂移」:以前按活动当前单价退款,把单价从 0 改成 100 时,没扣过分的取消者反而白拿 100 积分;现在报名/补位/审核通过时逐笔记账,退款一律按这笔实扣金额退回(老数据自动补记)
⑥ 修复「发布无分类活动时订阅广播被静默吞掉」:待广播标记已清零却没通知任何人;现在「有分类或有系列」都会广播
⑦ 修复系列订阅的内部键名(series:…)混进「你订阅的分类」文案性能
⑧ 不新增计划任务(递补并入既有「自动结束」任务、系列广播并入既有「订阅广播」任务);列表页/首页/签到面板查询数零增量,详情页仅归属系列的活动多 1 条系列查询,核销台与账单页各固定 2 条(与报名人数无关)升级说明
⑨ 升级自动完成、幂等可重入:自动新建系列表、补 series_id 及两枚索引、补 fee_paid/fee_refunded/standby_released 与 standby_warn_at/standby_done_at 等列,并按历史报名回填 fee_paid;到点自动递补默认关闭,需要到后台「活动报名」里手动打开并设定提前分钟数
⑩ 已知行为:从未发出提前告警的活动永不递补(需要计划任务在活动开始前 X 分钟内至少跑过一次);退款按逐笔实扣金额退回,与活动当前单价无关;核销码支持「报名记录编号 #N / 用户名 / 名单点选」三种方式版本 8.0.0 更新:
【8.0.0】一场活动的全流程都在这里:现场批量核销 + 活动反馈问卷 + 候补队列可视化 + 财务汇总仪表盘一、新增
- 现场批量核销(核销台)
- 核销台新增「批量核销」输入区:一次粘贴整份现场名单,每行一个订单号(
#N)或用户名;
换行、半角/全角逗号、分号、制表符都当分隔符,单批最多 200 行。
- 服务端逐行判定并回显明细:
✓ #12 alice 已签到、• 已签到过、• 与前面重复(同一人本轮只核销一次)、
✗ 第 N 行 xxx 没有找到对应报名记录、✗ 不在正式报名名单中(已取消)。- 整批只发一条候选行 IN 查询 + 一条带守卫的 IN 更新,成功行数取数据库真实影响行数;
若同一瞬间别人也在核销同一个人,会如实提示「其中 N 行已被他人抢先核销」,台账不会骗人。
- 活动反馈问卷联动(配合「问卷与投票」插件)
- 活动可挂一条问卷:编辑页下拉只列你自己的问卷(填别人的问卷 ID 会被静默降级为不挂载,不会越权)。
- 活动结束后报名者详情页出现「填写反馈问卷」入口;发起人面板显示「已回收 N 份答卷」与问卷结果入口。
- 对方插件未启用、或问卷被删除时整块优雅降级:只给发起人一句「问卷已不可用」,活动本身照常使用。
- 候补队列可视化
- 详情页显示「候补队列 N 人」与我的位次(「你在候补队列第 K 位,有人取消时按顺序自动补位」)。
- 发起人面板列出候补 Top 5(位次 + 昵称 + 排队时间,超出提示「还有 N 位未列出」)。
- 报名进入候补时当场告知「当前第 N 位」;「有位置空出」的提醒也带上位次。
- 位次与队列长度全部由已取回的名单在内存里算,零额外查询。
- 财务汇总仪表盘(新页面)
- 跨活动汇总收款 / 退款 / 净额:报名记录数、占用名额、应收(占用名额 × 单价)、已扣、已退、净额,
外加四块总计;每行标题可钻取到该活动的逐笔积分账单,两条路径口径逐项对账一致。
- 支持按报名时间的起止日期筛选,并导出 CSV(含合计行)。
- 一条
GROUP BY聚合查询出全部数字(不取明细行,因此不存在「超过 N 行后静默失真」);
管理团队看全站,普通用户只看自己发起的活动。
二、修复
- 导出文件里的公式注入(CWE-1236):名单 / 签到表 / 积分账单用 Excel、Sheets 打开时,
别人填的报名留言、昵称、活动标题若以
=+-@开头会被当公式执行(执行发生在打开文件的其他人电脑上)。
现在统一加单引号前缀中和;纯数字(含负号)例外,账单里的负数净额仍是可排序、可求和的数值。- 输入订单号却签到别人:某个用户名恰好是纯数字、又正好等于另一位参与者的订单号时,输
12会签到昵称叫「12」的人。
现在订单号命中优先于同名用户,且先挑可核销状态的行;同时兼容全角
#、全角数字、全角空格与不换行空格
(中文输入法与微信复制粘贴都能命中)。- 到点自动递补被重复执行:两轮计划任务重叠时,第一轮刚释放的名额会被第二轮再取消一次、积分重复退回、通知重复发。
现在改成先原子抢占再干活(
standby_done_at0 → now 的 CAS),抢不到的那一轮直接跳过。
代价与既有广播口径一致:抢占后若进程中断,该活动本轮不再重试(宁可漏一次自动释放,也不重复动别人的名额与积分)。- 系列 id ≥ 100000 时订阅收不到通知:订阅键被截断成别的系列(
series:100001→series:10000),
既通知不到、还会误命中 id=10000 的系列。现在系列键原样保存,只有普通分类才走 12 字上限。
- 删除活动留下孤儿数据:用户写的评价(含晒图)与场次定义会永远留在库里、指向一个不存在的活动。现已随活动一并清理。
- 财务汇总的「起始日期」被静默忽略:只填起始日期且填的是未来日期时,区间被视为非法并整段回落成「不限」,
于是页面把全部数据当成筛选结果返回——用户以为在看某段时间,其实看了全部。
现在只有「两个日期互相矛盾 / 结束日期写坏」才回落为不限;未来起始日会得到空账期,
并在账期标签里写明「起始日在未来,本区间没有记录」。三、性能
- 核销台查询数与参与人数无关:1 人活动与 3 人活动都是 4 条(活动 1 + 名单 1 + 骨架)。
- 财务汇总单页 3 条查询(骨架 + 一条聚合),与活动数、报名数无关。
- 页面请求路径上没有任何循环体内的数据库调用(静态审计:0 处);间接 N+1 审计:0 处。
四、已知行为(请先读这三条)
- 批量核销的「成功行数」是数据库真实影响行数,不是计划行数:同一个名字粘贴两次只核销一次(第二行标「与前面重复」);
已被别人抢先核销的行不计入成功,会在提示里单独说明。
- 候补不占名额、不扣费,补位成功时才扣费;候补位次按报名顺序(报名记录 id 升序)计算,取消后重新报名会排到队尾。
- 反馈问卷是单向只读联动:活动只读取「问卷是否存在 / 已回收多少份」,不改对方任何数据结构;
问卷被删除或对方插件停用时,活动页面照常可用,只有那一块给出降级提示。
五、升级说明
- 原地升级,无需卸载重装;老库第一次读写时自动补列/补索引,重复安装幂等。
- 新增一列:
plugin_event_rsvp_events.survey_id(挂载的问卷 id,0 = 不挂)。 - 本轮没有新增数据表;批量核销、候补可视化、财务汇总都是在既有表上算出来的。
- 未挂问卷、未开候补的活动,行为与 7.0.0 完全一致。
版本 9.0.0 更新:
【9.0.0】把活动现场也管起来:可视座位图(点座位即核销)+ 现场大屏 + 协作者分权 + 自定义报名字段 2.0 + 活动模板共享一、新增
- 座位图 2.0(新页面
?a=event_rsvp_seat)
- 活动可设「行 × 列」座位表(行 A–Z、列 1–40,最多 1040 座),座位号 = 行字母 + 列号(
A1、B12)。 - 页面用网格呈现三态:空位(半透明、按钮禁用)/ 已占待签到(描边)/ 已签到(填充加粗),
一眼就能看出「还有哪些位置没人来」。
- 点座位即核销:点一下就完成签到,走的是与核销台完全相同的状态机(只认正式报名 / 已签到,
已签到不会重复核销,已取消的人点不动)。
- 换座 / 指派 / 清空、行 × 列重设都在同一页完成;详情页在生成了座位图的活动上多一块只读座位预览。
- 座位仍然存在报名表里既有的
seat列上,没有新建座位表。
- 现场大屏(新页面
?a=event_rsvp_screen)
- 投影用只读大屏:内联 SVG 进度环(百分比 + 已签到 / 总人数)、进度条、四块数字
(已签到 / 总人数 / 未签到 / 候补)、最近 10 条签到(最新一条高亮)、活动签到二维码与口令。
- 自动刷新(后台可配秒数,0 = 关闭);整页固定三条查询,1 人到 1000 人查询数不变。
- 大屏是只读的:收到 POST 直接拒绝,页面上没有任何写操作。
- 协作者角色(细粒度授权 + 指派审计)
- 活动可指派协作者,并按三项权限位分别授权:核销 / 看名单 / 发通知。
- 有核销位:可进核销台、代签到 / 取消签到、点座位核销。
- 有看名单位:可看名单、签到统计、导出名单 CSV。
- 有通知位:可群发「现场通知」(页面只写一条待发队列,逐人送达交给计划任务)。
- 指派与移除都写审计(谁、给谁、当时的权限快照、时间);移除后立即失权。
- 协作者不能改活动、退款、删除、审核报名(审核通过会给对方扣费,属资金动作),
协作者之间也不能互相授权。
- 自定义报名字段 2.0
- 新增多选题型(同名复选框数组),与单选 / 下拉一样按选项白名单服务端校验,最多勾 12 项。
- 数字题型改由服务端校验整数;文本题先做全角空格归一化再判空;必填留空按题型给出准确文案
(
请填写「X」/请至少勾选一项「X」)。- 名单 CSV / 签到表 / 积分账单页 / 积分账单 CSV 全部带出自定义报名字段列——账单不必再和名单手工对表了。
- 活动模板共享
- 模板可指定用户共享(按用户名);被共享者在「我的模板」里看到「共享给我的模板」区块与来源标注,
可直接用它发布新活动(报名字段、场次数、名额与来源一致)。
- 被共享者改不了也删不掉模板本体;撤销共享后立即失效,已按模板发出的活动不受影响(模板是快照)。
二、修复(6 处)
- 数字题填文字也能报名:自定义报名字段设成「数字」时,服务端原本什么都不校验(只靠前端
type=number),
abc、1e5、-都能提交成功,名单与导出 CSV 里于是出现「数字题里写着文字」。
现在数字题型要求十进制整数(允许负号),非法值当场拒绝并提示「需要填写整数」。- 一个全角空格就能绕过必填:PHP 的
trim()不认识全角空格(U+3000),也不认识不换行空格与零宽字符,
于是只敲一个「 」就能通过必填校验。现在统一先做全角 / 不换行 / 零宽字符归一化再判空,空白答案进不来。
- 多选题的勾选被静默丢弃:表单里出现同名多值字段时,服务端会把整批勾选抹成空串并回一句「请填写」。
现在多选按数组取值、逐项白名单校验、去重后以「、」串联保存,必填 = 至少勾一项。
- 同一个人收到两条一模一样的活动提醒:两轮计划任务重叠时,提醒是「先发通知、后写标记」,
两轮都认为「这活动我还没提醒过」。现在两段提醒都改成先原子抢占再发(
remind_sent/remind2_sent的 CAS),
抢不到的那一轮直接跳过。- 活动自动结束后发起人收到两条结束小结:到点收尾同样是「先查后改」,两轮都觉得自己是结束它的人。
现在改成带守卫的原子抢占(
WHERE status=1),只有真正把状态从「进行中」改成「已结束」的那一轮才发小结。- 删除活动留下三类孤儿行:协作者授权、指派审计、还没发出去的现场通知会永远留在库里、指向一个不存在的活动
(排队中的通知尤其危险:计划任务会一直拿着空活动的队列行去查名单)。现在随活动一并清理。
顺手加固(不算独立 BUG,但与本轮功能直接相关):同一座位不能被安排给两个人;已取消报名者留下的陈旧座位不再永久锁位
(可以被重新安排给别人);删除模板时共享授权行一并清理。三、性能
- 新页面都不在循环里查库:座位图页 2 条(活动 + 名单),现场大屏 3 条(活动 + 计数聚合 + 最近签到
LIMIT 10),
且与参与人数无关。
- 既有查询预算全部持平:详情页 8 条、列表页 7 条、签到统计 ≤10 条、核销台 ≤5 条、积分账单 ≤10 条、财务汇总 ≤9 条。
详情页多出来的座位预览是纯函数渲染,零查询;协作者权限查询只对「非发起人且非管理团队」的人发一次。
- 页面请求路径上没有任何循环体内的数据库调用(静态审计:0 处);间接 N+1 审计:0 处。
- 通知走队列而不是在页面上循环:协作者发通知只写一条排队行,逐人送达交给计划任务(仍复用既有任务,
计划任务数量保持 3 个)。
四、已知行为(请先读这几条)
- 座位图的三态口径:空位 / 已占待签到 / 已签到。已取消报名者留下的
seat值是陈旧数据,
在图上显示为空位、也不锁位(可以重新安排给别人);但真把该座位提交核销时,会明确回「该用户不在正式报名名单中」,
不会含糊地说「空位」。- 缩小座位图行列不会删除任何已记录的座位:越界座位在图上标注为「图外 N 个」并保留数据,搬谁由发起人决定。
- 大屏不开放给访客:只有「看名单权」的人(发起人 / 管理团队 / 有看名单位的协作者)能打开——它会滚动显示真实昵称,
不做匿名化。未登录一律跳登录页。
- 协作者不能审核报名(审核通过会扣对方积分),也不能改活动、退款、删除;协作者不能互相授权。
- 现场通知的送达时间取决于计划任务间隔(默认 300 秒),页面上的提示是「已排队」而不是「已发送」;
每批最多 10 条通知、每条最多 500 人,超出的下一轮继续。
- 数字题型现在的口径是整数(允许负号,≤9 位):小数(
1.5)会被拒绝,需要小数请改用文本题。
这是上面第 1 条修复的直接结果。
- 模板共享是只读共享:被共享者只能用模板发新活动,模板本体的内容变更随时会被作者覆盖,
使用计数记在作者的模板行上。
五、升级说明
- 原地升级,无需卸载重装;老库第一次读写时自动补列 / 建表 / 建索引,重复安装幂等。
- 新增两张列:
plugin_event_rsvp_events.seat_rows/seat_cols(座位表行列,0 = 未生成座位图)。 - 新增四张表:
plugin_event_rsvp_helpers(协作者授权)、plugin_event_rsvp_audit(指派审计)、
plugin_event_rsvp_template_shares(模板共享)、plugin_event_rsvp_notices(现场通知队列),各带一枚索引。- 未生成座位图、未指派协作者、未共享模板的活动,行为与 8.0.0 完全一致。
- 座位图 2.0(新页面
版本 10.0.0 更新:
10.0.0 大版本更新:退款闭环 + 座位口径统一 + ICS 合规 + 动态签到口令 + 出席信用
本次是「先修 BUG,再加功能」的大版本:修掉 4 处真实缺陷,再补 3 项新能力。
一、修掉的 4 处缺陷(都可复现、都留了回归断言)
- 删除收费活动会吞掉报名者的积分(积分黑洞)
现象:一场 30 积分的活动被发起人删掉后,报名者已经扣掉的积分凭空消失,库里也再没有任何地方能证明该退多少。
根因:删除分支只清报名行,而「已扣」记在报名行的 fee_paid 上,行一删账目就没了。
修法:删除前先一条INSERT ... SELECT把「已扣未退」逐笔写进退款队列(带活动标题快照),活动照旧删除;
由 close 计划任务用 CAS 抢占逐笔user_points_change()原路退回并通知本人。新增「退款中心」页与台账 CSV,
队列行不随活动消失,事后仍对得上账。- 取消报名后再报名 / 候补递补会保留陈旧座位,导致两人同座
现象:alice 取消报名(座位 A1 留档)→ 发起人把 A1 正式安排给 bob → alice 重新报名(待审核,仍带 A1)→ 审核通过后 A1 上出现两位正式报名者,现场对不上号。
根因:状态迁移(重新报名 / 递补 / 审核通过)时没有校验旧座位是否已被别人合法占用。
修法:统一「占座 = 状态属于已报名/已签到」的口径,新增event_rsvp_seat_holders()(一次查询取回座位持有者)
与event_rsvp_seat_inherit()纯判断,三条迁移路径都回收被他人占走的旧座位,并写seat_reclaim审计与提示文案。- 座位图把「已取消 / 待审核 / 未通过」的人画成占座,与换座校验口径相反
现象:座位图显示 A1 有人,可发起人把别人安排到 A1 时系统却说空位——两套口径打架,现场只能靠猜。
根因:座位图用「凡有 seat 值就占座」,换座校验用「状态属于已报名/已签到才算占座」。
修法:座位图改用同一口径(event_rsvp_seat_map_detail()),失效座位单列成「失效座位」面板并可一键清理(写审计)。- ICS 日历导出的换行转义写反了顺序,且没有 75 字节折行
现象:多行活动介绍在苹果日历 / Outlook 里显示成字面量
\n;长正文还可能被严格客户端截断。
根因:旧代码先替换换行再转义反斜杠,刚插入的\被二次转义成\\n;且从未按 RFC 5545 折行。
修法:改成「先转义反斜杠/逗号/分号,最后处理换行」,新增 UTF-8 安全的 75 字节折行(续行前导空格)、
写出STATUS(已结束/已取消日历可跟随)、PRODID 带上真实插件版本。二、3 项新能力
- 退款中心:
?a=event_rsvp_refund(发起人看自己的、管理团队看全站)+ 台账 CSV;
统计待退笔数/待退积分/已退笔数/已退积分,退款由计划任务分批处理(可配单轮笔数),队列绝不丢。
- 动态签到口令:活动可设「每 N 秒自动换口令」(15–600 秒),口令由
HMAC(活动 id + 时间窗口, 活动独立种子)
派生、不落库;大屏与发起人面板显示当前口令与倒计时(前端每秒向发号接口取当前窗口口令),
核销接受当前与前后各一个窗口(容忍时钟误差),过期口令立即作废;二维码打印版不再夹带口令,
重置口令会同时换掉种子。不开轮换时行为与旧版逐字节一致。- 出席信用(到场 / 爽约台账):活动结束(或删除活动)时结算每人一行「到场 / 爽约」(集合写入、天然幂等);
名单上标出「爽约 N 次」(复用名单那一条 SQL 的 JOIN,零额外查询);可设爽约上限拦截报名;
候补递补在同等位次下优先补信用好的人;关闭开关即完全回到旧行为。三、验证
- 十套
tools/lab_verify_event*.sh串行全绿(v10 新增 134 项断言,其余套件期望值随版本推进就地更新并注明理由)。 - 六道静态门禁全部通过;计划任务仍为 3 个。
- 四张新预览图(退款中心 / 动态口令 / 失效座位 / 出席信用)与旧图聚合成 12 张。
很实用谢谢大佬分享
版本 11.0.0 更新:
11.0.0 大版本更新:出席信用「可纠正」+ 我的出席信用
本次继续「先修 BUG,再加功能」:修掉 3 处真实缺陷,再补 2 项能力(1 个管理动作 + 1 个用户页面)。
一、修掉的 3 处缺陷(都可复现、都留了回归断言)
- 手动「标记结束」的活动,出席信用永远不结算
现象:发起人在活动页点「标记结束」把状态改成「已结束」之后,这场活动永远不会给参与者记「到场 / 报名未到场」——而自动结束(计划任务)的活动会记。
根因:结算只发生在 close 计划任务里,这条任务只挑「状态 = 报名中 且 已过结束时间」的活动;手动改状态后它就再也看不到这场活动。
修法:手动结束时按同一套幂等口径补结算,并提示结算了几条;但只在活动时间确实已经过去时才结算——提前收工不该把全体报名者记成爽约。- 补签 / 代签到 / 撤回签到与出席台账互相矛盾
现象:活动结束、台账已结算之后,发起人给「到场但没签上」的人代签到(或撤回某人的签到),名册状态变了,信用台账还是旧的:名册显示「已签到」,信用页仍记「报名未到场」——而爽约会真实影响下一次报名的门槛与候补位次。
修法:报名状态与台账双向同步(各一条带条件的 UPDATE,天然幂等),且只在活动已结束时才多这一条查询,活动进行中的签到路径开销逐字节不变。- 删掉一场「还没发生」的活动,会给全体报名者记爽约
现象:活动因故取消,发起人直接删除,报名者却每人多了一次「报名未到场」;次数攒够就会被本站限制报名新活动。
修法:删除前只在「活动时间已经过去」时结算(保留「删掉活动也洗不掉爽约」的防洗白口径);没办成的活动不惩罚任何人。二、两项新能力
- 补签(出席信用申诉):活动页新增「待补签名单」,列出结算时被记为「报名未到场」的人,一键补签即可把报名状态与出席台账一起改成「已签到」。补签必须填写理由并写入活动审计(谁、给谁、为什么、什么时候),被补签者会收到通知;窗口为活动结束后 N 天(后台可配,0 = 关闭补签),只有发起人 / 管理团队 / 有核销权的协作者能操作。现实里的断网、二维码刷不出来、临时换人、签到台排队错过,终于有了一条有据可查的纠正通道。
- 我的出席信用:新页面
?a=event_rsvp_credit—— 到场 / 报名未到场 / 已结算场次 / 到场率四格总览,逐场台账(含已删除活动的标注:活动被删掉也照原样留着,不存在「删活动洗记录」),尚未结算的报名场次,以及规则与申诉指引(本站爽约上限、补签窗口与做法)。整页三条查询,场次再多查询数不变。
三、验证
- 六道静态门禁全绿(php -l / 循环内查库审计 / 间接 N+1 审计 / 插件规范审计 / 缺陷类别审计 / 未定义调用审计)。
- 新增
tools/lab_verify_event_v11.sh:93 项断言全部通过,其中修复类断言写成「11.0.0 之前是错的、之后是对的」;并覆盖权限(无权者补签被拒、越权不写审计)、窗口(关闭 / 超期一律拒绝)、幂等(重复结算、重复补签)、查询预算(补签面板固定一条查询、非管理者零增量)与防洗白(删除已结束活动后台账仍在)。 - 既有 10 套 event_rsvp 验收套件(v1–v10)全部复跑通过(版本号 / dist 文件名断言随之更新)。
说明:本次预览图仍沿用上一版画面(站点附件空间已满 20MB,新页面截图已生成在
plugin/preview_ev_pack_v11/,待配额释放后补传:01-amend-panel.png待补签名单、02-my-credit.png我的出席信用)。版本 11.0.1 更新:
11.0.1 修复:后台设置保存失败时看不到真正的错误原因 + 预览图顺序- 校验失败时直接 fall through 成整页 HTML,核心前端却按 JSON 解析 → 只弹「操作失败」;改为 AJAX 请求回
{"ok":0,"message":…}信封,无 JS 浏览器仍是整页渲染(字节不变)。 - 预览图顺序修正:11.0.0 的两张新图(补签面板 / 我的出席信用)此前排在 14 张的末尾,市场预览图有 12 张上限 → 被截断、列表里读不到。现已把两张新图排到最前,列表 12 张里可以逐条核对到它们。
- 校验失败时直接 fall through 成整页 HTML,核心前端却按 JSON 解析 → 只弹「操作失败」;改为 AJAX 请求回
版本 11.0.2 更新:
补丁版本:给「页面组件 DIY」加一个原生组件(未装 layout_diy 时行为逐字节不变)
- 新增只读组件注册(私有 Hook
diy_layout.components):具名渲染回调 + 声明查询成本 + 无数据时零查询降级(靠站点标记短路)+ 拿不到数据返回空串由宿主降级成占位(不抛异常,单块坏天气不会带走整页)。 - 查询形状与行数无关:列表/映射/计数各一条批查,条数参数只改
LIMIT的绑定值。 - 组件自带参数白名单(条数 / 显示哪些字段),后台可视化编辑、越界值拒绝保存。
- 未装「页面组件 DIY」时这个 Hook 无人调用:本插件的行为、查询数、页面字节与上一版逐字节一致(用「旧版 vs 新版、两边都停用 layout_diy」的 A/B 比对守着,含查询数)。
- 新增只读组件注册(私有 Hook
版本 12.0.0 更新:
12.0.0(大更新:先修缺陷,再加三项能力)
【新能力】- 活动变更勘误:改动开始时间 / 结束时间 / 地点 / 名额 / 费用时,自动记一条变更(改前值 → 改后值 + 操作者 + 时间),
并给全部报名者发一条站内通报;活动页出现「活动变更记录」,报名者可点「我已知悉」,发起人看得到「已确认 M / 应确认 N」。
没改过的活动零额外开销。- 电子票号:每位报名者一张自己的票(E<活动 id>-<8 位随机>,不含内部编号、不可由别的票推算),
票根页可打印,二维码里就是票号明文;核销台可按票号单点核销,也可与订单号 / 用户名混在同一个粘贴框里整批核销。
- 无责退出与自助顺延:活动改期 / 换地点后无法参加,可一键无责退出(全额退回积分,不受取消截止限制);
被候补递补上来却临时来不了,可把名额顺延给下一位候选。两者都会自动补位、写审计并通知双方。
【缺陷修复】- 修:被「到点自动递补」释放名额的人不再逃过出席信用台账(此前同场没到场却没被释放的人计爽约、被释放的人不计,
等于给「被释放」开了免罚通道);补签同样覆盖这批人(只更正台账,不恢复名额)。
- 修:导出的 ICS 里 PRODID 的版本号与插件实际版本一致(此前落后两个补丁号)。
- 修:重复提交「取消报名」不会再退两次款(改成带守卫的原子更新)。
- 修:重复提交「审核通过」不会重复扣对方积分。
- 修:报名行写入失败时,已扣的积分会原路退回,不再出现「钱扣了、记录却没有」。
【兼容】升级会自动补两张新表、四枚索引与三个列;卸载会一并清理。计划任务仍是 3 个,页面查询数只在不改活动的页面上保持不变。
版本 12.1.0 更新:
12.1.0(大更新:先修并发缺陷,再加能力)
【新能力】- 候补队列可视化与人工排序:活动页把候补队列摊开(前 10 位 + 报名时间),列表里每位候补者带 ▲▼ 一键调位
(可上调/下调优先级,范围 ±99)。递补顺序、页面队列顺序、位次提示三处同一条口径 ——
你调完顺序,下一个空出来的名额就按新顺序给出去;每次调位都写审计。
【缺陷修复(并发复核)】- 修:候补补位在并发/重复投递下「抢占失败的一方仍然扣对方的积分、发『你已转为正式报名』通知、还回报补位成功」——
一个人被扣两次费、收到两条通知。现在「抢占成功」是扣费与通知的唯一依据,抢不到就什么都不做。
- 修:补位的「名额判定」与「抢占」之间加了互斥(每场活动一把带 30 秒过期自愈的建议锁),
并发下不会再出现「多放一个名额 / 两个人同时转正式」。
【可用性补强】- 已取消(或还是草稿)的活动:票根直接打作废、不再输出可扫的二维码;代签到 / 扫码台 / 批量核销 / 点座位核销
一律拒绝并说明原因(此前这些路径会跳过时间窗判断,把取消掉的活动刷出一堆「已签到」)。
- 同一瞬间两次核销不再互相覆盖签到时间(首次签到时间不会被后到的请求改写)。
- 变更通报幂等:同一份变更在 120 秒内重复提交(双击保存 / 客户端重试)不再重复记账、不再重复通知。
【兼容】升级自动补两个列(候补优先级 / 建议锁),不新增表与索引;计划任务仍是 3 个;
首页与主题页上的语句数仍然是 0(本插件零查询),列表与详情页与 12.0.0 持平。版本 12.2.0 更新:
12.2.0 · 卸载残留- 修复:卸载时自有设置行(如「有即将开始的活动」缓存标记)没有被清理,会留在库里;重装后可能沿用旧值。现在卸载会把
plugin_event_rsvp%的设置一并清干净。 - 无数据结构变更,覆盖文件即生效。
- 修复:卸载时自有设置行(如「有即将开始的活动」缓存标记)没有被清理,会留在库里;重装后可能沿用旧值。现在卸载会把
版本 12.3.0 更新:
12.3.0 · 覆盖文件升级自愈- 修复(升级路径):本插件历经 9 代结构变化(2→3→4→5→6→7→11→13→15 组建表/补列语句),而建表补列此前只在
install内执行。老站覆盖新文件后,中间代缺的表与列永远不会补上,一旦被读到就抛异常、整插件被自动停用。现在运行期入口统一走三道门(内存副本 → 设置标记 → 才 DDL)幂等补齐;支持从任意中间代一次性补齐到最新表集(不只是从上一代)。 - 口径:稳态零查询(纯内存比较);补列全部走
app_db_ensure_columns()(CREATE TABLE IF NOT EXISTS改定义对已存在的表无效);不挂读钩子,页面预算不变。
- 修复(升级路径):本插件历经 9 代结构变化(2→3→4→5→6→7→11→13→15 组建表/补列语句),而建表补列此前只在
关注下逻辑问题,我想购买但是激活码是必填。。