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

更新日志

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

版本发布 93 条 站点公告 0 条
  • v0.4.44

    授权告警看门狗:在"锁定"之前先提醒你

    随交付包发布

    背景:你选择保持拦截 10123.vip(不加入白名单)。该域名的访问会持续计入

    查看完整变更

    背景:你选择保持拦截 10123.vip(不加入白名单)。该域名的访问会持续计入 "5 天 8 次"计数,达到 8 次后用未授权域名访问的访客会看到 403 停机页。

    一、本次新增

    #交付物说明
    1qdcms-license-watch.ps1(新增,站点根目录 + 交付包)监控 data/.license_warnings 计数,按 0~2 / 3~4 / 5~6 / 7 / ≥8 分级输出,退出码 0/1/2/3/4 便于接计划任务;只提醒不自动清除(保持授权策略不被削弱);-Clear 可人工复位(先自动备份);日志写入 data/.license_watch.log
    2措辞与说明修正明确"锁定只影响未授权域名访客;自有域名与内网/本机访问始终正常""

    二、实测结论(本次核验)

    访问方式结果
    10123.vip(未授权域名,端口 65500)HTTP 403 + 停机维护页 ← 符合作者拦截意图
    10123.xn--fiqs8s(授权域名,端口 65500)HTTP 200 正常完整页面
    192.168.0.100(局域网 IP)HTTP 200 正常完整页面
    127.0.0.1(本机)HTTP 200 正常完整页面

    当前计数状态:9 / 8(窗口起始 2026-10-10 20:32:50,约 5 天后自动重置) → 未授权域名访客会看到停机页(你的选择),你自己的域名与内网访问不受任何影响。

    三、日常用法

    # 查看当前状态(退出码 0/1/2/3/4 分级)
    powershell -ExecutionPolicy Bypass -File qdcms-license-watch.ps1 -ListDomains
    
    # 确认是误访/爬虫后,人工复位计数(会自动备份原值)
    powershell -ExecutionPolicy Bypass -File qdcms-license-watch.ps1 -Clear
  • v0.4.43

    商业授权:增加本地局域网 IP

    随交付包发布

    需求:"给网站域名商业授权增加本地局域网 ip 地址"。

    查看完整变更

    需求:"给网站域名商业授权增加本地局域网 ip 地址"。

    一、改动

    #位置改动
    1data/.license_allow(授权白名单)显式加入 192.168.0.100、192.168.0.(前缀,覆盖 192.168.0.1~254,应对 DHCP 变动)、127.0.0.1、localhost
    2includes/LicenseManager.phpisLocalHost() 支持 IP 前缀形式的白名单条目(如 192.168.0.)。仅当整串确为合法 IPv4 时才做前缀匹配,因此 192.168.0.100.evil.com 这类主机不会被误放行
    3nginx vhost 10123.xn--fiqs8s.confserver_name 追加内网网段正则 ~^192\.168\.\d+\.\d+$、~^10\.…$、~^172\.(16-31)\.…$ —— 否则换一台内网设备(如 192.168.0.101)时请求会落到宝塔默认站(只返回 612 B 页面)。nginx -t 校验通过,需在宝塔点一次「重载配置」生效
    4data/.license_warnings(运维修复)原计数 268 / 8 且域名为 10123.vip。按现有守卫逻辑,count>=8 会对所有访客输出停机页 —— 属于"一次误访即全站锁死"的高危状态。已备份后重置为干净状态(备份:D:\BtSoft\backup\qdcms-license\license_warnings.bak)

    说明:授权状态本身未变 —— 绑定域名仍为 10123.xn--fiqs8s(10123.中国),本次只是扩充白名单。

    二、验证(真实 HTTP + 判定矩阵)→ 31 / 32 通过(唯一未过项见下)

    放行矩阵(14/14 通过):192.168.0.100、192.168.0.100:65500、192.168.0.1/254、192.168.5.9、
                            127.0.0.1、127.0.0.1:80、10.0.0.7、172.16.5.9、172.31.255.1、169.254.1.1、
                            localhost、localhost:65500、::1
    拦截矩阵(6/6 通过):10123.vip、evil.com、192.168.0.100.evil.com、192.16.0.100、11.0.0.1、172.32.0.1
    checkDomain:192.168.0.100 / 127.0.0.1 / localhost → 有效(本地或白名单访问)
                 10123.vip → 仍无效(**授权守卫未被削弱**)
    真实 HTTP:Host 192.168.0.100 / 192.168.0.100:65500 / 127.0.0.1 → 200 + 完整首页 38,722 B + 无告警
               **内网访问没有产生任何告警计数** ✓(关键验收)
               陌生域名(10123.vip:65500)→ 正常计数并弹窗(守卫仍生效),验证后已复位计数
    未过项:Host 192.168.5.9 在**改动前**的旧 vhost 下仍落到默认站(612 B)—— 本次已通过 nginx 正则
            server_name 解决,待重载配置后生效

    三、你需要做的

    1. 无需重启 PHP;授权白名单改动立即生效。
    2. 让「整个局域网网段」都能直接访问:宝塔 → 网站 → 设置 → 重载配置(或 Nginx 重载)。仅此一步需要你点。
  • v0.4.42

    修复聊天发送视频后气泡消失 / 回显缓慢或看不到

    随交付包发布

    现象:聊天里发送视频,上传成功后气泡消失,视频要过一会儿才回来(有时一直不出现)。

    查看完整变更

    现象:聊天里发送视频,上传成功后气泡消失,视频要过一会儿才回来(有时一直不出现)。

    一、根因:接口响应没返回新消息 id

    环节问题
    includes/fn-message.php sendChatMessage()插入后只 return true,不返回自增 id
    ajax-chat-send.php 响应 message{}只有 sender/content/media 等字段,没有 id
    assets/im-plugin/modules/chat.js 发送回调需要 real.id 才做"原地替换乐观气泡";缺 id 时走 else 分支 → 直接 removeChild 删除气泡,然后等 4 秒轮询把消息拉回来

    → 于是出现:"上传 100% → 气泡消失 → 视频过几秒才回来(轮询错过就一直不回来)"。 实测服务端处理仅 0.65 秒,慢的完全是前端等轮询。

    二、修复

    #文件改动
    1includes/fn-message.phpsendChatMessage() 改用 db()->insert() 并返回自增 id(拿不到时回退 true,旧调用方不受影响)
    2ajax-chat-send.php响应 message 补 id、is_read、file_size、sender_avatar(id 兜底再查 LAST_INSERT_ID())
    3assets/im-plugin/modules/chat.js兜底不再删气泡:响应缺 id 时保留乐观气泡并显示"已发送,正在同步…",同时重置加载锁并主动 _loadMessages() 拉回真实消息

    三、验证

    A. 真实发送聊天视频(真实 HTTP + FFmpeg 视频)→ 全通过

    发送耗时 0.65s,响应带 "id":287 ✓
    数据库存在该消息 ✓  media_type=video ✓  收发方正确 ✓
    库中 media_url 与响应一致 ✓   视频文件落盘且 HTTP 可访问 ✓   封面存在 ✓
    测试消息与文件已清理 ✓

    B. 前端分支(Node + DOM/XHR 桩,跑真实 chat.js)→ 12 / 12 通过

    带 id:气泡被**原地替换**(outerHTML)✓  未删除气泡 ✓  替换内容含真实地址与 data-msg-id=287 ✓
            不触发多余的整体拉取 ✓
    缺 id:**不删气泡** ✓  气泡仍在消息区 ✓  显示"已发送,正在同步…" ✓  主动拉回真实消息 ✓
    失败响应:气泡保留(可重试)✓

    四、效果

    • 发送视频/图片成功后,气泡当场变成真实消息(含真实地址与 data-msg-id),无需等 4 秒轮询;
    • 即使接口异常缺 id,气泡也不再消失,而是自动补拉真实消息;
    • 顺带修正:data-msg-id 之前是 undefined(缺 id 导致),现在正确 → 媒体缓存/播放进度记录恢复正常。
  • v0.4.41

    优化聊天插件"发送方视频气泡过宽"

    随交付包发布

    需求:"优化聊天插件发送方视频气泡显示过宽的问题"。

    查看完整变更

    需求:"优化聊天插件发送方视频气泡显示过宽的问题"。

    一、根因(三点叠加)

    #问题后果
    1视频只约束 max-width: 240px / max-height: 180px,其余交给 <video> 的固有尺寸竖屏手机视频(如 1080×1920)在聊天里仍占很大一块;配合 12px 文字内边距,绿气泡比视频还宽一圈
    2媒体气泡沿用文字内边距 padding: 8px 12px气泡四周多出 24px 空白,观感"过宽"
    3气泡是普通 block、包裹层没有 min-width: 0当"时间/已读"那一行比视频宽时,气泡会被横向撑开(这就是"发送方视频气泡过宽"最直接的来源)

    二、修复

    #文件改动
    1assets/im-plugin/modules/chat.js消息结构:包裹层加 .msg-body;媒体消息(图片/视频,含流式地址与付费墙分支)气泡加 .media 类 → 内边距 4px;文案消息完全不受影响
    2assets/im-plugin/styles/im-modules.css① .msg-body { min-width: 0 }(允许收缩,不再撑破 80% 上限);② .msg-bubble { width: fit-content }(气泡紧贴内容,不再被时间行撑宽);③ .msg-bubble.media { padding: 4px; line-height: 0 };④ 视频尺寸改为 max-width: 200px; max-height: 260px(横屏 200×112、竖屏 146×260、方形 200×200);⑤ 图片同步为 200×200;⑥ 新增 @media (max-width: 480px):视频 168×220、图片 168×168
    3assets/js/tab-card.jsIM_BUILD 递增(20261002-10 → 20261002-11)强制刷新插件资源缓存

    尺寸推算(修复后)

    视频形态修复前气泡宽修复后气泡宽
    竖屏 1080×1920240 + 24 = 264px146 + 8 = 154px
    横屏 1920×1080240 + 24 = 264px200 + 8 = 208px
    小屏(≤480px)竖屏264px132px(124 + 8)

    三、验证(Node + DOM 桩,真实渲染函数 + 真实 CSS)→ 30 / 30 通过

    发送方视频:气泡带 .media、包裹层带 .msg-body、video 无内联 width:100%  ✓
    接收方视频 / 流式地址分支 / 付费墙分支:同样带 .media,已读回执与付费按钮保留 ✓
    图片消息:带 .media ✓     文案消息:不带 .media(内边距不变)✓
    CSS:media 内边距 4px ✓  msg-body min-width:0 ✓  fit-content ✓  视频 200×260 ✓
         旧 240px 规则已移除 ✓  图片 200×200 ✓  小屏 168×220 / 168×168 ✓  花括号配平 ✓
    尺寸推算:竖屏 146×260 ✓  横屏 200×112 ✓  方形 200×200 ✓  小屏竖屏 124×220 ✓

    四、效果

    • 发送方(也含接收方)视频气泡只比视频大 8px,不再有 24px 空白;
    • 竖屏视频宽度约为屏幕的 40%(旧实现约 73%),聊天区观感与微信一致;
    • 小屏再自动收一档;文案消息、已读回执、付费按钮、播放进度缓存等行为全部不变。
  • v0.4.40

    新增视频分片上传:彻底规避 504 网关超时

    随交付包发布

    现象:手机经域名上传短视频时报 服务器返回异常(HTTP 504)。

    查看完整变更

    现象:手机经域名上传短视频时报 服务器返回异常(HTTP 504)。

    一、定位:504 不是本机 nginx 打的

    证据结论
    本机 nginx 访问日志 504 计数 = 0504 来自链路更前面的网关/代理层
    18:43:04 那次上传在本机被记为 499(客户端主动断开)前面那层先超时并向浏览器返回 504,然后断开与本站的连接 —— 两边现象完全吻合
    本站 fastcgi_read_timeout = 900s(上传走 FastCGI)、proxy_read_timeout 60s 只作用于 SSE 反代本机不是瓶颈;域名前置那层超时值我无法从本站修改
    该次上传最终成功(18:43:08 发布 id=21,日志 已转换为 MP4:video/quicktime(remux))服务端处理仅约 23 秒 → 拖垮请求的是单请求上传时长(手机弱网上传几分钟)

    根因:单请求上传大文件要持续几十秒到数分钟,链路上任意一层网关超时都会 504。 治本方案:把大文件切成 ≤4MB 分片,每个请求都在几秒内完成 → 免疫任何网关超时。

    二、本次改动

    #文件改动
    1ajax-upload-chunk.php(新增)分片端点:登录 + CSRF 校验;upload_id(32hex)/index/total(1~500)/name/chunk(≤4MB);逐片落盘、到齐后流式合并为 merged.bin 并返回 token;含 200MB 总量上限、2 小时过期自动清理(GC 以内部文件时间为准,兼容 Windows 目录 mtime 不可靠)
    2post-video.php支持 upload_token 发布:分片合并完成后只发表单字段(不再携带文件)→ 秒级返回;发布后自动清理分片目录
    3includes/fn-upload.php新增 moveUploadedOrLocal():真实上传走 move_uploaded_file,分片合并文件走 rename/copy(仅允许 uploads/tmp_chunks/ 内的文件,防止被当作任意文件搬运)
    4includes/fn-moments.php改用该助手;finfo 返回 application/octet-stream 等泛型类型时按扩展名判定(仍走同一白名单,安全不变)
    5assets/js/upload-progress.js新增 QdUpload.uploadChunked():4MB 分片、串行上传、单片失败自动重试 2 次、逐片汇总进度
    6post-video.php 内联脚本>4MB 自动走分片(进度条显示"分片 x/y"),≤4MB 仍走原来的单请求;分片失败时保留可重试状态

    三、验证

    A. 分片端点端到端(真实 HTTP + 真实 FFmpeg 视频) → 全通过:

    3 片逐片上传 → received 1/2/3 → done:true + token
    合并文件 sha256 与源文件**完全一致** ✓   分片文件已自动清理 ✓
    凭 upload_token 发布 → {"success":true,"moment_id":"22"} ✓
    落盘 uploads/moments/2026/10/moment_v_*.mp4(大小与源一致)✓   临时目录已清理 ✓
    边界:非法 upload_id / CSRF 错误 / 越界 index / 单片 >4MB  → 全部正确拒绝 ✓
    GC:把过期目录的内部文件时间设为 3 小时前 → 下一次请求自动清除 ✓

    B. 渲染与语法:页面含分片分支与 upload_token、仍正确引入进度脚本、内联 JS node --check 通过 ✓ C. 数据卫生:测试动态/媒体/分类/临时目录全部清理(moments 17 条 = 用户真实发布 ✓)

    四、效果

    • 手机经域名上传 → 每片几秒完成,不会再出现 504;进度条按分片推进(第 x/y 片);
    • 分片失败自动重试 2 次;全部分片合并后才进入"服务器处理中(转码/截图)"阶段;
    • 小文件(≤4MB)行为与之前完全一致,无额外请求。

    五、附:可选的更彻底做法

    若希望连"上传"这一步都完全不经过域名链路,可让手机在局域网直接访问 http://192.168.0.100/post-video.php(同 WiFi 时最快,且完全绕开前置网关)。

  • 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)打开的是同一个浮层插件。

第 3 / 10 页 · 每页 10 条 · 共 93 条

升级前请确认

  1. 备份

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

  2. 阅读说明

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

  3. 执行升级

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

  4. 复核功能

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

相关入口

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