XIUNOX 更新记录贴 202600719

管理

  • [配置不同步] 修复 import_plugins_to_appcenter.php 在生产库报 Table bbs_setting doesn’t exist(用 SHOW TABLES 反推真实表前缀,与 conf.php 不符自动改用并警告)

  • [逻辑错误] 修复 import_plugins_to_appcenter.php 表前缀检测误用 setting 表(xiuno 实际用 kv 表存设置),基准表改为 kv 表+分类检查 SQL 同步修复

  • [逻辑错误] 修复 import_plugins_to_appcenter.php 无参数运行时所有插件被静默跳过(foreach 从 $argv[0] 脚本名开始误当 ONLY_DIR,改用 array_slice($argv, 1))

  • [类型误用] 修复 import_plugins_to_appcenter.php 写 attach.filetype 报 1406 Data too long(‘image/png’ MIME 9 字节 → ‘image’ 短类型标识,与 AttachmentService 一致)

  • [HTMX事件冲突] 修复 xnx_appcenter 我的应用页删除应用后列表不更新 + 提示不是 toast(htmx 4 evt.target 是 form 非结果容器+后端返回 alert 片段未走 XN.toast,改自定义事件+空 span+前端监听移除行)

  • [类型误用] 修复 xnx_appcenter 管理员审核通知第一次就不发 + 开发者无通知 + 通知无模板(防抖判断 !== NULL 改兼容 MySQL FALSE/Redis NULL+防抖标记条件写入+TTL 24h→30min+notify_format 保留 url+开发者通知+后台文案模板)

  • [逻辑错误] 修复 xnx_appcenter 编辑应用免费改付费报 500(通知链路异常未隔离导致编辑主流程崩溃,updateApp/createApp/updateAppStatus 通知调用包裹 try-catch+路由层兜底)

  • [逻辑错误] 统一修复其他 4 个插件审核通知无 try-catch 保护(xnx_verify/xnx_medal/xnx_ad_selfbuy/xnx_report 的 audit 调用异常仅 error_log 不阻塞主流程)

  • [死代码/检测缺失] 修复 PluginScanner.collectFiles 不收集 json 扩展名导致 conf.json 字段检测(bbs_version 兼容性/version 三位制/capabilities 格式)全部为死代码从未执行;上传 zip 与本地 install 两条路径均不检测 conf.json 字段

    • 必测: 上传缺 name 或 bbs_version 的插件 zip 应被阻止安装并显示具体原因

  • [新增检测] conf.json name 必填字段校验(conf_required_fields 分类,fatal 级,force=1 不可跳过)

    • 必测: conf.json 缺 name 字段时两条安装路径均阻止安装

  • [逻辑错误] 修复本地 install 路径 force=1 可跳过 forceBlocked 分类(conf_version/conf_required_fields 等"不可跳过"检查)的漏洞;原代码 if(!can_install && !force) 与 getForceCategories 设计意图冲突

    • 必测: 缺 bbs_version 的插件 force=1 强制安装仍应被阻止

  • [显示缺陷] 修复安装阻断提示只显示 fatal 不显示 error 级问题(如 conf_version);两条路径合并 fatal+force_blocked+error 去重显示

  • [功能新增] xnx_appcenter v1.7.0:发布/编辑应用前强制阅读《XIUNOX 插件上架前必看》文档(Modal 内嵌 iframe 加载 static/appcenter_guide.html,点击"我已阅读并理解"后启用提交按钮,后端 guide_read 字段二次校验)

    • 必测: appcenter-publish 页面点击"查看必看文档"打开 Modal,点击"我已阅读并理解"后提交按钮启用

    • 必测: appcenter-edit-{app_id} 页面同样需要阅读后才能提交

    • 必测: 直接 POST 提交(绕过 JS)应被后端拦截返回"请先阅读上架前必看文档"

  • [函数未定义] 修复 xnx_appcenter setting.htm 第331行 esc_textarea() 未定义错误(WordPress 函数误用,改为 esc_html)

    • 必测: 后台 xnx_appcenter 插件设置页打开无 fatal,通知模板 body 文本框正常显示已保存内容

  • [安全漏洞+逻辑错误] 修复发帖版块白名单(post_forum_ids)双重缺口:6 个发帖按钮入口(forum.htm/thread_right.inc.htm/sidebar_right.inc.htm/bottom_nav.inc.htm/floating_action.inc.htm/forum_followers.htm)未根据白名单隐藏 + route/thread.php POST 提交与 route/post.php 移帖场景未拦截白名单外 fid(可被 curl 绕过)。新增 forum_can_post($fid,$gid) 辅助函数到 model/forum.func.php 统一判断语义(管理员豁免/空白名单放行/fid=0 放行/白名单内放行),PHP 按钮用 if 包裹隐藏,floating_action JS 端传入 postForumIds 数组支持 htmx 导航后动态判断

    • 必测: admin/?setting-display.htm 设置白名单后,受限版块页 forum-xxx.htm 与帖子页 thread-xxx.htm 发帖按钮应隐藏(含悬浮按钮/底部导航);curl 直接 POST 到受限版块应返回 user_group_insufficient_privilege

  • [字段缺失] 修复 xnx_appcenter 审核通过后不发帖:createForumThread 调用 thread_create 缺少 time/longip/doctype 字段导致 Undefined array key time(app_id=9016)

    • 必测: 后台 appcenter 应用详情页点"通过审核",检查配置版块是否生成讨论帖

  • [逻辑缺陷] 修复 updateAppStatus 审核通过条件 && r 导致已审核但发帖失败的 app 无法补发帖(去掉 && r,empty(thread_tid) 去重兜底)

    • 必测: 对 app_id=9016 重新点"通过审核",应补发讨论帖

  • [表单校验] xnx_appcenter 发布页新增必填校验:功能标签必选且最多2个、应用介绍必填>100字、图标/截图/下载包必填(前端JS+后端PHP双重校验)

    • 必测: appcenter-publish 页面提交时各项校验 toast 提示

  • [UI调整] xnx_appcenter 发布页隐藏开发者字段(自动取登录用户,避免泄露登录账号),发布按钮前加提示文字

    • 必测: appcenter-publish 页面无开发者输入框,按钮前有蓝色提示条

  • [语言同步] 新增 xnx_appcenter 校验相关语言键(zh-cn/zh-tw/en-us 三语言同步)

    • 必测: 切换语言后校验提示正确显示

  • [函数误用] 修复 xnx_appcenter setting.htm 第331行 esc_textarea() 未定义错误(WordPress 函数误用,改为 esc_html)

    • 必测: 后台 xnx_appcenter 插件设置页打开无 fatal,通知模板 body 文本框正常显示已保存内容

  • [UI优化] xnx_appcenter 详情页:已审核通过但讨论帖未发时,管理员看到"补发讨论帖"按钮(黄色),点击触发 createForumThread 补发帖

    • 必测: 对 app_id=9016 详情页点"补发讨论帖",检查配置版块生成讨论帖

  • [Bug修复] 修复 xnx_appcenter 发布表单 AIEditor 字数检测失效:aiEditorInstance 是 IIFE 局部变量未暴露到 window,validateForm 读旧 textarea(已被重命名为 _description_old)

    • 必测: appcenter-publish 页面输入不足100字提交时 toast 提示"应用介绍至少 100 字"

  • [新功能] xnx_appcenter 新增"一句话介绍"字段(brief,必填≤50字),显示在应用名称下方

    • 必测: appcenter-publish 填写一句话介绍 + 详情页名称下方显示

  • [Bug修复] 修复 xnx_appcenter createForumThread 下载链接为相对地址,改为拼接 $conf[url] 绝对 URL

    • 必测: 审核通过后讨论帖内下载链接 为完整地址

  • [UI优化] xnx_appcenter 详情页引入 aieditor style.css,富文本描述正确渲染

    • 必测: appcenter 详情页应用介绍 Tab 的 HTML 样式正常

  • [新功能] xnx_appcenter 详情页右侧增加作者信息卡(头像+用户名+发帖/回帖/加入时间统计)

    • 必测: appcenter 详情页右侧显示作者卡片

  • [新功能] xnx_appcenter 详情页底部增加评论区,引用讨论帖回复(最新10条),支持发表评论(htmx 提交到对应帖子)

    • 必测: appcenter 详情页底部显示评论列表 + 评论表单,提交后评论追加到列表

  • [数据库] xnx_appcenter upgrade.php 新增 brief 字段(xnx_appcenter_app 表),conf.json 版本号 1.7.0 → 1.8.1

    • 必测: 后台插件列表显示"需升级",升级后 brief 字段存在

  • [语言同步] 新增 xnx_appcenter brief/作者/评论相关语言键(zh-cn/zh-tw/en-us 三语言同步)

    • 必测: 切换语言后各项文案正确显示

  • [致命bug] 修复 xnx_ai_reply AI自动回复完全不触发:thread_info_end.php 第12行误用 function_exists(“AiTriggerService”) 检查类是否存在(function_exists 永远返回 false),导致所有访问都进入 service_missing 分支被跳过,整个插件触发逻辑永不执行。改为 class_exists + 兜底 include

    • 必测: 访问帖子详情页 ?thread-xxx.htm,检查 log/202607/ai_trigger_error.php 是否出现 reason=triggered 或其他非 service_missing 日志

  • [逻辑错误] 修复 xnx_ai_reply 失败过的帖子被永久拦截:hook 误用 AiReplyService::hasReplied (只要有记录就 true,含失败 status=0),改为 AiTriggerService::hasReplied (只检查 status=1 成功回复),失败帖子可重试,已回复帖子由 checkTrigger 检测新动作再次触发

    • 必测: 对曾失败的帖子再次访问,检查是否重新触发(log 出现 reason=triggered)

  • [路由缺失] 修复 xnx_appcenter appcenter-scan 路由 404(路由表未注册 appcenter_scan,JS fetch 相对路径解析错误)

    • 必测: appcenter-publish 页面上传下载包后扫描正常执行

  • [占位符未替换] 修复 xnx_appcenter 发布提示"致命问题({count})"占位符未替换(后端 message 直接返回带占位符的 scan_fatal 文案)

    • 必测: 扫描未通过时发布,提示文案为"插件包扫描未通过,存在致命问题"

  • [UI增强] xnx_appcenter 详情页作者信息卡增强:展示开发者简介、官网、应用数、安装数(替换原发帖/回帖统计)

    • 必测: appcenter 详情页右侧作者卡显示 intro/官网/应用数/安装数

  • [UI调整] xnx_appcenter 详情页评论区改为预览+跳转:保留最新10条评论预览,移除简化评论表单,底部加"查看全部评论/发表评论"按钮跳转到讨论帖

    • 必测: appcenter 详情页底部显示评论预览+跳转按钮,点击跳转 thread-xxx.htm

  • [新功能] xnx_appcenter 后台设置新增"展示应用的版块"白名单配置项(多选 checkbox)

    • 必测: 后台 xnx_appcenter 设置页勾选版块保存

  • [新功能] xnx_appcenter 新增 thread_postlist_before.htm hook:帖子详情页(帖子和评论之间)展示作者发布的应用(随机3个),仅白名单版块展示

    • 必测: 白名单版块的帖子详情页显示作者应用模块

  • [数据库] xnx_appcenter conf.json 版本号 1.8.1 → 1.8.2(新增 thread_postlist_before.htm hook 注册)

    • 必测: 后台插件列表显示"需升级"

  • [语言同步] 新增 xnx_appcenter 作者卡/评论跳转/应用展示/scan_fatal_msg 相关语言键(zh-cn/zh-tw/en-us 三语言同步)

    • 必测: 切换语言后各项文案正确

  • [模板编译错误] 修复 xnx_appcenter/hook/thread_postlist_before.htm 注释中包含 字符串导致模板编译器递归注入,引发 ParseError: Unmatched } in tmp/view_htm_thread_main.inc.htm on line 853

    • 必测: 帖子详情页 thread-xxx.htm 正常加载,作者应用展示模块(白名单版块)正常显示

  • [新功能] 新增 xnx_poll 帖子投票插件:发帖页右侧栏配置(单/多选+倒计时+可见性+游客+用户组),帖子正文下方投票卡片(进度条+倒计时+剩余票数),htmx 无刷新投票+作者/管理员提前结束,后台投票管理(列表/参与记录/CSV 导出/强制结束/删除),三语言 zh-cn/zh-tw/en-us 同步

  • [逻辑错误] 修复 xnx_ai_reply 每刷新都触发:markReplied 误用 $_latest[0][pid] 取最新 post pid,但 post__find 返回关联数组(key=pid),[0] 永远不存在导致 Warning + last_pid=0;改用 reset() 取第一个元素

    • 必测: 访问已回复过的帖子,检查 log/202607/ai_trigger_error.php 是否出现 markReplied_internal update_ret=true 日志,且不再重复触发

  • [逻辑错误] 修复 xnx_ai_reply trigger_uid 丢失:hook register_shutdown_function use 没传 $_ai_viewer_uid,executeByTid 第三参 trigger_uid 永远 0;补传并在 catch 块记录 uid

  • [健壮性] hook catch(Exception) 改 catch(Throwable):捕获 PHP 7+ 的 Error(如 TypeError),原 catch(Exception) 漏捕会导致 shutdown 函数静默中断,队列记录不清理

  • [可观测性] executeByTid 加关键节点日志:selectProvider_start/done、publishReply_start/done、markReplied_start/done、deleteQueue_done;markReplied 内部记录 db_update/db_insert 返回值,便于排查 status=1 是否成功写入

  • [UI重构] xnx_appcenter 详情页评论区完全重构:移除简化评论,完整复用 thread 详情页评论系统(include post_list.inc.htm)

    • 样式与帖子详情页一模一样:一级评论+楼中楼二级回复+折叠展开+回复引用条+点赞+编辑/删除

    • 保留最新10条一级评论(desc排序),一级评论下的所有子评论和回复都展示

    • 底部加完整回复表单(快速回复+高级回复+表情+验证码),提交到 post_create 标准路由

    • 引入 thread_js.inc.htm 交互JS(回复、点赞、折叠、代码高亮、主题切换)

    • 右上角保留"查看全部"跳转按钮

    • 必测: appcenter 详情页底部评论区样式与 thread 详情页一致,可回复/点赞/折叠展开

  • [路由增强] appcenter 详情页路由完整复用 thread 两级评论查询逻辑(post__find + reply_map 递归查询+权限变量+安全配置+待审过滤+点赞预加载)

    • 必测: 评论区显示最新10条一级评论+所有子回复

  • [版本号] xnx_appcenter conf.json 1.8.2 → 1.8.3,static_version 1.2.2 → 1.2.3

    • 必测: 后台插件列表显示"需升级"

  • [Bug修复] 修复 xnx_appcenter createForumThread 下载链接仍为相对地址(/appcenter/9001)

    • 根因: 之前用 $conf[url] 拼接绝对URL,但 $conf[url] 是导航菜单字段不是站点根URL,为空导致拼接结果仍为相对路径

    • 修复: 改用 http_url_path() 提取 scheme://host 部分(不含path,避免子目录双重前缀),再拼接 route_url 返回的路径(已含base_path)

    • 必测: 审核通过/补发讨论帖后,帖子内隐藏下载地址为完整URL(如 https://xiuno.com/appcenter/9001)

  • [UI调整] xnx_appcenter 详情页评论区改为纯展示模式(保留时间,移除所有交互功能)

    • 移除: 点赞、回复、编辑、删除、封禁、置顶、审核、折叠展开、回复表单、表情选择器、验证码、thread_js.inc.htm

    • 保留: 头像、用户名、用户组、楼主标识、待审标识、评论内容、时间、二级回复(含回复对象标识)

    • 底部: "查看全部评论/发表评论"按钮跳转讨论帖(完整交互功能在讨论帖)

    • 原因: appcenter 详情页复用 post_list.inc.htm 的交互功能(点赞/回复/编辑等)依赖 thread_js.inc.htm 的 JS 绑定,但该 JS 绑定在 #postlist 容器上的事件监听与 appcenter 页面上下文不兼容导致功能不可用

    • 必测: appcenter 详情页底部评论区纯展示,无任何交互按钮,时间正常显示,点击"查看全部评论"跳转讨论帖

  • [UI增强] xnx_appcenter 帖子详情页作者应用模块 header 右侧增加"查看全部"按钮,跳转作者应用主页(appcenter_developer?uid=xxx)

    • 必测: 帖子详情页作者应用模块右上角显示"查看全部"按钮,点击跳转开发者主页

  • [UI调整] xnx_appcenter 开发者主页布局调换:左侧 col-lg-9 应用列表,右侧 col-lg-3 作者信息;应用卡片改为 col-md-4 col-lg-3(每行3-4个),卡片样式优化(图标+名称+简介+分类+下载数)

    • 必测: appcenter_developer 页面左侧应用列表,右侧作者信息

  • [UI调整] xnx_appcenter 应用详情页布局调整:左侧 Tab 内容 col-lg-8 → col-lg-9,右侧信息卡 col-lg-4 → col-lg-3

    • 必测: appcenter 详情页左侧内容区更宽,右侧信息卡更窄

  • [语言同步] 新增 xnx_appcenter_author_apps_view_all 语言键(zh-cn/zh-tw/en-us 三语言同步)

    • 必测: 切换语言后"查看全部"文案正确

  • [方法缺失] 修复 AppCenterService::checkPriceLimit() 未定义导致应用发布/编辑提交 fatal(路由两处调用但 service 类未定义方法,补齐价格上限校验方法)

    • 必测: appcenter-publish 发布价超 max_price、appcenter-my-2 编辑应用提交

  • [JS 语法错误] 修复 xnx_poll 发帖页 poll_post.js 报 Uncaught SyntaxError: Unexpected identifier xnx_poll_options

    • 根因:static/js/poll_post.js 是纯静态 .js 文件不会被 PHP 解析,但代码中嵌入 <?php echo lang(\"xnx_poll_options\"); ?> 等导致浏览器解析为裸标识符

    • 同文件还有 2 处同类问题(max_options/min_options toast);poll.js(帖子详情页投票卡)有 7 处同类问题

    • 修复:hook/post_js.htm 和 hook/footer_js_after.htm 中通过 window.XNX_POLL_I18N_POST / window.XNX_POLL_I18N 注入翻译字符串,JS 文件改用 window 全局读取

    • 必测: thread-create 页面开启投票后选项列表正常显示与增删;thread-read 页面投票卡按钮可点击

  • [后台设置页优化] xnx_poll setting.htm 重构

    • 顶部新增跳转到「投票管理」对称入口按钮(与 poll_admin.htm 已有的「设置」按钮对称)

    • 删除 result_style 单选项下拉(只有「进度条」一个选项,无意义)

    • 删除模板中重复的 PollService::getSettings() 调用(setting.php GET 已赋值)

    • 数字字段加单位提示(2-20 / 小时),用 input-group-text 展示范围

    • 表单提交改为 fetch 拦截 + 按钮 loading spinner + toast 反馈,成功后不跳转页面

    • 新增范围校验:min>=2、max>=min、max<=20,校验失败 toast 警告

    • 必测: admin/?plugin-setting-xnx_poll.htm 保存后右上角 toast 成功提示,按钮恢复

  • [代码清理] setting.php 清理冗余变量 $_grouplist 中间变量

  • [语言包同步] 新增 xnx_poll_hours 键(zh-cn/zh-tw/en-us 同步 lang/ 和 hook/lang_*_bbs.php 两套)

  • [版本号] conf.json.version 递增至 1.0.1,清理 tmp/plugin_xnx_poll_.php 和 tmp/lang__bbs.php 编译缓存

  • [正则错误] 修复 PluginScanner 扫描时 preg_match missing closing parenthesis 报错(规则中字面 ( 未转义被 isRegex 误判为正则后传入 preg_match 失败,统一转义为 ()

    • 必测: admin/?plugin-scanner-preinstall.htm?dir=xnx_poll 扫描不再 Warning

  • [模板缺失] 修复 xnx_poll 后台设置页/管理页缺少 header/footer

    • 根因:setting.htm 和 poll_admin.htm 未 include ADMIN_PATH view/htm/header.inc.htm 和 footer.inc.htm,导致页面无后台导航栏/侧边栏

    • 修复:两个模板首尾分别 include _include(ADMIN_PATH . "view/htm/header.inc.htm") 和 footer.inc.htm

    • 必测: admin/?plugin-setting-xnx_poll.htm 显示后台顶部导航与侧边栏;admin/?poll_admin-list–1.htm 同样显示

  • [字段遗漏] 修复 AppCenter 应用详情页一句话简介不显示(createApp insert 数组与 updateApp 字段白名单均漏 brief,导致发布/编辑填的简介未写入数据库)

    • 必测: appcenter-publish 新发布应用详情页名称下方显示简介;appcenter-my 编辑已有应用 brief 后详情页更新

  • [投票数据丢失] 修复发帖提交后 poll_data 未传到后端导致投票未写入数据库

    • 根因:post.htm 表单是 htmx 提交(hx-post),htmx 4 在触发 htmx:config:request 事件时已完成 new FormData(form) 表单序列化,此时修改 DOM 中 hidden input 的 value 不会进入已构建的 FormData,后端 param(\"poll_data\") 拿到空字符串,PollService::createPoll 未被调用

    • 修复:poll_post.js 改为直接 evt.detail.ctx.request.body.append(\"poll_data\", json) 修改 htmx 已构建的 FormData 对象(先 delete 再 append 避免重复),保留 submit 捕获阶段兜底(非 htmx 场景)

    • 必测: thread-create 页面开启投票 → 填选项 → 提交 → 帖子详情页应显示投票卡

  • [版本号] xnx_poll conf.json.version 1.0.1 → 1.0.2

  • [新功能] xnx_reward Task 12: 帖子列表标题旁悬赏标签 hook(thread_list_inc_subject_after.htm 用静态缓存避免同 tid 重复查 + thread_subject_after.htm 详情页直接 getByTid 缓存),显示「💰 悬赏 X 积分」徽章

    • 必测: forum-XXX.htm 列表页含悬赏帖子标题旁显示橙色徽章;thread-XXX.htm 详情页标题下方独占一行显示徽章

  • [新功能] xnx_reward Task 13: 回复列表采纳按钮 hook(post_list_inc_subject_after.htm 用静态缓存加载悬赏数据,含 thread_display_start.php 未生效兜底;显示条件:悬赏进行中+楼主/管理员可操作+非主帖+非用户中心列表+回复作者非楼主非游客),htmx hx-post 到 reward_accept 路由,hx-target=#xnx_reward_card 触发卡片刷新

    • 必测: thread-XXX.htm 帖子详情页回复列表,楼主/管理员看到的非自己回复旁显示「采纳为最佳答案」按钮,点击弹出确认对话框

    • 必测: my_post.htm / user_post.htm 用户中心回帖列表不显示采纳按钮

    • 必测: 主帖(first pid)不显示采纳按钮

  • [新功能] xnx_reward Task 22: 静态 JS 文件 + footer_js_after hook(reward.js 用原生 JS + htmx 4 事件实现发帖表单 checkbox 切换字段显示 + 采纳成功/失败 toast + 页面刷新;footer_js_after.htm 仅在 thread-create/post-create/thread-read 加载,用 G() 取 $route/$action,esc_attr + $conf[static_version] 拼接 URL)

    • 必测: thread-create 发帖页勾选"启用悬赏"后悬赏金额/积分类型/留言字段展开,取消勾选则收起

    • 必测: thread-read 帖子详情页楼主/管理员点"采纳为最佳答案"成功后 toast 提示 + 1.5s 后刷新显示最佳答案置顶卡片

    • 必测: 采纳失败(重复采纳/权限不足/网络错误)toast 显示后端返回的错误消息或默认"采纳失败"

    • 必测: my_post.htm / user_post.htm 用户中心页面不加载 reward.js(G(route) 不匹配)

  • [显示缺陷] 修复 xnx_appcenter 审核通过/补发讨论帖后,xnx_hidden 启用时下载链接为裸 URL 不可点击([hidden] 内部漏 包裹,HiddenService::renderHiddenContent 用 xn_html_purify 处理内容是支持 的)

    • 必测: 后台应用审核通过/补发讨论帖后,帖子内隐藏下载链接回复可见后是可点击的 标签

  • [新功能] xnx_reward v1.0.0 悬赏插件正式完成(共 18 个文件):conf.json/install.php/uninstall.php/setting.php+setting.htm/RewardService.php(854 行,CAS 并发防护+哨兵版本号+CreditsService 守卫)/route/reward.php+admin_reward.php/admin/view/htm/reward_admin.htm/view/htm/my_reward.htm+reward_card.htm+reward_best_answer.htm/static/js/reward.js

    • 路由架构:所有路由统一以 reward 作为 $route 前缀(xn_url_parse 用 - 拆分,第一个段为 $route),避免 my-reward/admin-reward-list 等被错拆

    • Hook 注册:model_inc_file.php 注册 RewardService;model_route_table_end.php 注册 8 条路由;index_route_case_end.php 前台分发 case reward;admin_index_route_case_end.php 后台分发 case reward

    • 发帖表单:post_ref_thread_after.htm(PC)+ post_ref_thread_after_mobile.htm(手机端 input id 加 _m 后缀防冲突)+ if(route==thread&action==create) 区分发帖/回复

    • 帖子详情:thread_info_start.php 加载悬赏数据(重命名自 thread_display_start.php 匹配核心标记)+ thread_postlist_before.htm 插入 reward_card.htm 和 reward_best_answer.htm(重命名自 thread_post_list_before.htm 匹配核心 postlist 标记)

    • 帖子列表:thread_subject_after.htm + thread_list_inc_subject_after.htm 显示「💰 悬赏 X 积分」徽章(静态缓存避免 N+1)

    • 回复采纳:post_list_inc_subject_after.htm 显示「采纳为最佳答案」按钮,htmx hx-post 到 reward-accept-{reward_id}-{pid},hx-target=#xnx_reward_card

    • 删帖级联:model_thread_delete_end.php 仅 status==0 退还积分(reason=reward_delete_refund),删主表+日志表+清缓存

    • 个人中心:user_nav_end.htm 添加「我的悬赏」入口(ti-coin 图标),my_reward.htm 双 tab(published/earned)+ 分页

    • 后台管理:reward_admin.htm 列表+筛选+强制结束/手动退还/手动发放(Modal 输入 pid)+ 双 tab 导航(设置/列表)

    • 语言包:lang_zh_cn_bbs.php + lang_zh_tw_bbs.php + lang_en_us_bbs.php 各 47 个语言键

    • 静态资源:static/js/reward.js 原生 JS + htmx 4 事件(htmx:after:swap/htmx:response:error),footer_js_after.htm 仅在 thread-create/post-create/thread-read 加载

    • 必测: admin/?plugin-setting-xnx_reward.htm 设置页保存;admin/?reward-list.htm 后台悬赏列表显示

    • 必测: thread-create 允许版块显示悬赏配置卡片,勾选启用后填写金额提交 → 扣积分 → 帖子详情页显示悬赏卡

    • 必测: thread-XXX.htm 楼主/管理员点采纳按钮 → 积分划转 → 最佳答案卡片置顶 + 状态已采纳

    • 必测: 悬赏过期(懒加载触发)→ 按配置退还发帖人/归入平台,状态已过期

    • 必测: my-reward-published / my-reward-earned 双 tab 切换正常

    • 必测: 删进行中悬赏帖 → 退还积分,删悬赏记录

    • 必测: forum-XXX.htm 列表页悬赏帖标题旁显示徽章

    • 同步: conf.php static_version 1.2.5 → 1.2.6,清理 tmp/route_.php + tmp/view_htm_.htm + tmp/lang_*_bbs.php + tmp/model.min.php 编译缓存

  • [隐私泄露] 修复 xnx_feeds 左下角动态 toast 通知直接取 user.username(登录账号)暴露用户身份,改用 display_name(user_format 派生:nickname 优先 fallback username,匿名化用户统一显示「已注销用户」),fallback 到 nickname 兜底缓存为空场景

    • 必测: 前台任意页面左下角弹出的动态 toast 显示用户昵称而非登录账号;匿名化用户显示「已注销用户」

  • [功能完善] xnx_appcenter 应用列表页卡片名称下方增加一句话介绍(brief)

    • 必测: appcenter-list.htm 页面,每个应用卡片应显示 brief 一行

  • [粘贴转换] 修复发帖编辑器粘贴 Markdown 文档被原样插入为代码块的问题

    • 根因1:从 VSCode/Typora 等 IDE 复制 .md 文件时 text/html 形如 <pre><code class=\"language-markdown\">...</code></pre>,AIEditor 内置 PasteExt 直接按代码块插入,未走 insertMarkdown 转换

    • 根因2:looksLikeMarkdown 要求 ≥2 个特征匹配,但只有 # 标题/## 子标题 的纯 Markdown 文档只命中标题 1 个特征被判定为非 Markdown 放行

    • 修复1:新增 isMarkdownCodeBlock 检测,识别 text/html 中 language-markdown class 时强制走 insertMarkdown 转换为 HTML

    • 修复2:looksLikeMarkdown 标题特征单独判定(≥2 行 # 开头即认定),避免 shell 单行注释误判

    • 必测: thread-create 页面粘贴含 # 标题 的 Markdown 文档应转为 HTML 标题/段落,而非 <pre><code class=\"language-markdown\"> 代码块

    • 必测: 粘贴 Python/JS 等其他语言代码块仍按代码块原样插入(language 非 markdown 不强制转换)

    • 必测: 粘贴普通纯文本(无 Markdown 特征)仍按纯文本插入

  • [功能完善] xnx_appcenter 三项移动端与语言包优化

    • 必测: appcenter-list.htm 标签筛选移动端左右滑动

    • 必测: appcenter-list.htm 移动端隐藏「我的应用」「发布应用」按钮

    • 必测: appcenter-purchases.htm 移动端图标缩小/日期换行/下载按钮只显示图标

    • 必测: appcenter-my.htm 表头「操作」应显示中文「操作」而非字面量 operate

    • 修复: 核心 lang(.operate.) 语言键未定义(zh-cn/zh-tw/en-us 三语言包同步补齐)

  • [样式调整] xnx_appcenter 应用列表卡片一句话介绍位置调整到名称下方、徽章上方

    • 必测: appcenter-list.htm 应用卡片顺序为 名称 → 一句话介绍 → 徽章

  • [样式调整] xnx_appcenter 应用卡片布局调整:brief 改为 2 行省略,徽章组移至开发者名称右侧

    • 必测: appcenter-list.htm brief 超过 2 行应显示省略号;徽章紧贴开发者名称后

  • [样式调整] xnx_appcenter 应用卡片徽章分组:价格徽章移至名称右侧同一行,分类徽章保留在开发者名称右侧

    • 必测: appcenter-list.htm 卡片显示「名称 [免费/付费]」一行,下方 brief;底部「用户 开发者 [分类] | 下载量」

  • [功能完善] xnx_appcenter 应用卡片底部在分类徽章后追加显示标签徽章

    • 必测: appcenter-list.htm 卡片底部应显示「开发者 [分类] [标签1] [标签2] | 下载量」

  • [样式修复] xnx_appcenter 应用列表网格断点修正为 mobile-first(md=3列, lg=4列)

    • 必测: appcenter-list.htm 中屏(≥768px)一行3个,大屏(≥992px)一行4个

  • [样式优化] xnx_appcenter 价格徽章(免费/付费)改为卡片右上角斜角飘带样式

    • 必测: appcenter-list.htm 卡片右上角显示 45 度斜角徽章(绿色「免费」/橙色「付费 N」)

  • [样式优化] xnx_appcenter 斜角价格徽章改用固定宽度+居中对齐,解决字多时文字偏离中心问题

    • 必测: appcenter-list.htm 「免费」和「付费 100」都应在斜角飘带中心居中

  • [功能完善] xnx_appcenter 审核通过自动发帖标题加【XIUNOX{分类名}】前缀,话题自动同步「标签名+分类名」拼接(如登录+插件=登录插件)

    • 必测: 后台审核通过一个有标签的应用,自动发的帖子标题应带【XIUNOX插件】等前缀

    • 必测: 该帖子的话题列表应包含每个「标签名+分类名」拼接的话题

  • [粘贴转换] 增强 IDE 复制 Markdown 文档识别:Trae CN/VSCode 等 IDE 复制 markdown 文档时 text/html 含 IDE 主题样式(JetBrains Mono/Menlo/Monaco 等宽字体 + 深色背景色),ratio 高达 4+ 触发"高比例放行"分支导致按富文本原样插入(丢失 markdown 语义)。新增 isIdeStyledHtml 检测等宽字体+深色背景样式特征,配合 looksLikeMarkdown(text) 双重判断,强制走 insertMarkdown 转换为 HTML

    • 必测: thread-create 页面从 Trae CN/VSCode 复制含 #/##/### 标题的 Markdown 文档应转为 HTML 标题/段落,而非带 IDE 样式的 span 标签

    • 必测: 粘贴真富文本(网页复制含彩色样式但非 markdown 内容)仍按富文本原样插入

    • 必测: 粘贴 Python/JS 代码块(IDE 复制但 text/plain 非 markdown)仍按代码块原样插入

  • [重构] 编辑器粘贴 Markdown 转 HTML 逻辑抽公共模块,appcenter 应用介绍编辑器同步支持

    • 抽取 view/js/editor-paste-markdown.js(导出 window.setupEditorPasteMarkdown),发帖页 EditorService 与 xnx_appcenter 应用介绍编辑器共享同一份 paste 逻辑

    • EditorService.php 内联 paste 逻辑(约 150 行)替换为调用 setupEditorPasteMarkdown,heredoc JS 体积减 8KB

    • appcenter_desc_editor.js 调用 setupEditorPasteMarkdown 启用粘贴 markdown 转 HTML(之前完全没有此功能)

    • getEditorAssets() 注册 editor-paste-markdown.js(filemtime 版本号),appcenter_publish.htm 通过 $_editorAssets 自动加载

    • appcenter_publish.htm 修正 appcenter_publish.js/appcenter_desc_editor.js 引用添加 ?v=$static_version 强制浏览器刷新缓存

    • 必测: thread-create 发帖页粘贴 markdown 文档转 HTML(原功能不回归)

    • 必测: appcenter-publish 页面应用介绍编辑器粘贴 markdown 文档转 HTML(新功能)

    • 必测: appcenter-edit-{app_id} 编辑应用页面应用介绍编辑器粘贴 markdown 文档转 HTML

  • [样式回滚] xnx_appcenter 取消斜角飘带,免费/付费徽章放回应用名称右侧同一行

    • 必测: appcenter-list.htm 卡片名称行显示「应用名 [免费/付费]」

  • [样式调整] xnx_appcenter 应用卡片名称与价格徽章改为 space-between 两端对齐

    • 必测: appcenter-list.htm 应用名靠左、免费/付费徽章靠右

  • [BUG 修复] 修复 3 个 fatal/warning

    • 修复: xnx_appcenter promoteAttach() 中 $log() 误写为变量调用导致 “Value of type null is not callable” fatal,改回 xn_log()

      • 必测: appcenter-publish.html 发布应用上传图标/截图/下载包不应再报 fatal

    • 修复: sitemap.xml 路由调用 forum_format() -> esc_attr() 时 EscapeService.php 未加载(index.inc.php 才加载,但 sitemap 在 index.inc.php 之前拦截),sitemap 拦截块前提前 include_once EscapeService.php

      • 必测: /sitemap.xml 应正常输出 XML 不再 500

    • 修复: attach_gc() 并发清理临时文件时 unlink 报 warning(文件已被另一进程删除),加 @ 抑制

      • 必测: 并发请求触发 attach_gc 时日志不再出现 unlink No such file or directory warning

  • [Bug修复] xnx_hidden/AttachAccessService: mb_substr(null) 在 PHP 8.1+ 触发弃用警告

    • 必测: /thread-470.html 帖子详情页底部解锁用户列表渲染(display_name 为 null 的用户)

  • [Bug修复] xnx_appcenter: 附件 tmp_files key 算法用 count() 导致并发或非连续 key 重叠覆盖

    • 必测: attach-create 多次上传后看 key 是否唯一

  • [Bug修复] xnx_appcenter: promoteAttach 中 @unlink 在 PHP 8 不再完全抑制自定义 ErrorHandler,改用 is_file() 守卫

    • 必测: 编辑应用删除截图/图标,看日志是否还有 unlink No such file or directory

  • [Bug修复] xnx_appcenter: 编辑页图标 promote 失败时旧图标被覆盖为 0,截图合并静默吞错

    • 必测: 编辑应用上传新图标失败时保留旧图标,截图部分失败时全部失败才报错

  • [优化] xnx_appcenter: 编辑页隐藏《上架前必看》卡片和 guide_read 校验,仅发布时要求

    • 必测: 编辑应用页面不应显示上架必看卡片

  • [优化] xnx_appcenter: 应用名称限制 9 个字符以内

    • 必测: 发布应用输入 10 字以上的名字看是否被前端拦下

  • [新功能] xnx_appcenter: 应用 slug(商店唯一 ID),前缀需匹配开发者资料 brand_prefix,全局唯一

    • 必测: 发布应用未填 slug/格式错误/前缀不匹配/已存在 都会被拦下

    • 必测: 升级 1.9.0 触发 upgrade.php 给 xnx_appcenter_app 加 slug 字段+UNIQUE 索引

  • [BUG 修复] xnx_appcenter v1.9.0 升级时 UNIQUE KEY slug 未添加(存量应用 slug 为空字符串冲突)

    • 修复: upgrade.php 新增 v1.9.1 补丁块,SHOW INDEX 检测 slug 索引不存在时,先 UPDATE 空值行为 app_{id} 再 ADD UNIQUE KEY

    • 修复: v1.9.0 原块也补上 UPDATE 空值逻辑(新装/未升级站点走这条)

    • 版本: conf.json 1.9.0 → 1.9.1,后台插件管理页将显示「需升级」红色按钮

    • 必测: 后台点 xnx_appcenter 升级按钮,升级完成后 SHOW INDEX FROM bbs_xnx_appcenter_app 应包含 slug 索引

    • 必测: 升级后 appcenter-publish.html 发布应用不再报 Column not found

  • [htmx 嵌套 bug] 修复首页/版块页点击最热/精华/关注 tab 后导航布局失效

    • 根因: hx-target=#body + hx-select=#body + hx-swap=innerHTML 组合下,htmx 把响应中的 元素整体插入到当前 #body 的 innerHTML,造成嵌套 元素(HTML 规范禁止),导致左侧栏/tabs/右侧栏样式失效

    • 修复: hx-swap 由 innerHTML 改为 outerHTML,用响应中的新 #body 整体替换旧 #body 元素本身

    • 影响文件: index.htm(7) + forum.htm(6) + layout_three_column.inc.htm(1) + xnx_medal/medals_layout.htm(1) + xnx_moments_theme 覆盖 layout(1) 共 16 处

    • 必测: 首页点击最热/精华/关注 tab 后左侧栏与 tabs 仍在;版块页同样测试;勋章墙页面切换

  • [伪静态设置] 去掉检测失败时的自动回滚逻辑,改为只警告

    • 根因: 保存伪静态设置时若自检失败会自动回滚到旧值(默认0),用户以为保存没生效;且自检可能因 DNS 回环慢/SSL 证书校验等误判失败

    • 修复: 删除 admin/route/setting.php 中检测失败时的 file_replace_var 回滚代码,保留用户选择,仅返回 code=-1 警告

    • 语言: 同步更新 zh-cn/zh-tw/en-us 的 admin_permalink_detect_fail 文案,去掉"已回滚"字样

    • 必测: 后台 setting-permalink 页面从默认切到伪静态模式,若检测失败应看到红色警告但 conf.php 保留新值

最新回复

请先登录后再回复 登录

uid:1 管理
关注
随遇而安,随缘而行
发帖 106
评论 411
粉丝 13
关注 1
目录
XIUNOX 更新记录贴 202600719
此广告位招租
此广告位招租
此广告位招租
广告招租
广告招租
广告招租
广告招租
广告招租
广告招租