# 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` 已经可以后移。