3867 lines
111 KiB
Markdown
3867 lines
111 KiB
Markdown
# 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/<host>/detail`
|
||
- `code/data/seo_copy_published/<host>/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/<host>/detail`
|
||
- `code/data/seo_copy_published/<host>/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|首页导览|<title>|<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`
|
||
- 前面已单独确认:
|
||
- 本地 SEO 文案文件仍在
|
||
- 主题缓存里也有 GPT 路由定义
|
||
- 但线上外部路径直接回 nginx `404`
|
||
- 更像部署 / 回源未命中 GPT 路由
|
||
- 2026-04-17 追加抽样:
|
||
- 直接访问 `https://liangzuan.net` 时,证书校验失败
|
||
- 使用 `curl -k` 忽略证书后,根站返回 `404`
|
||
- 当前应优先判断:
|
||
- 域名证书与站点入口配置异常
|
||
- 不是 seo_copy 或 GPT 模板正文层的问题
|
||
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`
|
||
|
||
### 6. 对后续 Codex 的明确提醒
|
||
|
||
后面如果再看到:
|
||
|
||
1. 模板还在
|
||
2. 但是详情页 / 播放页文案突然变得非常通用
|
||
3. 像是“之前的优化白做了”
|
||
|
||
优先先查:
|
||
|
||
1. `code/app/services/VideoService.php`
|
||
2. 有没有再引入“只剩 default 时不读 default、强制 fallback”的逻辑
|
||
|
||
不要第一反应就:
|
||
|
||
1. 怀疑模板被整套回滚
|
||
2. 重新重写全部引导文
|
||
3. 重新批量生成一轮 seo_copy
|
||
|
||
这类问题很可能不是生成层丢了,而是读取优先级被改坏了。
|