跳到主要内容
奇点CMS v0.4.72 · 官方网站 登录 / 注册 在线激活

更新日志

版本发布逐版本列出变更说明,站点公告按置顶与时间倒序排列,共 98 条记录;升级前请先阅读对应版本的变更说明与升级步骤。

版本发布 98 条 站点公告 0 条
  • v0.4.39

    修复聊天插件"靓号特效"不显示

    随交付包发布

    需求:"修复聊天插件靓号特效显示失败的问题"。

    查看完整变更

    需求:"修复聊天插件靓号特效显示失败的问题"。

    一、根因:特效样式进不了插件的 Shadow DOM

    现象说明
    全站页面里靓号有"七彩顺时针流光描边"定义在 assets/css/style.css:.vip-active(conic-gradient 彩虹环 + mask 挖空)与 .pretty-number(渐变流动文字)
    聊天插件里完全没有特效插件渲染在 Shadow DOM 内,页面 CSS 无法穿透;而插件的 5 个样式表里一条相关规则都没有(实测 vip-active/glow/流光/pretty 命中 0)
    插件 JS 也没加类chat.js / friends.js / messages.js 渲染头像时从不加 vip-active,号码也没套 .pretty-number

    → 结论:不是数据问题,是插件缺样式 + 缺类名。

    二、修复内容

    #文件改动
    1assets/im-plugin/styles/im-pretty.css(新增,3,584 B)把同一套特效搬进 Shadow DOM:.vip-active 七彩流光描边(含 mask-clip: content-box + mask-composite: exclude 长属性写法,避免简写导致描边消失)、.pretty-number 渐变流动文字;插件头像较小,描边取 2px;另加 @supports 回退(无 mask-composite 的老内核退化为彩色描边光晕)
    2assets/im-plugin/core/im-sdk.js① cssFiles 登记新样式表;② 新增 window.IMPretty 助手:is(n)(判定 10000~999999,与站内 numberText() 规则一致)、cls(n, base)(靓号追加 vip-active)、num(n)(输出 .pretty-number 号码 HTML)
    3assets/js/tab-card.jsIM_PREFETCH_FILES 同步登记;IM_BUILD 递增(20261002-9 → 20261002-10)强制刷新插件资源缓存
    4modules/chat.js联系人头像加 vip-active、标题带流光号码;聊天头部号码用流光文字;消息头像(对方用 sender_user_number、自己用 AGENT_CONFIG.userNumber)加 vip-active
    5modules/friends.js好友项 / 好友申请 / 搜索结果的头像加 vip-active,ID 行号码套流光
    6modules/messages.js站内信列表头像加 vip-active,发送者号码套流光

    三、验证(Node + DOM 桩,用真实 IMPretty 与真实渲染函数)→ 39 / 39 通过

    判定规则:10000 / 123456 / 999999 → 靓号 ✓    9999 / 1000000 / 0 / null → 非靓号 ✓
             563474767、403742444(九位)→ 非靓号 ✓(与站内 numberText 规则一致)
    聊天联系人:靓号头像 <div class="im-avatar-placeholder vip-active">站</div> + 流光号码 ✓
               九位普通号 → 无 vip-active/pretty-number ✓
    消息头像:对方靓号 ✓  自己(AGENT_CONFIG.userNumber=10000)✓  普通号 ✗(无特效)✓
    好友项 / 搜索结果 / 站内信:靓号带特效 ✓,普通号与系统消息不带 ✓
    插件样式表:含 conic-gradient、@keyframes imVipRainbowSpin、mask 长属性、花括号配平 12/12 ✓
    资源登记:im-sdk.js cssFiles ✓  tab-card.js 预取列表 ✓  IM_BUILD 已递增 ✓

    四、顺带发现(需要你确认)

    站内对"靓号"的判定是 10000 ~ 999999(includes/fn-user.php 的 numberText() / userDisplayName())。 当前三个账号的号码是:

    账号号码是否靓号(按站内规则)
    origin(站长)10000✅ 是(全站与插件都会显示流光特效)
    okay563474767(九位)❌ 否 —— 属于"普通号"
    upon403742444(九位)❌ 否 —— 属于"普通号"

    所以这三个账号里只有站长会看到特效;若你希望其它账号也有特效,需要把它们的号码换成 10000~999999 区间的靓号(后台「靓号管理」/号池分配),这与本次修复无关。

  • v0.4.38

    修复:短视频上传一直卡在"上传中"

    随交付包发布

    需求:"修复短视频上传时一直卡在上传状态"。

    查看完整变更

    需求:"修复短视频上传时一直卡在上传状态"。

    一、根因:上传进度脚本从未被引入页面(v0.4.34 的漏插)

    排查链条:

    1. 访问日志里 17:42 之后没有任何 POST /post-video.php → 说明浏览器根本没发出上传请求;
    2. C:\Temp(PHP 上传临时目录)无进行中的临时文件 → 也不是"正在上传";
    3. 服务端渲染结果里,upload-progress.js 只出现在HTML 注释里, 没有独立的 <script src="...upload-progress.js"> 标签;
    4. 于是页面执行到 QdUpload.submit(...) → ReferenceError(QdUpload is not defined), 而按钮在此前一行已被置为 发布中... → 界面永远停在"上传中",请求从未发出。

    漏插原因(我方缺陷):v0.4.34 的补丁里,插入脚本标签前用了 if 'upload-progress.js' not in t: 作为守卫,而同一补丁早前已插入的注释里恰好含这串文字 → 整段插入被静默跳过;随后的自检又用 'upload-progress.js' in t 判断(同样被注释命中)→ 假通过。

    二、修复内容

    #文件改动
    1post-video.php补上 <script src="assets/js/upload-progress.js?v=…"></script>(位于内联脚本之前)
    2post-video.php兜底提交:window.QdUpload 缺失或 submit 不是函数时,自动改用 fetch 提交(同样的 JSON 处理与跳转)→ 即使进度组件加载失败也能正常发布
    3post-video.php提交整体 try/catch:任何前端异常都会恢复按钮 + 显示原因,绝不停在"发布中"
    4post-video.phpMutationObserver 增加存在性判断(旧 X5/IE 内核无此 API,原写法会抛错)
    5drama-upload.php / drama-update.php用严格正则复检独立 <script src> 标签(两页均已具备,无需改动)

    三、验证

    A. 提交路径回归测试(test-post-video-submit.js,直接跑服务端渲染出的内联脚本)→ 15 / 15 通过:

    场景 1 QdUpload 可用        → 调 QdUpload.submit、按钮禁用、未走 fetch           ✅
    场景 2 QdUpload 缺失(本次故障原形)→ 自动回退 fetch、POST 成功并跳转播放页        ✅ ← 关键
    场景 3 QdUpload.submit 抛异常 → 捕获、按钮恢复"发布"、显示"提交异常:boom"        ✅
    场景 4 兜底 fetch 业务失败   → 按钮恢复 + 显示"视频大小不能超过 50MB"             ✅
    场景 5 兜底 fetch 网络异常   → 按钮恢复 + 显示"网络错误: …"                      ✅
    场景 6 submit 非函数         → 同样走兜底                                        ✅

    B. 线上验证(严格正则匹配真实标签,不再被注释骗过)→ 11 / 11 通过:

    检查结果
    短视频上传 / 短剧上传 / 短剧编辑 三页HTTP 200,独立 <script src> 标签 + 进度条容器 + QdUpload 调用 全部 ✓
    真实上传回归(小 MKV){"success":true,"moment_id":"20"},落盘 moment_v_*.mp4(自动转封装)✓
    测试数据清理moments 16 / moment_media 20 / short_drama 0 / 无自检分类 ✓(与修复前一致)

    四、经验教训与流程改进

    本次自检之所以"假通过",是用子串匹配判断"页面已引入脚本",而注释里也含同样文字。 现已统一改为严格标签正则 /<script[^>]+src="[^"]*upload-progress\.js[^"]*"[^>]*><\/script>/, 并对三个上传页逐页复检(本次验证 B 部分即用此法)。

  • v0.4.37

    修复:从好友列表进入聊天窗口不同步聊天历史

    随交付包发布

    需求:"修复聊天插件好友列表进入聊天窗口没有同步聊天历史记录"。

    查看完整变更

    需求:"修复聊天插件好友列表进入聊天窗口没有同步聊天历史记录"。

    一、根因(两个叠加缺陷)

    #缺陷后果
    1_loadMessages() 用单一布尔锁 if (this._loadingMessages) return;切回聊天 Tab 时 refresh() 会先给上一个会话发起加载(锁被占用)→ 紧接着 openChatWith(新好友) 的历史请求被直接 return 挡掉 → 新会话消息区永远空白
    2响应不校验归属上一个会话的在途响应回来后,会把它的消息渲染进新会话的窗口(串话),或用空结果覆盖
    3模块初始化是异步的(loadJsFiles 回调里才 new IMChatModule() / 暴露 window._imChatModule),而好友模块点击时同步直调 window._imChatModule.openChatWith(...)聊天模块尚未就绪时该分支被 if (... && window._imChatModule) 静默跳过 → 点了没反应/没有历史

    二、修复内容

    #文件改动
    1assets/im-plugin/modules/chat.js_loadMessages() 改为 "同一会话才挡重复请求"(_loadingPartnerId 比对),换会话立刻放行;每次请求带令牌 _loadToken,响应回来先校验令牌与会话 id,过期响应直接丢弃
    2同上_openChat() 进入新会话时重置加载状态并递增令牌(让上一个会话的在途响应失效)
    3同上openChatWith() 在模块尚未挂载时把请求记入 _pendingOpen,init() 完成后自动补打开(消除异步初始化竞态,靓号也一并保留)
    4assets/im-plugin/core/im-sdk.js新增插件级 IMPlugin.openChatWith(userId, nickname, avatar, userNumber):先 switchTab('chat'),再轮询等待聊天模块就绪(最多约 4 秒)后打开
    5assets/im-plugin/modules/friends.js好友列表"💬 发消息"改用插件级 API(保留旧路径兜底)

    三、验证(Node + DOM/网络桩,驱动真实模块代码)

    qdcms-release/test-chat-history-sync.js → 17 / 17 通过:

    场景 1(原缺陷复现点):A 会话加载中 → 立刻打开 B
      [PASS] A 的历史请求已发出 → [1]
      [PASS] 切到 B 后 B 的历史请求**仍然发出**(修复核心) → 请求序列 chat_with=[1,2]
    场景 2:过期响应不得串话
      [PASS] B 的消息已渲染(2 条)        [PASS] A 的过期响应被丢弃(B 的 2 条仍在)
      [PASS] 加载标志未卡死
    场景 3:_openChat 重置状态
      [PASS] 重置加载标志 / 递增令牌(1 → 3)/ 新会话请求已发出(chat_with=5)
      [PASS] 新会话消息已渲染 / 旧会话响应仍被丢弃
    场景 4:模块未挂载竞态
      [PASS] 未挂载时记录待打开、不发请求 → init 后自动打开并补发历史请求(chat_with=7)、靓号带入

    反向验证(把第 1 条改回旧的"单一布尔锁"再跑):立即出现 [FAIL] 切到 B 后 B 的历史请求仍然发出 → 请求序列 chat_with=[1]、 [FAIL] B 的消息已渲染 → 渲染 0 条 —— 与用户描述的现象完全一致,证明测试确实覆盖该缺陷。

    线上核对:chat.js(同会话去重字段 / 请求令牌 / 过期丢弃 / 未挂载挂起)、im-sdk.js(插件级 openChatWith)、friends.js(改用插件 API)6 / 6 关键改动就位;三个资源 HTTP 200;首页 200 ✅

    四、效果

    • 从好友列表点「💬 发消息」→ 一定会切到聊天窗口并加载该好友的完整历史(即使聊天模块还在加载中);
    • 快速在多个会话间切换 → 不会串话(旧响应被丢弃)、不会卡在"加载中";
    • 修复同时覆盖了"发送视频后返回列表再进入"的历史卡死路径(_loadingMessages 不再残留)。
  • v0.4.36

    修复聊天插件"靓号失效"

    随交付包发布

    需求:"修复聊天插件靓号失效问题"。

    查看完整变更

    需求:"修复聊天插件靓号失效问题"。

    一、排查结论:服务端全对,问题在插件前端"没把靓号传/显示出来"

    环节实测
    用户靓号数据users.user_number 正常:站长 10000、okay 563474767、upon 403742444 ✅
    ajax-chat-contacts.php(联系人)返回 user_number ✅(403742444 / 10000)
    ajax-chat-history.php(聊天记录)返回 sender_user_number ✅(563474767)
    api-friend.php(好友列表)返回 user_number ✅(10000 / 403742444)
    friends.js 点"发消息"调 openChatWith(id, name, avatar) —— 把靓号丢掉了 ❌ → 聊天头部退回显示普通用户 id
    chat.js 的 openChatWith参数只有 3 个,且 user_number: '' 写死为空 ❌
    messages.js(站内信)完全没用接口已返回的 sender_user_number ❌ → 站内信里看不到靓号

    → 结论:"靓号失效"= 前端接线缺陷(显示回落成普通 id),不是号码数据或接口问题。

    二、修复内容

    #文件改动
    1ajax-user-card.php(新增)按 user_id 返回昵称/头像/靓号;登录 + CSRF 校验;role=9 统一对外显示(不暴露用户名);头像与其它接口同样处理
    2assets/im-plugin/modules/chat.js① openChatWith(userId, nickname, avatar, userNumber) 支持第 4 个参数;② 聊天窗口若拿不到号码,自动向 ajax-user-card.php 补取一次并即时刷新头部(失败静默,不影响聊天)
    3assets/im-plugin/modules/friends.js好友列表"发消息"按钮把 friend.user_number 一起传入
    4assets/im-plugin/modules/messages.js站内信列表显示 发送者 · ID: 靓号,详情显示 来自: 发送者(ID: 靓号)(系统消息无号码时不显示)
    5includes/footer.phpAGENT_CONFIG 新增 userNumber(当前用户靓号),供插件/页面显示"我的号码"

    三、验证

    测试结果
    ajax-user-card.php 四情形未登录被拒 ✅ / CSRF 错被拒 ✅ / 用户不存在 ✅ / 正常返回(站长 10000、okay 563474767)✅
    头像基址与 ajax-chat-contacts.php 同为根相对路径 ✅
    friends.jsopenChatWith(... friend.user_number ...) 已生效 ✅
    chat.js 兜底存在补取调用、成功后更新 _chatWith.user_number 与 .partner-status、失败静默 ✅
    messages.js列表 senderLabel、详情 fromText 均含靓号 ✅
    页面下发个人资料页 AGENT_CONFIG.userNumber = 563474767(user2 靓号)✅
    静态资源三个模块 HTTP 200 ✅
    数据3 位用户靓号完好(10000 / 563474767 / 403742444)✅
    合计18 / 18 断言通过(另含 4 项接口实测)

    四、效果

    • 插件里点好友"发消息" → 聊天头部显示 ID: 403742444(此前显示 ID: 3);
    • 从其它入口打开聊天(未带号码)→ 自动补取后同样显示靓号;
    • 站内信列表/详情显示发送者靓号;
    • 页面脚本可读 window.AGENT_CONFIG.userNumber 显示"我的靓号"。
  • v0.4.35

    个人资料页「站内信 / 好友 / 聊天」改为打开新版 IM 插件浮层

    随交付包发布

    需求:"修复个人资料页站内信,好友,聊天三个链接点击后进入老聊天插件,没有进入新聊天插件"。

    查看完整变更

    需求:"修复个人资料页站内信,好友,聊天三个链接点击后进入老聊天插件,没有进入新聊天插件"。

    一、问题定位

    项目实际情况
    个人资料页三个入口messages.php、messages.php?tab=friends、messages.php?tab=chat —— 都是整页跳转
    新版聊天插件assets/im-plugin/(window.IMPlugin,浮层容器,含 messages / chat / friends 三个模块),由 tab-card.js 按需加载 im-sdk.js
    结论三个链接进的是旧的全页聊天界面(messages.php),没有走新版浮层插件 → 与用户描述一致

    二、修复方案:新增 assets/im-plugin/core/im-links.js

    一个全站通用的链接接管脚本(事件委托,一次监听全局生效):

    能力说明
    接管规则任何带 `data-im-open="messages\friends\chat"的元素,点击 →IMPlugin.open(tab)` 打开新版浮层
    按需加载若 im-sdk.js 尚未加载 → 自动注入(基础路径由自身 src 推导,兼容子目录部署),加载完成即打开
    失败回退加载失败或 4 秒超时 → 自动回退到原有 href 跳转(不会卡住)
    保留原生行为ctrl/cmd/shift/alt + 点击、中键、无 JS 环境 → 一律放行,仍可新窗口打开
    渐进增强模板里 href 全部保留,老页面 messages.php 仍可直接访问

    三、接入点

    文件改动
    assets/im-plugin/core/im-links.js新增(4,962 B)
    includes/footer.php在 tab-card.js 之后引入该脚本(全站生效)
    profile.php3 个快捷入口(站内信/好友/聊天)+ 2 个统计入口(好友/未读消息)加 data-im-open
    includes/header.php导航栏「站内信」加 data-im-open="messages"

    四、验证

    测试结果
    im-links.js 行为(Node + DOM 桩,test-im-links.js)17 / 17 通过:点击接管、子元素委托、插件就绪直接打开、按需注入 im-sdk、加载成功自动打开、加载失败回退、4 秒超时回退、ctrl/中键放行、普通链接不受影响、IMLinks.open() 直调
    线上个人资料页(真实登录会话)HTTP 200;data-im-open="messages" 3 处(快捷入口+统计+导航)、friends 2 处、chat 1 处;im-links.js 已引入;href 保留 ✅
    首页导航「站内信」已接管,im-links.js 已引入 ✅
    静态资源im-links.js HTTP 200(4,962 B)、im-sdk.js HTTP 200(26,253 B)✅
    回退路径messages.php、?tab=friends、?tab=chat 三个地址仍返回 200(老界面未被破坏)✅

    说明:Tab 标识与插件模块一致(messages / chat / friends,默认进入 chat), 与站内浮动聊天按钮(tab-card)打开的是同一个浮层插件。

  • v0.4.34

    短视频 / 短剧上传页新增真实上传进度条

    随交付包发布

    需求:"给短视频和短剧上传页面增加上传进度条显示"。

    查看完整变更

    需求:"给短视频和短剧上传页面增加上传进度条显示"。

    一、为什么不能沿用 fetch

    fetch() 无法获取"已上传字节数"(只能等到响应返回),浏览器里唯一能给真实上传进度的是 XMLHttpRequest 的 xhr.upload.onprogress。因此本次新增通用组件并改造提交方式。

    二、新增:assets/js/upload-progress.js(通用上传进度条)

    能力说明
    真实进度按已传字节计算百分比(不是假动画)
    数据信息已传 / 总量、实时速度(KB/s、MB/s)、预计剩余时间
    三阶段状态① 上传中(蓝紫渐变)→ ② 服务器处理中(橙色动画,转码/截图期间;避免用户以为卡死)→ ③ 成功(绿色)/ 失败(红色)
    失败可读服务端 JSON 的 error 原样显示;非 JSON 响应提示"服务器返回异常(HTTP xxx)";区分网络中断 / 超时 / 取消
    交互保护上传期间禁用提交按钮(防重复提交),失败后自动恢复可重试
    零侵入只依赖一个容器元素(#uploadProgress);若缺失组件会自动创建并插到表单后;样式由组件自身注入

    用法:

    QdUpload.attach(formEl, { box: '#uploadProgress', button: btn, timeout: 1800000,
                              onSuccess: function (d) { location.href = d.redirect; } });

    三、三个页面接入

    页面改动
    post-video.php(短视频)fetch → QdUpload.submit()(保留原 FormData 组装与错误提示;失败原因同时写入原错误框)
    drama-upload.php(短剧上传)传统表单 POST → XHR + JSON 分支:新增 $isAjax 判定、门禁/成功/错误三处 JSON 返回;表单接入 QdUpload.attach()
    drama-update.php(短剧编辑 / 追加剧集)同上(两个表单各自独立进度条:#uploadProgressEdit、#uploadProgressAdd)

    踩坑记录(已修):这两个短剧页在文件顶部就 require header.php,整页 HTML 已进入输出缓冲; 若直接 echo json_encode(...),响应会变成「HTML + JSON」导致前端 JSON.parse 失败。 因此新增 dramaUploadJson() 助手:先 ob_end_clean() 清空缓冲再输出 JSON 并 exit。

    顺带统一:短剧剧集(上传与追加)也接入 convertVideoToMp4() —— MOV/MKV/AVI 等容器会自动转封装/转码为 MP4, 与短视频动态保持一致(此前短剧允许 mkv/mov 却原样落盘,浏览器可能无法播放)。

    四、验证

    测试结果
    进度条组件行为(Node + DOM/XHR 桩,test-upload-progress.js)23 / 23 通过:50% 进度、3.00 MB / 8.00 MB | 6.59 MB/s | 剩余约 1 秒、处理中状态、成功/失败/网络/超时、按钮恢复、attach 拦截
    post-video.php / drama-upload.php 页面渲染HTTP 200,含进度条容器与 JS 引用 ✅
    drama-update.php(临时短剧 + 所有者会话)HTTP 200,两个容器 + 2 处 QdUpload.attach ✅(验证后临时数据已删除)
    短剧 AJAX JSON 分支{"success":false,"error":"请至少上传一集视频"}、CSRF 失败 JSON、非 XHR 仍是 HTML(传统流程不受影响)✅
    真实上传回归(AJAX + MKV){"success":true,"moment_id":"19"},落盘 moment_v_*.mp4(已转 MP4)✅
    数据卫生测试动态/短剧/分类/会话文件全部清理;moments 16、moment_media 20、short_drama 0(与测试前一致)✅

    本次改动不需要重启 PHP / 重载 nginx(纯 PHP + JS)。 但 v0.4.33 的 15 分钟超时配置仍需你在宝塔执行一次「PHP 8.0 重启 + Nginx 重载配置」才生效。

  • v0.4.33

    短视频上传:支持 MOV/MKV/AVI 等自动转 MP4;超时对齐 15 分钟

    随交付包发布

    需求:"检测网站短视频上传报错"。结论:上传功能本身正常(14 次提交:200 ×10 / 499 ×3 / 400 ×1),

    查看完整变更

    需求:"检测网站短视频上传报错"。结论:上传功能本身正常(14 次提交:200 ×10 / 499 ×3 / 400 ×1), 报错来自格式与体积限制以及弱网超时,本次针对性修复。

    一、体检结论

    项目结果
    上传端点 POST /post-video.php200 ×10、499(客户端主动断开)×3、400 ×1 —— 无 500/502/413 ✅
    已成功入库moments 今日新增 13 条,moment_media 记录齐全 ✅
    最大成功视频4.41 MB(10-02);今日的 1.35~2.39 MB ✅
    PHP 限制upload_max_filesize 500M / post_max_size 600M / max_execution_time 300 ✅
    nginxclient_max_body_size 600m(与 PHP 对齐)✅
    业务限制(真正卡点)单视频 50MB(MOMENT_VIDEO_MAX_SIZE)、仅 mp4/webm、前端 5 分钟超时 ⚠️

    报错成因(按出现概率):

    1. 格式不支持:只接受 video/mp4、video/webm → 手机下载来的 MKV / MOV / AVI / TS 会被拒: xxx.mkv 不是支持的视频格式(仅支持 MP4 / WebM);
    2. 体积超限:超过 50MB → xxx 超过 50MB 限制(而 php/nginx 允许到 500M/600M,限制在业务层);
    3. 弱网超时:前端 AbortController 5 分钟 + PHP/FastCGI 300s → 手机上传大文件超时中断(日志里的 499)。

    二、修复内容

    #改动说明
    1新增 convertVideoToMp4()(includes/fn-upload.php)先用 -c copy -movflags +faststart 无损转封装(MKV/MOV/TS/FLV 内含 H.264 时通常数秒完成);失败再回退 libx264 + aac 转码
    2放宽视频白名单(includes/fn-moments.php)新增 video/quicktime(mov)、video/x-matroska(mkv)、video/x-msvideo(avi)、video/x-m4v、video/mp2t(ts)、video/x-flv、video/x-ms-wmv、video/3gpp、video/mpeg、video/ogg
    3上传后自动转 MP4 落盘非 mp4/webm 的容器自动转成 .mp4 后发布(转封装失败则保留原文件并交给后台压缩流程重试);file_size 记录实际落盘大小
    4前端放宽可选类型accept 与类型正则同步扩展(含 .mov/.mkv/.avi/.ts/...),提示文案改为支持的完整列表
    5超时对齐 15 分钟前端 AbortController 300s → 900s;php.ini max_execution_time/max_input_time 300 → 900;nginx fastcgi_send/read_timeout 300 → 900
    6上传期间显示已用时间按钮文案变为"发布中… 已用 N 秒(请勿关闭页面)",减少误判卡死而重复提交(此前的 499 多为此因)
    7nginx fastcgi_request_buffering off大文件请求体直接流给 PHP,避免 nginx 先整包落盘再转发(省一半磁盘 I/O)

    三、验证(真实端到端)

    用 ffmpeg 生成 2 秒 H.264+AAC 测试视频 → 转封装为 .mkv → 通过真实登录会话上传:

    POST /post-video.php(media[]=vtest_upload.mkv;type=video/x-matroska)
    → {"success":true,"moment_id":"18","redirect":"video-play.php?id=18&index=0"}   ✅
    
    落盘:uploads/moments/2026/10/moment_v_1791626149_9548.mp4(30,579 B,扩展名已是 .mp4)✅
    ffprobe:h264,video / aac,audio; duration=2.001;format=mov,mp4,m4a,3gp,3g2,mj2 ✅
    同目录残留 .mkv:0 个 ✅   封面已生成:uploads/covers/moments/thumb_1791626150_5795.jpg ✅

    测试数据已全部清理:moment 18、moment_media 记录、视频文件、封面、测试分类均已删除, moments 恢复 16 条 / moment_media 20 条,上传目录无残留、无遗留 ffmpeg 进程 ✅

    四、需要用户操作(生效用)

    1. 宝塔 → 软件商店 → PHP 8.0 → 重启(max_execution_time/max_input_time = 900 生效);
    2. 宝塔 → 软件商店 → Nginx → 重载配置(fastcgi_*_timeout = 900 与 fastcgi_request_buffering off 生效)。

    可选项:若希望放宽单视频 50MB 限制,改 includes/fn-moments.php 第 22 行 define('MOMENT_VIDEO_MAX_SIZE', 50 * 1024 * 1024) 即可(php/nginx 已允许到 500M/600M); 但手机弱网下上传体积越大越易失败,建议同时考虑保持 50MB 并提示用户压缩。

  • v0.4.32

    错误日志体检:清理历史噪音、补齐 favicon/robots、日志分流与 PHP 日志落地

    随交付包发布

    需求:"检测网站错误日志"。范围:10123.xn--fiqs8s.error.log(2596 行 / 793 KB,覆盖 10-02 10-10)

    查看完整变更

    需求:"检测网站错误日志"。范围:10123.xn--fiqs8s.error.log(2596 行 / 793 KB,覆盖 10-02 ~ 10-10) 与访问日志近 5000 条。

    一、体检结论:站点健康,无致命错误

    类别条数结论
    PHP Fatal / Parse error0✅ 无致命错误
    502 / 504 / FastCGI 错误0✅ PHP-FPM 正常
    数据库错误0(MySQL error log 亦为空)✅ 正常
    /im-stream 上游提前关闭458⚠️ 良性:客户端换令牌/切页导致 SSE 主动断开(见下)
    uploads/agent-icons/agent-default.png 缺失248✅ 已解决(文件 10-02 20:54 补齐,此后 0 条)
    assets/images/default-avatar.png 缺失17✅ 已解决(同上)
    robots.txt 缺失124(今日 16)⚠️ 仍在发生 → 本次补齐
    favicon.ico 缺失52(今日 1)⚠️ 仍在发生 → 本次补齐
    扫描器探测(.env / .git / wp-* / 各类 shell)~100✅ 站点正确返回 404,无需处理

    404 占比:近 5000 条访问中 404 有 2458 条(49%),绝大多数是自动化漏洞扫描(/wp-content/...、/.env、/chosen.php、/1.php 等), 属正常现象;403 共 336 条,其中 210 条是 GET /(带 WP 风格参数)—— 站点安全层正常拦截。

    二、/im-stream 458 条的成因(已确认非故障)

    • nginx 侧 SSE 代理配置完全正确(proxy_buffering off、proxy_read_timeout 3600s、gzip off 等);
    • Go 侧 im_sse.go 亦正确(text/event-stream、X-Accel-Buffering: no、20 秒心跳、Flush()、客户端断开即 return);
    • 实证:ajax-im-token.php 今日调用 242 次、中位间隔 11 秒,每次换新令牌都会关闭旧事件流 → nginx 便记录一条 "upstream prematurely closed"。属于 SSE 正常重连的副产物。

    处理:在该 location 内把这类日志分流到独立文件并只记 crit,主错误日志从此清爽:

    location = /im-stream {
        error_log D:/BtSoft/wwwlogs/im-stream.error.log crit;
        ...
    }

    三、本次修复

    #项目内容
    1robots.txt新增(569 B):放行正常抓取,屏蔽 /admin/ /data/ /includes/ /install/ /vendor/ 等敏感路径,并拒绝 Semrush/Ahrefs/MJ12 等扫描型爬虫
    2favicon.ico由站点 logo 生成多尺寸 ICO(16/32/48/64,12,431 B,魔数 00 00 01 00、4 张图像),另生成 apple-touch-icon-180/192.png
    3nginx 日志分流/im-stream 的良性错误写入 D:/BtSoft/wwwlogs/im-stream.error.log(crit 级),主日志不再被淹没
    4PHP 错误日志落地php.ini 的 error_log = syslog → error_log = D:/BtSoft/php/80/logs/php_errors.log(Windows 下 syslog 等于丢弃,PHP 报错此前无处可查)

    四、验证

    检查结果
    nginx -tsyntax is ok / test is successful ✅
    /robots.txt(Host=127.0.0.1 / 192.168.0.100 / 域名入口 :65500)HTTP 200(569 B)✅
    /favicon.icoHTTP 200(12,431 B,有效 ICO,4 尺寸)✅
    /assets/images/apple-touch-icon-180.pngHTTP 200 ✅
    首页 / receipt-check.phpHTTP 200 ✅(38.5 KB / 13.8 KB)
    备份D:\BtSoft\backup\qdcms-logfix-20261010-174609(nginx 配置、php.ini 均已备份)

    五、需要用户点击生效的两项

    1. 宝塔面板 → 网站 → 设置 → 配置文件 → 保存/重载(或 软件商店 → Nginx → 重载配置) —— 让 /im-stream 日志分流生效(nginx -s reload 需管理员权限,命令行被拒 Access is denied);
    2. 宝塔 → 软件商店 → PHP 8.0 → 重启 —— 让 error_log 指向文件生效(此后 PHP 报错会写入 D:/BtSoft/php/80/logs/php_errors.log)。

    另可选(生产建议):把 display_errors 关掉,避免报错信息直接显示给访客(与上面同一次重启即可生效)。

  • v0.4.31

    修复手机脚本 ReferenceError:screenOnOk 未定义;新增脚本端到端桩测试

    随交付包发布

    用户报错:错误: ReferenceError: "screenOnOk" 未定义。

    查看完整变更

    用户报错:错误: ReferenceError: "screenOnOk" 未定义。 性质:v2.8 引入的作用域缺陷(我方 bug),已修复并补上自动测试防止复发。

    一、根因

    v2.8 我把"屏幕常亮"的变量声明写在了 main() 函数内部:

    function main() {
        var screenOnOk = false;     // ← 只属于 main 的作用域
        ...
    }
    function sendHeartbeat() {
        ... screen: screenOnOk ? 1 : 0   // ← 另一个函数里引用 → ReferenceError
    }

    而 wakeLockOk / foregroundOk / stableModeOk / notifSeen / lastHbAt 都是模块级声明, 唯独 screenOnOk 漏在了函数内 → 每次发心跳就抛 ReferenceError, 脚本启动后立刻中断(心跳发出前就报错),照旧收不到回执。

    二、修复(v2.8.1)

    • 把 var screenOnOk = false; 移到模块级(与其它状态变量并列),main() 内只做赋值;
    • 静态检查:sendHeartbeat() 引用的 6 个状态变量全部在顶层声明 ✓;
    • node --check 通过 ✓。

    三、新增:脚本端到端桩测试(qdcms-release/test-listener.js)

    用 Node + AutoX.js API 桩(http / events / device / $settings / storages / files / Packages / context) 把手机脚本完整跑一遍,无需真机即可捕获"只在手机上才暴露"的错误:

    检查项结果
    脚本启动无异常(无 ReferenceError)✅
    已开启通知监听 / 唤醒锁 / 屏幕常亮✅
    心跳报文含 ver/screen/wake/notif/gap 且带双鉴权头✅
    模拟"微信支付 收款到账 10.00 元" → 正确解析金额并上报 receipt✅
    非收款通知 → 回传通知样本✅
    非微信通知 → 忽略✅
    合计15 / 15 通过

    反向验证(把 bug 精确还原后再跑):测试立即报 [FAIL] 脚本启动无异常 → screenOnOk is not defined(5 项失败,退出码 1) —— 与用户在手机上看到的报错完全一致,证明该测试确实能拦住此类缺陷。

  • v0.4.30

    手机脚本 v2.8:内置屏幕常亮保活

    随交付包发布

    需求:"再次检测手机脚本"。检测结论:脚本功能全正常(ver=2.7、wake=1、心跳按 1.73.1 分钟稳定上报),

    查看完整变更

    需求:"再次检测手机脚本"。检测结论:脚本功能全正常(ver=2.7、wake=1、心跳按 1.7~3.1 分钟稳定上报), 唯独 fg=0 / stable=0 —— AutoX.js 的「前台服务 / 稳定模式」在该机型上无法通过脚本设置生效 (重启脚本后依然为 0)。既然 API 开关不生效,v2.8 直接内置最确定有效的兜底。

    一、本次检测(03:29:56 心跳)

    {"type":"heartbeat","device":"收款手机","ver":"2.7","notif":0,"gap":0,"wake":1,"fg":0,"stable":0}
    项目结果
    脚本版本v2.7 ✅
    唤醒锁wake=1 ✅
    前台服务 / 稳定模式fg=0 / stable=0 ⚠️(重启后仍为 0 → 脚本设置不生效)
    心跳节奏03:25→03:28(3.1 分)、03:28→03:29(1.7 分)✅(手机被使用时正常)
    回执0 条

    二、v2.8 改动

    改动说明
    内置屏幕常亮(device.keepScreenOn(),配置项 KEEP_SCREEN_ON)脚本运行期间屏幕不灭 → 进程始终处于前台活动状态,OriginOS/Android 不会清理它;配合充电器即等效于彻底解决"进程被杀"
    心跳新增 screen 字段服务端可远程确认屏幕常亮是否生效
    使用说明补充明确提示"请把收款手机插上充电器"

    为什么用它:PARTIAL_WAKE_LOCK 只能防"CPU 休眠",防不住系统杀进程; 而"屏幕常亮 + 充电"会让 App 处于前台活跃状态,是该机型上最可靠的保活方式。

    三、验证标准

    换 v2.8 后(插上充电器),自检页心跳报文应为:

    {"type":"heartbeat","device":"收款手机","ver":"2.8","notif":N,"gap":2~4,"wake":1,"fg":0/1,"stable":0/1,"screen":1}

    screen:1 且 gap 稳定在 2~4 分钟 → 保活到位;随后收款即可产生回执并自动入账。

第 4 / 10 页 · 每页 10 条 · 共 98 条

升级前请确认

  1. 备份

    备份站点目录与数据库,尤其是 uploads/ 与 config/。

  2. 阅读说明

    在 docs/版本升级说明.md 中找到对应版本,确认是否需要执行数据库迁移。

  3. 执行升级

    解压覆盖站点目录 → 执行 migration → 后台「系统 → 在线更新」复核版本状态。

  4. 复核功能

    检查前台首页、播放、支付与后台工作面板等关键入口是否正常。

相关入口

站点公告 官网试运行中,如需购买或试用请通过「联系我们」留言。