feat: sync latest GPT SEO routing and docs

This commit is contained in:
root
2026-04-18 01:31:44 +08:00
parent c8fb6956ef
commit 5cb11b4476
48 changed files with 6000 additions and 172 deletions

View File

@@ -99,11 +99,7 @@ class SiteContext
*/
public function getViewConfig(): array
{
$strDomain = $this->Request->rootDomain();
$this->DomainModel = DomainModel::getDomainOnCacheByDomain($strDomain);
$this->DomainModel = $this->resolveCurrentDomainModel();
if (empty($this->DomainModel)) {
throw new HttpException(404, 'Site config not Found');
@@ -1159,8 +1155,7 @@ class SiteContext
public function getTemplate(): string
{
$strDomain = $this->Request->rootDomain();
$this->DomainModel = DomainModel::getDomainOnCacheByDomain($strDomain);
$this->DomainModel = $this->resolveCurrentDomainModel();
if (empty($this->DomainModel)) {
throw new HttpException(404, 'Site config not Found');
@@ -1173,6 +1168,19 @@ class SiteContext
return $this->TemplatesModel['t_code'];
}
protected function resolveCurrentDomainModel(): ?DomainModel
{
$strHost = (string)$this->Request->host();
$arrResolvedDomain = DomainModel::resolveDomainContextByHost($strHost);
$RuntimeDomainModel = $arrResolvedDomain['runtime'] ?? null;
if ($RuntimeDomainModel instanceof DomainModel) {
return $RuntimeDomainModel;
}
$strDomain = (string)$this->Request->rootDomain();
return DomainModel::getDomainOnCacheByDomain($strDomain);
}
public function getPinlunData(int $intVideoId): array
{
$strDomain = $this->DomainModel->d_domain ?? request()->domain();

View File

@@ -887,13 +887,21 @@ class VideoService
$intVId = (int)$intVId;
$intVForgeId = $intVForgeId === null ? -1 : (int)$intVForgeId;
$strPinyin = trim((string)$strPinyin);
$boolRequirePlayable = (string)request()->route('strPlayType') !== '' || (int)request()->route('intPlayIndex') > 0;
if ($intVId > 0) {
return $this->getVideoByVId($intVId, $intVForgeId);
}
if ($strPinyin !== '') {
$arrVideo = $this->VideoModel->getVideoByNameEn($strPinyin);
foreach ($this->normalizeRouteSlugCandidates($strPinyin) as $strSlugCandidate) {
$arrVideo = $this->VideoModel->getVideoByNameEn($strSlugCandidate);
if (!empty($arrVideo)) {
return $this->hydrateResolvedVideo($arrVideo, (int)($arrVideo['v_id'] ?? 0), $intVForgeId);
}
}
$arrVideo = $this->resolveFallbackVideoBySlug($strPinyin, $boolRequirePlayable);
if (!empty($arrVideo)) {
return $this->hydrateResolvedVideo($arrVideo, (int)($arrVideo['v_id'] ?? 0), $intVForgeId);
}
@@ -902,11 +910,81 @@ class VideoService
return $this->getVideoByVId($intVId, $intVForgeId);
}
protected function normalizeRouteSlugCandidates(string $strPinyin): array
{
$strPinyin = strtolower(trim($strPinyin));
if ($strPinyin === '') {
return [];
}
$arrCandidates = [$strPinyin];
if (str_starts_with($strPinyin, 'pinyin-')) {
$arrCandidates[] = substr($strPinyin, 7);
}
$arrNormalized = [];
foreach ($arrCandidates as $candidate) {
$candidate = trim((string)$candidate, "- \t\n\r\0\x0B");
if ($candidate === '') {
continue;
}
$arrNormalized[$candidate] = $candidate;
}
return array_values($arrNormalized);
}
protected function resolveFallbackVideoBySlug(string $requestedSlug, bool $requirePlayable = false): ?array
{
$arrCandidates = $this->normalizeRouteSlugCandidates($requestedSlug);
if (empty($arrCandidates)) {
return null;
}
$strHost = (string)($this->SiteContext->DomainModel->d_domain ?? 'default');
$arrBindings = $this->readFallbackBindings($strHost);
foreach ($arrCandidates as $strSlugCandidate) {
$strBindingKey = 'slug:' . $strSlugCandidate;
$boundVId = (int)($arrBindings[$strBindingKey] ?? 0);
if ($boundVId > 0) {
$arrVideo = $this->VideoModel->getVideoByVId($boundVId);
if (!empty($arrVideo) && (!$requirePlayable || $this->hasPlayableSource($arrVideo))) {
$arrVideo['_fallback_reason'] = 'bound_slug_video';
$arrVideo['_requested_slug'] = $requestedSlug;
return $arrVideo;
}
}
}
$arrVideo = $this->resolveFallbackVideoByRequest(0, $requirePlayable);
if (empty($arrVideo)) {
return null;
}
$intResolvedVId = (int)($arrVideo['v_id'] ?? 0);
if ($intResolvedVId <= 0) {
return null;
}
foreach ($arrCandidates as $strSlugCandidate) {
$arrBindings['slug:' . $strSlugCandidate] = $intResolvedVId;
}
$this->writeFallbackBindings($strHost, $arrBindings);
$arrVideo['_fallback_reason'] = 'random_slug_video';
$arrVideo['_requested_slug'] = $requestedSlug;
return $arrVideo;
}
protected function resolveFallbackVideoByRequest(int $requestedVId, bool $requirePlayable = false): ?array
{
$strHost = (string)($this->SiteContext->DomainModel->d_domain ?? 'default');
$arrBindings = $this->readFallbackBindings($strHost);
$strBindingKey = (string)$requestedVId;
$boolPersistBinding = $requestedVId > 0;
$strBindingKey = $boolPersistBinding ? (string)$requestedVId : '';
$this->debugFallbackProbe('enter_resolve_fallback', [
'requested_v_id' => $requestedVId,
@@ -915,7 +993,7 @@ class VideoService
'existing_bindings' => count($arrBindings),
]);
$boundVId = (int)($arrBindings[$strBindingKey] ?? 0);
$boundVId = $boolPersistBinding ? (int)($arrBindings[$strBindingKey] ?? 0) : 0;
if ($boundVId > 0 && $boundVId !== $requestedVId) {
$arrVideo = $this->VideoModel->getVideoByVId($boundVId);
if (!empty($arrVideo) && (!$requirePlayable || $this->hasPlayableSource($arrVideo))) {
@@ -964,8 +1042,10 @@ class VideoService
continue;
}
$arrBindings[$strBindingKey] = $candidateId;
$this->writeFallbackBindings($strHost, $arrBindings);
if ($boolPersistBinding) {
$arrBindings[$strBindingKey] = $candidateId;
$this->writeFallbackBindings($strHost, $arrBindings);
}
$this->debugFallbackProbe('sample_success', [
'requested_v_id' => $requestedVId,
'candidate_v_id' => $candidateId,
@@ -982,8 +1062,10 @@ class VideoService
if (!empty($arrVideo)) {
$candidateId = (int)($arrVideo['v_id'] ?? 0);
if ($candidateId > 0 && $candidateId !== $requestedVId) {
$arrBindings[$strBindingKey] = $candidateId;
$this->writeFallbackBindings($strHost, $arrBindings);
if ($boolPersistBinding) {
$arrBindings[$strBindingKey] = $candidateId;
$this->writeFallbackBindings($strHost, $arrBindings);
}
$this->debugFallbackProbe('ordered_fallback_success', [
'requested_v_id' => $requestedVId,
'candidate_v_id' => $candidateId,