This commit is contained in:
www
2026-05-26 17:08:20 +08:00
parent 97aefcf86b
commit 7f910ee22f
7 changed files with 1537 additions and 1 deletions

View File

@@ -1293,7 +1293,9 @@ class VideoService
$arrData = SeoCopyFallbackBuilder::build($strScene, $this->buildSeoCopyFacts($strScene, $arrOptions));
}
return $this->normalizeSeoCopyBlock($strScene, $arrData);
$arrData = $this->normalizeSeoCopyBlock($strScene, $arrData);
return $this->enrichSeoCopyBlockWithKeywordFeedback($strScene, $arrData);
}
private function mergeLegacySeoCopyWithDefault(string $strHost, string $strScene, array $arrPageKeys, array $arrData): array
@@ -1560,6 +1562,134 @@ class VideoService
return $arrMerged;
}
private function enrichSeoCopyBlockWithKeywordFeedback(string $strScene, array $arrData): array
{
if (!in_array($strScene, ['home', 'category_index', 'category_list', 'search'], true)) {
return $arrData;
}
$arrFeedback = $this->getSeoResourceKeywordFeedback();
$arrKeywords = (array)($arrFeedback['keywords'] ?? []);
if (empty($arrKeywords)) {
return $arrData;
}
$strKeywordText = implode('、', array_slice($arrKeywords, 0, 3));
if ($strKeywordText === '') {
return $arrData;
}
$arrData['_keyword_feedback'] = [
'source' => (string)($arrFeedback['source'] ?? 'seo_resource_keyword_feedback'),
'latest_metric_date' => (string)($arrFeedback['latest_metric_date'] ?? ''),
'indexed_like' => (bool)($arrFeedback['indexed_like'] ?? false),
'keyword_count' => count($arrKeywords),
'keywords' => $arrKeywords,
];
$strIntroMeta = trim((string)($arrData['intro_meta'] ?? ''));
if ($strIntroMeta !== '' && mb_strpos($strIntroMeta, $arrKeywords[0]) === false) {
$strIntroMeta = preg_replace('/[。;;]+$/u', '', $strIntroMeta) ?? $strIntroMeta;
$arrData['intro_meta'] = $strIntroMeta . ',近期重点承接:' . $strKeywordText . '。';
}
$arrCards = (array)($arrData['guide_cards'] ?? []);
foreach ($arrCards as $arrCard) {
if (is_array($arrCard) && mb_strpos((string)($arrCard['text'] ?? ''), $arrKeywords[0]) !== false) {
return $arrData;
}
}
$arrCards[] = [
'title' => '近期检索方向',
'text' => '外部反馈更集中在' . $strKeywordText . '等方向,本页优先承接相关分类、搜索、详情和播放入口。',
];
$arrData['guide_cards'] = array_slice($arrCards, 0, 5);
return $arrData;
}
private function getSeoResourceKeywordFeedback(): array
{
$strHost = trim((string)($this->SiteContext->DomainModel->d_domain ?? ''));
if ($strHost === '') {
return [];
}
$strHostKey = strtolower($strHost);
$strHostKey = preg_replace('/^www\./', '', $strHostKey) ?? $strHostKey;
$strHostKey = preg_replace('/[^a-z0-9]+/', '-', $strHostKey) ?? $strHostKey;
$strHostKey = trim($strHostKey, '-');
if ($strHostKey === '') {
return [];
}
$strPath = dirname(__DIR__, 2) . '/data/seo_resource/keyword_feedback/by_host/' . $strHostKey . '.json';
if (!is_file($strPath)) {
return [];
}
$strJson = @file_get_contents($strPath);
if ($strJson === false || trim($strJson) === '') {
return [];
}
$arrPayload = json_decode($strJson, true);
if (!is_array($arrPayload)) {
return [];
}
$arrSummary = (array)($arrPayload['summary'] ?? []);
$arrKeywords = [];
foreach ((array)($arrPayload['keywords'] ?? []) as $arrKeyword) {
if (!is_array($arrKeyword)) {
continue;
}
$strKeyword = $this->normalizeSeoFeedbackKeyword((string)($arrKeyword['keyword'] ?? ''));
if ($strKeyword === '' || in_array($strKeyword, $arrKeywords, true)) {
continue;
}
$arrKeywords[] = $strKeyword;
if (count($arrKeywords) >= 3) {
break;
}
}
if (empty($arrKeywords)) {
$strDomainKeyword = $this->normalizeSeoFeedbackKeyword((string)($arrPayload['domain_keyword'] ?? ''));
if ($strDomainKeyword !== '') {
$arrKeywords[] = $strDomainKeyword;
}
}
if (empty($arrKeywords)) {
return [];
}
return [
'source' => (string)($arrPayload['generated_by'] ?? 'seo_resource_keyword_feedback'),
'latest_metric_date' => (string)($arrSummary['latest_metric_date'] ?? ''),
'indexed_like' => (bool)($arrSummary['indexed_like'] ?? false),
'keywords' => $arrKeywords,
];
}
private function normalizeSeoFeedbackKeyword(string $strKeyword): string
{
$strKeyword = trim($strKeyword);
if ($strKeyword === '') {
return '';
}
$strKeyword = preg_replace('/\s+/u', '', $strKeyword) ?? $strKeyword;
$strKeyword = trim($strKeyword, " \t\n\r\0\x0B,,、。;;|");
if ($strKeyword === '' || mb_strlen($strKeyword) > 48) {
return '';
}
return $strKeyword;
}
private function interpolateSeoCopyData(array $arrData, array $arrTokens): array
{
foreach ($arrData as $strKey => $mValue) {