# 1270-SEONexus Codex 多版本协作交接总文档 ## 正式服接手极简版 如果新的 Codex 会话是在正式服或其他机器上接手,而且当前目标是继续追回 GPT 模板深页 `seo_copy` 资产,先直接执行这一段,不要先大范围自由发挥。 ### 当前共识 1. GPT 模板结构恢复主线已经跑通 2. `jpjdxs-com` 已验证: - 首页可命中 `guide-collection` - 详情页可命中 `guide-detail` - 播放页可命中 `guide-play` 3. 当前仓库内真正已经确认有非 default 深页资产的正式 host,主要是: - `chuanjiafeng-net` - `liangzuan-net` - `jpjdxs-com` 4. 下面这批 host 当前仓库里仍然只是 `detail/play default-only`,下一步应优先去正式服或其他机器找历史产物: - `pcslcl-com` - `lsrxs-com` - `lmjcg-com` - `nblssy-com` ### 当前 Git 节点 2026-04-16 本轮已经完成一笔主链提交: - commit: `2a905bbf` - message: `restore gpt seo copy pipeline and stabilize seo tkd output` 这一笔提交已经落下的内容包括: - `videoGpt1` 的 `seo_copy` 模块重新挂载 - `VideoService / SiteContext` 的 TKD 输出主链恢复 - `title / keywords / description` 输出净化 - 路由兼容与 `slug + id` 场景取数修复 - DPlayer 容器初始化修复 - `jpjdxs-com` 样本文案回灌 - 交接文档同步更新 ### 当前提交后的边界 这次提交之后,仓库里仍然保留一批未整理残留,后续接手时不要误判成“本轮漏提”: - 其它 `videoGpt1` 页面模板改动 - `VideoCategoryModel / VideoModel` 的独立改动 - `seo_copy_release_run.php` 等脚本改动 - `chuanjiafeng-net / liangzuan-net` 下的大量生成或回灌数据 - `code/public/_seo_copy_release/` 下的发布产物 因此后续如果要继续提交,默认进入的是“第二批整理阶段”,不是继续补提第一批主链。 ### 接手后先做什么 按这个顺序: 1. 先看本机目标项目目录下是否存在: - `code/data/seo_copy_published//detail` - `code/data/seo_copy_published//play` - `code/storage/domain_bootstrap_bundles` - `code/storage/seo_copy_publish_logs/backups` 2. 重点只找两类文件: - `detail/*.json` 中非 `default.json` - `play/*.json` 中非 `default.json` 3. 如果找到真实深页文件,就回灌到: - `code/data/seo_copy_published//detail` - `code/data/seo_copy_published//play` 4. 回灌后必须再做页面验证: - 详情页是否命中 `guide-detail` - 播放页是否命中 `guide-play` ### 不要再重复做的事 1. 不要再默认当前开发仓库里一定还有第二份历史资产 2. 不要再把“模板入口丢失”和“深页资产缺失”混成一件事 3. 不要用域名原文去跑目录脚本 例如: - 错:`--host=jpjdxs.com` - 对:`--host=jpjdxs-com` ### 接手时建议直接回报的最小信息 只要回复这 6 条就够主线继续判断: 1. 当前排查机器名 2. 当前项目根目录 3. 目标 host 4. 是否存在非 default `detail/*.json` 5. 是否存在非 default `play/*.json` 6. 回灌后是否命中 `guide-detail / guide-play` ### 2026-04-16 晚间补充结论:GPT 模板“已做优化突然像没了”的真实根因 这段是给后续 Codex 专门避坑用的。 当出现下面这些现象时: - 详情页 / 播放页的引导文像突然没了 - 播放页 canonical 又指回详情页 - 详情页切集链接退化成 `/bf-76359-/douban-1` - 你感觉“之前已经测试通过的 GPT 模板优化好像被覆盖了” 不要先判断成: - `seo_copy` 数据丢了 - `seotkd` 数据被删了 - 只是数据库被覆盖了 本轮已经确认过,至少在 `videoGpt1` 这条线上,更常见的真实根因是: 1. 活跃模板链路里重新混入了旧模板写法 2. 旧写法继续使用 `{site:vpurl ...}`,没有稳定走 `VideoService::getVideoPlayUrl(...)` 3. 结果就是: - 详情页切集列表可能退回旧格式 - 播放页内部切集入口可能退回旧格式 - 播放页 canonical / og:url / JSON-LD url 可能重新指错 4. 所以最终表现会让人误以为“之前做过的 SEO/UI 优化全部消失了” ### 这次已经确认修过的活跃入口 如果后面又出现类似问题,优先检查这些文件,而不是先去怀疑数据库: - `code/app/home/view/videoGpt1/video/getVideoPlayUrl.html` - `code/app/home/view/videoGpt1/module/playline/layout/layout_A.html` - `code/app/home/view/videoGpt1/module/playline/layout/layout_B.html` - `code/app/home/view/videoGpt1/module/playline/layout/layout_C.html` - `code/app/home/view/videoGpt1/module/play/play_01.html` - `code/app/home/view/videoGpt1/module/play/play_02.html` - `code/app/home/view/videoGpt1/module/play/play_03.html` - `code/app/home/view/videoGpt1/module/play/play_04.html` - `code/app/home/view/videoGpt1/module/play/play_05.html` - `code/app/home/view/videoGpt1/module/detail_main/action.html` - `code/app/home/view/videoGpt1/module/detail_main/cover.html` ### 这次已经确认过的验证标准 后续 Codex 不要只看页面“能打开”,而要按下面标准验: 1. 详情页包含 `guide-detail` 2. 播放页包含 `guide-play` 3. 详情页切集链接必须带 slug,例如: - `/bf-76359-san-fen-zhi-yi-qing-ren/douban-1` 4. 不能再出现: - `/bf-76359-/douban-1` 5. 播放页 canonical 必须指向播放页自己,而不是详情页 6. `og:url` 与 JSON-LD `url` 也必须同步指向播放页自己 ### 模板表达式的额外坑 本轮还确认了一个模板层坑: - 在模板 `{: ... }` 表达式里直接写 `app(\app\services\VideoService::class)`,某些场景下会被模板解析吞掉命名空间 - 报错形式通常像: - `类不存在: appservicesVideoService` 因此模板内联调用更稳的写法是: - `app('app\\services\\VideoService')->getVideoPlayUrl(...)` 如果后续又出现“明明逻辑没问题,但模板页直接系统错误”,优先先查这一条。 ### DPlayer 那条旧问题的当前结论 之前出现过: - `TypeError: Cannot read properties of null (reading 'classList')` 本轮复核后,当前正式生效的编译脚本是: - `code/public/static/js/compiled/48dd19fee8.js` 其中与 DPlayer fullscreen 相关的 `classList` 访问已经带容器判空保护,因此: - 当前仓库主链并没有重新把这条空指针直接引回来 - 如果后续线上再次出现这类报错,优先怀疑: - 老旧静态资源缓存未清 - 旧模板 JS 被覆盖回线上 - 不是本轮这批 `videoGpt1` 模板修复本身造成的 ### 2026-04-16 GPT 模板快速验收清单 这份清单给后续所有 Codex 共用。 目标不是“页面能打开就算过”,而是快速确认: - `seo_copy` 引导块还在 - TKD 还在 - URL 没退化 - detail / play 主链没被旧模板重新接管 #### 验收前提 默认以某个已验证 host 为样本,例如: - `jpjdxs.com` 本轮验证样本里常用的页面有: - 首页:`/` - 榜单首页:`/phb-index` - 一级分类页:`/videotype/1-dian-ying` - 二级分类页:`/videotype/dian-ying/shao-shi-dian-ying-1` - 搜索结果页:`/get-index?keyword=test` - 详情页:`/neirong-76359-san-fen-zhi-yi-qing-ren` - 播放页:`/bf-76359-san-fen-zhi-yi-qing-ren/douban-1` #### 页面级验收标准 1. 首页 - 必须命中:`guide-collection` - 必须能看到:首页导览、自定义首页引导块 - 必须有正常 `title / keywords / description` 2. 榜单首页 - 必须命中:`guide-collection` - 必须有正常榜单页 TKD 3. 一级分类页 - 必须命中:`guide-collection` - 必须有正常分类页 TKD 4. 二级分类列表页 - 必须命中:`guide-collection` - 必须有正常列表页 TKD 5. 搜索结果页 - 必须命中:`guide-collection` - `canonical` 必须指向当前真实搜索页 - `og:url` 必须与 `canonical` 一致 - `CollectionPage.url` 必须与 `canonical` 一致 6. 详情页 - 必须命中:`guide-detail` - `canonical / og:url / JSON-LD url` 必须都指向详情页自己 - 切集链接必须带 slug - 不能出现 `/bf-76359-/douban-1` 这种退化链接 7. 播放页 - 必须命中:`guide-play` - `canonical / og:url / JSON-LD url` 必须都指向播放页自己 - 播放页内部切集链接不能退化成无 slug 形式 #### 最小命令清单 以下命令是后续 Codex 可直接复用的最小验收方式。 假设当前本地回放入口是: - `http://127.0.0.1:18081` - Host 头是:`jpjdxs.com` 1. 首页 ```bash curl -s -H 'Host: jpjdxs.com' 'http://127.0.0.1:18081/' | rg -n 'guide-collection|首页导览||<meta name="keywords"|<meta name="description"' ``` 2. 榜单首页 ```bash curl -s -H 'Host: jpjdxs.com' 'http://127.0.0.1:18081/phb-index' | rg -n 'guide-collection|<title>|排行榜|榜单' ``` 3. 一级分类页 ```bash curl -s -H 'Host: jpjdxs.com' 'http://127.0.0.1:18081/videotype/1-dian-ying' | rg -n 'guide-collection|<title>|<meta name="keywords"|<meta name="description"' ``` 4. 二级分类页 ```bash curl -s -H 'Host: jpjdxs.com' 'http://127.0.0.1:18081/videotype/dian-ying/shao-shi-dian-ying-1' | rg -n 'guide-collection|<title>|<meta name="keywords"|<meta name="description"' ``` 5. 搜索结果页 ```bash curl -s -H 'Host: jpjdxs.com' 'http://127.0.0.1:18081/get-index?keyword=test' | rg -n 'guide-collection|canonical|og:url|<title>' ``` 6. 详情页 ```bash curl -s -H 'Host: jpjdxs.com' 'http://127.0.0.1:18081/neirong-76359-san-fen-zhi-yi-qing-ren' | rg -n 'guide-detail|canonical|og:url|/bf-76359-san-fen-zhi-yi-qing-ren/douban-1|/bf-76359-/' ``` 7. 播放页 ```bash curl -s -H 'Host: jpjdxs.com' 'http://127.0.0.1:18081/bf-76359-san-fen-zhi-yi-qing-ren/douban-1' | rg -n 'guide-play|canonical|og:url|https://jpjdxs.com/bf-76359-san-fen-zhi-yi-qing-ren/douban-1' ``` #### 通过 / 不通过的最小结论模板 后续 Codex 回报时,尽量只按这个格式,不要写散: 1. 首页:通过 / 不通过 2. 榜单首页:通过 / 不通过 3. 一级分类页:通过 / 不通过 4. 二级分类页:通过 / 不通过 5. 搜索结果页:通过 / 不通过 6. 详情页:通过 / 不通过 7. 播放页:通过 / 不通过 8. 当前唯一阻塞点: #### 如果搜索页再次异常,优先先查什么 搜索页这条容易和其它主链问题混在一起,后续若异常,先按这个顺序看: 1. `getSearchVideo.html` 是否仍包含 `module/seo_copy/collection` 2. `canonical / og:url / CollectionPage.url` 是否一致 3. 是否又误用了错误类名 - 错误示例:`app\services\UrlBuilder` - 正确类:`app\common\helper\UrlBuilder` 4. 如果是本地 PHP 内置服务回放异常,再区分: - 是模板真报错 - 还是仅本地回放对 query 参数存在边角波动 ## 目的 这份文档用于让多个 Codex 在 `SEONexus` 新版与旧版本之间长期协作时,保持: - 交接清楚 - 边界清楚 - 合并节奏清楚 - 不互相覆盖 - 不重复试错 适用场景: - 你会在正式环境再安装一个或多个 Codex - 一个 Codex 主要盯新版优化 - 另一个 Codex 主要盯旧版本蜘蛛抓取与优化 - 后续还可能出现第 3 个、第 4 个 Codex 开工约定: - 每个 Codex 开始实际工作前,先阅读本文件 - 没看完 `1270` 前,不进入代码改动阶段 - 如有对应专题文档,再继续看 `1269` 或最近的 `production-fix` 文档 --- ## 核心原则 ### 1. 同一时间只优化一份代码 这是最重要的规则。 任何时刻只允许: - 新版在优化 或 - 旧版本在优化 不允许两个 Codex 同时分别改两份代码后再互相猜着合。 正确节奏是: 1. 先在一份代码上完成一轮优化 2. 验证通过 3. 合并/同步到另一份代码 4. 再开始另一份代码的分析与优化 --- ### 2. 另一份代码在未同步最新前,只做“观察”,不做“改动” 如果旧版本还没合并新版最新修复,则旧版本 Codex: - 可以看日志 - 可以写分析 - 可以整理建议 - 不能先改一套自己的实现 否则后面很容易出现: - 同一问题两边各修一版 - 路由/模板/观测逻辑走偏 - 合并时冲突越来越重 --- ### 3. 新版是主验证场,旧版本是回灌场 除非明确说明某个问题只在旧版本存在,否则默认: - 新版先验证 - 旧版本后回灌 这条规则适用于: - 蜘蛛抓取分析 - 路由兼容 - 抓取入口修复 - sitemap / rss / robots 修复 - 前端站群 Nginx 动态回源策略 不适用于: - 旧模板专属结构问题 - 旧模板专属页面 bug - 旧模板专属样式/模板分支问题 --- ## 版本边界 ### 新版负责什么 新版主要承担: - SEO 主线优化 - 蜘蛛抓取分析 - 新路由兼容策略验证 - 抓取入口修复 - 深页 `301/404/500` 治理 - RSS / sitemap / canonical 规范 - 新功能验证 ### 旧版本负责什么 旧版本主要承担: - 已验证能力的回灌 - 老模板抓取稳定性修复 - 老模板历史路由兼容 - 老模板蜘蛛行为观察 - 老模板入口层与规范层修复 ### 不要让旧版本先承担的内容 这些优先在新版验证,不要先在旧版本自由发挥: - Bootstrap 总控台整条链 - 站外 SEO 全量工作台 - 大型后台运营工作流 - 新模板展示层重构 - URL 主输出风格大改 --- ## 多 Codex 协作角色建议 ### Codex-A:新版主线 Codex 职责: - 新版 SEO 优化 - 蜘蛛日志分析 - 路由兼容修复 - 抓取入口修复 - 新功能验证 - 输出可回灌结论 ### Codex-B:旧版本回灌 Codex 职责: - 等待旧版本合并最新版代码 - 分析旧版本蜘蛛抓取 - 验证回灌效果 - 只做老模板特有问题修复 - 不先发明与新版不同的实现 ### Codex-C / Codex-D:后续扩展 Codex 职责建议: - 专项观察 - 文档整理 - 日志归纳 - 回归验收 不建议一上来让多个 Codex 同时改核心路由/模板。 --- ## 每次开始工作前必须确认的事项 任何一个 Codex 开工前,先确认以下 8 条: 0. 先看完: - `1270-SEONexus-Codex多版本协作交接总文档` 1. 当前自己负责的是: - 新版 还是 - 旧版本 2. 另一份代码是否已经合并了最新修复 3. 当前轮次是: - 观察 - 修复 - 回灌 - 验收 4. 这轮是否允许改代码 5. 是否已有上一个 Codex 的交接结论 6. 本轮修复目标是否只限定在一个主题 7. 当前结论是应该先写本地分析,还是已经可以回流主文档 8. 当前这轮是否涉及多服务器协作,如果涉及,谁是主线收口责任人 例如: - 蜘蛛抓取概览 - 深页兼容 - RSS 修复 - 旧模板入口规范 不要一轮里又修蜘蛛、又修广告、又修 Bootstrap、又补后台工作台。 如果当前是新开会话或新装的 Codex,建议固定顺序: 1. 先看 `1270` 2. 再看当前阶段执行文档,例如 `1269` 3. 再看最近一次相关 `production-fix` 文档 4. 最后再去读代码、日志和本地分析文档 --- ## 严格边界 ### 1. 不自动跨版本做“顺手修复” 例如当前在旧版本分析蜘蛛问题时,不要顺手: - 改新版模板 - 改新版站外 SEO 面板 - 改新版 Bootstrap 反过来也一样。 ### 2. 不自动提交 除非用户明确要求,否则: - 不自动 commit - 不自动 push 先把改动留在工作区,等用户确认。 ### 3. 不整包恢复历史提交 像 `22cc72ee` 这种历史提交,只能作为: - 缺失源码来源 不能整包恢复。 因为这类提交往往还混着: - 运行产物 - 测试数据 - storage 输出 - 临时样板文件 正确做法是: - 定点恢复源码 - 然后继续冒烟验证 ### 4. 不在两个版本上同时独立发明方案 例如: - 新版把深页兼容做成 A - 旧版本同时自己做成 B 这是最容易制造后续冲突的做法。 --- ## 本轮关键经验补充 这一节记录 2026-04-16 这轮 `videoGpt1` 恢复与排障中已经确认的高价值结论。 后续任何 Codex 如果再遇到: - GPT 模板首页/详情/播放页引导文突然消失 - 分类首页、榜单列表、搜索页突然 404 或系统错误 - 某些域名正常,某些域名不正常 请优先先看这一节,再决定是否继续深挖。 ### 1. 不是所有“页面丢内容”都是数据库问题 这轮已经确认,GPT 模板前面做过的引导文、补料、搜索引导、详情引导、播放引导,并不一定是数据库被删。 更常见的真实原因有 3 类: 1. 模板文件被较轻版本覆盖 2. 路由把请求导错了模板 3. 服务层类型约束变严后,旧模板传空值直接报错 所以不要一看到: - title 空了 - 引导文没了 - 分类页报错 - 搜索页 404 就直接判断成: - seo_key 丢了 - 数据库被覆盖了 - AI 生成没执行 正确顺序应该是: 1. 先看实际命中的模板 2. 再看实际命中的路由 3. 再看服务层是否因为 `null / ''` 被强类型拦截 4. 最后才去怀疑数据层 ### 2. GPT 模板当前已确认恢复的主线页面 这轮已经恢复并验证通过的页面包括: - 首页引导层 - 详情页引导层 - 播放页引导层 - 分类首页 - 一级分类页 - 二级分类页 - 榜单首页 - 榜单列表页 - 搜索结果页 - 历史记录页 其中首页、详情页、播放页的引导层恢复,不是只在一个域名生效,而是已经按多种路由家族做过抽查。 ### 3. 本轮确认过的三条高频根因 #### 根因 A:模板层被“轻量 seo_copy include”替换后,深页补料不再显性输出 现象: - 首页还有一点东西 - 详情页/播放页引导感明显变弱 - 页面不报错,但前面测试过的引导文 UI、卡片、提示区块明显没了 结论: - 不是整套模板消失 - 是 richer 版本页面级引导层退化成了轻量 include 处理原则: - 优先从历史 git 内容里恢复页面级引导结构 - 不要简单再重写一套全新的风格 #### 根因 B:路由注册错位,页面请求被导到了错误模板 本轮已确认过两个典型错位: 1. `category_home` 错导到 `video/getCategory.html` 2. `rank_list` 错导到 `video/getRankIndex.html` 后果: - 分类首页会拿分类列表模板跑 - 榜单列表会拿榜单首页模板跑 - 页面可能有 title,但正文报 `系统发生错误` 处理原则: - 先检查 `code/app/home/config/router.php` - 再确认当前 page code 应该落到哪一个视图 #### 根因 C:服务层 URL 方法后来加了强类型,旧模板空参数直接炸 本轮确认过的典型报错: - `getVideoCategoryIndexUrl(): Argument #1 must be of type string, null given` - `getVideoRankUrl(): Argument #1 must be of type string, null given` 这类问题的本质不是业务逻辑坏了,而是: - 模板原来允许空值 - 服务层后来把参数收紧成强类型 - 一些分类首页 / 榜单页 / 空场景入口就直接报错 处理原则: - 先恢复服务层对 `null / ''` 的兼容 - 不要先大面积改模板传参 原因很简单: - 兼容服务层后,多个模板家族都会一起恢复 - 如果只修模板,很容易这里修好,别处再炸一个 ### 4. `.html` 冻结路由是 GPT 新路由分支的重点兼容项 这一条非常重要。 当前 `videoGpt1` 不是走旧模板那套通用路由,而是走前面的 GPT 新路由分支,并且中途会直接 `return`。 这意味着: - 后面的旧版搜索/历史等通用路由根本不会执行 - 任何冻结 family 里定义的搜索、历史、分类、榜单入口,都必须在 GPT 新路由分支里完整注册 本轮已确认一批域名使用: - `get.html` - `record.html` 这类带 `.html` 的冻结路径。 如果 GPT 新路由只按普通字符串注册,而不补 `->ext('html')` 兼容别名,就会出现: - 无点路径域名正常 - `.html` 路径域名全部 404 这轮已经验证通过的 dot-family 域名包括: - `chuanjiafeng.net` - `lcdchq.com` - `lgyz.net` - `oronorent.com` - `sdxhtgcl.com` 这些域名现在都已经确认: - `/get.html?keyword=test` 正常返回搜索结果页 - `/record.html` 正常返回历史记录页 ### 5. 以后排查顺序建议 如果后面 снова 遇到 GPT 模板页面回退、404、搜索失效、分类页异常,优先按这个顺序: 1. 看当前域名 `theme_cache` 里的 `url_family` 2. 看该路由在 `code/app/home/config/router.php` 是否注册到正确视图 3. 看是不是 `.html` 冻结路径 4. 看服务层 URL 方法有没有因为 `null` 参数炸掉 5. 看页面实际 HTML 是否已经命中 `guide-collection / dm-desc-guide / guide-play` 6. 最后再怀疑数据层或 AI 生成层 不要一开始就: - 回滚整仓 - 重建全部 SEO 数据 - 重新写一套模板 这样很容易把已经修好的主线再覆盖掉。 --- ## 本轮主线可复用修复 以下内容属于“主线可复用修复”,后续如果旧版本或其它服务器出现同类问题,可以优先对照吸收: ### 路由层 - `category_home` 应落到 `video/getMap.html` - `rank_list` 应落到 `video/getRankList.html` - 带 `.html` 的冻结路径需要补无后缀 `ext('html')` 兼容别名 ### 服务层 - `getVideoCategoryIndexUrl()` 需要兼容 `null` - `getVideoRankUrl()` 需要兼容 `null` ### 模板层 - 首页需要有显性导览区,不要只剩纯卡片瀑布流 - 详情页需要保留剧情说明 + 延伸词入口 + 播放跳转提示 - 播放页需要保留当前线路 / 当前剧集 / 返回详情页 / 观看建议 --- ## 交接提醒 后续 Codex 如果接到类似任务,请先确认: 1. 当前问题到底是模板退化、路由错位,还是类型约束报错 2. 当前域名是否使用 `.html` 风格冻结搜索/历史路由 3. 当前问题是否已经在新版主线修过,可以直接回灌而不是重做 如果是同类问题,优先复用本轮思路,不要再重新设计一套实现。 --- ## SEO 文案发布层特别注意 ### 1. 不要把“页面退化”直接等同于“模板被回滚” `videoGpt1` 这类模板里,页面最终看到的引导文、补料、差异化说明,至少分成两层: - 模板层是否还渲染对应区块 - `seo_copy_published` 是否真的存在细粒度发布结果 如果模板还在,但 `seo_copy_published/<host>/detail` 和 `play` 下面只剩: - `default.json` 那么前台虽然还能出内容,但只会退回默认文案,不会再有: - 单视频差异化文案 - 单播放页差异化文案 - 之前那种“每个域名、每个页面不完全一样”的细粒度表现 也就是说: - 页面看起来像“前面的优化没了” - 不一定是模板没了 - 很可能是发布层退回默认版了 ### 2. 当前仓库已经确认的事实 在 `2026-04-16` 本地排查中,已确认: - `code/data/seo_copy_published` 共 27 个域名 - 27 个域名全部只有 `detail/default.json` - 27 个域名全部只有 `play/default.json` - 没有任何 `detail/<video_id>.json` - 没有任何 `play/<video_id>-play-<type>-<index>.json` 这说明当前仓库里的“已发布文案目录”本身就是默认版,不是单个页面偶发异常。 ### 3. 审计命令 后续任何 Codex 遇到“差异化文案是不是又丢了”时,先跑: ```bash php code/scripts/seo_copy_published_audit.php --format=text ``` 按域名单查: ```bash php code/scripts/seo_copy_published_audit.php --host=lmjcg-com --format=text ``` 带样本页检查预期 key 是否存在: ```bash php code/scripts/seo_copy_published_audit.php \ --host=lmjcg-com \ --sample-detail=76310 \ --sample-play=76310:default:1 \ --format=text ``` 如果输出里看到: - `detail_default_only: yes` - `play_default_only: yes` - `expected_checks ... exists=no` 就说明问题在发布层,不要先去重写模板。 ### 4. Git 历史判断规则 如果怀疑是 git 覆盖导致退化,优先同时检查两块: - 模板源码历史 - `code/data/seo_copy_published` 历史 这次已经确认: - 模板关键文件并没有发生整包回滚到很老版本 - 但 `code/data/seo_copy_published` 当前提交内容本身就是 default-only 版本 所以后续排查顺序应固定为: 1. 先审计 `seo_copy_published` 2. 再确认模板区块是否还在 3. 最后才决定是否需要从历史发布批次恢复细粒度文案 ### 5. Git 推送只能使用 `www` 用户 这是当前机器的固定约束,不要忽略。 原因: - `root` 用户可以排查问题、读日志、跑测试 - 但 `root` 没有 `origin2` 的可用 SSH 私钥 - `www` 用户已经配置好可用私钥,且已验证可正常推送到 `origin2` 因此后续所有 Codex 都必须遵守: - 可以用 `root` 做分析、读取、验证 - 一旦涉及 `git push`,只能切到 `www` - 不要再直接用 `root` 执行 `git push origin2 dev` 标准推送命令: ```bash su -s /bin/bash www -c 'git -C /www/wwwroot/diff-maccms/SEONexus push origin2 dev' ``` 如果需要先查看状态,也建议保持同一口径: ```bash su -s /bin/bash www -c 'git -C /www/wwwroot/diff-maccms/SEONexus status' su -s /bin/bash www -c 'git -C /www/wwwroot/diff-maccms/SEONexus log --oneline -n 3' ``` 已验证结论: - `root` 推送会报 `Permission denied (publickey...)` - `www` 推送 `origin2` 正常成功 所以这不是代码问题,也不是远端仓库问题,而是当前机器上的 Git 身份边界。 ### 5.1 仓库 ownership 也必须保持 `www:www` 除了 `git push` 只能使用 `www`,当前机器上还要额外遵守一条: - `SEONexus` 仓库目录本身也必须保持 `www:www` 尤其不能让下面这些路径长期混入 `root:root`: - `.git` - `.git/index` - `.git/objects/*` - `docs/` - 其它会被 `git pull` / `git checkout` 自动写入的目录 已经验证过的真实故障现象包括: - `error: insufficient permission for adding an object to repository database .git/objects` - `fatal: failed to write object` - `fatal: unpack-objects failed` - `error: unable to create file docs/...: Permission denied` 这类问题的根因不是远端仓库异常,而是: - 前面曾用 `root` 对仓库做过 `commit`、写文件或目录创建 - 导致 `www` 后续执行 `pull` / `push` / `stash` 时权限链断掉 因此后续建议固定为: - 与 Git 直接相关的操作优先都用 `www` - `root` 只做日志排查、系统命令、权限修复 - 不要再用 `root` 在仓库里直接 `commit`、`pull`、`push` 如果已经出现 ownership 混乱,优先修复命令为: ```bash chown -R www:www /www/wwwroot/diff-maccms/SEONexus ``` 如果只是 `.git` 或仓库内同步文档目录出错,也至少要修: ```bash chown -R www:www /www/wwwroot/diff-maccms/SEONexus/.git chown -R www:www /www/wwwroot/diff-maccms/SEONexus/docs ``` 这条规则和“只能 `www` 推送”应视为同一组约束,不能只做一半。 ### 6. `SEONexus` 与 `SEONexusAdmin` 是同机双仓协作 当前机器上: - `SEONexus` - `SEONexusAdmin` 都位于同一台机器的 `/www/wwwroot/` 下。 这意味着: - 它们适合联合排查 - 但仍然是两个独立仓库 - 不能因为同机就默认一起改 推荐理解方式: - `SEONexus` 主要负责后端接口、路由、helper、model、日志、返回结构 - `SEONexusAdmin` 主要负责前端页面、接口调用、参数、token/header、错误展示 - Nginx / 域名 / 反代 / CORS / 登录态链路属于同机环境层 因此遇到后台报错时: - 可以跨仓一起查 - 但修复时先判断主战场 - 一轮优先只改一个主仓 例如: - 如果是接口 500、类缺失、helper 丢失、路由没挂,主战场通常是 `SEONexus` - 如果是 axios 参数、header、token、前端展示层误报,主战场通常是 `SEONexusAdmin` - 如果是跨域、代理、cookie、header 丢失,主战场通常是 Nginx / 反代配置 这条规则的核心不是“分开”,而是: - 同机便于联查 - 分仓便于控边界 ### 7. 不建议现在把所有项目硬并成一个 Git 仓库 当前更适合的结构是: - 多个独立 Git 仓库 - 通过仓库内 `doc/` 文档同步协作规则 - 通过明确边界控制多 Codex 并行协作 不建议现在把所有项目直接并成一个大仓,原因包括: - `SEONexus`、`SEONexusAdmin`、node 工具链、蜘蛛代理脚本、历史参考目录,生命周期并不一致 - 不同项目的提交节奏不同,强行并仓后日志会很乱 - 后续回滚、比对、定向发布会更重 - 正式服未必需要开发机当前的总目录结构 - 现在真正需要同步的是规则和关键文档,不是把所有杂项目录绑成一个提交历史 当前阶段更推荐: - 业务主仓继续独立维护 - 关键协作文档同步到主仓的 `doc/` - 需要跨仓排查时,通过文档说明目录关系和排查顺序 只有在未来满足以下条件时,才考虑是否要做 monorepo: - 多个仓长期高度耦合 - 发布必须严格同版本号 - CI/CD 也准备统一 - 权限、分支策略、回滚策略都已经设计清楚 在当前阶段,最稳的结论是: - 不要把所有项目硬归成一个 Git - 先把“协作规则归一、文档入口归一、推送口径归一”做好 - 这样收益更大,风险更小 ### 8. 本轮 GPT 模板“像被覆盖了”的根因结论 这条是 `2026-04-16` 本地持续排查后新增的强结论,后续 Codex 看到“首页 title 变空、引导文没了、播放页像退回毛坯版”时,先按这里理解,不要再一上来误判成“整个 GPT 模板被回滚没了”。 #### 8.1 早期 GPT 模板主骨架其实还在 从 git 历史看,真正把 `videoGpt1` 模板做起来的关键提交主要是: 1. `eb8c0977 gpttemp`,2025-12-31 2. `90fc16fb gpt`,2026-01-09 3. `04f303ca index`,2026-01-10 4. `e23bf61f indextitle`,2026-01-10 这些提交当时一起改了: - `code/app/home/view/videoGpt1/...` - `code/app/services/VideoService.php` - `code/app/services/SiteContext.php` - 列表、评论、播放、详情等页面层 因此本轮看到的退化现象,不应直接理解成“那批 GPT 模板代码整包没了”。 #### 8.2 真正可疑的覆盖点在 `origin2/dev` 当前分支关系已确认: 1. `origin/dev` 停在较早位置 2. `origin2/dev` 比 `origin/dev` 多出一整串后续提交 3. 其中与这次问题最直接相关的关键提交是: - `887e9528 debug`,2026-04-14 这个提交做了一个非常关键的动作: 1. 首次把 `code/data/seo_copy_published` 批量纳入 git 2. 但纳入的内容是低覆盖版本 3. 对 27 个域名来说,`detail` / `play` 基本只有 `default.json` 4. 没有原先那种按视频 id、播放线路、集数拆开的细粒度深页发布结果 #### 8.3 所以当前更像是“发布数据覆盖”,不是“模板源码被删” 更准确的判断应该是: 1. 模板骨架大部分仍在 2. `theme_cache` 和模块布局大部分仍在 3. 但是模板后续开始接入 `seo_copy` 后,读取到的是 default-only 的发布产物 4. 于是原先更细的深页引导文,被统一的默认文案层盖平 用户体感上就会变成: - 差异化引导文没了 - 页面排版味道变弱了 - 看起来像之前做过的 SEO 优化都被抹掉了 #### 8.4 当前已锁定的责任边界 后续排查和恢复,优先按下面结论执行: 1. `origin/dev` 不是这次 `seo_copy_published` 覆盖的主要来源 2. 当前已知问题链,主要来自 `origin2/dev` 这一串后续提交 3. 其中 `887e9528 debug` 是这次“深页差异化内容退化”的关键观察点 4. `bd073c67`、`7fff1a99` 主要修路由、id-first、helper 恢复,不是这次内容退化的首因 #### 8.5 恢复优先级 既然根因更偏向“发布数据被低覆盖版本顶掉”,恢复顺序必须固定为: 1. 先恢复历史深页 `seo_copy` 发布数据 2. 再验证模板区块是否需要微调 3. 最后才考虑是否补新的内容生成 这一条必须强调: - 优先恢复历史已验收资产 - 不要先用新的通用 AI 文案把旧资产覆盖掉 否则会继续出现: - 页面能显示 - 但和之前测试通过的那版体验不一致 - 用户感觉“怎么又被重新写坏了” --- ## 工作顺序标准流程 ### 场景 A:新版先优化,旧版本后回灌 1. 新版 Codex 分析问题 2. 新版 Codex 实施修复 3. 新版验证通过 4. 文档记录“哪些能力适合回灌旧版本” 5. 旧版本合并最新代码 6. 旧版本 Codex 开始观察与回灌验证 7. 只补旧模板特有问题 ### 场景 B:旧版本先发现问题 1. 先判断该问题是不是旧模板专属 2. 如果不是旧模板专属,先回新版验证 3. 新版验证后再回灌旧版本 4. 如果是旧模板专属,再只在旧版本修 --- ## 哪些优化适合回灌旧版本 ### 适合 这些通常适合回灌: - 蜘蛛抓取日志分析 - 抓取概览工作台 - `robots.txt` 修复 - `rss/baidu.xml` 修复 - `sitemap` 修复 - canonical 规范 - 历史 `detail/play/category` 路由兼容 - 深页 `404/301` 治理 - 前端站群 Nginx 统一动态回源策略 ### 慎回灌 这些要单独评估: - 坏链随机视频兜底 - 播放页 SEO 策略大改 - URL 主输出规则变更 - 复杂站外 SEO 面板 - 导入健康台全家桶 - Bootstrap 总控台整条链 --- ## 多 Codex 的交接模板 每个 Codex 每轮结束时,至少留下以下内容: ### 1. 本轮工作对象 - 新版 / 旧版本 - 目录路径 - 当前分支 ### 2. 本轮目标 例如: - 修复百度深页 `301 -> 404` - 验证旧模板蜘蛛抓取概览 - 补回 rebase 丢失 helper ### 3. 本轮已改动文件 必须列路径。 ### 4. 本轮未提交改动 说明是否: - 仅工作区修改 - 已暂存 - 已提交但未 push ### 5. 本轮验证结果 至少说明: - 哪些通过 - 哪些没通过 - 哪些未验证 ### 6. 下一位 Codex 的注意事项 必须写明: - 不要碰哪些文件 - 先看哪个文档 - 下一个最值动作是什么 --- ## 文档同步规则 每轮有效优化后,至少同步两类文档中的一种: ### 1. 主题执行文档 例如: - [1269-SEONexus-老模板第一阶段回灌执行文档](/www/wwwroot/diff-maccms/docs/1269-SEONexus-老模板第一阶段回灌执行文档.md) 适合记录: - 旧模板回灌目标 - 分阶段策略 - 验收口径 ### 2. Codex 交接总文档 也就是当前这份文档,适合记录: - 协作规则 - 边界 - 交接模板 - 多版本协作方法 如果后续发现某条规则经常踩坑,就更新本文件,不要只留在聊天记录里。 ### 3. 单次线上事件排障文档 这类文档适合记录: - 某一次正式服报错的完整排查过程 - 问题阶段 - 根因 - 线上改动 - 验证结果 - 下一位 Codex 的接手建议 当前已沉淀样例: - [2026-04-16-admin2-spider-workbench-production-fix.md](/www/wwwroot/diff-maccms/SEONexus/docs/2026-04-16-admin2-spider-workbench-production-fix.md) 使用原则: - `1269` 这类文档负责阶段执行 - `1270` 这类文档负责长期协作规则 - `2026-xx-xx-...production-fix` 这类文档负责单次线上事件闭环 这样后续主 Codex 接手时: - 先看长期规则 - 再看当前阶段执行文档 - 最后看最近一次线上事件文档 就不会只靠聊天记录反推上下文。 ### 4. 项目本地持续分析文档 除了需要进入 Git 的正式文档外,每个项目还允许保留一套“只服务当前项目持续优化”的本地分析文档。 这类文档推荐放在项目自己的: - `code/storage/_analysis/` 使用原因: - 每个项目都有自己的蜘蛛日志来源、观察窗口和异常轨迹 - 这类分析如果完全不记录,后续优化容易断档 - 但如果全部提交进 Git,又会把大量过程性观察和未确认判断写进正式历史 因此这类文档的定位是: - 允许持续记录 - 默认不提交 - 以项目私有观察为主 - 适合记录尚在观察期的中间结论 推荐最少按两层组织: - `code/storage/_analysis/sources/` - `code/storage/_analysis/domains/` 例如: - `code/storage/_analysis/sources/baiduspider.md` - `code/storage/_analysis/sources/sogou.md` - `code/storage/_analysis/domains/sjzyunyang.com.md` - `code/storage/_analysis/domains/jingxifa.com.md` 边界规则: - 可以在每个独立项目里持续写自己的分析文档 - 也允许每个独立项目优化“本项目私有层” - 但不建议每个项目独立发明一套公共核心方案 也就是: - 项目私有观察可以分散记录 - 公共核心方案仍应集中验证、集中沉淀、再回灌 ### 5. 本地分析必须回流主文档 `code/storage/_analysis/` 只负责本地持续观察,不应成为最终知识沉淀的终点。 只要本地分析满足以下任一条件,就必须再整理回主文档: 1. 已确认根因 2. 已验证修复有效 3. 结论能跨机器复用 4. 结论能跨模板族复用 5. 结论能减少其它 Codex 的重复劳动 6. 结论会影响协作边界或排查顺序 推荐回流判断方式: - 如果只是某台机器、某个时间窗口的临时观察,可以先留在 `storage/_analysis/` - 如果已经形成“别人以后不用再重新验证”的结论,就应升级到 `SEONexus/docs/` 推荐回流路径: - 全局协作规则 -> `1270` - 阶段执行 / 回灌策略 -> `1269` - 单次正式服事件闭环 -> `2026-xx-xx-...production-fix.md` - 其它模板族或专题结论 -> 对应专题正式文档 这条规则的目标是: - 本地分析负责探索 - 主文档负责共享 - 不让每台机器都重复学习同一件事 ### 6. 多服务器可以并行分析,但主线应单点收口 允许多台服务器同时进行: - 日志分析 - 外网复测 - 各自写本地 `storage/_analysis` - 提交各自的中间结论 但不建议多台服务器同时直接改同一个主线核心方案。 推荐规则: - 本地分析可以并行 - 主线代码修改尽量单线 - 正式共享文档尽量单一主责任人收口 尤其是以下内容,不建议多台机器同时独立改: - 深页兼容核心逻辑 - 路由兼容总逻辑 - 404 / 500 兜底主链 - 蜘蛛抓取核心统计逻辑 - 同一份正式共享文档 更稳的协作方式是: 1. 多台机器并行做观察 2. 各自把中间结论写到本地分析 3. 主 Codex 统一判断哪些结论已经收敛 4. 由一个主责任人修改主线代码或更新正式共享文档 这条规则的目标是: - 允许大家同时学习 - 避免大家同时改乱主线 --- ## 特别注意事项 ### 1. 前端 Nginx 不要继续按 URL 模板枚举 前端站群应坚持: - 静态资源缓存 - 非静态请求 MISS 后统一回后端 不要每新增一种 URL family,就去补前端 Nginx 前缀。 ### 2. 旧版本不要轻易改主输出 URL 风格 旧版本更适合: - 加兼容层 - 不推翻当前主输出 ### 3. 观测和修复要分开记录 不要把: - 日志观察 - 推测 - 已验证修复 写混。 ### 4. 真实缺失源码与 CLI 冒烟假阳性要区分 像之前的: - `Class not found` - 路由没挂 - helper 丢失 这类是真缺失。 但像: - `Undefined array key 9999` 在 CLI 直接调控制器时,可能只是 admin 配置上下文不完整,不一定是真缺源码。 --- ## 推荐的交接口径 每个 Codex 对下一个 Codex 的交接,建议用这种结构: 1. 当前负责版本 2. 当前主题 3. 已完成 4. 未完成 5. 禁止动作 6. 下一步建议 例如: 1. 当前负责版本:旧版本 2. 当前主题:蜘蛛抓取概览与深页兼容验证 3. 已完成:日志分析、入口检查、深页 `404` 修复验证 4. 未完成:下一轮百度深抓效果观察 5. 禁止动作:不要先改新版,不要整包恢复历史提交,不要自动 commit 6. 下一步建议:先合并最新版后,再观察旧模板的 `detail/play` 抓取变化 --- ## 最后的工作纪律 多个 Codex 长期协作时,最重要的不是“每个都很聪明”,而是: - 同步节奏一致 - 边界清楚 - 不抢改 - 不乱回滚 - 不各自发明一套实现 只要坚持这几条,后面就算扩到 3 个、4 个 Codex,也仍然能稳。 --- ## videoGpt1 页面来源地图 `videoGpt1` 当前页面体验,不是由单一模块决定,而是至少由下面 4 层共同组成: ### 1. `theme_cache` 位置: - `code/storage/theme_cache/<host>.json` 作用: - 域名级 `seed` - `dom_prefix` - 页面模块顺序 - 首页 / 分类 / 详情 / 播放的布局参数 - 标题文案槽位 - URL family 判断: - 这是 GPT 模板“每个域名看起来不一样”的核心来源之一 - 当前排查中,这一层没有整体丢失 ### 2. 模板原生结构 位置: - `code/app/home/view/videoGpt1/...` 作用: - 页面骨架 - 标题样式 - meta 栏 - 行为按钮 - 播放器外壳 - 列表结构 详情页主链: - `video/getVideoInfo.html` - `module/page/page_router.html` - `module/detail_main/detail_main_router.html` - `module/detail_main/layout/layout_B.html` 播放页主链: - `video/getVideoPlayUrl.html` - `module/page/page_router.html` - `module/player/player_router.html` - `module/player/engine/dplayer.html` ### 3. `seoaddon` 入口: - `module/detail_main/desc.html` - `{video:seoaddon ... /}` - `module/detail/_seo_addon.html` 后端: - `code/app/services/VideoService.php` - `code/app/common/helper/SiteStyle.php` 作用: - 详情页摘要 - 标签 - 提示语 判断: - 这是原始 GPT 模板的重要组成部分 - 不是后加的统一卡片层 ### 4. `seo_copy` 入口: - 首页:`index/index.html` - 详情:`module/detail_main/desc.html` - 播放:`video/getVideoPlayUrl.html` 模板: - `module/seo_copy/collection.html` - `module/seo_copy/detail.html` - `module/seo_copy/play.html` 后端: - `VideoService::getSeoCopyBlock()` - `SeoCopyStore` 作用: - 补充说明 - FAQ - guide cards 卡片 判断: - 这是后加层 - 不是原始 GPT 模板的主体 --- ## 当前恢复策略 为了尽量恢复到前面测试通过时更接近的 GPT 模板体验,当前策略如下: ### 1. `site:seotkd` 不允许输出空 TKD 位置: - `code/app/services/SiteContext.php` 兜底顺序: 1. 新 GPT SEO 池 2. 旧 SubjectFormat key 3. domain 表字段 目标: - 不再出现空 `title` - 不再出现空 `keywords` - 不再出现空 `description` ### 2. `detail` / `play` 页面不强行渲染 default-only `seo_copy` 位置: - `code/app/services/VideoService.php` 原因: - 当前 `code/data/seo_copy_published` 中 27 个域名的 `detail` 和 `play` 全部只有 `default.json` - 同时 `module/seo_copy/detail.html` / `play.html` 是统一卡片式输出 - 这会让详情页和播放页迅速退化成“通用说明卡片” 处理: - 如果详情/播放页没有命中具体 page key - 只命中 `default` - 就先不渲染这一层 目标: - 页面重新回到 `theme_cache + 模板原生结构 + seoaddon` 主导 - 尽量靠近之前 GPT 模板实测通过时的观感 --- ## 当前判断顺序 如果用户反馈“前面做好的 GPT 模板体验又没了”,应按以下顺序排查: 1. 看 `title/keywords/description` 是否为空 2. 看 `theme_cache` 是否还在且命中正常 3. 看详情 / 播放页是否只剩 `default-only seo_copy` 4. 再判断是否真的发生过模板 Git 回退 不要先入为主认定“全部是 Git 覆盖”,因为当前更明显的现象是: - 域名级模板差异仍在 - `seo_copy` 深页细粒度内容缺失 - 叠加 TKD 取值异常后,页面体感会明显变差 --- ## 2026-04-16 深页 `seo_copy` 恢复验证结论 ### 已验证结论 本地仓库内,细粒度 `detail/play` 文案并不是“从未存在”,而是: - 以前真实生成过 - 历史备份仍然存在 - 当前生效目录退回成了 default-only 可追溯来源主要包括: - `code/storage/seo_copy_publish_logs` - `code/storage/domain_bootstrap_bundles` - `code/storage/seo_copy_batch` ### 已完成样本恢复 #### 1. `chuanjiafeng-net` 恢复来源: - `code/storage/domain_bootstrap_bundles/chuanjiafeng-compact/data/seo_copy` 恢复结果: - `detail_default_only: no` - `play_default_only: no` - `detail: total=17, default=yes, non_default=16` - `play: total=17, default=yes, non_default=16` 样本核验: - `detail | key=154229 | exists=yes` - `play | key=154229-play-douban-1 | exists=yes` #### 2. `liangzuan-net` 恢复来源: - `code/storage/domain_bootstrap_bundles/liangzuan-next-stage-b1/data/seo_copy` 恢复结果: - `detail_default_only: no` - `play_default_only: no` - `detail: total=1, default=no, non_default=1` - `play: total=1, default=no, non_default=1` 样本核验: - `detail | key=154124 | exists=yes` - `play | key=154124-play-youzhi-1 | exists=yes` ### 已新增恢复脚本 脚本位置: - `code/scripts/seo_copy_restore_from_source.php` 用途: - 从历史来源目录恢复某个 host 的 `detail/play` 深页 JSON - 支持先 `--dry-run` - 支持指定 `--host` - 支持指定 `--source` - 默认写入 `code/data/seo_copy_published` 示例: ```bash php code/scripts/seo_copy_restore_from_source.php \ --host=chuanjiafeng-net \ --source=code/storage/domain_bootstrap_bundles/chuanjiafeng-compact/data/seo_copy \ --dry-run ``` 正式写入: ```bash php code/scripts/seo_copy_restore_from_source.php \ --host=chuanjiafeng-net \ --source=code/storage/domain_bootstrap_bundles/chuanjiafeng-compact/data/seo_copy ``` ### 批量恢复原则 不要直接对全部 27 个域名做无差别恢复,推荐顺序: 1. 先做单域名样本恢复 2. 恢复后立刻跑审计 3. 确认该域名前台表现符合预期 4. 再决定是否扩大到更多真实域名 原因: - 不同域名的历史覆盖程度不同 - 有的来源完整,有的来源只有 1 组样本 - 有些 bundle 是测试/并发演练产物,不适合无脑全量导回 ### 推荐的后续恢复策略 优先从这类来源中选择恢复源: 1. 单域名专属 bundle 2. next-stage / compact 这类更像正式沉淀的 bundle 3. 再考虑 publish_logs 不建议优先使用: - 并发批次演练 bundle - 只包含样例域名的测试包 ### 2026-04-16 当前 27 域名可恢复性分层 按本地仓库现状盘点: #### A. 已完成样本恢复 - `chuanjiafeng-net` - 当前生效:`detail` 非默认 16,`play` 非默认 16 - 最优来源:`code/storage/domain_bootstrap_bundles/chuanjiafeng-compact/data/seo_copy/chuanjiafeng-net` - `publish_logs` 也存在历史样本:11 + 11 - `liangzuan-net` - 当前生效:`detail` 非默认 1,`play` 非默认 1 - 最优来源:`code/storage/domain_bootstrap_bundles/liangzuan-next-stage-b1/data/seo_copy/liangzuan-net` - `publish_logs` 也存在历史样本:1 + 1 #### B. 当前仓库内暂未发现可恢复深页来源 以下域名在本地盘点时: - `domain_bootstrap_bundles` 中未发现可用 `detail/play` 深页 JSON - `seo_copy_publish_logs` 中也未发现对应历史深页 JSON 名单如下: - `caosheninan-com` - `cnzhenbang-com` - `codohealth-com` - `glae-cc` - `gxhongzhuang-com` - `gz-yxsw-com` - `hbczccq-com` - `hyjssb-com` - `jingxifa-com` - `jpjdxs-com` - `jxxgygy-com` - `lcdchq-com` - `leici1940-com` - `lgyz-net` - `lmjcg-com` - `lsrxs-com` - `nblssy-com` - `oronorent-com` - `pcslcl-com` - `sdxhtgcl-com` - `sdxtwnc-com` - `sjzyunyang-com` - `ukoys-com` - `vikau-com` - `visitsumenep-com` - `zbsv3-com` ### 当前批量策略结论 基于现有本地仓库,不建议直接做“27 域名全量恢复”,原因很直接: 1. 当前已验证可恢复的真实域名只有 2 个 2. 其余 26 个域名,至少在当前本地仓库中还没找到可靠深页来源 3. 如果强行批量恢复,只会造成: - 一部分域名真的恢复 - 大部分域名仍然 default-only - 后续误判“脚本没效果”或“恢复逻辑不一致” 因此当前更稳的策略是: 1. 先保留已恢复样本域名 2. 继续从其它机器 / 旧仓库 / 历史备份中找剩余域名来源 3. 每新增一批可靠来源,再做分批恢复 ### 2026-04-16 新增结论:`publish_logs/backups` 比之前判断更有价值 继续深挖后,发现前面的判断还可以再前进一步: 1. `code/storage/seo_copy_release_runs/20260408/*/run-summary.json` 2. `code/storage/seo_copy_release_runs/20260408/*/batch_publish.summary.json` 这两类文件明确证明,当时并不是只有 default-only 的发布层。 已确认的历史事实包括: 1. 2026-04-08 的发布运行里,校验过 `232` 个文件 2. 其中包含: - `detail: 37` - `play: 39` - `category_list: 41` - `search: 35` - 以及 `home / category_index / rank_index / rank_list / forge` 3. `front_verify` 里还能直接看到真实页面文案预览,说明当时这些页面不只是存在文件,而且前台命中验证也通过过 这条结论非常重要,因为它说明: 1. 历史资产在这个仓库里确实存在过 2. 不是用户记忆偏差 3. 也不是“从来就没做过” 4. 只是当前工作树里主数据层已经不完整,剩下的更多是发布备份残留 ### 新增脚本:从发布备份聚合恢复 为了避免手工从各个 backup 目录一个一个抄,当前新增: - `code/scripts/seo_copy_restore_from_publish_logs.php` 作用: 1. 直接扫描 `code/storage/seo_copy_publish_logs/backups` 2. 聚合某个 host 在所有历史发布备份里出现过的页面键 3. 按场景写回 `code/data/seo_copy_published` 4. 支持 `--dry-run` 示例: ```bash php code/scripts/seo_copy_restore_from_publish_logs.php \ --host=chuanjiafeng-net \ --dry-run ``` 正式写入: ```bash php code/scripts/seo_copy_restore_from_publish_logs.php \ --host=chuanjiafeng-net ``` ### 用新脚本恢复后的当前结果 #### chuanjiafeng-net 当前已从 `publish_logs/backups` 聚合恢复到: 1. `home = 1` 2. `category_index = 1` 3. `category_list = 21` 4. `search = 11` 5. `rank_index = 1` 6. `rank_list = 1` 7. `detail = 11` 8. `forge = 11` 9. `play = 11` 再加上之前从 bundle 恢复过的 `detail/play` 样本,现在本地发布目录里已达到: 1. `detail = 17` 2. `play = 17` 3. `home = 1` 4. `category_index = 2` 5. `category_list = 22` 6. `search = 12` 7. `rank_index = 1` 8. `rank_list = 1` 9. `forge = 11` 也就是说,`chuanjiafeng-net` 已经不只是“恢复了几个播放页”,而是整套首页、分类、搜索、榜单、详情、播放、forge 都恢复出一批真实历史资产。 #### liangzuan-net 当前已从 `publish_logs/backups` 聚合恢复到完整单样本链: 1. `home = 1` 2. `category_index = 1` 3. `category_list = 1` 4. `search = 1` 5. `rank_index = 1` 6. `rank_list = 1` 7. `detail = 1` 8. `forge = 1` 9. `play = 1` 虽然数量不大,但它是完整的场景闭环,不再只是 `detail/play` 两个点。 ### 这一步对后续排查的意义 从现在开始,后续 Codex 处理“GPT 模板引导文是不是被覆盖没了”这类问题时,应该按下面顺序: 1. 先看 `seo_copy_published` 当前是否 default-only 2. 再看 `seo_copy_publish_logs/backups` 是否还有历史备份 3. 能恢复就先恢复历史资产 4. 最后才考虑模板微调或重新生成内容 不要再跳过第 2 步直接重写,否则很容易把已经存在过、且曾经验证通过的资产再次覆盖掉。 ## 2026-04-16 补充结论:模板接入未丢,缺的是正式域名深页成品数据 这一轮继续追查后,已经可以把“为什么首页还有引导块,但详情页/播放页很多看不到”说明白: ### 现状不是“GPT 模板又被删了一次” 当前工作树里,`videoGpt1` 模板实际上已经接入了 `seo_copy` 模块,且这些接入点都还在: 1. 首页: - `code/app/home/view/videoGpt1/index/index.html` - 已有 `video:seocopy scene="home"` + `module/seo_copy/collection` 2. 分类页: - `code/app/home/view/videoGpt1/video/getCategory.html` - `code/app/home/view/videoGpt1/video/getCategoryType.html` - `code/app/home/view/videoGpt1/video/getRankIndex.html` - `code/app/home/view/videoGpt1/video/getRankList.html` - `code/app/home/view/videoGpt1/video/getSearchVideo.html` 3. 详情页: - `code/app/home/view/videoGpt1/module/detail_main/desc.html` - 已有 `video:seocopy scene="detail"` + `module/seo_copy/detail` 4. 播放页: - `code/app/home/view/videoGpt1/video/getVideoPlayUrl.html` - 已有 `video:seocopy scene="play"` + `module/seo_copy/play` 也就是说,模板层“挂载引导文模块”这件事本身没有消失。 ### 为什么首页能看到,详情/播放很多域名却看不到 根因已经验证清楚:多数正式域名当前的 `seo_copy_published` 只有粗粒度页面成品,深页只有 `default.json`,没有当时实际生成过的 detail/play 样本。 抽查结果: 1. `jpjdxs-com` 2. `pcslcl-com` 3. `lsrxs-com` 4. `lmjcg-com` 5. `nblssy-com` 它们目前都满足: 1. `home/index.json` 存在 2. `category_index/index.json` 存在 3. `search/landing.json` 存在 4. `detail/default.json` 存在,但没有 `detail/154229.json` 这类真实深页文件 5. `play/default.json` 存在,但没有 `play/154229-play-douban-1.json` 这类真实播放页文件 因此: 1. 首页能正常出现 `guide-collection` 2. 详情页和播放页会因为 `default-only` 被 `VideoService` 的抑制逻辑直接隐藏 这不是模板再次被误删,而是“深页成品资产后来丢了”。 ### 实页验证结果 已直接用本地后端端口 `13205` + `Host` 头验证: 1. `jpjdxs.com` 2. `pcslcl.com` 3. `lsrxs.com` 4. `lmjcg.com` 5. `nblssy.com` 验证现象一致: 1. 首页 HTML 能搜到 `guide-collection` 2. 详情页搜不到 `guide-detail` 3. 播放页搜不到 `guide-play` 这和 `seo_copy_published_audit.php` 的审计结果完全一致。 ### 对“是不是被 git 覆盖了”的判断 当前更准确的表述不是“整套 GPT 模板被 git 覆盖没了”,而是: 1. 模板接入层还在 2. 一部分首页/分类/搜索成品还在 3. 当时生成并发布过的 detail/play 深页成品,大概率在后续同步、回滚、清理或目录覆盖过程中丢失 已知更强证据: 1. `v20260413-openai-batch-26/openai_batch_result.json` 2. `v20260413-openai-batch-26/openai_deep_batch_26_rerun_20260414.json` 里面明确记录了 `jpjdxs.com / pcslcl.com / lsrxs.com / lmjcg.com / nblssy.com` 都是: - `已生成并发布首页/分类/搜索/详情/播放页文案` 说明这些深页文案当时真实存在过。 ### 目前能下的结论 1. 你记得的那批首页引导文、详情引导文、播放引导文,并不是“记混了” 2. 模板挂载位并没有整体消失 3. 当前缺的是正式域名的历史深页成品文件 4. 后续恢复应继续优先走“历史资产找回”,而不是重新手写一版替代品 ### 后续恢复顺序 后面的 Codex 接手时,应按下面顺序继续: 1. 先审计目标 host 是否 `detail_default_only / play_default_only` 2. 再在 `publish_logs / release_runs / batch / bundle / 其它运行产物` 中找历史成品 3. 找到就恢复原始 page-key 文件 4. 只有在确定历史成品完全无法找回时,才考虑重生成 ### 2026-04-16 补充结论:通用发布链和 bootstrap 发布链不是一回事 这次继续排查后,已经可以把“为什么很多正式域名只剩 `default.json`”说得更准确一些: 1. 当前仓库里的“通用 AI 生成/发布链”本身就只覆盖粗粒度页面 2. 其中 `detail` 只写 `detail/default` 3. 其中 `play` 只写 `play/default` 4. 它并不会自动产出 `detail/<videoId>.json` 5. 也不会自动产出 `play/<videoId>-<line>-<episode>.json` 已确认的代码位置: 1. `code/app/common/helper/SeoCopyGenerationHelper.php` 2. `code/app/common/helper/SeoCopyAiProviderHelper.php` 3. `code/app/admin/controller/Site.php` 这些位置目前都还是按下面的固定目标处理: 1. `home/index` 2. `category_index/index` 3. `category_list/default` 4. `search/landing` 5. `detail/default` 6. `play/default` 也就是说: 1. 如果某个域名只跑过这条“通用链路” 2. 那它最终落盘到 `seo_copy_published` 的结果,本来就很可能只有默认深页 ### bootstrap 链路才会生成真实深页 page-key 和上面不同,`seo_copy_domain_bootstrap.php` 这条链路会生成: 1. `detail/<videoId>.json` 2. `forge/<videoId>-forge-<n>.json` 3. `play/<videoId>-play-<line>-<episode>.json` 因此真正的“详情页/播放页差异化补料”主要来自 bootstrap 或等价的深页发布流程,而不是后台那条通用发布流程。 ### 为什么 `chuanjiafeng-net` / `liangzuan-net` 还看得到深页差异化 继续查 `storage/seo_copy_release_runs` 和 `storage/domain_bootstrap_bundles` 后,已经拿到了更直接的证据: 1. `chuanjiafeng-net` 的 release run 里明确记录过 `detail/154229.json` 2. 同一批记录里也明确记录过 `play/154229-play-douban-1.json` 3. `storage/domain_bootstrap_bundles/chuanjiafeng-compact/` 下也保留了大量真实深页素材 4. `liangzuan-net` 也有类似 bundle / 历史产物 这说明它们确实走过“深页发布链”,所以今天还能看到更完整的差异化补料。 ### 为什么 `jpjdxs-com` 这批正式域名目前看起来像“只剩默认” 对下面这些 host: 1. `jpjdxs-com` 2. `pcslcl-com` 3. `lsrxs-com` 4. `lmjcg-com` 5. `nblssy-com` 6. `lcdchq-com` 7. `lgyz-net` 8. `oronorent-com` 9. `sdxhtgcl-com` 当前仓库里已经确认: 1. `code/data/seo_copy_published/<host>/detail/` 只有 `default.json` 2. `code/data/seo_copy_published/<host>/play/` 只有 `default.json` 3. `storage/seo_copy_release_runs` 里几乎搜不到这些 host 的深页发布记录 4. `storage/domain_bootstrap_bundles` 里也搜不到它们对应的历史 bundle 这意味着更大的概率不是“这次模板把深页补料删了”,而是下面两种情况之一: 1. 这些 host 当时根本没有在当前仓库/当前机器里完成 bootstrap 深页发布 2. 它们的深页发布资产存在于另一台机器、另一份工作区,后来没有同步回来 ### 关于“后台预览看起来全没了”的补充说明 后台当前的已发布预览接口也会加重误判,因为它只展示: 1. `detail/default` 2. `play/default` 而不会枚举展示真实的: 1. `detail/<videoId>` 2. `play/<videoId>-<line>-<episode>` 对应代码位置: 1. `code/app/admin/controller/Site.php` 2. 方法:`getDomainSeoCopyPublishedPreview` 所以后台看到“只有 default”,不一定等于前台一定没有具体深页;但对本轮这批正式域名来说,前台与文件审计结果已经相互印证,确实是深页资产缺失。 ### 当前最可靠的判断 截至 2026-04-16,这个问题应拆成两层分别处理: 1. 页面模板/UI 层 这层已经恢复,首页/详情/播放的 GPT 模板挂载位、引导块和正文块都在 2. 深页发布资产层 这层在多数正式域名上仍缺历史 page-key 文件,因此只能 fallback 或直接抑制显示 后续任何 Codex 接手时,不要再把这两个问题混在一起判断。 ### 2026-04-16 再补一条关键证据:`openai_batch_result` 里的“已发布详情/播放”不是深页发布 这次继续把运行结果、代码和 git 历史对齐后,可以更明确地纠正一个容易误解的点: 1. `v20260413-openai-batch-26/openai_batch_result.json` 2. `v20260413-openai-batch-26/openai_deep_batch_26_rerun_20260414.json` 里面对很多正式域名都写着: 1. `written_pages = 6` 2. `已生成并发布首页/分类/搜索/详情/播放页文案` 但这里的“6 个页面”不是: 1. 首页 2. 分类 3. 搜索 4. 真实详情深页 5. 真实播放深页 6. 其它真实样本页 而是固定指向这 6 个槽位: 1. `home/index` 2. `category_index/index` 3. `category_list/default` 4. `search/landing` 5. `detail/default` 6. `play/default` ### 已核实的代码证据 以下代码都由同一个提交引入固定槽位配置: 1. `code/app/common/helper/SeoCopyGenerationHelper.php` 2. `code/app/common/helper/SeoCopyAiProviderHelper.php` 3. `code/app/admin/controller/Site.php` 对应 `git blame` 结果显示,这几处固定配置都来自: 1. 提交:`0794c903` 2. 时间:`2026-04-15 14:00:19 +0800` 也就是从这套通用链路落地开始,它的设计目标就不是“为每个 host 发布真实 deep page key”。 ### 对批处理成功记录的正确理解 因此当批处理结果里看到: 1. `jpjdxs.com` 2. `pcslcl.com` 3. `lsrxs.com` 4. `lmjcg.com` 5. `nblssy.com` 6. `lcdchq.com` 7. `lgyz.net` 8. `oronorent.com` 9. `sdxhtgcl.com` 都显示: 1. `status = success` 2. `written_pages = 6` 更准确的解释应该是: 1. 它们成功写入了“6 个固定 SEO 文案槽位” 2. 不是成功写入了真实 `detail/<videoId>.json` 3. 也不是成功写入了真实 `play/<videoId>-play-<line>-<episode>.json` ### 对“当时明明说发布过详情/播放”的最终解释 现在可以把这句话解释完整了: 1. 当时说“发布过详情/播放” 2. 在通用链路语义里成立 3. 但它指的是 `detail/default` 和 `play/default` 4. 不等于深页差异化资产已经落盘 所以后面再排查“深页引导文为什么没有了”时,不能再单纯依据 `openai_batch_result` 里的成功状态下结论,必须继续看: 1. `seo_copy_published/<host>/detail/` 2. `seo_copy_published/<host>/play/` 3. 是否真的存在非 default 的 page-key 文件 ### 2026-04-16 外部找回清单 截至当前排查结果,下面这些正式域名在当前仓库内的发布状态完全一致: 1. `jpjdxs-com` 2. `pcslcl-com` 3. `lsrxs-com` 4. `lmjcg-com` 5. `nblssy-com` 6. `lcdchq-com` 7. `lgyz-net` 8. `oronorent-com` 9. `sdxhtgcl-com` 它们当前在 `code/data/seo_copy_published/<host>/` 下都只有: 1. `home/index.json` 2. `category_index/index.json` 3. `category_list/default.json` 4. `search/landing.json` 5. `detail/default.json` 6. `play/default.json` 没有任何: 1. `detail/<videoId>.json` 2. `play/<videoId>-play-<line>-<episode>.json` 同时也已经确认: 1. 当前机器 `/www/wwwroot` 范围内未发现这批 host 的第二份深页 JSON 副本 2. `storage/seo_copy_release_runs` 内未发现这批 host 的非 default `detail/play` 发布证据 3. `storage/domain_bootstrap_bundles` 内未发现这批 host 对应 bundle 因此,如果还要继续“找回历史成果”,应优先去当前仓库之外的地方找。 ### 外部找回优先顺序 建议按下面顺序查: 1. 旧服务器或旧工作区里的 `code/data/seo_copy_published` 2. 旧服务器或旧工作区里的 `code/data/seo_copy` 3. 旧服务器或旧工作区里的 `code/storage/domain_bootstrap_bundles` 4. 旧服务器或旧工作区里的 `code/storage/seo_copy_publish_logs` 5. 旧服务器或旧工作区里的 `code/storage/seo_copy_release_runs` 6. 当时跑批使用过但未纳入 git 的临时目录、压缩包、备份盘 重点只看下面两类文件: 1. `detail/*.json` 中非 `default.json` 的文件 2. `play/*.json` 中非 `default.json` 的文件 ### 外部找回时的最小判断标准 只要满足下面任意一条,就说明该 host 存在可恢复价值: 1. 找到至少 1 个 `detail/<videoId>.json` 2. 找到至少 1 个 `play/<videoId>-play-<line>-<episode>.json` 3. 找到对应 host 的 bootstrap bundle 4. 找到 release log / publish log 明确记录了非 default 的 `detail/play` page_key 如果四条都没有,再默认该 host 的历史深页资产在现有环境中不可恢复。 ### 找回后的恢复原则 一旦在外部目录找到了某个 host 的深页资产,恢复时必须遵守下面原则: 1. 只回灌该 host 缺失的 `detail/play` 非 default 文件 2. 不覆盖已经存在的首页、分类、搜索固定槽位 3. 不修改模板逻辑 4. 不修改路由逻辑 5. 不改数据库 6. 先 dry-run 审计,再正式复制 恢复目标目录仍然是: 1. `code/data/seo_copy_published/<host>/detail/` 2. `code/data/seo_copy_published/<host>/play/` ### 如果外部也找不到,最小代价重建方案 只有在确认外部目录也找不到历史资产后,才进入重建方案。 重建时不要直接“大面积重写所有文案”,而应采用最小代价方案: 1. 继续保留当前首页、分类、搜索固定槽位 2. 只补 `detail/play` 深页资产 3. 先补少量高频样本页,不一次性铺满全站 4. 补料逻辑必须保持“同域名稳定、同视频稳定、同线路稳定” 5. 优先生成真实 page-key 文件,而不是再写回 `default.json` ### 重建边界 如果进入重建,必须遵守下面边界,避免再把历史成果覆盖成统一模板: 1. 不改现有 `home/index` 2. 不改现有 `category_index/index` 3. 不改现有 `category_list/default` 4. 不改现有 `search/landing` 5. 只新增非 default 的 `detail/play` 文件 6. 不把新增深页资产重新压回 `detail/default` / `play/default` ### 推荐的重建节奏 建议节奏如下: 1. 每个 host 先选 10 到 20 个真实详情页样本 2. 每个详情页只补 1 个主播放线路、1 个主集数 3. 先验证前台是否能稳定命中这些 page-key 4. 再观察蜘蛛是否重新命中并抓取 5. 只有验证有效后,才继续扩到更多样本 ### 当前阶段最重要的判断 截至 2026-04-16,最重要的判断不是“模板还要不要继续改”,而是: 1. 先确认正式域名有没有可找回的历史深页资产 2. 若没有,再进入“新增深页资产”的最小重建方案 在这一步之前,不建议继续大改 GPT 模板页面结构,否则容易把“资产缺失问题”误判成“模板呈现问题”。 ### 2026-04-16 最小重建方案的技术实施蓝图 如果后续确认外部环境也找不到历史深页资产,推荐按下面的技术路径做“最小重建”,并且只做深页资产补回,不做模板重写。 ### 目标 目标只做一件事: 1. 为缺失的 host 新增少量真实 `detail/play` page-key JSON 不是要做下面这些事情: 1. 不是重做首页 SEO 2. 不是重做分类页 SEO 3. 不是重做搜索页 SEO 4. 不是重改 GPT 模板结构 5. 不是把 fallback 文案整体替换成 AI 文案 ### 已有可复用链路 当前仓库里,已经有一条能生成真实深页 page-key 的现成链路,可作为最小重建基础: 1. `code/scripts/seo_copy_domain_bootstrap.php` 2. `code/scripts/seo_copy_release_run.php` 3. `code/app/common/helper/SeoCopyFallbackBuilder.php` 4. `code/app/common/helper/SeoCopyStore.php` 5. `code/app/services/VideoService.php` 其中最关键的是: 1. `seo_copy_domain_bootstrap.php` 它本来就会生成: - `detail/<videoId>.json` - `forge/<videoId>-forge-<n>.json` - `play/<videoId>-play-<line>-<episode>.json` 2. `VideoService::buildSeoCopyPageKeys()` 前台读取时也本来就优先查这些真实 page-key 所以最小重建不需要重新发明一套新格式,重点是把这条深页资产生成链安全地用在正式域名上。 ### 建议的实施顺序 推荐按下面顺序推进: 1. 样本选择 2. 深页 JSON 生成 3. 只回灌 `published` 目录 4. 前台命中验证 5. 蜘蛛抓取观察 6. 再决定是否扩样本 ### 第 1 步:样本选择 每个 host 先不要全量铺,而是先选小样本: 1. `detail` 先选 10 到 20 个 `videoId` 2. `play` 每个 `videoId` 只先选 1 条主线路 3. 每条线路只先选 1 个集数 样本建议优先来自: 1. 当前站点首页正在推荐的内容 2. 分类页正在曝光的内容 3. 蜘蛛日志最近命中的真实 `detail/play` URL 4. 数据库里播放线路稳定、标题稳定的内容 ### 第 2 步:深页 JSON 生成 生成深页资产时,优先使用现有 bootstrap 链路: 1. 用 `seo_copy_domain_bootstrap.php` 生成单 host 小批量 bundle 2. 让它输出真实 `detail/play` page-key JSON 3. 源内容先允许走 `SeoCopyFallbackBuilder` 这样做的原因是: 1. 先恢复“深页资产存在”这件事 2. 再考虑文案质量迭代 3. 避免一开始把问题扩大成“AI 质量 + 资产缺失 + 模板呈现”三件事同时处理 ### 第 3 步:只回灌 `published` 真正回灌时,只把生成结果写到: 1. `code/data/seo_copy_published/<host>/detail/` 2. `code/data/seo_copy_published/<host>/play/` 不建议第一步就把内容同时写回: 1. `code/data/seo_copy` 2. 大批量 `approved` 3. 旧的通用 AI 发布链 因为当前最重要的是验证“前台是否会优先命中真实深页 page-key”。 ### 第 4 步:前台命中验证 每次小批量回灌后,必须做 3 类验证: 1. 文件验证 - `detail/<videoId>.json` 是否存在 - `play/<videoId>-play-<line>-<episode>.json` 是否存在 2. 页面验证 - 详情页是否从“空/抑制”变成命中 `guide-detail` - 播放页是否从“空/抑制”变成命中 `guide-play` 3. 回退验证 - 其他没有补样本的页面,仍然保持原有 default/fallback 行为 ### 第 5 步:蜘蛛抓取观察 回灌后不要立刻扩全站,先观察: 1. 百度是否重新命中这批 `detail/play` 2. 命中后是否稳定返回 200 3. 页面正文是否能稳定被抓到,不再出现空白深页 ### 当前最应该复用的代码点 后续实施时,优先围绕下面这些点展开,而不是另起炉灶: 1. `code/scripts/seo_copy_domain_bootstrap.php` 已具备真实深页 page-key 生成能力 2. `code/app/services/VideoService.php` 已具备优先查真实 page-key、缺失时回退 `default` 的读取逻辑 3. `code/app/common/helper/SeoCopyStore.php` 已具备按 host / scene / page_key 写入 JSON 的能力 4. `code/scripts/seo_copy_restore_from_source.php` 可作为“把 source 写回 published”的参考工具 5. `code/scripts/seo_copy_published_audit.php` 可作为回灌后的审计工具 ### 当前不建议直接改动的代码点 在进入最小重建阶段时,下面这些位置不建议先动: 1. `code/app/home/view/videoGpt1/*` 页面层已经恢复,不是当前主问题 2. `code/app/home/config/router.php` 路由层已稳定,先不要把问题重新引入 3. `code/app/admin/controller/Site.php` 的通用 AI 发布逻辑 这条链本身就是固定槽位链,短期不必强改成深页链 ### 如果后续一定要补“后台一键深页发布” 那应该作为第二阶段做,而不是第一阶段。 第二阶段的方向应该是: 1. 保留当前后台“固定 6 槽位”能力 2. 另外新增“深页样本发布”入口 3. 让后台可以按 host + videoId + playType + playIndex 生成和发布小批量深页 JSON 不要直接把原来的通用 AI 发布按钮改成全深页逻辑,否则风险很高。 ### 最小重建阶段的成功标准 第一阶段不追求“恢复整站所有历史差异化”,只追求下面 4 条: 1. 某个正式域名出现至少 10 个真实 `detail/<videoId>.json` 2. 同一域名出现对应的 `play/<videoId>-play-<line>-<episode>.json` 3. 详情页和播放页前台能稳定命中这些 page-key 4. 蜘蛛开始重新抓到这些非空深页 做到这 4 条,就说明“深页资产链”已经重新打通,后面再扩量才有意义。 ### 2026-04-16 试点重建 checklist 下面这份 checklist 用于“先拿 1 个正式域名做小样本试点”,目标是先验证链路,不追求一次铺满。 ### 一、试点前准备 开始前先确认下面 4 件事: 1. 只选 1 个 host,不并行多 host 2. 不改模板 3. 不改路由 4. 不改数据库结构 建议优先试点 host: 1. `lgyz-net` 2. `lcdchq-com` 3. `jpjdxs-com` 原因: 1. 这几个 host 当前都属于典型 default-only 2. 前台路由已经验证过可访问 3. 更适合做“补深页资产后是否立刻生效”的观察 ### 二、样本选择 checklist 每次试点先准备: 1. 10 到 20 个 `videoId` 2. 每个 `videoId` 只选 1 条主线路 3. 每条线路只选 1 个主集数 样本优先级: 1. 首页正在推荐的内容 2. 分类页正在曝光的内容 3. 蜘蛛最近命中的详情/播放 URL 4. 播放线路最稳定的内容 不建议选: 1. 没有稳定播放线路的视频 2. 刚入库、字段不完整的视频 3. 需要复杂 slug 才能访问、当前又不稳定的视频 ### 三、生成 bundle 的建议方式 推荐优先用现有 bootstrap 脚本做单 host 小样本 bundle。 参考命令模板: ```bash php scripts/seo_copy_domain_bootstrap.php <host> \ --detail-id=<videoId> \ --detail-slug=<slug> \ --search-keyword=<keyword> \ --category-parent=<parent> \ --category-child=<child> \ --bundle-root=storage/domain_bootstrap_bundles/<bundle-name> \ --index-root=storage/domain_bootstrap_bundles \ --portal-root=public/_seo_copy_release ``` 说明: 1. 这一步的核心是拿到 bundle 里的真实 `detail/play` page-key JSON 2. 不要求一开始就把 10 到 20 个样本一次性都塞进去 3. 可以先跑通 1 个样本,再扩到 10 个 ### 四、bundle 生成后先做 dry-run 生成 bundle 后,先不要正式应用,先 dry-run。 建议顺序: ```bash php scripts/domain_bootstrap_run.php <bundle-root> --dry-run=1 --format=text ``` 必要时再分步: ```bash php scripts/domain_bootstrap_register.php <bundle-root>/site-register.sample.json --dry-run=1 --format=text php scripts/domain_seo_bootstrap_apply.php <bundle-root>/site-bootstrap.sample.json --dry-run=1 --format=text ``` dry-run 通过后,再决定是否继续。 ### 五、写回 `published` 前的文件检查 在真正回灌前,先确认 bundle/source 里已经出现: 1. `detail/<videoId>.json` 2. `play/<videoId>-play-<line>-<episode>.json` 如果只有: 1. `detail/default.json` 2. `play/default.json` 那说明这次生成仍然没有产出真实深页资产,不能继续写回。 ### 六、回灌方式 如果 bundle/source 中已经有真实深页文件,优先用现成恢复脚本回灌: ```bash php code/scripts/seo_copy_restore_from_source.php \ --host=<host-dir> \ --source=<bundle-or-source-root> \ --dry-run ``` 确认无误后,再正式写入: ```bash php code/scripts/seo_copy_restore_from_source.php \ --host=<host-dir> \ --source=<bundle-or-source-root> ``` 当前版本的这个脚本已经升级为: 1. 不传 `--scenes` 时,自动识别 source 里实际存在的已知场景并回灌 2. 传 `--scenes=...` 时,只恢复指定场景 目前默认支持: 1. `home` 2. `category_index` 3. `category_list` 4. `search` 5. `rank_index` 6. `rank_list` 7. `detail` 8. `forge` 9. `play` 如果只想做最小恢复,仍然可以显式指定: ```bash php code/scripts/seo_copy_restore_from_source.php \ --host=<host-dir> \ --source=<bundle-or-source-root> \ --scenes=detail,play \ --dry-run ``` ### 七、回灌后的文件审计 写回后第一时间跑审计: ```bash php scripts/seo_copy_published_audit.php --host=<host-dir> --format=text ``` 必要时加样本检查: ```bash php scripts/seo_copy_published_audit.php \ --host=<host-dir> \ --sample-detail=<videoId> \ --sample-play=<videoId>:<playType>:<episode> \ --format=text ``` 通过标准: 1. `detail_default_only: no` 2. `play_default_only: no` 3. 指定 sample 的 `expected_page_key` 存在 ### 八、前台命中验证 文件审计通过后,再做前台读取验证。 读回验证: ```bash php scripts/seo_copy_readback.php <host> detail <videoId> --format=text php scripts/seo_copy_readback.php <host> play <videoId> <playType> <episode> --format=text ``` 前台验证: ```bash php scripts/seo_copy_front_verify.php <host> detail <videoId> --base-url=http://127.0.0.1:13205 --format=text php scripts/seo_copy_front_verify.php <host> play <videoId> <playType> <episode> --base-url=http://127.0.0.1:13205 --format=text ``` 通过标准: 1. 详情页命中 `guide-detail` 或等价正文引导块 2. 播放页命中 `guide-play` 或等价正文引导块 3. 不是继续走空白或被抑制状态 ### 九、试点观察窗口 第一次试点完成后,不要立刻扩全量,建议至少观察一个抓取窗口: 1. 先观察数小时到 1 天 2. 看蜘蛛是否回打这批深页 3. 看命中后是否稳定 200 4. 看正文是否真实输出,不再是空深页 ### 十、试点成功后的扩量规则 只有试点成功后,才允许扩量。 扩量时建议: 1. 先从 10 个样本扩大到 30 个 2. 再从 30 个扩大到 100 个 3. 每次扩量后都要重复审计和前台验证 不要直接: 1. 一次生成全站所有 `detail/play` 2. 一次回灌所有 host ### 十一、试点失败时怎么判断原因 如果试点失败,优先按下面顺序排查: 1. bundle/source 是否真的产出非 default `detail/play` 2. `restore_from_source` 是否真的写入 `published` 3. `seo_copy_published_audit` 是否仍显示 default-only 4. `seo_copy_readback` 是否能读到真实 page-key 5. `seo_copy_front_verify` 是否命中了对应前台 URL 只有先把这 5 层排干净,才允许怀疑模板或路由。 ### 2026-04-16 第一试点 host 建议 基于当前仓库与本机回测结果,第一试点 host 建议优先选: 1. `jpjdxs.com` 原因: 1. 当前属于典型 `detail_default_only / play_default_only` 2. 首页和详情页都能稳定打开 3. 已经能从详情页直接抽到真实播放链接 4. 详情 URL 和播放 URL 规则相对清晰,便于做第一批 dry-run 当前已确认的 URL 形态: 1. 详情页:`/neirong-<videoId>-<slug>` 2. 播放页:`/bf-<videoId>-<slug>/<playType>-<episode>` 例如: 1. 详情页:`/neirong-154229-xiang-feng-bu-shi-jiu-shi-ren` 2. 播放页:`/bf-154229-xiang-feng-bu-shi-jiu-shi-ren/douban-1` 同时也已确认: 1. `seo_copy_published` 下不存在 `detail/154229.json` 2. `seo_copy_published` 下不存在 `play/154229-play-douban-1.json` 这正适合作为第一批“从无到有补深页资产”的试点。 ### `jpjdxs.com` 第一批样本候选 当前已从首页与详情页抽到一批真实样本,建议先从下面 8 个详情样本开始: 1. `76342` / `se-jiang-zhi-xue-mei-gui` 2. `76318` / `she-sha-shou` 3. `76347` / `se-jie` 4. `76341` / `se-qing-dian-ying-da-shui-qiang-de-liu-de-wang` 5. `76324` / `shao-nv-de-you-huo` 6. `76346` / `se-gui-tou-tai` 7. `76359` / `san-fen-zhi-yi-qing-ren` 8. `76325` / `shao-nv-de-you-huo` 对应已抽到的播放页候选如下: 1. `76342` - `default-1` - `douban-1` - `youzhi-1` 2. `76318` - `default-1` - `douban-1` - `youzhi-1` 3. `76347` - `default-1` - `douban-1` 4. `76341` - `default-1` - `douban-1` 5. `76324` - `default-1` - `douban-1` 6. `76346` - `default-1` - `douban-1` - `youzhi-1` 7. `76359` - `default-1` - `douban-1` - `youzhi-1` 8. `76325` - `default-1` - `douban-1` ### 第一试点最小建议组合 如果要把风险再压低,建议第一轮不是 8 个全上,而是先从下面 3 个 detail + 3 个 play 开始: 1. `detail/76342` 2. `detail/76318` 3. `detail/76347` 4. `play/76342-play-douban-1` 5. `play/76318-play-douban-1` 6. `play/76347-play-douban-1` 原因: 1. 这 3 个样本都来自首页当前真实曝光内容 2. 详情页与播放页链接都已实测能抽到 3. `douban-1` 在线路上最统一,适合先打通第一轮 ### 当前试点前的已知空缺验证 已直接验证: 1. `jpjdxs.com detail 154229` 当前无对应 `seo_copy_published` 深页文件 2. `jpjdxs.com play 154229 douban 1` 当前无对应 `seo_copy_published` 深页文件 这说明当前环境仍然符合试点前置条件: 1. 深页资产缺失是真实存在的 2. 不是已经生成但前台没命中 ## 2026-04-16 `jpjdxs.com` 第一批深页试点已落地 这段不是计划,是本地已经执行过的结果。 ### 本次选择的最小样本 详情页: 1. `76318` 2. `76342` 3. `76347` 播放页: 1. `76318-play-douban-1` 2. `76342-play-douban-1` 3. `76347-play-douban-1` ### 已执行动作 1. 用 `seo_copy_domain_bootstrap.php` 分别为这 3 个样本生成 bundle 2. 从 bundle 中抽出真实 `detail/play` page-key JSON 3. 先在临时目录做了 `seo_copy_batch_import.php` 闭环验证 4. 再把这 6 个深页 JSON 回灌到真实: - `code/data/seo_copy_published/jpjdxs-com/detail/` - `code/data/seo_copy_published/jpjdxs-com/play/` ### 当前结果 当前 `jpjdxs-com` 已从原来的深页接近 `default-only`,变成: 1. `detail` 目录: - `default.json` - `76318.json` - `76342.json` - `76347.json` 2. `play` 目录: - `default.json` - `76318-play-douban-1.json` - `76342-play-douban-1.json` - `76347-play-douban-1.json` ### 审计结果 重新跑 `seo_copy_published_audit.php` 后已确认: 1. `detail_default_only: no` 2. `play_default_only: no` 3. `detail non_default_count: 3` 4. `play non_default_count: 3` 也就是说: 1. 第一批深页资产链已经重新打通 2. 当前不是停留在“理论上可恢复” 3. 而是 `jpjdxs.com` 已经具备最小规模的真实深页 page-key 资产 ## 2026-04-16 再确认:当前仓库里的“生成能力”和“导入能力”边界 这段是给后续所有接手的 Codex 看的,避免再把问题判断错方向。 ### 1. `SeoCopyAiProviderHelper` 这条通用链,只会发布固定槽位 已再次核对: - `code/app/common/helper/SeoCopyAiProviderHelper.php` - `code/app/common/helper/SeoCopyGenerationHelper.php` 当前通用发布链固定只处理: 1. `home/index` 2. `category_index/index` 3. `category_list/default` 4. `search/landing` 5. `detail/default` 6. `play/default` 也就是说: 1. 它不会自动产出 `detail/<videoId>.json` 2. 它不会自动产出 `play/<videoId>-play-<line>-<episode>.json` 3. 所以某个 host 就算“通用 AI 发布成功”,深页也仍然可能是 `default-only` 这一点非常重要,后面不要再把“通用发布成功”误判成“深页差异化一定已经恢复”。 ### 2. 真正的深页差异化资产,来自 bootstrap 深页链 已再次核对: - `code/scripts/seo_copy_domain_bootstrap.php` 这条链会直接生成真实 page-key: 1. `detail/<videoId>.json` 2. `forge/<videoId>-forge-<n>.json` 3. `play/<videoId>-play-<line>-<episode>.json` 因此: 1. 你之前记得的那批 GPT 模板详情引导文、播放引导文、差异化块 2. 本质上更接近 bootstrap 深页资产链的结果 3. 不是后台那条“固定 6 槽位”通用发布链的自然产物 ### 2.1 2026-04-17 再确认:旧 `restore_from_source` 的缺口已经补上 这轮继续排查 `jpjdxs.com` 后,已经进一步确认: 1. 有些 host 不是“source 没有资产” 2. 而是“source 里有更多场景,但旧恢复脚本只写回了 `detail/play`” 以本机这次实际找到的 source 为例: - `code/storage/domain_bootstrap_bundles/jpjdxs-seed-a1/data/seo_copy/jpjdxs-com` 里面实际存在: 1. `home/index.json` 2. `category_index/dian-ying.json` 3. `category_list/dian-ying--shao-shi-dian-ying.json` 4. `search/h-2d9bf00ea1f2e5ee.json` 5. `rank_index/index.json` 6. `rank_list/daily.json` 7. `detail/76342.json` 8. `forge/76342-forge-1.json` 9. `play/76342-play-douban-1.json` 但旧版 `code/scripts/seo_copy_restore_from_source.php` 只会扫: 1. `detail` 2. `play` 所以会出现一种很容易把人带偏的现象: 1. bundle/source 里明明有榜单、forge、分类、搜索资产 2. 执行恢复后却只有 `detail/play` 被补进 `published` 3. 前台就会表现成“有些引导文回来了,有些还是像没恢复” 这轮已经把: - `code/scripts/seo_copy_restore_from_source.php` 升级成“按 source 中实际存在场景自动回灌”的版本,默认支持: 1. `home` 2. `category_index` 3. `category_list` 4. `search` 5. `rank_index` 6. `rank_list` 7. `detail` 8. `forge` 9. `play` 并且已在本机对 `jpjdxs-com` 做过 dry-run 与正式写回验证: ```bash php code/scripts/seo_copy_restore_from_source.php \ --host=jpjdxs-com \ --source=code/storage/domain_bootstrap_bundles/jpjdxs-seed-a1/data/seo_copy \ --dry-run php code/scripts/seo_copy_restore_from_source.php \ --host=jpjdxs-com \ --source=code/storage/domain_bootstrap_bundles/jpjdxs-seed-a1/data/seo_copy ``` 写回后重新审计,已经新增恢复出: 1. `category_index/dian-ying.json` 2. `category_list/dian-ying--shao-shi-dian-ying.json` 3. `search/h-2d9bf00ea1f2e5ee.json` 4. `rank_index/index.json` 5. `rank_list/daily.json` 6. `forge/76342-forge-1.json` 同时前台闭环验证已经通过: ```bash php code/scripts/seo_copy_front_verify.php jpjdxs.com rank_index --target-root=code/data/seo_copy_published --base-url=https://jpjdxs.com --format=text php code/scripts/seo_copy_front_verify.php jpjdxs.com rank_list daily --target-root=code/data/seo_copy_published --base-url=https://jpjdxs.com --format=text php code/scripts/seo_copy_front_verify.php jpjdxs.com forge 76342 1 --target-root=code/data/seo_copy_published --base-url=https://jpjdxs.com --format=text ``` 结果都已经: 1. `status: 200` 2. `all_matched: yes` 这条结论以后非常重要: 1. 如果 `source` 里有 `rank_index / rank_list / forge / category / search` 2. 但 `published` 里只有 `detail / play` 优先先查: 1. 当前机器上的 `seo_copy_restore_from_source.php` 是否已经是“全场景版本” 2. 之前是不是只跑过旧脚本或 `--scenes=detail,play` 不要再直接误判成: 1. 这些资产从来没生成过 2. bundle/source 已经失效 3. 之前做好的差异化已经全部被删光 ### 3. 系统并不是“不能导入深页文件”,而是“缺少深页源文件” 已再次核对: - `code/scripts/seo_copy_batch_import.php` - `code/app/common/helper/SeoCopyBatchImportHelper.php` 当前导入器支持的目录结构就是: 1. `<source-dir>/<host-dir>/<scene>/<page_key>.json` 这意味着: 1. 它支持导入任意 `detail/<videoId>.json` 2. 它支持导入任意 `play/<videoId>-play-<line>-<episode>.json` 3. 当前真正缺的不是导入能力 4. 当前真正缺的是: - 历史深页源文件 - 或新生成出来的深页源文件 ### 4. 以后再排查“引导文没了”,统一按这个顺序 1. 先看模板层是不是挂载还在 2. 再看运行时是不是被 suppress / fallback 卡住 3. 再看 `seo_copy_published/<host>/detail` 和 `play` 是否只剩 `default.json` 4. 再看 `storage/domain_bootstrap_bundles` / `storage/seo_copy_publish_logs` / `storage/seo_copy_release_runs` 里有没有历史深页成品 5. 确认历史成品确实不存在后,才进入“小批量 bootstrap 深页重建” ## 2026-04-16 深夜补充:不是“模板又没了”,而是 `runtime/home/temp` 权限污染 这次线上又出现了一次很容易误判的现象,必须单独记下来。 ### 1. 现象 当时看到的是: 1. 首页 `title/keywords/description` 正常 2. 详情页大多正常 3. 播放页有时正常,有时直接变成 ThinkPHP 错误页 4. 从体感上很像: - 之前做好的 GPT 模板引导文又没了 - 页面又像被 git 覆盖回旧状态 - SEO 头信息像“忽然空掉” ### 2. 实际根因 实测抓到的不是模板逻辑丢失,而是: - `code/runtime/home/temp` 里混进了一批 `root:root` 的编译模板文件 - 实际 PHP-FPM 进程是 `www` 用户 - 所以当 ThinkPHP 需要重写这些模板缓存时,会报: - `file_put_contents(...runtime/home/temp/...php): Failed to open stream: Permission denied` ### 3. 为什么它会表现得像“优化被覆盖了” 因为这个问题不是“所有页面一起死”,而是: 1. 已经命中旧缓存的页面,可能还能正常显示 2. 需要重新编译模板的页面,会直接报错 3. 于是现场看起来就像: - 一部分 GPT 引导文还在 - 一部分页面像恢复成旧样子 - 一部分页面干脆系统错误 所以这种现象不能第一时间认定成: 1. git 又把模板覆盖了 2. SEO key 又丢了 3. 数据库把引导文清空了 ### 4. 这次实际处理方式 已在正式排查中确认: 1. `php-fpm` 运行用户是 `www` 2. `runtime/home/temp` 中存在多份 `root root` 文件 3. 将 `runtime/home` 下属主纠正回 `www:www` 后 4. 再复测: - 详情页恢复正常 - 播放页恢复正常 - `guide-detail` / `guide-play` 正常输出 - `canonical` / `og:url` / JSON-LD `url` 恢复到正确页面 ### 5. 后续所有 Codex 统一排查顺序 以后再遇到“GPT 模板像突然失忆”时,统一先做这 4 步: 1. 先抓线上实际 HTML,不要只凭浏览器体感判断 2. 看是不是 ThinkPHP 错误页,尤其关注 `runtime/home/temp` 写入失败 3. 检查 `runtime/home/temp` 是否混入 `root:root` 4. 只有确认运行时缓存正常后,才继续判断是不是模板 / SEO copy / git 历史问题 ## 2026-04-17 凌晨补充:搜索页串页不是模板错,是前端缓存 key 漏了 query string 这也是一个很容易把人带偏的问题,必须单列。 ### 1. 实测现象 同一时间分别抓: 1. `/get-index?keyword=爱情` 2. `/get-index?keyword=动作` 结果两次返回: 1. `x-cache-status: HIT` 2. HTML 里的 `title` 3. `canonical` 4. `og:url` 全部都是“爱情”那一页的内容。 也就是说: 1. 不同关键词请求 2. 命中了同一份前端缓存 3. 不是后端模板在实时生成对应 query 的页面 ### 2. 结论 这说明当前前端缓存层对搜索页的 cache key 存在高概率配置问题: 1. cache key 没有带上 query string 2. 或搜索页请求被错误归入“只按 URI 缓存”的 location 它会直接造成: 1. 搜索页串页 2. `canonical` / `og:url` / `title` 与真实 query 不一致 3. SEO 表现看起来像“模板或 SEO 数据随机失效” ### 3. 这类问题的判定规则 以后凡是看到: 1. 搜索页关键词 A 打开后像关键词 B 2. `canonical` 看着像随机错乱 3. 源码明明已经修对,但线上输出不稳定 优先先看: 1. 响应头里的 `x-cache-status` 2. 前端缓存 key 是否包含 query string 不要第一时间误判为: 1. 模板回滚 2. seo_copy 丢失 3. 数据库内容被覆盖 ### 4. 当前前端 nginx 模板里的直接根因 已对照当前仓库内的前端配置模板: - [站点伪静态.txt](/www/wwwroot/diff-maccms/前端站群服务器nginx配置/站点伪静态.txt) 问题点在于动态页缓存 key 原来是: ```nginx proxy_cache_key "$scheme$request_method$host$uri"; ``` 这意味着: 1. `/get-index?keyword=爱情` 2. `/get-index?keyword=动作` 会共用同一个缓存 key,因为它们的 `uri` 都只是 `/get-index`。 ### 5. 最小修复方案 动态页缓存 key 至少改成: ```nginx proxy_cache_key "$scheme$request_method$host$uri$is_args$args"; ``` 这样: 1. 不同 query string 会拆分缓存 2. 搜索页不会再互相串页 3. `canonical` / `og:url` / `title` 不会再被别的关键词页面污染 ### 6. 推荐同步修复范围 不要只改搜索页单点 location。 当前建议直接同步到: 1. `location /` 2. `location ~* \.(html|htm)$` 原因是: 1. 搜索页当前命中的是 `location /` 2. 但以后如果某些动态页走 `.html` 风格并带 query,也会遇到同类问题 ### 7. 上线后复测方法 改完 nginx 并清缓存后,用两组不同关键词直接抓响应头和 HTML: ```bash curl -s -D - 'https://你的域名/get-index?keyword=爱情' -o /tmp/a.html curl -s -D - 'https://你的域名/get-index?keyword=动作' -o /tmp/b.html rg '<title>|canonical|og:url' /tmp/a.html rg '<title>|canonical|og:url' /tmp/b.html ``` 通过标准: 1. 两个页面的 `title` 不同 2. `canonical` 分别指向各自关键词 3. `og:url` 分别指向各自关键词 4. 不再出现“动作词页返回爱情 HTML”的现象 ## 2026-04-17 继续补充:`chuanjiafeng-net` 已完成一轮多场景恢复 这条是本机继续排查后的新增结论,目的是把“哪些 host 还需要修、哪些已经可以当样板”区分清楚。 ### 1. 先看 source / published 差额 本机对比后确认: 1. `code/storage/domain_bootstrap_bundles/chuanjiafeng-compact/data/seo_copy/chuanjiafeng-net` 2. `code/data/seo_copy_published/chuanjiafeng-net` 之间之前确实存在明显差额。 最典型的是: 1. `category_index`:source 远多于 published 2. `category_list`:source 远多于 published 3. `search`:source 远多于 published 4. `rank_list`:source 有 `daily / weekly / monthly / total`,published 原先只有 `daily` 5. `forge`:source 比 published 多出多批真实 page-key 也就是说,`chuanjiafeng-net` 在这台机器上虽然已经不是“default-only”,但之前仍属于“只恢复了一部分”的状态。 ### 2. 本轮采用的恢复策略 为了避免把首页已有主文案冲掉,这轮没有恢复 `home`,只恢复下面这些场景: ```bash php code/scripts/seo_copy_restore_from_source.php \ --host=chuanjiafeng-net \ --source=code/storage/domain_bootstrap_bundles/chuanjiafeng-compact/data/seo_copy \ --scenes=category_index,category_list,search,rank_index,rank_list,detail,forge,play \ --dry-run php code/scripts/seo_copy_restore_from_source.php \ --host=chuanjiafeng-net \ --source=code/storage/domain_bootstrap_bundles/chuanjiafeng-compact/data/seo_copy \ --scenes=category_index,category_list,search,rank_index,rank_list,detail,forge,play ``` 这个策略的好处是: 1. 保住首页现成资产 2. 只补短板场景 3. 恢复面又足够大 ### 3. 恢复后的审计结果 恢复后重新审计: ```bash php code/scripts/seo_copy_published_audit.php --host=chuanjiafeng-net --format=text ``` 关键结果已经变成: 1. `category_index: total=6, non_default=6` 2. `category_list: total=32, non_default=31` 3. `search: total=16, non_default=16` 4. `rank_index: total=1, non_default=1` 5. `rank_list: total=4, non_default=4` 6. `detail: total=17, non_default=16` 7. `forge: total=16, non_default=16` 8. `play: total=17, non_default=16` 说明这轮恢复后,`chuanjiafeng-net` 已经不是“局部样本恢复”,而是多场景资产都补齐了一大截。 ### 4. 前台验证结果 这轮不是只看文件数量,还做了前台验证: ```bash php code/scripts/seo_copy_front_verify.php chuanjiafeng.net rank_list weekly --target-root=code/data/seo_copy_published --base-url=https://chuanjiafeng.net --format=text php code/scripts/seo_copy_front_verify.php chuanjiafeng.net category_list dian-ying dong-zuo-pian --target-root=code/data/seo_copy_published --base-url=https://chuanjiafeng.net --format=text ``` 结果都已经: 1. `status: 200` 2. `all_matched: yes` 其中已确认命中的新增场景包括: 1. `rank_list/weekly` 2. `category_list/dian-ying--dong-zuo-pian` 这说明 `chuanjiafeng-net` 这轮新增恢复出来的: 1. 非日榜周期页 2. 细分类列表页 都已经被前台真实读到,不是只停留在离线文件层。 ### 5. 后续判断结论 从现在开始,`chuanjiafeng-net` 在这台机器上应视为: 1. 已恢复成功的多场景样板 host 2. 不是当前优先抢修对象 后续如果还要继续扩它,优先考虑: 1. 补更多 `home` 变体 2. 补更大规模的 `detail / play / forge` 样本 但在“先救火、先补漏恢复 host”这个优先级里,`chuanjiafeng-net` 已经可以后移。 ## 2026-04-17 继续补充:`liangzuan.net` 当前更像“前台部署/回源未命中 GPT 路由”,不是文案文件丢失 这条结论很重要,避免后面把“前台 404”误判成“SEO 文案又没了”。 ### 1. 本机已确认 `liangzuan-net` 的发布文件仍然存在 当前本机发布层里,下面这些文件都还在: 1. `code/data/seo_copy_published/liangzuan-net/home/index.json` 2. `code/data/seo_copy_published/liangzuan-net/category_index/dian-ying.json` 3. `code/data/seo_copy_published/liangzuan-net/category_list/dian-ying--xi-ju-pian.json` 4. `code/data/seo_copy_published/liangzuan-net/search/h-c37e405008e4e8c5.json` 5. `code/data/seo_copy_published/liangzuan-net/rank_index/index.json` 6. `code/data/seo_copy_published/liangzuan-net/rank_list/daily.json` 7. `code/data/seo_copy_published/liangzuan-net/detail/154124.json` 8. `code/data/seo_copy_published/liangzuan-net/forge/154124-forge-1.json` 9. `code/data/seo_copy_published/liangzuan-net/play/154124-play-youzhi-1.json` 而且文件内容不是空壳,已经确认存在真实引导文,例如: 1. `rank_list/daily` 有榜单导语与引导卡片 2. `category_list/dian-ying--xi-ju-pian` 有分类导语 3. `search/h-c37e405008e4e8c5` 对应关键词“圣诞不独行” 4. `detail/154124` 与 `play/154124-play-youzhi-1` 都有正文引导 所以这一轮不能再把 `liangzuan.net` 判成“发布文件被删了”。 ### 2. 当前主题缓存里的 GPT 路由族已经能确定 `code/storage/theme_cache/liangzuan.net.json` 当前记录的 `url_family` 为: 1. 详情页:`film/{strPinyin}/{intVId}` 2. 伪详情页:`film/{strPinyin}/{intVId}-{intVForgeId}` 3. 播放页:`player/{intVId}-{strPlayType}-{intPlayIndex}` 4. 一级分类:`leixing/{strParentCategory}/home` 5. 二级分类:`leixing-{strParentCategory}/{strCategory}/page{intPage}` 6. 榜单首页:`phb/all` 7. 榜单列表:`phb/{strSortType}/home` 8. 搜索:`get/index` 9. 历史:`record/index` 按这套路由推导,理论访问地址应类似: 1. `https://www.liangzuan.net/phb/daily/home` 2. `https://www.liangzuan.net/leixing-dian-ying/xi-ju-pian/page1` 3. `https://www.liangzuan.net/get/index?keyword=圣诞不独行` 4. `https://www.liangzuan.net/film/sheng-dan-bu-du-xing-meng-fei-si-lian-qu/154124` 5. `https://www.liangzuan.net/player/154124-youzhi-1` ### 3. 当前外部访问结果不是“页面文案缺失”,而是整页直接回 nginx 404 实测以上路径时,当前线上直接返回: 1. `HTTP/2 404` 2. `server: nginx` 3. `content-length: 2616` 4. 固定静态错误页特征一致 这说明当前症状更像: 1. 域名没有回源到这套应用 2. 或前台 nginx / 站点发布目录没有接这组 GPT 路由 3. 或线上跑的仍是另一套路由族 总之,**不是单纯 seo_copy 文件缺失导致的 404**。 ### 4. 历史验收记录说明这个站点的路由族曾经发生过切换 本机历史运行记录里至少存在两种路径形态: 1. 2026-04-06 早期记录里,成功路径是: - `https://www.liangzuan.net/detail/pinyin-sheng-dan-bu-du-xing-meng-fei-si-lian-qu` - `https://www.liangzuan.net/detail/pinyin-sheng-dan-bu-du-xing-meng-fei-si-lian-qu/1` 2. 2026-04-08 后期记录里,成功路径变成: - `https://www.liangzuan.net/film/sheng-dan-bu-du-xing-meng-fei-si-lian-qu/154124` - `https://www.liangzuan.net/film/sheng-dan-bu-du-xing-meng-fei-si-lian-qu/154124-1` 这说明: 1. `liangzuan.net` 不是一直固定在单一路由族 2. 历史上至少发生过一次从 `detail/...` 向 `film/...` 的切换 3. 如果线上站点还停在旧路由,或 DNS/回源指到了旧发布目录,就会出现“本地文件正常、外部全 404” ### 5. 当前最合理的判断 对 `liangzuan.net`,现阶段更合理的结论是: 1. 本地 SEO 文案文件仍在 2. 主题缓存里也有当前期望的 GPT 路由定义 3. 但线上域名访问没有命中这套路由 4. 因此当前问题优先看前台部署 / nginx / 回源 / 实际运行版本 5. 不要再优先怀疑“seo_copy 又被删了” ### 6. 后续排查顺序建议 如果后面要继续接手 `liangzuan.net`,建议按这个顺序: 1. 先确认线上域名当前真正回源到哪个项目目录 2. 再确认前台 nginx 是否把 `/film`、`/player`、`/phb`、`/leixing`、`/get/index` 这组路径交给后端 3. 再确认线上实际 `theme_cache` / 运行缓存是否还是 `A043` 4. 如果线上仍在旧路由族,再决定是: - 回切旧路由兼容 - 还是统一切到新路由族 在这几步没确认前,不建议继续对 `liangzuan-net` 做大规模文案重建,因为大概率修的不是根因。 ## 2026-04-17 继续补充:`detail/play` 引导文退化的一个明确根因已经定位 这条结论直接对应“前面做好的引导文和排版怎么像没了一样”。 ### 1. 模板骨架本身没有整体丢失 本轮继续核对 `videoGpt1` 模板历史后,已经确认: 1. 首页导览、`guide-collection` 2. 详情页 `dm-desc-guide` 3. 播放页 `guide-play` 这些核心区块目前代码里都还在。 例如当前文件里仍然能看到: 1. `code/app/home/view/videoGpt1/module/seo_copy/collection.html` 2. `code/app/home/view/videoGpt1/module/seo_copy/detail.html` 3. `code/app/home/view/videoGpt1/module/seo_copy/play.html` 4. `code/app/home/view/videoGpt1/module/detail_main/desc.html` 而且 `detail_main/desc.html` 与 `2a905bbf restore gpt seo copy pipeline and stabilize seo tkd output` 这次提交相比,主体结构并没有被后续提交删掉。 所以: 1. 不是“整套引导区块被模板回滚掉了” 2. 更像是“模板还在,但喂进去的数据退回了通用 fallback” ### 2. 明确的代码拐点发生在 `56644e7f` 这次提交: `56644e7f fix(videoGpt1): normalize seo pages and fallback services` 在 `code/app/services/VideoService.php` 里加入了一段新逻辑: 1. 对 `detail` 2. 对 `play` 如果当前 host 只有: 1. `default.json` 2. 没有对应 `video_id` / `play_key` 的细粒度 JSON 那就: 1. 不再读取 `default.json` 2. 直接返回空数组 3. 后续走 `SeoCopyFallbackBuilder::build(...)` 这会带来一个非常直接的结果: 1. 模板区块还在 2. 但不再读 host 自己的默认引导文案 3. 而是统一退回通用 fallback 句式 页面体感上就会像: 1. “前面做好的细腻引导文没了” 2. “页面又变成一坨通用说明” ### 3. 这个 suppress 逻辑影响面不小 本机已确认有一批 host 当前 `detail/play` 都只有 `default.json`,例如: 1. `lcdchq-com` 2. `lgyz-net` 3. `oronorent-com` 4. `sdxhtgcl-com` 5. `gz-yxsw-com` 6. `jpjdxs-com` 7. 以及其它多批 host 也就是说,一旦这段 suppress 逻辑开启,这些 host 的详情页与播放页就会: 1. 放弃本域名已有的 `default.json` 2. 强制退回 fallback ### 4. `default.json` 本身并不差,反而通常比 fallback 更像“之前做好的内容” 本轮直接抽查了几个 host 的默认文案,例如: 1. `code/data/seo_copy_published/jpjdxs-com/detail/default.json` 2. `code/data/seo_copy_published/jpjdxs-com/play/default.json` 3. `code/data/seo_copy_published/lcdchq-com/detail/default.json` 4. `code/data/seo_copy_published/lcdchq-com/play/default.json` 确认这些 `default.json` 里本来就包含: 1. `detail_body_lead` 2. `detail_play_link_lead` 3. `play_intro` 4. `play_body_lead` 5. `guide_cards` 并且还是带占位符插值的版本,比如: 1. `{video_name}` 2. `{video_alias}` 3. `{year}` 4. `{play_line}` 这类内容在渲染后,明显比通用 fallback 更接近“前面已经做好的可读引导”。 ### 5. 本轮已经做的修复 当前已经把这段 suppress 逻辑撤掉,恢复为: 1. 详情页、播放页仍然优先读 `seo_copy` 发布文件 2. 即使只有 `default.json`,也允许先使用 `default.json` 3. 只有完全读不到可用数据时,才退回 `SeoCopyFallbackBuilder` 这次修复文件: 1. `code/app/services/VideoService.php` 修复后逻辑重新回到更符合直觉的顺序: 1. 优先细粒度 page-key 2. 其次 host 自己的 `default.json` 3. 最后才是通用 fallback 另外,本轮继续往下排查后又确认了一层: 1. 有些 host 虽然存在细粒度 `detail/play` page-key 文件 2. 但这些具体文件本身是旧低配格式 3. 它们没有 `title_template / keywords_template / description_template / guide_cards` 4. 同时文案主体比 `default.json` 更通用 典型样本: 1. `jpjdxs-com/detail/76342.json` 2. `jpjdxs-com/play/76342-play-douban-1.json` 这类文件会继续压住 `default.json`,导致页面仍然表现得像“引导文退化”。 所以这轮又补了一层兼容: 1. 如果 `detail/play` 命中的具体 page-key 文件属于旧低配格式 2. 则自动合并 `default.json` 里的 richer 字段 3. 重点补入: - `guide_cards` - `title_template` - `keywords_template` - `description_template` - `detail_body_lead / detail_play_link_lead / detail_body_tail / detail_faq` - `play_intro / play_meta_note / play_body_lead / play_body_next` 这样可以尽量保留具体 page-key 已有的主题信息,同时恢复默认版更成熟的引导结构。 ### 5.1 这一层兼容的实测现象 当前前台实测已经出现分层结果: 1. `jpjdxs.com` 播放页真实页面已出现: - `当前为色降2之血玫瑰播放页` - `如果你已在详情页确认...` - `播放前建议...` - `先看线路` 2. 同站详情页暂时仍显示旧通用句式 这更像: 1. 代码逻辑已经生效 2. 但详情页前台仍可能被页面缓存 / 反向代理缓存顶住 后续如果继续验证,不要只看一轮 curl,就直接下结论说“修复无效”,要先区分: 1. 代码逻辑未生效 2. 还是前台缓存未刷新 ### 5.2 2026-04-17 本轮抽样后的三类状态清单 为了避免后面继续把“代码问题 / 缓存问题 / 部署问题”混在一起,这里先把本轮真实抽样结果按三类归档。 #### A 类:前台已经明确恢复,可视为“代码修复已落地” 这类站点的共性是: 1. 首页 `title/keywords/description` 正常 2. 真实详情页 / 播放页至少有一页已经命中更丰富的引导文 3. 不再只是通用 fallback 话术 已确认样本: 1. `lcdchq.com` - 详情页:`/movie/76328-shan-zhong-yan-tan` - 播放页:`/kan/shan-zhong-yan-tan-76328/douban-1` - 前台已出现: - `本页为山中艳谭的资料详情页...` - `先核对资料` - `当前页面为山中艳谭的播放页...` - `播放前建议...` 2. `oronorent.com` - 详情页:`/shipin/76347-se-jie` - 播放页:`/m3u8/se-jie-76347/youzhi-1` - 前台已出现: - `本页汇总...` - `先核对资料` - `如果你已经确认是目标内容` - `先选线路` - `当前为...` - `若你已从详情页确认目标内容` 3. `lgyz.net` - 详情页:`/movie/76332-shang-di-zhi-guo` - 详情页前台已出现: - `先核对资料` - 说明详情页方向已对,文案修复至少已在详情页落地 4. `jpjdxs.com` - 详情页:`/neirong-76342-se-jiang-zhi-xue-mei-gui` - 播放页:`/bf-76342-se-jiang-zhi-xue-mei-gui/default-1` - 2026-04-17 在前端清缓存后再次复测,详情页正文已出现: - `本页为色降2之血玫瑰的详情资料页...` - `如果你已确认片名与资料信息...` - `先核对资料` - 播放页仍正常输出: - `当前为色降2之血玫瑰播放页...` - `播放前建议...` - 说明这站最终不是代码回退,而是前端整页缓存顶住旧 HTML,清缓存后已恢复 #### B 类:代码逻辑大概率已生效,但前台可能仍受缓存影响 这类站点的共性是: 1. 本地 `seo_copy_published` 已有更丰富默认文案 2. 本地逻辑验证已确认 richer 字段可以被合并出来 3. 前台某一类页面已恢复,但另一类页面仍停留在旧通用句式 已确认样本: 1. 当前暂无新的稳定 B 类样本。 - `jpjdxs.com` 原先属于这一类 - 但 2026-04-17 在前端清缓存并切换新版 nginx 动态页缓存策略后,已转入 A 类 - 这次案例可作为“代码没问题,只是前端缓存顶着旧 HTML”的标准样本 当前更合理的判断是: 1. 若再次出现 B 类问题,优先先看前端整页缓存 2. 老配置里动态页 cache key 若只按 path 或只按 URI,极容易把旧 HTML 顶很久 3. 加 query 参数不一定能绕过缓存,要结合当前 nginx 的 `proxy_cache_key` 判断 #### C 类:本地文案完整,但线上细页路径/部署仍需单独确认 这类站点的共性是: 1. 本地发布文件存在 2. 但外部访问时,用当前猜测路径会直接 404 3. 更像线上真实路由族、nginx 回源或部署目录与本机认知不完全一致 已确认样本: 1. `chuanjiafeng.net` - 本地文件: - `detail/154229.json` - `play/154229-play-douban-1.json` - 内容完整 - 2026-04-17 追加抽样: - 根站首页可正常打开 - 已出现 `首页导览` - 已出现 `guide-collection` - 详情页真实路由已确认是: - `/film/154229-xiang-feng-bu-shi-jiu-shi-ren` - 播放页真实路由已确认是: - `/player/xiang-feng-bu-shi-jiu-shi-ren-154229/douban-1` - `/player/xiang-feng-bu-shi-jiu-shi-ren-154229/youzhi-1` - 详情页前台已出现: - `本页整理《相逢不识旧时人》的剧情主线与基础资料...` - `如果你已经确认作品,可继续查看播放线路页...` - `先看剧情主线` - `核对基础资料` - `再进播放页` - 说明该站不是模板失效,也不是 seo_copy 丢失,而是前面人工猜的细页路径错误 2. `liangzuan.net` - 前面已单独确认: - 线上外部路径直接回 nginx `404` - 2026-04-17 追加抽样: - 直接访问 `https://liangzuan.net` 时,证书校验失败 - 使用 `curl -k` 忽略证书后,根站返回 `404` - `curl -k -I https://liangzuan.net/favicon.ico` 同样返回 `404` - 说明当前不是“只有深页坏了”,而是域名入口本身没有正确落到站点内容 - 本地 `theme_cache/liangzuan.net.json` 存在,但当前未看到可用 `route_paths` - 本地 `seo_copy_published/liangzuan-net/` 当前只有 `home/index.json` - `detail/default.json` 与 `play/default.json` 均不存在 - 当前应优先判断: - 域名证书与站点入口配置异常 - 这域名当前也不像是已完成完整 seo_copy 回灌的站点 - 不是“模板突然丢了”,而是“入口未接通 + 内容资产未完整” 2. `liangzuan.net` - 前面已单独确认: - 本地 SEO 文案文件仍在 - 主题缓存里也有 GPT 路由定义 - 但线上外部路径直接回 nginx `404` - 更像部署 / 回源未命中 GPT 路由 - 2026-04-17 追加抽样: - 直接访问 `https://liangzuan.net` 时,证书校验失败 - 使用 `curl -k` 忽略证书后,根站返回 `404` - 当前应优先判断: - 域名证书与站点入口配置异常 - 不是 seo_copy 或 GPT 模板正文层的问题 3. `lgyz.net` - 详情页已可直测 - 但本轮手工猜的播放路径 `/bf-76332-shang-di-zhi-guo/youzhi-1` 返回 `404` - 需要继续按真实播放路由再确认,不宜直接判成文案问题 ### 5.3 当前阶段的工作重点建议 到这一步,后续排查优先级应改成: 1. 先用 A 类站点继续验证“default / legacy merge”是否稳定 2. 再对 B 类站点重点清缓存、复测详情页 3. 对 C 类站点先排真实路由 / nginx / 回源,不要急着重写 seo_copy 数据 ### 5.4 2026-04-17 前端 nginx 动态页安全缓存方案已验证生效 这轮已经把前端 nginx 新规则真实上线验证通过,当前建议作为长期标准方案使用。 #### 当前建议规则 1. 搜索页 `/get-index` - `cache key` 带 `$args` 2. 详情页 / 播放页 / 分类页 / 榜单页 - `cache key` 不带 `$args` 3. 所有动态页支持 `?__nocache=1` - 仅用于人工排障 4. 所有动态页返回调试响应头 - `X-Cache-Status` - `X-Cache-Mode` - `X-Cache-Bypass` 5. 受管蜘蛛版继续保留 - `X-Managed-Spider` #### 线上已验证现象 以 `jpjdxs.com` 为样本,2026-04-17 再次验证: 1. 详情页普通访问: - `X-Cache-Status: STALE` - `X-Cache-Mode: path-only` - `X-Cache-Bypass: 0` - `X-Managed-Spider: normal` 2. 搜索页: - `X-Cache-Status: MISS` - `X-Cache-Mode: with-args` 3. 详情页加 `?__nocache=1`: - `X-Cache-Status: BYPASS` - `X-Cache-Mode: bypass` - `X-Cache-Bypass: 1` #### 对后续 Codex 的直接结论 1. 如果前端响应头里已经有: - `X-Cache-Mode` - `X-Cache-Bypass` - `X-Managed-Spider` 说明新版伪静态已经生效 2. 如果页面内容看起来像旧版,但 `?__nocache=1` 正常 - 优先判断为前端缓存问题 - 不要先判断成 git 覆盖或后端模板回退 3. 当前最优模板文件是: - `前端站群服务器nginx配置/站点伪静态-受管蜘蛛放行版-动态页安全缓存.txt` ### 5.5 2026-04-17 晚间补充:国内蜘蛛有效窗口结论 这轮继续看蜘蛛日志时,发现: 1. `latest/spider-crawl.summary.json` 当前更像最新一轮 `ingest` 基础摘要 2. 它没有展开成适合直接看趋势的聚合视角 3. 所以 latest 看起来像“空壳”,不等于国内蜘蛛完全停抓 #### 手工筛选后的国内蜘蛛窗口 从最近约 180 个 `crawl-logs.summary.json` 中,只筛: - `baiduspider` - `sogou` - `bytespider` 重新轻量聚合后,当前累计大致为: 1. 页面类型: - `home`:`144` - `other`:`96` - `robots`:`87` - `detail`:`37` - `category`:`34` - `play`:`27` 2. 状态码: - `403`:`149` - `301`:`117` - `200`:`113` - `444`:`30` - `404`:`16` #### 当前最重要的更新判断 1. 国内蜘蛛最近窗口里,`detail/play` 并没有消失 2. `baiduspider` 深页修复方向仍成立,而且继续出现新的 `301 -> 200 MISS -> 200 HIT` 样本 3. `sogou` 深页当前仍大量是 `403` 4. 所以下一阶段不要把“百度恢复”和“搜狗恢复”混为一谈 #### 最近确认到的百度正向样本 1. `www.codohealth.com` - `/voddetail/gu-chuan-jin-zhen-qian-jin-jing-shi-feng-jian-lao-zu-zong-73272` - `200 HIT` 2. `www.codohealth.com` - `/voddetail/xing-qiu-da-zhan-hei-shi-chuan-shuo-78631` - `301 -> 200 MISS -> 200 HIT` 3. `sjzyunyang.com` - `/video-detail/jia-zheng-fu-san-tian-yuan-60513` - `301 -> 200 MISS -> 200 HIT` 4. `gxhongzhuang.com` - `/voddetail/xi-xue-gui-ji-nv-184448` - `301 -> 200 MISS -> 200 HIT` 5. `jingxifa.com` - `/video-detail/xing-jian-fu-guo-ji-di-wu-ji-107484` - `301 -> 200 MISS -> 200 HIT` 6. `jingxifa.com` - `/video-bofang/hei-yi-nv-ren-de-xiang-shui-183894-default-1` - `301 -> 200 MISS -> 200 HIT` 7. `sjzyunyang.com` - `/video-bofang/wu-lu-ke-tao-185896-default-1` - `301 -> 200 MISS -> 200 HIT` #### 当前新增阻塞点 最近窗口里持续能看到: 1. `www.lgyz.net /vodplay/...` 2. `www.vikau.com /vodplay/...` 3. `www.vikau.com /voddetail/...` 4. `www.jingxifa.com /video-detail/...` 5. `www.jingxifa.com /video-bofang/...` 这些 `sogou` 深页当前大多表现为: - `403` - `cache_status = NONE` 因此当前阶段更准确的表述是: 1. 页面恢复层面:成立 2. 百度深页恢复层面:成立 3. `latest` 空壳:只是展示层问题,不代表停抓 4. 当前真正值得继续单独分析的新问题: - `sogou` 深页 `403` #### `sogou` 深页 `403` 的阶段性判断与线上复核结果 先记录上一阶段的判断依据: 这轮继续核对前端 nginx 受管蜘蛛配置样例后,曾看到: 1. `managed_spiders.map.conf.example` 当前默认只有: - `baiduspider 1;` 2. `受管蜘蛛映射-最优方案.txt` 里也明确写着: - 当前先只放行百度 - 若后续要加 `bytespider / sogou`,只在受管蜘蛛映射里增加一行 因此当时更合理的判断是: 1. `baiduspider` 已被纳入 managed spider 放行链 2. `sogou` 目前默认未被纳入 managed spider 白名单 3. 所以 `sogou` 深页请求继续落到常规拦截链,表现为: - `403` - `cache_status = NONE` 这说明上一阶段的 `sogou 403` 更像: 1. `sogou 403` 当前更像前端蜘蛛放行策略结果 2. 不是后端详情页 / 播放页内容链突然失效 3. 如果后续要继续提升搜狗覆盖面,应优先评估: - 是否把 `sogou` 加入 `/www/server/panel/vhost/nginx/ua/managed_spiders.map.conf` 但在后续线上继续复测时,已经得到新的实时结果: 1. `https://www.jpjdxs.com/` - `Baiduspider` 请求返回: - `200` - `X-Managed-Spider: managed` - `Sogou` 请求返回: - `200` - `X-Managed-Spider: managed` 2. `https://www.jpjdxs.com/neirong-154229-xiang-feng-bu-shi-jiu-shi-ren` - 普通访问: - `200` - `X-Managed-Spider: normal` - `Sogou` 访问: - `200` - `X-Managed-Spider: managed` 3. `https://www.jpjdxs.com/bf-154229-xiang-feng-bu-shi-jiu-shi-ren/default-1` - 普通访问: - `200` - `X-Managed-Spider: normal` - `Sogou` 访问: - `200` - `X-Managed-Spider: managed` 所以截至这次线上复测,至少在 `jpjdxs.com` 当前实际生效的前端配置里: 1. `sogou` 已经被纳入 managed spider 放行链 2. `sogou` 并不是“现在还完全没放行” 3. earlier 日志里看到的 `sogou 403`,更可能属于: - 前一轮旧日志样本 - 其他尚未切到最新版 nginx 规则的站点 - 或受管蜘蛛映射尚未同步到位的个别机器 因此后续判断要改成: 1. 不要再把“`sogou` 未纳入 managed map”当成全局定论 2. 必须按站点、按机器、按生效配置分别验证 3. 当前 `jpjdxs.com` 已可视为: - `sogou` 首页、详情页、播放页均已放行 #### 同机多站继续复测结果 为避免把 `jpjdxs.com` 当成单站偶发样本,这轮又继续抽测了同机另外 3 个站: 1. `lgyz.net` - 首页 TKD 正常 - 真实详情路由形态: - `/movie/154223-wo-zai-nv-zong-dang-nan-xiu` - 普通访问: - `200` - `X-Cache-Mode: path-only` - `X-Managed-Spider: normal` - `Sogou` 访问: - `200` - `X-Cache-Mode: path-only` - `X-Managed-Spider: managed` - `?__nocache=1`: - `200` - `X-Cache-Mode: bypass` - `X-Cache-Bypass: 1` 2. `lcdchq.com` - 首页 TKD 正常 - 真实详情路由形态: - `/movie/154180-yi-gua-ding-qing-yuan-ye-ya-tou-jin-cheng-bei-tuan-chong` - 普通访问: - `200` - `X-Cache-Mode: path-only` - `X-Managed-Spider: normal` - `Sogou` 访问: - `200` - `X-Cache-Mode: path-only` - `X-Managed-Spider: managed` 3. `oronorent.com` - 首页 TKD 正常 - 真实详情路由形态: - `/shipin/154173-yi-gua-ding-qian-kun` - 普通访问: - `200` - `X-Cache-Mode: path-only` - `X-Managed-Spider: normal` - `Sogou` 访问: - `200` - `X-Cache-Mode: path-only` - `X-Managed-Spider: managed` 当前可以先下这个阶段性结论: 1. 这轮前端 nginx 新规则不是只在 `jpjdxs.com` 单站生效 2. 同机至少已验证 `jpjdxs.com / lgyz.net / lcdchq.com / oronorent.com` 都正常 3. 受管蜘蛛放行、动态页安全缓存、`__nocache=1` 排障能力,已经具备批量复用价值 4. 后续如果某台站还有 `sogou 403`,优先怀疑: - 不在这台已切新版规则的机器上 - 或站点尚未同步到同一份前端 nginx 配置 #### 最新汇总快照复核 继续核对 `latest/spider-crawl.summary.json` 后,已经看到: 1. 最新生成时间: - `2026-04-17T16:20:03+08:00` 2. 当前这份快照中,国内蜘蛛可见样本已经变成: - `baiduspider` - `sogou` 3. 当前快照里,已没有新的国内蜘蛛 `403` 从 `summary_records` 可直接看到: 1. `www.jpjdxs.com` - `sogou`: - `robots => 200` - `home => 200` - `other => 200` - `baiduspider`: - `home => 200` 2. `www.glae.cc` - `baiduspider`: - `home => 301` - `home => 200` - `home => 200` 随后继续对 `www.glae.cc` 线上补测: 1. 普通访问首页: - `200` - `X-Managed-Spider: normal` 2. `Baiduspider` 访问首页: - `200` - `X-Managed-Spider: managed` 因此这一轮可以继续修正判断: 1. 目前国内蜘蛛异常已不再表现为持续性 `403` 2. `www.glae.cc` 的 `301` 更像旧窗口日志残留或跳转过程样本 3. 当前线上主趋势已经切换为: - 国内蜘蛛可正常进首页/robots/部分内容页 - 已验证机器上的受管蜘蛛放行策略正在稳定生效 #### 2026-04-17 国内蜘蛛“历史大盘”与“最新转折点” 继续把 `runs/20260417/*/crawl-logs.summary.json` 全量按国内蜘蛛拆开后,可以得到两个层面的判断: ##### 1. 历史大盘 按 `2026-04-17` 当天已归档 run 聚合后: 1. `baiduspider` - 总量:`170` - 状态: - `200 => 98` - `301 => 61` - `404 => 11` - 页面类型: - `home => 110` - `detail => 28` - `play => 8` - `other => 24` 2. `sogou` - 总量:`147` - 状态: - `200 => 7` - `301 => 39` - `403 => 101` - 页面类型: - `other => 68` - `category => 28` - `play => 19` - `detail => 11` - `robots => 11` - `home => 10` 3. `bytespider` - 总量:`63` - 状态: - `301 => 8` - `403 => 31` - `444 => 24` - 页面类型: - 基本集中在 `robots` 这说明: 1. 从整天历史大盘看,`baiduspider` 已明显恢复 2. `sogou` 历史累计仍然以旧的 `403` 样本为主 3. `bytespider` 目前仍主要停留在 `robots` 层 ##### 2. 最新转折点 但如果只看最新两批关键 run,已经能看到与历史大盘不同的新信号: 1. `162003_crawl_log_push_9592ea` - `www.jpjdxs.com` - `sogou /robots.txt => 200` - `sogou / => 200` - `sogou /neirong-154229-xiang-feng-bu-shi-jiu-shi-ren => 200` - `sogou /bf-154229-xiang-feng-bu-shi-jiu-shi-ren/default-1 => 200` - `www.glae.cc` - `baiduspider / => 301 -> 200 -> 200` 2. `163002_crawl_log_push_92f872` - `www.lgyz.net` - `sogou /movie/154223-wo-zai-nv-zong-dang-nan-xiu => 200` - `www.lcdchq.com` - `sogou /movie/154180-yi-gua-ding-qing-yuan-ye-ya-tou-jin-cheng-bei-tuan-chong => 200` - `www.oronorent.com` - `sogou /shipin/154173-yi-gua-ding-qian-kun => 200` 这说明: 1. `sogou` 的历史大盘虽然还难看,但最新窗口已经开始出现真实恢复样本 2. 这些 `200` 样本,与本轮线上人工实测结果完全一致 3. 因此当前更合理的判断应是: - `sogou` 正在从旧的 `403` 状态切换到新规则生效后的 `200` - 当前处于“恢复初期,旧日志权重仍然较高”的阶段 #### 对“仍高频出现在 sogou 403 里的站”做了当前线上复测 为了避免被历史累计误导,这轮又对 `sogou 403` 高频站做了当前线上实测: ##### 1. 先测首页 对以下域名直接用 `Sogou` UA 请求首页: 1. `www.cnzhenbang.com` 2. `www.jingxifa.com` 3. `www.vikau.com` 4. `www.hyjssb.com` 当前结果全部为: 1. `200` 2. `X-Managed-Spider: managed` 这说明: 1. 这些站当前首页入口层已经放开 2. 已不属于“首页还被前端直接拦截”的状态 ##### 2. 再测历史上曾出现 `403` 的真实深页 直接复测日志里出现过的典型历史路径: 1. `https://www.cnzhenbang.com/category/dong-man` - `Sogou => 200` - `X-Managed-Spider: managed` 2. `https://www.jingxifa.com/video-detail/cheng-shi-jian-ke-190614` - `Sogou => 200` - `X-Managed-Spider: managed` 3. `https://www.vikau.com/vodplay/xiu-zhen-zhe-zhi-fu-qin-de-cai-fu-110943-maotai-36` - `Sogou => 200` - `X-Managed-Spider: managed` 4. `https://www.hyjssb.com/shipinfenlei-dian-ying/shao-shi-dian-ying-2012-all-all/all-page1` - `Sogou => 404` - `X-Managed-Spider: managed` 这说明: 1. `cnzhenbang / jingxifa / vikau` 这几台的历史 `sogou 403` 路径,当前线上复测已转为 `200` 2. 这些站更像“旧日志还没退干净”,不是当前还在被前端规则持续拦截 3. `hyjssb` 当前这条路径返回 `404`,更像: - 老路径已失效 - 或站内路由/分类页本身变化 - 不像单纯前端蜘蛛拦截问题 因此当前“还没恢复”的怀疑顺序应继续下调: 1. `cnzhenbang` 2. `jingxifa` 3. `vikau` 而 `hyjssb` 更值得单独按: 1. 分类路由是否真实存在 2. 站内分类分页路径是否改版 3. 是否是旧路径在日志里持续残留 #### `hyjssb` 已进一步坐实为“旧路径残留”,不是当前前端拦截 继续对 `hyjssb.com` 当前站内真实路由做了核对: 1. 首页当前可见真实路由模式: - 搜索: - `/get/index` - 分类: - `/genres/dian-ying/home` - `/genres/dian-shi-ju/home` - 详情: - `/movie/yi-gua-ding-qing-yuan-ye-ya-tou-jin-cheng-bei-tuan-chong/154180` 2. 这说明它当前并不是旧日志里的: - `/shipinfenlei-...` - `/shipin-xiangqing/...` - `/shipin-bofang/...` 随后继续做当前线上复测: 1. `Sogou` 请求真实分类页: - `https://www.hyjssb.com/genres/dian-ying/home` - 返回: - `200` - `X-Managed-Spider: managed` 2. `Sogou` 请求真实详情页: - `https://www.hyjssb.com/movie/yi-gua-ding-qing-yuan-ye-ya-tou-jin-cheng-bei-tuan-chong/154180` - 返回: - `200` - `X-Managed-Spider: managed` 3. 普通访问旧日志里的旧分类路径: - `https://www.hyjssb.com/shipinfenlei-dian-ying/shao-shi-dian-ying-2012-all-all/all-page1` - 返回: - `404` 因此当前可以把 `hyjssb` 正式归类为: 1. 当前真实站点路由已经切换 2. `Sogou` 访问当前真实分类页 / 详情页均已正常放行 3. 历史日志里的 `404/403` 样本,主要是旧路径残留 4. 不应再把 `hyjssb` 归入“当前前端蜘蛛拦截未修复”的问题列表 #### `bytespider` 当前判断:未进入 managed 标记,但 robots 实测已基本可通 继续把 `bytespider` 单独拆开后,可以看到: 1. `2026-04-17` 当天历史累计: - `301 => 9` - `403 => 33` - `444 => 24` 2. 页面类型高度集中在: - `robots` 按当天历史样本看,`bytespider` 确实比 `baidu/sogou` 恢复得慢。 但继续做当前线上实测后,已看到: 1. `https://www.lgyz.net/robots.txt` - `Bytespider => 200` - `X-Managed-Spider: normal` 2. `https://www.jpjdxs.com/robots.txt` - `Bytespider => 200` - `X-Managed-Spider: normal` 3. 历史里曾出现 `bytespider 403` 的站再测: - `https://www.codohealth.com/robots.txt => 200` - `https://www.vikau.com/robots.txt => 200` - `https://www.gz-yxsw.com/robots.txt => 200` - `https://www.lmjcg.com/robots.txt => 200` - 以上均表现为: - `X-Managed-Spider: normal` 这说明当前更合理的判断是: 1. `bytespider` 目前大概率还未纳入 managed spider 映射 2. 但在当前这批已复测站点上,也没有继续被前端统一拦截 3. 历史 `403/444` 更像旧样本残留,或早前 robots 层策略未统一时留下的记录 4. 如果后续业务要主动提升头条/字节系抓取优先级,再考虑把 `bytespider` 纳入 managed spider 映射即可 ### 6. 对后续 Codex 的明确提醒 后面如果再看到: 1. 模板还在 2. 但是详情页 / 播放页文案突然变得非常通用 3. 像是“之前的优化白做了” 优先先查: 1. `code/app/services/VideoService.php` 2. 有没有再引入“只剩 default 时不读 default、强制 fallback”的逻辑 不要第一反应就: 1. 怀疑模板被整套回滚 2. 重新重写全部引导文 3. 重新批量生成一轮 seo_copy 这类问题很可能不是生成层丢了,而是读取优先级被改坏了。