这篇接在《给 MacCMS 站点做「前台访客一键换肤」》之后。上一回是让站点能「换」模板,这一回是真正从零「写」一套模板——并把模板上线之后连着踩到的三类硬故障一并解决:播放器窗口矮到只有 156px、默认线路排序不符合预期、以及最要命的「视频明明在播、屏幕却一直转圈」。全文按时间顺序还原,每个坑都给出可直接复用的判定方法与修法。
〇、先给结论:这几个数字
站点是一套 MacCMS v10 影视门户,跑在一台新加坡节点的服务器上,前端 nginx + PHP 8.1,模板从海螺(conch)起步。自写模板这条线从 9 月 23 日中午开始,到 9 月 24 日中午收尾,约一天时间里完成了「从零写模板 → 站点默认模板切换 → 视觉重塑 → 播放链路连续排障」的完整闭环。
一、缘起:先做事实核查,再决定「不搬运」
需求起点很直接:给了一个演示站,要求「复刻这个主题」。
这一步我没有直接开工,而是先做了一次事实核查——结果改变了整个方案:
- 演示站跑的是
/template/hl093/,即海螺模板的 2026 新版。 - 该模板的官方站点是会员制,而其公开模板库最新只到 HLMB-073,没有 093。
- 本地归档同样止步于 hl073——此前批量下载的 36 个可下载模板里,最新的就是这个版本。
也就是说,hl093 并不存在公开获取途径。我最初口头断言它「在售」,属于推断而非实证,这里必须更正:后来的结论是「没有可下载的官方包」。于是方案改为——按演示站的设计语言,自写一套原创模板。

二、模板从零搭建:标签体系与 5 个隐形坑
产出是一套名为 momo2026 的暗色影视门户模板,共 262 个文件,装进站点模板目录后由换肤器自动收录。
页面体系:Hero 大图轮播(5 张 + 缩略图 + 进度点)→ 追剧日历条(7 天,今天高亮)→ 3D 封面流热播推荐 → 分区网格 → 页脚;另有分类列表(筛选 / 排序 / 分页)、详情(线路切换 + 选集)、播放、搜索、周表、榜单、专题、留言。
首轮验证:home 72 卡 / week 36 / hot 54 / new 48 / search 36,全部 HTTP 200,无 System Error,页面无残留标签。
写模板的难点不在 HTML,而在 MacCMS 的标签编译规则——它是「先编译成 PHP,再执行」,所以很多写法在源码里看着对,编译完就变了。记录在案的 5 个坑:
| 坑 | 现象 | 正解 |
|---|---|---|
| 标签属性不解析运行时变量 ★ | 写 type="$sec.type_id" 被编译成字面量字符串,查询条件失效 |
先拼成实际值再进标签:type="'.$sec['type_id'].'" |
| 注释语法 | ThinkPHP 只认 {/* */},写成 {* *} 会被当正文原样输出 |
批量改正 23 个文件 |
level 过滤 |
首页轮播写 level="1..9",一条都不出 |
全站 vod_level 都是 0,去掉该条件即可 |
$__LIST__ 时序 |
在标签执行前读它判空,永远是 0 | 判空放到标签之后,改读 $__PAGING__.record_total |
搜索页缺 pageurl |
搜索永远 0 条 | 必须写 pageurl="vod/search";关键词在 $param.wd |
另有一个语法级陷阱:{:函数($x|过滤器)} 是非法写法,编译直接产出 syntax error。需要兜底取值时用三元表达式替代:
判定「标签到底编译成了什么」有一个极好用的办法——直接去看编译产物:
三、站点开启 + 访客门禁,两件事要能共存
站点上线要「正式开启」,同时保留访客门禁。看似简单,实际踩了一个结构性的坑。
原实现把密码校验塞在维护模式分支里(site_status==0 的 check_site_status())。问题在于——站点一开启,这个分支就永远不走了,门禁随之失效。
修法是让门禁独立于维护模式:新增 check_site_gate(),挂在控制器构造函数里、label_user() 之后、check_force_login() 之前;并在 site_status==0 时直接 return,与维护分支互斥,避免双重门禁。
| 放行条件 | 说明 |
|---|---|
| 已登录会员 | 正常放行 |
session('site_pwd_verified') |
输对通行密码后打上的标记 |
user@login|oauth|logincallback |
登录页自身必须可达,否则死循环 |
非 index 入口(如 api.php) |
给采集/对接留通道 |
未通过则输出统一提示页。这里有一个容易被忽略但很关键的点——缓存安全:页面缓存在 label_fetch()(action 阶段)读写,而门禁在构造函数里就终止了请求,匿名访客根本碰不到缓存副本,所以不需要额外做防穿透。
验证:匿名访问首页、分类页、详情页,均返回「访问验证」标题;错密码返回 code=0;正确密码返回 code=1;登录页 200;接口入口放行。
四、首页「追剧日历」全是空壳:id 与 include 变量错位
反馈是:首页追剧日历只显示「周几 + 即将更新」的框架,影片卡全是空壳(有格子、没内容);热播推荐 3D 流也不自动切换。
先说结论——查询本身完全正常,问题在模板变量名对不上。
主因:html/index/week.html 里标签写的是 id="wv",但它 include 的子模板取的是 $vo.xxx —— 变量根本不存在,于是循环照跑、卡片照出,只是每个卡片的链接、名字、图片全空。同一个 copy-paste 错误在另外 3 处也存在(详情页与播放页的相关推荐、榜单页 TOP6),共 4 个文件。
修复是统一的:把 id 改回 id="vo" key="vk"。
至于「轮播不切换」——JS 逻辑本身没问题(无头浏览器实测 4.2s 自动轮转正常)。真实原因是浏览器缓存了旧版 app.js(当天改过文件,但引用的版本号没变)。顺手还修了一个真 bug:圆点容器在轮播包裹层之外,而查询用了限定作用域的写法,导致圆点高亮永远不亮——改成全局查询即可,并顺手把版本号推进一位强制刷新。
五、用户中心整备:42 个 404 与一条断掉的深色链路
反馈是「用户中心界面比较乱」。排查下来是三层问题叠加,逐层拆:
第一层:资源全缺。用户中心目录当初是从官方默认模板整目录拷来补齐的,但只带了 HTML、没带配套资源——页面引用的 42 个 css / js / 图片全部 404,布局样式彻底失效,这就是「乱」的直接来源。修法是按文件粒度建软链,把默认模板的样式资源目录链过来,共 533 个链接,且只补缺失、不覆盖模板自带的样式。404 从 42 降到 1(残留那一个,官方默认模板自己也缺)。
第二层:深色链路断。默认深色是靠 body 上的一个类名驱动的,但在这个模板下,三段链路全没接上:页面头部的主题判定、全局模板颜色配置、以及主题小部件里后执行的默认模式设置——最后执行的赢,于是深色被覆盖。修法是在两处写死默认深色,不动全站共用的配置(那个配置被所有模板共用,改它会连带影响线上正在跑的主题)。
第三层:运行时 body class 被清空。这是「class 明明写了却不生效」的真凶。页面内联脚本先把 body 的类清空,随后另一个脚本又补了一个语言类,结果布局类和主题类全丢。这个用打调用栈的方式才定位到——挂上 classList / setAttribute 的钩子看是谁改的。另外默认模板的样式里还有一处硬编码浅色背景且没有深色变体,在用户中心注入覆盖规则解决。
验收用的是「对比度巡检」——把渲染后文字色与背景色的对比度低于 3 的位置全部找出来(低于 3 基本等于不可读):
| 页面 | 修复前 | 修复后 |
|---|---|---|
| 用户中心 / 登录 / 注册 / 找回密码 | 18 / 2 / 1 / 0 处低对比度,整片白底 | 0 处(深色生效,深底 rgb(22,21,27)) |
| 充值页 | 35 处 | 2 处(绿底白字按钮,属设计本身) |
| 播放记录 | 35 处 | 2 处 |
| 静态资源 404 | 42 个 | 0(用户中心)/ 1(模板自身缺失) |

六、全维度视觉美化:从「能用」到「赏心悦目」
功能齐了之后做了一轮整体视觉重塑。改动集中在四件事:
- 设计令牌与氛围底色:底色重置为深邃通透的深黛夜空,叠加三层弥散极光雾光与磨砂玻璃质感。
- 文本对比度:把原本看不清的弱化灰字提亮到 Slate-400 一档,主字提亮到接近纯白,解决暗色下久看疲劳。
- 卡片质感:全站卡片与封面统一圆角,边框加一道超细微光线,悬浮轻微抬升并配弥散柔光投影;播放遮罩升级为渐变脉冲圆钮。
- 播放页沉浸光影:为播放器容器注入外溢的环境光,选集胶囊升级为圆角流光高亮。
这一轮里最有价值的是一个移动端重大缺陷的修复:手机端(390px 视口)详情页与播放页横向溢出到 583px,页面能左右拖动。根因是网格项默认的 min-width: auto —— 内容撑破了容器。重置为自适应两列后,scrollWidth 严格等于 390px,零溢出。

七、播放器窗口太小了:先读行业标杆代码,再动手
反馈很直接:「视频播放器的窗口太小了吧,看看最新最热的播放器代码」。
先量了一下——实测播放窗口高度只有 156px,在一台 1440×900 的屏幕上几乎是一条缝。定位到根因:此前那轮视觉美化的样式替换用的是非贪婪正则,匹配区间从播放器容器一路吃到控制栏,把中间定义 16:9 比例和绝对填充的两条规则一起删掉了——容器失去比例约束,高度就塌回到默认行内高度。
接着去读了生态里几套主流模板的播放器实现,对比之下就很容易判断「现代播放器该长什么样」:
| 模板 | 比例实现 | 交互特性 |
|---|---|---|
| 海螺(生态里最流行) | Bootstrap 式 embed-responsive-16by9,用 padding-bottom:56.25% 撑高,并由 JS 按 PC/移动端分别注入配置值 |
9/12 宽度分栏 + 报错 / 刷新 / 上一集 / 下一集快捷条 |
| 奈飞(颜值代表) | 同样是 embed-responsive-16by9 |
独立全屏切换按钮 + 右侧浮动推荐 / 二维码面板 |
| 官方默认 | 传统固定纵横比响应式垫片 | 基础控制条 |
共性很清楚:都必须有明确的 16:9 比例约束。所以我这里没有照抄 Bootstrap 垫片方案,而是用现代的 aspect-ratio,并加上一层「视口双保险」——下限保证大屏沉浸感,上限保证不超出视口产生纵向滚动:
效果:PC 端播放窗口从 156px 变成 750px(正好吃满「900 − 150」的上限),宽度 1374px。在此基础上补了三个现代播放器该有的能力:
- 剧场模式:一键把播放器摊成 100vw 巨幕(实测 1440×780),并把这个偏好记到本地存储,翻页后保持。
- 关灯模式:铺一层 94% 的暗场遮罩,播放器提权到最上层并加一圈聚焦光晕,做出电影院的沉浸感;再点遮罩或按钮即柔和退灯。
- 播放器单点刷新:第三方解析线路卡顿时,只重载内层 iframe,不刷新整个页面、不丢当前选集。



移动端则单独保底:强制重置视口上限,保持自适应比例,横向滚动严格为 0。
八、播放线路默认排序:让 m3u8 排在前
需求是「播放器的顺序默认 m3u8 在前」。这件事看起来只是改个排序值,实际有个陷阱。
先看机制。播放线路列表由 mac_play_list() 生成,它只收录状态为启用的线路;当排序开关打开时,会按播放器配置里的排序值倒序重排。
站内数据有个很规整的规律——几乎都是「普通播放器 + 同名 m3u8」成对出现,例如 liangzi$$$lzm3u8、feifan$$$ffm3u8、dytt$$$dyttm3u8。而原先每一对里,非 m3u8 的排序值反而更高,所以默认落在普通播放器上。
第一层改动很直白:把排序值重排,让所有 m3u8 线路整体优先(顺带修掉一个排版里混进来的异常小值)。
但只改排序是不够的——这是我事先没预料到的地方。因为这条线路列表只在详情页生成,列表页的数据里根本没有这个字段,模板里取到的线路号是空的,于是全站大量入口(首页幻灯片、热门区、列表页的播放按钮、海报点击、旧书签、订阅)都硬编码回落到第 1 条线路。结果就是:切换线路的标签页上 m3u8 排第一,但点「立即播放」进的却是另一条线路。
所以第二层改动才是关键:在 mac_play_list() 排序之后,把线路号重新编号为 1..n,让「优先级最高的线路」恒等于 1 号。这样全站所有指向 1 号的入口一次性对齐,不用去逐个改模板。同时加了「空线路沉底」——没有剧集内容的线路排到最后,避免默认落到一条空线路上。
验证覆盖了站内 5 种不同的线路组合,结果全部是 m3u8 排在首位,「立即播放」与所有指向 1 号的入口均落在 m3u8 线路上。
九、视频「一直转圈」:一次三层修复(最硬的一仗)
这是整段里最难的一个,因为第一直觉是错的。
反馈是「视频播放不了一直转圈」。按常规思路应该去查播放器、查线路、查地址。但我先做了一件不太一样的事——量化验证「视频到底有没有在播」:
| 观测项 | 实测值 | 含义 |
|---|---|---|
video.readyState |
4(HAVE_ENOUGH_DATA) | 数据充足,播放器已就绪 |
| 视频时长 | 2776 秒 | 清单已解析,时长正常 |
currentTime 推进 |
3.47 → 8.66 → 16.76 秒 | 视频其实一直在正常播放 |
也就是说——播放没有失败,是有一层东西把画面盖住了。于是换个问法:屏幕上那个位置,最上层到底是谁?用 document.elementsFromPoint() 取屏幕中心的层叠链,答案立刻就出来了:

根因链是这样的:
- CMS 原生播放器脚本会在播放器之上再叠两个 iframe(
#buffer与#install),其中#buffer指向一个第三方加载页,就是那张「加载中」转圈图。 - 本站用的是自定义播放器壳(按地址形态选壳:直链走播放器页、网页直接内嵌),壳自己设置内容后走的是自定义流程,原生那两个遮罩不会被自动摘除。
- 自定义播放器页本来是靠
postMessage向父页上报「就绪 / 失败」的,而父页从来没有监听这个消息——整条链是断的。 - 为什么现在才暴露:原先默认线路是资源站的分享页(普通内嵌),这次按需求改成 m3u8 优先、走自定义播放器壳,才把这个历史缺陷翻了出来。这两件事是同一条时间线上的因果。
修复分三层落地:
| 层级 | 改动 |
|---|---|
| 配置层 | 把「加载页 / 缓冲页」两个地址从第三方域名改成同源的本地加载页 |
| 缓存层 | 同步更新前端那份播放器配置缓存,否则旧第三方地址继续生效 |
| 页面层 | 播放页注入「遮罩治理脚本」:立即并持续压制两层遮罩、监听播放器上报(就绪即撤遮罩 / 失败则提示并自动切换下一条线路)、并用观察器常驻自愈 |
页面层这段脚本是整场排查的技术核心,值得完整贴出来:
getComputedStyle() 读计算样式,不能用元素的内联样式值。因为第三方脚本会把内联的 display:none 重写并丢掉 !important,而 CSS 里另有更高优先级的规则在生效——于是出现「内联读出来是 none、实际计算出来还是 block」的诡异状态,代码误判为「已隐藏」就不再重写。改用计算样式判断之后,逻辑同时变得幂等,顺带解决了另一个坑:观察器被自己的改动反复触发,形成无限循环。中途出现过一次「加固版反而全量失效」,就是这个原因。
回归验证 7/7 全通过(5 部影片 × 2 条线路):两层遮罩的计算样式均为 none、屏幕中心最上层是真实播放器、影片均处于播放中;并且原有那条分享页线路没有回归。同时覆盖了 iPhone Safari、Android Chrome 与微信内置浏览器三种移动端 UA。
十、复盘:可复用的方法论与坑清单
把这一天的经验压缩成几条可直接套用的规则:
- 先核查可获取性,再决定方案。「照这个做」的第一件事是确认目标物能不能拿到、拿了合不合规。
- 判断元素真实状态,读计算样式;读内联值会被第三方脚本骗。这是本次最贵的一课。
- 排查前台问题前,先确认「生效模板到底是哪个」。站点配置里可能还挂着别的模板,改了半天改在不生效的那套上。
- 只改显示顺序往往不够,要顺着「默认值从哪来」一路查到入口。线路排序就是这样:改了标签顺序,全站入口还在用硬编码的 1 号。
- 「内容全空但循环正常」是模板最阴的 bug——卡片数、布局都没错,只有内容是空的,必须专门比对变量名。
- 每次 CMS / 主题升级之后,都要重跑一次播放层修复。升级会静默还原自定义播放器壳,表现为「突然又不能播了」,而报错日志里什么都没有。
坑清单汇总:
| # | 坑 | 判定 / 修法 |
|---|---|---|
| 1 | 标签属性不解析运行时变量 | 看编译缓存确认条件;先拼值再进标签 |
| 2 | 注释语法只认一种写法 | 页面出现原样输出的注释字样即中招 |
| 3 | 等级过滤条件与数据不符 | 先查库里该字段的实际分布,再决定要不要过滤 |
| 4 | 判空读到的是标签执行前的值 | 判空放到标签之后,读分页对象里的总数 |
| 5 | 搜索页缺分页地址参数 | 搜索恒为 0 条时优先查这里 |
| 6 | 标签与子模板变量名错位 | 卡片全空但数量正常——比对 include 入参 |
| 7 | 运行时 body 类被脚本清空 | 钩住类名操作打调用栈 |
| 8 | 宽高比规则被样式替换误删 | 容器高度塌成一条缝时,先找比例约束还在不在 |
| 9 | 网格项默认最小宽度撑破容器 | 移动端能左右拖 = 查 scrollWidth |
| 10 | 「在播但被遮罩盖住」被误判为「播放失败」 | 先量进度有没有推进,再查屏幕中心最上层是谁 |
| 11 | 用内联样式判断隐藏状态 | 改读计算样式,同时获得幂等性 |
| 12 | 升级静默还原自定义播放层 | 把修复脚本化、幂等化,升级后固定重跑 |
附:这次动到的文件与回滚点
所有生产改动一律「先备份、再覆盖、后验证」,备份文件名带改动语义与时间戳,出问题可以按语义精确定位回滚:
| 改动 | 涉及文件 | 备份后缀 |
|---|---|---|
| 自写模板 | 模板目录下 262 个文件(新增,无覆盖) | — |
| 门禁独立化 | 控制器基类、站点配置 | .bak-gateopen-* |
| 变量错位修复 | 首页周表、详情、播放、榜单 4 个模板 | 同目录备份 |
| 用户中心整备 | 用户中心 28 个页面、主题判定与颜色配置 | .bak-dark*-* |
| 视觉美化 | 模板样式表 | .bak-beautify-* |
| 播放器窗口修复 | 模板样式表、播放页 | .bak-player-* |
| 线路排序 | 公共函数库、播放器配置 | .bak-sidrenum-* / .bak-sort-* |
| 转圈故障修复 | 站点配置、前端播放器配置缓存、播放页 | .bak-overlay-* |
说明:文中所有服务器地址、访问口令、数据库凭据均已隐去或不含具体值;涉及线上数据的数字均为实测值。
2026-09-24 增补:AI 搜索前端(仿 kanju.ai)与 L 站登录修复
本日围绕「前端 AI 的使用」对搜索链路做了整备,并顺带修复 L 站 OAuth 自动注册的两个阻断性缺陷。所有改动依旧遵循「先备份、再覆盖、后验证」。
1. 搜索结果页 AI 速答条(仿 kanju.ai 设计语言)
- 搜索结果页新增 AI 速答条:状态药丸(打开中/已完成/失败)→ 概要行(AI 找到 N 部相关影片)→ AI 文字解读(编号列表可读化排版)→ 横排海报卡(左海报右信息,绿色「查看」按钮)→ 底部「结果不满意?」操作区(站内搜索定位 + 去 AI 对话追问)。
- 零搜索结果时自动触发一次速答:站内搜不到的片名,AI 会扩展检索词并从片库捞出相关影片。
- 后端错误翻译为友好降级文案(未登录/需验证/额度用尽/熔断维护),任何失败都不影响原搜索功能。
2. 「问AI」开关三端打通
- 搜索中心、搜索结果页、站点头部三处共用同一份 localStorage 开关(
mac_search_hub_ask_ai),任意一处切换处处同步。 - 开启后搜索/回车直达 AI 对话页并自动提问;关闭走普通搜索。
- 修复搜索中心 AI 提示行挤压定高面板导致「问AI/搜索」按钮行被裁掉的问题(提示行移到搜索栏挂载,状态挂 body 类)。
3. 头部搜索框集成 ✦ 开关
- 独立的「问AI」文字胶囊移除,✦ 开关收进搜索框内部(放大镜左侧),节省头部空间;独立入口在移动端保留为 30px 纯图标兜底(移动端搜索框本就隐藏)。
- 顺带修复
app.js的 searchSync 回车处理会覆盖 AI 跳转的问题(两边逻辑统一为 AI 感知)。
4. 搜索中心桌面端升级
- 修复热榜海报全量破图:懒加载链在本页失效(data-original 有值、src 为空),监听列表渲染直接补真实封面,加载失败给暗色占位。
- 桌面端容器 696px → 880px,热榜改双列卡片、海报 52×74 → 76×106,深色主题标题提亮。
- 补上默认模板缺口:
bstem深色模式下主区背景只在 ≥821px 媒体查询覆盖,移动端出现白底浅字(文字隐形)。
5. L 站 OAuth 自动注册修复(三个叠加缺陷)
- 同 IP 每日注册限额误伤:后台
reg_num=1对第三方注册同样生效,共享代理出口 IP 的第二个新用户当天必然失败 → 第三方 OAuth 身份已由 L 站平台验证,予以豁免。 - 账号名不足 6 位:openid 为短数字串时派生用户名不过 min:6 校验(报错「名称最少不能低于6个字符」)→ 优先用 L 站用户名(仅留字母数字)生成,不足 6 位回退 openid,再不足补随机数字。
- 撞名:派生名与已有账号冲突时自动加随机后缀重试一次。
- 注册失败时错误信息透出真实原因,不再一律显示「请联系管理员」。
- 实测:普通注册仍被 reg_open=0 正确拦截;两个同 IP 的模拟 L 站注册连续成功(修复前第二个必挂)。
6. 用户中心管理后台入口
- 个人中心侧栏(PC + 移动端双导航)新增「管理后台」绿色盾牌入口,指向后台入口文件。
- 仅
mac_admin表中 admin_status=1 的账号可见(普通会员实测 0 处渲染);后台自身仍有独立登录校验,隐藏入口只是体验层。
| 改动范围 | 备份后缀 |
|---|---|
| 搜索结果页 / 搜索中心模板、AI 速答条全套 | .bak-aiopt-* |
| 头部搜索框 AI 集成(head.html / ai-entry.css / app.js) | .bak-aiint-* |
| L 站 OAuth 注册(控制器 + 用户模型) | .bak-oauth-* / .bak-oauth2-* |
| 用户中心管理后台入口(left_nav) | .bak-admin-* |
说明:AI 后端沿用站内 ajax/ai_chat(new-api 网关,deepseek-flash),本日改动全部为前端叠加层与少量控制器/模型修复,未动核心框架。
2026-09-25 增补:后台菜单瘦身 + 暗色极光主题
- 后台菜单瘦身:按数据库实况(相关表 0 行)移除从未使用的模块入口——整组扔掉文章(含漫画)、网址导航、静态生成;子项扔掉专题、友链、评论、聊天室、弹幕、演员、角色、充值卡、金币商城、提现、优惠券、秒杀、AI 注解、Meilisearch、域名绑定、模板市场、URL 推送。菜单分组 15→11,可见功能项 98→74。控制器文件保留未删,随时可从备份恢复。
- 后台主题:曾短暂切换为暗色极光风,应用站长偏好已恢复默认绿色风格(覆盖层 CSS 保留在服务器备用,未链接)。
2026-09-25 增补(二):功能集成日——AI 搜索落地、友链体系、大屏剧照与 Hermes 自动化
- L 站注册修复(第二段):错误透出后定位到「账号名不足 6 位」——L 站 openid 为短数字串时派生用户名过不了 min:6 校验。修复:账号名优先取 L 站用户名(仅留字母数字),不足 6 位回退 openid,再不足自动补随机数字;配合此前的撞名重试与额度豁免,L 站新账号注册链路完整打通。
- 头部搜索框集成 ✦ 开关:独立的「问AI」文字胶囊移除,✦ 开关收进搜索框内部(放大镜左侧),开启后回车直达 AI 对话;移动端保留 30px 图标入口兜底。三处开关(头部/搜索中心/结果页)共用同一状态。顺带修复
app.jssearchSync 回车处理覆盖 AI 跳转的问题。 - 用户中心管理后台入口:个人中心侧栏(PC+移动)新增「管理后台」绿色盾牌入口,仅
mac_admin表 status=1 的账号可见(后台自身另有独立登录校验)。 - 友链体系完整化:① 回加后台「友情链接管理」菜单;② 修复一个影响面更大的缺陷——后台基类统一声明 view_new 视图路径。此前 Link/System 等未声明控制器的页面全部渲染空白(旧 view 目录几乎只剩 4 个模板,TplConfig 的主题设置页也是同因空白);③ 博客「momo的存货」与 L站(linux.do) 加入友链;④ 前端 UI 胶囊化:圆角 chip + 悬停青色发光上浮 + 首字母渐变头像(m 青/L 金交替),支持友链 logo 字段优先显示图片。
- 大屏海报高清化:首页轮播原直接用竖版封面硬裁,观感差。搭建豆瓣剧照管线——条目匹配(标题+年份双校验) → 移动端剧照接口取 1600px 级横版物料 → 下载到本地
upload/vod/slide/→ 写入影片「幻灯图」字段(轮播模板本就优先读取)。当前 5 部轮播片全部换装(1620×1080 级,一瓯春 3375×1080 超宽)。爱奇艺/腾讯搜索页为 JS 壳+接口签名,服务器端直抓不可靠,故选豆瓣官方物料(即各平台分发用的同源图)。 - Hermes 自动化:管线封装为 Hermes 技能
momo-hero-slides(动态识别首页轮播片,无需维护片单;幂等跳过已有剧照;支持 –name/–force)。注册每日 04:30 定时任务(增量采集之后),抓到新图推送 Telegram,无新图静默。 - 热榜轮播间隔可配置:后台「momo2026 主题设置」新增「轮播间隔」字段(hot_delay,默认 2000ms,0=只手动切换,悬停暂停),封面流自动播放从写死 4200ms 改为配置下发。
| 改动范围 | 备份后缀 |
|---|---|
| 头部搜索框 AI 集成(head.html/ai-entry.css/app.js) | .bak-aiint-* |
| L 站注册账号名派生(控制器) | .bak-oauth2-* |
| 用户中心管理后台入口(left_nav) | .bak-admin-* |
| 友链管理菜单回加 / 快捷菜单(auth.php/quickmenu.php) | .bak-trim-* / .bak-quickmenu-* |
| 后台视图路径统一(Base.php) | .bak-viewpath-* |
| 热榜轮播间隔(app.js/hot.html/TplConfig/momo.html) | .bak-hotdelay-* |
说明:大屏剧照管线已封装为 Hermes 技能 momo-hero-slides(每日 04:30 自动运行),轮播片单变化后无需人工补图。
2026-09-25 增补(三):分类页筛选全面修复与补全
- 根因:分类页的筛选从来没真正生效过——MacCMS 的
mac_url在生成 vod/type 链接时只保留 id 和 page 两个参数,其余筛选参数(年份/排序等)全部丢弃,点击筛选按钮后 URL 里无参数、列表永不过滤。这是核心 URL 生成层的行为,模板正常调用无法绕过。 - 修复:在分类页模板内置筛选 URL 构造器——以干净的基础类型 URL 为底、手工拼接筛选查询串(
?year=2026&area=大陆&lang=国语&by=hits_month)。列表查询(paging="yes"+mac_param_url)原生支持这些参数,断点只在 URL 生成一环,故无需改核心代码。 - 维度补全:筛选从 2 维扩到 4 维——分类、年份、地区(新增)、语言(新增)。地区/语言选项不是写死清单,而是按当前顶级分类的实际数据聚合(出现次数降序),有内容的才出现。
- 联动互持:各维度切换时保留其余已选条件——选「大陆」再选「2026」,地区条件保留。
- 实测:电影片页 7204 部 → 地区=大陆 1434 部 → 加年份=2026 剩 32 部,URL 参数正确、选中态高亮。
备注:搜索结果页目前未加筛选区,如需要可复用同一套构造器。
2026-09-26 增补(四):首页轮播全是老片——采集刷新与推荐级治理
- 现象:首页 Hero 轮播清一色 2009–2021 的老片(官能的法则 2014 / 处处有贼 2012 / 澳门风云 2014…),而站点明明每天都有新片入库。
- 排查:模板 → 标签 → 配置 → 数据库逐层下钻,最后用「短暂切维护模式换会话、真实渲染首页」的方式拿到实测结果。轮播取片规则是
hero_by=time(vod_time 最后更新时间)倒序取前 5,而这些片的 vod_time 恰好全是当天凌晨 01:35——一批刚被采集任务「碰」过的老片。 - 根因:vod_time 在每次采集命中时都会刷新。7 个资源站的定时任务每小时拉「最近 24 小时更新」,资源站会持续把库内老片重推进更新流,于是「最后被采集器碰过的片」永远是轮播候选,与影片真实年份彻底脱钩。顺带证实:全站 hits 系列全是采集时随机生成的 1–1000 假数据,换「热度」排序同样救不了轮播。
- 修复:轮播两个 vod 标签加双重过滤——
level="9"(推荐级·幻灯,人工可控) +year="2024,2025,2026"(年份兜底)。MacCMS 的 Vod 模型原生支持这两个参数(vod_level IN / vod_year IN),零核心改动。 - 一个反转:正文第二节记过「轮播写 level 一条都不出,去掉即可」——本质是当时全库 vod_level 全 0、没有数据。这次反过来操作:先批量给 15 部 2026 新片打上推荐 9(vod_level=9),再启用 level 过滤,同一个参数从「弃用」变成「治理入口」。另有一个细节:level 过滤一生效,可见性检查标签也查不到数据,轮播区块会整个隐藏而非渲染空盒——这反而是想要的优雅降级。
- 实测:渲染结果 5 张幻灯全部变为 2026-09 新片(甲武神 / 未尽之言 / 反恐特警组:放逐者 / 分道扬镳 / 我家那闺女2026),老片清零。运营语义从此清晰:后台把影片推荐级别设为「9-幻灯」即上轮播,改回 0 下架。
备注:追剧日历里的老剧属正常语义(它本就是「今天有什么在播」的日程表);热榜(hot_by=hits_week)还在吃随机假热度,后续可用同一套「推荐级+年份」过滤治理。回滚点:slide.html.bak-level9-20260926。
2026-09-26 增补(五):轮播图很模糊——高清剧照管线从静默故障到 TMDB 双源兜底
- 现象:增补(四)换上来的新片单,轮播 5 张里 4 张很模糊。原因:这些片的
vod_pic_slide(幻灯图)字段是空的,模板回退用采集来的竖版小海报(约 600px 宽)全屏拉伸,自然糊成一片。 - 既有管线找到时,它已经静默坏了:服务器上本来就有一套「高清横版剧照自动抓取」——root 侧 Hermes 技能 momo-hero-slides,每日 04:30 运行、结果投递 Telegram。查执行记录:当天 04:30 确实触发了,
last_status: error, Script exited with code 1。根因是它的第一步设计为「匿名抓首页 HTML、解析当前轮播片名」,而站点凌晨刚开启强制登录,匿名首页只剩 302 跳转——脚本抓不到内容直接退出。更隐蔽的是包装脚本采用静默模式,只在输出含 ✓/✗ 时才投递,这条不含两者的报错被完全吞掉,Telegram 无感知。教训:依赖前台页面状态的定时任务,会随着站点门禁策略变化而集体静默失效。 - 脚本改造:选片不再抓页面,直接查库——
level/year过滤条件用正则从slide.html里提取,数量与排序读mctheme_momo.php的 hero_* 配置,与模板永久同源,对登录态彻底免疫;豆瓣剧照接口取图量从 12 张提到 50 张。 - TMDB 双源兜底:豆瓣无横版剧照时自动走 TMDB——
search/multi按片名+年份加权匹配,取 w1280 backdrop。api_key 从 maccms.php 配置读取(实测时还发现该配置的父级层级与预想不同,第一版脚本因此读空,修正后才生效——读配置前先var_export确认真实路径,别靠记忆)。 - 密钥生成:TMDB 注册账号 → Developer 计划申请(个人用途认证勾选 + 应用信息表单) → 生成 v3 key 配置入库。全程浏览器自动化完成,注意其表单的电话号码是必填项,且提交按钮的 click 事件需要用页面脚本触发(常规定位点击会超时)。
- 结果:15 部打标影片 11 部拿到高清横版剧照(豆瓣 8 张 1080p 级 + TMDB 3 张 1280×720);4 部国漫/网剧两边都查无收录,暂撤出轮播。实测渲染:轮播 5 张全部为 1270–1620px 宽的本地剧照,模糊清零。
备注:方法论上这一轮的收获是「定时任务的可观测性」——静默失败比失败更贵,包装层的输出过滤把唯一的报错信号也滤掉了;改造后选片与模板同源、报错逐片可见。脚本最终版已备份进 server-scripts 仓库。同日顺手把热榜从 hot_by=hits_week(随机假热度,老片钉死)改为 time——至此首页全板块(轮播/追剧日历/热榜/分区/专题)统一按最新更新时间排列,配置改动,模板零改动。
2026-09-26 增补(六):年份过滤从轮播推广到首页全板块
- 问题:分区列表(电影片/连续剧/综艺片…)虽然按
by=time排序,但排在前面的依旧全是 2014–2021 老片——「最新更新」排在最前,而最新更新恰恰是采集器刚重推过的老板,和轮播当初是同一个病:排序治不了数据源的刷新噪音。 - 推广治理:把轮播验证过的
year="2024,2025,2026"过滤推广到全部板块——list.html(分区 rail)、hot.html(热榜,2 处标签)、week.html(追剧日历)。改前用 SQL 预检了 2024+ 影片的星期分布(898–5567 部/天),确认日历 7 天不会空。 - 结果:渲染实测,6 个分区 + 热榜全部变为 2024+ 新片且按最新更新排列(电影片:黑箱日记/互帮互助/海岛巨蟒…;连续剧:夺宝天团第二季/宛如阿修罗2025…),此前 12 部样本老片在首页零残留。
- 边界:追剧日历与分区列表里可能出现「年份新但内容旧」的片(如 2025 年上架的经典重映),这是过滤语义的天然边界;若想更严格可在年份之上再叠推荐级,但内容量会骤减,现阶段不建议。
备注:至此 MacCMS 的「时间字段被采集刷新」问题形成完整解法——轮播(推荐级+年份)、板块(年份)、排序(全部 time)、配图(双源高清剧照管线)。模板改动已推送 GitHub。同日稍晚:预检各分类 2026 年库存(连续剧 514/电影片 389/动漫片 321/综艺片 249/体育 72/解说 137)后,把年份过滤统一收紧为 year="2026",首页所有板块只显示当年内容;轮播原样(精选片单本就是 2026 片)。
2026-09-28 增补(七):手机版个人中心重叠——两代头部系统的叠层打架
- 现象:手机版会员中心,「Personal Center」标题和积分行被站点导航条盖住,人物卡整体顶进导航底下。
- 排查:用测试账号种合法登录 cookie + 手机视口(390×844)真实渲染截图复现;逐层测量发现内容根容器渲染位置比文档流预期高约 130–280px,且随宽度变化。逐个禁用样式表二分定位,最终锁定 legacy
user-head-early.css在 ≤820px 的沉浸式头部设计——人物卡.tou { margin-top:-3.7rem }上拉、假设顶部导航透明。 - 根因:momo2026 模板自带另一套头部(sticky .site-head),两代头部系统叠加后,负 margin 沿
.tou→#left→#member→#mac-user-info-root逐级外边距塌陷,把整块内容顶进「固定 54px 滚动感知导航 + sticky 66px 站点导航」双层导航条底下。计算值全部正常(0/12px),只有真实渲染几何暴露问题——这类叠层 bug 用 computed style 排查会一无所获,必须量 getBoundingClientRect。 - 修复:移动端归零 .tou 负 margin,内容恢复从导航下方流式排列;user-center.css 版本参数升级强制刷新缓存。实测 390–800px 全部宽度内容稳定落在导航下 12px。
- 方法论:先复现、再二分、后归因。逐个禁用样式表把 173KB 的 legacy CSS 嫌疑范围收窄到一条规则,比通读 minified 源码快一个数量级。
备注:排查用的临时种 cookie 跳板页已删除;修复随 user-center.css 推送 GitHub(8315f72)。




暂无评论内容