diff --git a/code/app/services/VideoService.php b/code/app/services/VideoService.php index 1d932bf..862f15f 100644 --- a/code/app/services/VideoService.php +++ b/code/app/services/VideoService.php @@ -1195,9 +1195,7 @@ class VideoService $arrPageKeys = $this->buildSeoCopyPageKeys($strScene, $arrOptions); - $boolSuppressDefaultOnlySeoCopy = $this->shouldSuppressDefaultOnlySeoCopy($strScene, $strHost, $arrPageKeys); - - $arrData = (!$boolSuppressDefaultOnlySeoCopy && !empty($arrPageKeys)) + $arrData = !empty($arrPageKeys) ? SeoCopyStore::getPreferredPageData($strHost, $strScene, $arrPageKeys) : []; @@ -1212,43 +1210,6 @@ class VideoService return $this->normalizeSeoCopyBlock($strScene, $arrData); } - private function shouldSuppressDefaultOnlySeoCopy(string $strScene, string $strHost, array $arrPageKeys): bool - { - if (!in_array($strScene, ['detail', 'play'], true)) { - return false; - } - - $arrSpecificKeys = array_values(array_filter($arrPageKeys, static function ($strPageKey): bool { - $strPageKey = trim((string)$strPageKey); - return $strPageKey !== '' && $strPageKey !== 'default'; - })); - - if (empty($arrSpecificKeys)) { - return false; - } - - foreach (SeoCopyStore::preferredRoots() as $strRoot) { - $strRoot = rtrim(trim((string)$strRoot), '/'); - if ($strRoot === '' || !is_dir($strRoot)) { - continue; - } - - foreach ($arrSpecificKeys as $strPageKey) { - $strPath = SeoCopyStore::resolvePagePathFromRoot($strRoot, $strHost, $strScene, $strPageKey); - if ($strPath !== '' && is_file($strPath)) { - return false; - } - } - - $strDefaultPath = SeoCopyStore::resolvePagePathFromRoot($strRoot, $strHost, $strScene, 'default'); - if ($strDefaultPath !== '' && is_file($strDefaultPath)) { - return true; - } - } - - return false; - } - /** * BSONDocument / 对象 / array 统一转数组(递归) */ diff --git a/docs/1270-SEONexus-Codex多版本协作交接总文档.md b/docs/1270-SEONexus-Codex多版本协作交接总文档.md index 8aeb23e..72a2d84 100644 --- a/docs/1270-SEONexus-Codex多版本协作交接总文档.md +++ b/docs/1270-SEONexus-Codex多版本协作交接总文档.md @@ -3485,3 +3485,146 @@ php code/scripts/seo_copy_front_verify.php chuanjiafeng.net category_list dian-y - 还是统一切到新路由族 在这几步没确认前,不建议继续对 `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 + +### 6. 对后续 Codex 的明确提醒 + +后面如果再看到: + +1. 模板还在 +2. 但是详情页 / 播放页文案突然变得非常通用 +3. 像是“之前的优化白做了” + +优先先查: + +1. `code/app/services/VideoService.php` +2. 有没有再引入“只剩 default 时不读 default、强制 fallback”的逻辑 + +不要第一反应就: + +1. 怀疑模板被整套回滚 +2. 重新重写全部引导文 +3. 重新批量生成一轮 seo_copy + +这类问题很可能不是生成层丢了,而是读取优先级被改坏了。