refactor: move private seo artifacts into storage

This commit is contained in:
www
2026-04-19 21:10:02 +08:00
parent 53a1d7e4fd
commit 566e966582
10 changed files with 108 additions and 67 deletions

View File

@@ -2302,11 +2302,11 @@ class Site extends BaseController
public function getDomainExternalSeoSearchConsolePropertyMapTemplate(Request $Request, ?AdminUserModel $AdminUserModel) public function getDomainExternalSeoSearchConsolePropertyMapTemplate(Request $Request, ?AdminUserModel $AdminUserModel)
{ {
try { try {
$strOutputDir = $this->bootstrapCodeRoot() . '/public/_admin_templates/domain-seo-external/search-console'; $strOutputDir = $this->bootstrapCodeRoot() . '/storage/external-seo/search-console';
$arrTemplate = DomainExternalSeoSearchConsoleConfigHelper::writeTemplate($strOutputDir); $arrTemplate = DomainExternalSeoSearchConsoleConfigHelper::writeTemplate($strOutputDir);
return $this->success([ return $this->success([
'file_name' => (string)($arrTemplate['file_name'] ?? ''), 'file_name' => (string)($arrTemplate['file_name'] ?? ''),
'file_path' => $this->publicRelativePath((string)($arrTemplate['file_path'] ?? '')), 'file_path' => $this->storageRelativePath((string)($arrTemplate['file_path'] ?? '')),
'summary' => (array)($arrTemplate['summary'] ?? []), 'summary' => (array)($arrTemplate['summary'] ?? []),
]); ]);
} catch (\Throwable $Throwable) { } catch (\Throwable $Throwable) {
@@ -2970,7 +2970,7 @@ class Site extends BaseController
$arrTemplate = DomainExternalSeoManualImportHelper::writeTemplate($this->domainExternalSeoManualImportRoot()); $arrTemplate = DomainExternalSeoManualImportHelper::writeTemplate($this->domainExternalSeoManualImportRoot());
return $this->success([ return $this->success([
'file_name' => (string)($arrTemplate['file_name'] ?? ''), 'file_name' => (string)($arrTemplate['file_name'] ?? ''),
'file_path' => $this->publicRelativePath((string)($arrTemplate['file_path'] ?? '')), 'file_path' => $this->storageRelativePath((string)($arrTemplate['file_path'] ?? '')),
'summary' => $arrTemplate['summary'] ?? [], 'summary' => $arrTemplate['summary'] ?? [],
]); ]);
} catch (\Throwable $Throwable) { } catch (\Throwable $Throwable) {
@@ -3021,12 +3021,12 @@ class Site extends BaseController
} }
return $this->success([ return $this->success([
'uploaded_excel_path' => $this->publicRelativePath($strUploadedPath), 'uploaded_excel_path' => $this->storageRelativePath($strUploadedPath),
'uploaded_report_path' => $this->publicRelativePath($strUploadedPath), 'uploaded_report_path' => $this->storageRelativePath($strUploadedPath),
'csv_path' => $this->publicRelativePath((string)($arrResult['csv_path'] ?? '')), 'csv_path' => $this->storageRelativePath((string)($arrResult['csv_path'] ?? '')),
'run_root' => $this->publicRelativePath($strRunRoot), 'run_root' => $this->storageRelativePath($strRunRoot),
'run_csv_path' => $this->publicRelativePath((string)($arrResult['run_csv_path'] ?? '')), 'run_csv_path' => $this->storageRelativePath((string)($arrResult['run_csv_path'] ?? '')),
'run_uploaded_report_path' => $this->publicRelativePath($strRunUploadedPath), 'run_uploaded_report_path' => $this->storageRelativePath($strRunUploadedPath),
'rows_total' => (int)($arrResult['rows_total'] ?? 0), 'rows_total' => (int)($arrResult['rows_total'] ?? 0),
'imported_count' => (int)($arrResult['imported_count'] ?? 0), 'imported_count' => (int)($arrResult['imported_count'] ?? 0),
'real_summary_status' => (string)($arrRealSummary['status'] ?? ''), 'real_summary_status' => (string)($arrRealSummary['status'] ?? ''),

View File

@@ -152,9 +152,9 @@ class Video extends BaseController
$arrSummary = VideoMetadataMissingWorkbenchHelper::writeArtifacts($this->metadataMissingWorkbenchRoot(), $arrSummary); $arrSummary = VideoMetadataMissingWorkbenchHelper::writeArtifacts($this->metadataMissingWorkbenchRoot(), $arrSummary);
} }
$arrSummary['summary_json_path'] = $this->publicRelativePath((string)($arrSummary['summary_json_path'] ?? '')); $arrSummary['summary_json_path'] = $this->storageRelativePath((string)($arrSummary['summary_json_path'] ?? ''));
$arrSummary['summary_html_path'] = $this->publicRelativePath((string)($arrSummary['summary_html_path'] ?? '')); $arrSummary['summary_html_path'] = $this->storageRelativePath((string)($arrSummary['summary_html_path'] ?? ''));
$arrSummary['prompt_markdown_path'] = $this->publicRelativePath((string)($arrSummary['prompt_markdown_path'] ?? '')); $arrSummary['prompt_markdown_path'] = $this->storageRelativePath((string)($arrSummary['prompt_markdown_path'] ?? ''));
return $this->success($arrSummary); return $this->success($arrSummary);
} catch (\Throwable $Throwable) { } catch (\Throwable $Throwable) {
@@ -176,7 +176,7 @@ class Video extends BaseController
return $this->success([ return $this->success([
'prompt' => (string)($arrSummary['codex_dispatch_prompt'] ?? ''), 'prompt' => (string)($arrSummary['codex_dispatch_prompt'] ?? ''),
'prompt_markdown_path' => $this->publicRelativePath((string)($arrSummary['prompt_markdown_path'] ?? '')), 'prompt_markdown_path' => $this->storageRelativePath((string)($arrSummary['prompt_markdown_path'] ?? '')),
'generated_at' => (string)($arrSummary['generated_at'] ?? ''), 'generated_at' => (string)($arrSummary['generated_at'] ?? ''),
]); ]);
} catch (\Throwable $Throwable) { } catch (\Throwable $Throwable) {
@@ -214,8 +214,8 @@ class Video extends BaseController
$arrSummary = VideoMetadataMissingTaskPoolHelper::writeArtifacts($this->metadataMissingTaskPoolRoot(), $arrSummary); $arrSummary = VideoMetadataMissingTaskPoolHelper::writeArtifacts($this->metadataMissingTaskPoolRoot(), $arrSummary);
} }
$arrSummary['summary_json_path'] = $this->publicRelativePath((string)($arrSummary['summary_json_path'] ?? '')); $arrSummary['summary_json_path'] = $this->storageRelativePath((string)($arrSummary['summary_json_path'] ?? ''));
$arrSummary['summary_html_path'] = $this->publicRelativePath((string)($arrSummary['summary_html_path'] ?? '')); $arrSummary['summary_html_path'] = $this->storageRelativePath((string)($arrSummary['summary_html_path'] ?? ''));
return $this->success($arrSummary); return $this->success($arrSummary);
} catch (\Throwable $Throwable) { } catch (\Throwable $Throwable) {
@@ -231,10 +231,10 @@ class Video extends BaseController
$this->metadataMissingTaskPoolRoot() $this->metadataMissingTaskPoolRoot()
); );
$arrSummary['workbench']['summary_json_path'] = $this->publicRelativePath((string)($arrSummary['workbench']['summary_json_path'] ?? '')); $arrSummary['workbench']['summary_json_path'] = $this->storageRelativePath((string)($arrSummary['workbench']['summary_json_path'] ?? ''));
$arrSummary['workbench']['summary_html_path'] = $this->publicRelativePath((string)($arrSummary['workbench']['summary_html_path'] ?? '')); $arrSummary['workbench']['summary_html_path'] = $this->storageRelativePath((string)($arrSummary['workbench']['summary_html_path'] ?? ''));
$arrSummary['task_pool']['summary_json_path'] = $this->publicRelativePath((string)($arrSummary['task_pool']['summary_json_path'] ?? '')); $arrSummary['task_pool']['summary_json_path'] = $this->storageRelativePath((string)($arrSummary['task_pool']['summary_json_path'] ?? ''));
$arrSummary['task_pool']['summary_html_path'] = $this->publicRelativePath((string)($arrSummary['task_pool']['summary_html_path'] ?? '')); $arrSummary['task_pool']['summary_html_path'] = $this->storageRelativePath((string)($arrSummary['task_pool']['summary_html_path'] ?? ''));
return $this->success($arrSummary); return $this->success($arrSummary);
} catch (\Throwable $Throwable) { } catch (\Throwable $Throwable) {
@@ -250,10 +250,10 @@ class Video extends BaseController
$this->metadataMissingTaskPoolRoot() $this->metadataMissingTaskPoolRoot()
); );
$arrSummary['workbench']['summary_json_path'] = $this->publicRelativePath((string)($arrSummary['workbench']['summary_json_path'] ?? '')); $arrSummary['workbench']['summary_json_path'] = $this->storageRelativePath((string)($arrSummary['workbench']['summary_json_path'] ?? ''));
$arrSummary['workbench']['summary_html_path'] = $this->publicRelativePath((string)($arrSummary['workbench']['summary_html_path'] ?? '')); $arrSummary['workbench']['summary_html_path'] = $this->storageRelativePath((string)($arrSummary['workbench']['summary_html_path'] ?? ''));
$arrSummary['task_pool']['summary_json_path'] = $this->publicRelativePath((string)($arrSummary['task_pool']['summary_json_path'] ?? '')); $arrSummary['task_pool']['summary_json_path'] = $this->storageRelativePath((string)($arrSummary['task_pool']['summary_json_path'] ?? ''));
$arrSummary['task_pool']['summary_html_path'] = $this->publicRelativePath((string)($arrSummary['task_pool']['summary_html_path'] ?? '')); $arrSummary['task_pool']['summary_html_path'] = $this->storageRelativePath((string)($arrSummary['task_pool']['summary_html_path'] ?? ''));
return $this->success([ return $this->success([
'summary' => $arrSummary, 'summary' => $arrSummary,
@@ -383,8 +383,8 @@ class Video extends BaseController
$arrSummary = VideoMetadataMissingTaskPoolHelper::buildSummary($arrWorkbenchSummary, $intBatchSize, $intBatchLimit); $arrSummary = VideoMetadataMissingTaskPoolHelper::buildSummary($arrWorkbenchSummary, $intBatchSize, $intBatchLimit);
$arrSummary = VideoMetadataMissingTaskPoolHelper::writeArtifacts($this->metadataMissingTaskPoolRoot(), $arrSummary); $arrSummary = VideoMetadataMissingTaskPoolHelper::writeArtifacts($this->metadataMissingTaskPoolRoot(), $arrSummary);
$arrSummary['summary_json_path'] = $this->publicRelativePath((string)($arrSummary['summary_json_path'] ?? '')); $arrSummary['summary_json_path'] = $this->storageRelativePath((string)($arrSummary['summary_json_path'] ?? ''));
$arrSummary['summary_html_path'] = $this->publicRelativePath((string)($arrSummary['summary_html_path'] ?? '')); $arrSummary['summary_html_path'] = $this->storageRelativePath((string)($arrSummary['summary_html_path'] ?? ''));
return $this->success([ return $this->success([
'status' => 'success', 'status' => 'success',
@@ -458,9 +458,9 @@ class Video extends BaseController
$arrSummary = VideoMetadataMissingWorkbenchHelper::buildSummary($intSample, $intQueueLimit, $intPromptLimit); $arrSummary = VideoMetadataMissingWorkbenchHelper::buildSummary($intSample, $intQueueLimit, $intPromptLimit);
$arrSummary = VideoMetadataMissingWorkbenchHelper::writeArtifacts($this->metadataMissingWorkbenchRoot(), $arrSummary); $arrSummary = VideoMetadataMissingWorkbenchHelper::writeArtifacts($this->metadataMissingWorkbenchRoot(), $arrSummary);
$arrSummary['summary_json_path'] = $this->publicRelativePath((string)($arrSummary['summary_json_path'] ?? '')); $arrSummary['summary_json_path'] = $this->storageRelativePath((string)($arrSummary['summary_json_path'] ?? ''));
$arrSummary['summary_html_path'] = $this->publicRelativePath((string)($arrSummary['summary_html_path'] ?? '')); $arrSummary['summary_html_path'] = $this->storageRelativePath((string)($arrSummary['summary_html_path'] ?? ''));
$arrSummary['prompt_markdown_path'] = $this->publicRelativePath((string)($arrSummary['prompt_markdown_path'] ?? '')); $arrSummary['prompt_markdown_path'] = $this->storageRelativePath((string)($arrSummary['prompt_markdown_path'] ?? ''));
return $this->success([ return $this->success([
'status' => 'success', 'status' => 'success',
@@ -473,7 +473,7 @@ class Video extends BaseController
protected function metadataMissingWorkbenchRoot(): string protected function metadataMissingWorkbenchRoot(): string
{ {
return rtrim((string)root_path(), '/') . '/app/public/_admin_templates/video-metadata-missing-workbench'; return rtrim((string)root_path(), '/') . '/storage/video-metadata-missing/workbench';
} }
protected function metadataMissingWorkbenchRunRoot(): string protected function metadataMissingWorkbenchRunRoot(): string
@@ -483,15 +483,15 @@ class Video extends BaseController
protected function metadataMissingTaskPoolRoot(): string protected function metadataMissingTaskPoolRoot(): string
{ {
return rtrim((string)root_path(), '/') . '/app/public/_admin_templates/video-metadata-missing-task-pool'; return rtrim((string)root_path(), '/') . '/storage/video-metadata-missing/task-pool';
} }
protected function publicRelativePath(string $strPath): string protected function storageRelativePath(string $strPath): string
{ {
$strPublicRoot = rtrim(str_replace('\\', '/', rtrim((string)root_path(), '/') . '/app/public/'), '/'); $strStorageRoot = rtrim(str_replace('\\', '/', rtrim((string)root_path(), '/') . '/storage/'), '/');
$strPath = str_replace('\\', '/', $strPath); $strPath = str_replace('\\', '/', $strPath);
if ($strPath !== '' && str_starts_with($strPath, $strPublicRoot . '/')) { if ($strPath !== '' && str_starts_with($strPath, $strStorageRoot . '/')) {
return substr($strPath, strlen($strPublicRoot . '/')); return substr($strPath, strlen($strStorageRoot . '/'));
} }
return $strPath; return $strPath;

View File

@@ -26,7 +26,7 @@ class VideoMetadataMissingWorkbenchCommand extends Command
$intSample = max(1, min(100, (int)$input->getOption('sample'))); $intSample = max(1, min(100, (int)$input->getOption('sample')));
$intQueueLimit = max(1, min(500, (int)$input->getOption('queue-limit'))); $intQueueLimit = max(1, min(500, (int)$input->getOption('queue-limit')));
$intPromptLimit = max(1, min(100, (int)$input->getOption('prompt-limit'))); $intPromptLimit = max(1, min(100, (int)$input->getOption('prompt-limit')));
$strOutputRoot = rtrim((string)root_path(), '/') . '/app/public/_admin_templates/video-metadata-missing-workbench'; $strOutputRoot = rtrim((string)root_path(), '/') . '/storage/video-metadata-missing/workbench';
$arrSummary = VideoMetadataMissingWorkbenchHelper::buildSummary($intSample, $intQueueLimit, $intPromptLimit); $arrSummary = VideoMetadataMissingWorkbenchHelper::buildSummary($intSample, $intQueueLimit, $intPromptLimit);
$arrSummary = VideoMetadataMissingWorkbenchHelper::writeArtifacts($strOutputRoot, $arrSummary); $arrSummary = VideoMetadataMissingWorkbenchHelper::writeArtifacts($strOutputRoot, $arrSummary);

View File

@@ -10,7 +10,7 @@ class DomainExternalSeoManualImportHelper
{ {
public static function defaultRoot(string $strCodeRoot): string public static function defaultRoot(string $strCodeRoot): string
{ {
return rtrim($strCodeRoot, '/') . '/public/_admin_templates/domain-seo-external/manual-import'; return rtrim($strCodeRoot, '/') . '/storage/external-seo/manual-import';
} }
public static function getHeaders(): array public static function getHeaders(): array

View File

@@ -6,12 +6,12 @@ namespace app\common\helper;
class DomainExternalSeoManualImportRunIndexHelper class DomainExternalSeoManualImportRunIndexHelper
{ {
protected static function publicRelativePath(string $strPath): string protected static function storageRelativePath(string $strPath): string
{ {
$strPublicRoot = str_replace('\\', '/', rtrim(dirname(__DIR__, 3) . '/public', '/')); $strStorageRoot = str_replace('\\', '/', rtrim(dirname(__DIR__, 3) . '/storage', '/'));
$strPath = str_replace('\\', '/', $strPath); $strPath = str_replace('\\', '/', $strPath);
if (str_starts_with($strPath, $strPublicRoot . '/')) { if (str_starts_with($strPath, $strStorageRoot . '/')) {
return substr($strPath, strlen($strPublicRoot . '/')); return substr($strPath, strlen($strStorageRoot . '/'));
} }
return $strPath; return $strPath;
@@ -47,16 +47,16 @@ class DomainExternalSeoManualImportRunIndexHelper
$arrItems[] = [ $arrItems[] = [
'run_id' => basename($strRunRoot), 'run_id' => basename($strRunRoot),
'run_root_public' => self::publicRelativePath($strRunRoot), 'run_root_public' => self::storageRelativePath($strRunRoot),
'status' => (string)($arrSummary['status'] ?? 'empty'), 'status' => (string)($arrSummary['status'] ?? 'empty'),
'provider_key' => (string)($arrSummary['provider_key'] ?? 'manual_csv_import'), 'provider_key' => (string)($arrSummary['provider_key'] ?? 'manual_csv_import'),
'rows_total' => self::countCsvRows($strCsvPath), 'rows_total' => self::countCsvRows($strCsvPath),
'hosts_count' => self::countCsvHosts($strCsvPath), 'hosts_count' => self::countCsvHosts($strCsvPath),
'metrics' => (array)($arrSummary['metrics'] ?? []), 'metrics' => (array)($arrSummary['metrics'] ?? []),
'uploaded_report_path' => $strUploadedPath !== '' ? self::publicRelativePath($strUploadedPath) : '', 'uploaded_report_path' => $strUploadedPath !== '' ? self::storageRelativePath($strUploadedPath) : '',
'csv_path' => is_file($strCsvPath) ? self::publicRelativePath($strCsvPath) : '', 'csv_path' => is_file($strCsvPath) ? self::storageRelativePath($strCsvPath) : '',
'summary_json_path' => self::publicRelativePath($strSummaryPath), 'summary_json_path' => self::storageRelativePath($strSummaryPath),
'summary_html_path' => is_file($strRunRoot . '/seo-external-real.summary.html') ? self::publicRelativePath($strRunRoot . '/seo-external-real.summary.html') : '', 'summary_html_path' => is_file($strRunRoot . '/seo-external-real.summary.html') ? self::storageRelativePath($strRunRoot . '/seo-external-real.summary.html') : '',
'updated_at' => date(DATE_ATOM, (int)(filemtime($strSummaryPath) ?: time())), 'updated_at' => date(DATE_ATOM, (int)(filemtime($strSummaryPath) ?: time())),
]; ];
} }
@@ -69,16 +69,16 @@ class DomainExternalSeoManualImportRunIndexHelper
$arrSummary = is_array($arrDecoded) ? $arrDecoded : []; $arrSummary = is_array($arrDecoded) ? $arrDecoded : [];
array_unshift($arrItems, [ array_unshift($arrItems, [
'run_id' => 'latest_manual_import', 'run_id' => 'latest_manual_import',
'run_root_public' => self::publicRelativePath($strLatestDir), 'run_root_public' => self::storageRelativePath($strLatestDir),
'status' => (string)($arrSummary['status'] ?? 'empty'), 'status' => (string)($arrSummary['status'] ?? 'empty'),
'provider_key' => (string)($arrSummary['provider_key'] ?? 'manual_csv_import'), 'provider_key' => (string)($arrSummary['provider_key'] ?? 'manual_csv_import'),
'rows_total' => self::countCsvRows($strLatestDir . '/manual-seo-import.csv'), 'rows_total' => self::countCsvRows($strLatestDir . '/manual-seo-import.csv'),
'hosts_count' => self::countCsvHosts($strLatestDir . '/manual-seo-import.csv'), 'hosts_count' => self::countCsvHosts($strLatestDir . '/manual-seo-import.csv'),
'metrics' => (array)($arrSummary['metrics'] ?? []), 'metrics' => (array)($arrSummary['metrics'] ?? []),
'uploaded_report_path' => '', 'uploaded_report_path' => '',
'csv_path' => self::publicRelativePath($strLatestDir . '/manual-seo-import.csv'), 'csv_path' => self::storageRelativePath($strLatestDir . '/manual-seo-import.csv'),
'summary_json_path' => self::publicRelativePath($strLatestSummaryJsonPath), 'summary_json_path' => self::storageRelativePath($strLatestSummaryJsonPath),
'summary_html_path' => self::publicRelativePath(dirname($strRoot) . '/latest/seo-external-real.summary.html'), 'summary_html_path' => self::storageRelativePath(dirname($strRoot) . '/latest/seo-external-real.summary.html'),
'updated_at' => date(DATE_ATOM, (int)(filemtime($strLatestSummaryJsonPath) ?: time())), 'updated_at' => date(DATE_ATOM, (int)(filemtime($strLatestSummaryJsonPath) ?: time())),
]); ]);
} }

View File

@@ -14,9 +14,9 @@ class VideoMetadataMissingRefreshHelper
$intBatchSize = max(5, min(100, (int)($arrOptions['batch_size'] ?? 20))); $intBatchSize = max(5, min(100, (int)($arrOptions['batch_size'] ?? 20)));
$intBatchLimit = max(1, min(50, (int)($arrOptions['batch_limit'] ?? 10))); $intBatchLimit = max(1, min(50, (int)($arrOptions['batch_limit'] ?? 10)));
$strPublicRoot = rtrim((string)root_path(), '/') . '/app/public'; $strStorageRoot = rtrim((string)root_path(), '/') . '/storage/video-metadata-missing';
$strWorkbenchRoot = $strPublicRoot . '/_admin_templates/video-metadata-missing-workbench'; $strWorkbenchRoot = $strStorageRoot . '/workbench';
$strTaskPoolRoot = $strPublicRoot . '/_admin_templates/video-metadata-missing-task-pool'; $strTaskPoolRoot = $strStorageRoot . '/task-pool';
$arrWorkbenchSummary = VideoMetadataMissingWorkbenchHelper::buildSummary( $arrWorkbenchSummary = VideoMetadataMissingWorkbenchHelper::buildSummary(
$intSample, $intSample,

View File

@@ -413,11 +413,11 @@ class VideoMetadataMissingTaskPoolHelper
); );
self::writeFile($strPromptPath, (string)($arrBatch['codex_prompt'] ?? '')); self::writeFile($strPromptPath, (string)($arrBatch['codex_prompt'] ?? ''));
$arrSummary['batches'][$intIndex]['detail_json_path'] = self::publicRelativePath($strDetailPath); $arrSummary['batches'][$intIndex]['detail_json_path'] = self::storageRelativePath($strDetailPath);
$arrSummary['batches'][$intIndex]['prompt_markdown_path'] = self::publicRelativePath($strPromptPath); $arrSummary['batches'][$intIndex]['prompt_markdown_path'] = self::storageRelativePath($strPromptPath);
$arrSummary['batches'][$intIndex]['history_json_path'] = is_file($strHistoryPath) $arrSummary['batches'][$intIndex]['history_json_path'] = is_file($strHistoryPath)
? self::publicRelativePath($strHistoryPath) ? self::storageRelativePath($strHistoryPath)
: self::publicRelativePath($strHistoryPath); : self::storageRelativePath($strHistoryPath);
} }
return $arrSummary; return $arrSummary;
@@ -437,12 +437,12 @@ class VideoMetadataMissingTaskPoolHelper
return 'video-metadata-missing-task-pool-' . date('Ymd-His'); return 'video-metadata-missing-task-pool-' . date('Ymd-His');
} }
protected static function publicRelativePath(string $strPath): string protected static function storageRelativePath(string $strPath): string
{ {
$strPublicRoot = str_replace('\\', '/', rtrim(dirname(__DIR__, 2) . '/public', '/')); $strStorageRoot = str_replace('\\', '/', rtrim(dirname(__DIR__, 3) . '/storage', '/'));
$strPath = str_replace('\\', '/', $strPath); $strPath = str_replace('\\', '/', $strPath);
if (str_starts_with($strPath, $strPublicRoot . '/')) { if (str_starts_with($strPath, $strStorageRoot . '/')) {
return substr($strPath, strlen($strPublicRoot . '/')); return substr($strPath, strlen($strStorageRoot . '/'));
} }
return $strPath; return $strPath;

View File

@@ -53,9 +53,9 @@ class VideoMetadataMissingWorkbenchIndexHelper
'top_field_missing_count' => (int)(($arrTopFields[0] ?? [])['missing_count'] ?? 0), 'top_field_missing_count' => (int)(($arrTopFields[0] ?? [])['missing_count'] ?? 0),
'health_label' => $strHealthLabel, 'health_label' => $strHealthLabel,
'health_reason' => $strHealthReason, 'health_reason' => $strHealthReason,
'summary_json_path' => self::publicRelativePath($strSummaryPath), 'summary_json_path' => self::storageRelativePath($strSummaryPath),
'summary_html_path' => self::publicRelativePath($strRunDir . '/video-metadata-missing-workbench.summary.html'), 'summary_html_path' => self::storageRelativePath($strRunDir . '/video-metadata-missing-workbench.summary.html'),
'prompt_markdown_path' => self::publicRelativePath($strRunDir . '/prompt.md'), 'prompt_markdown_path' => self::storageRelativePath($strRunDir . '/prompt.md'),
]; ];
} }
@@ -86,12 +86,12 @@ class VideoMetadataMissingWorkbenchIndexHelper
return ['steady', '当前缺字段问题相对可控,适合按优先队列持续收敛。']; return ['steady', '当前缺字段问题相对可控,适合按优先队列持续收敛。'];
} }
protected static function publicRelativePath(string $strPath): string protected static function storageRelativePath(string $strPath): string
{ {
$strPublicRoot = str_replace('\\', '/', rtrim(dirname(__DIR__, 2) . '/public', '/')); $strStorageRoot = str_replace('\\', '/', rtrim(dirname(__DIR__, 3) . '/storage', '/'));
$strPath = str_replace('\\', '/', $strPath); $strPath = str_replace('\\', '/', $strPath);
if (str_starts_with($strPath, $strPublicRoot . '/')) { if (str_starts_with($strPath, $strStorageRoot . '/')) {
return substr($strPath, strlen($strPublicRoot . '/')); return substr($strPath, strlen($strStorageRoot . '/'));
} }
return $strPath; return $strPath;

View File

@@ -50,6 +50,46 @@
- sitemap 入队 - sitemap 入队
- starter published copy - starter published copy
### 2.1 运行产物存储口径补充
`2026-04-19` 开始,新增一条更严格的后端存储口径:
1. 后台运行产物
2. 工作台快照
3. 任务池快照
4. 手工导入中间文件
5. Search Console 模板
6. 站外 SEO latest / snapshot 摘要
以上这类数据,统一视为:
- 私有数据
- 运行时数据
- 不应默认纳入 Git 的数据
所以默认都应落在:
- `code/storage/...`
而不是:
- `code/public/...`
- `code/app/public/...`
当前已完成的收口包括:
1. `domain-seo-external latest / snapshot / snapshot-validate` 已迁到 `storage/external-seo/...`
2. `video-metadata-missing-workbench` 已迁到 `storage/video-metadata-missing/workbench`
3. `video-metadata-missing-task-pool` 已迁到 `storage/video-metadata-missing/task-pool`
4. `domain-seo-external/manual-import` 已迁到 `storage/external-seo/manual-import`
5. `domain-seo-external/search-console` 模板目录已迁到 `storage/external-seo/search-console`
以后如果再新增类似后台产物目录,优先原则是:
1. 先想能不能放 `storage`
2. 默认不要放 `public`
3. 只有明确需要前台公开访问的静态资源,才考虑进入 `public`
### 3. 公共规则侧 ### 3. 公共规则侧
已确立为全项目公共主线的内容: 已确立为全项目公共主线的内容:

View File

@@ -56,6 +56,7 @@
2. 需要分清哪些是 `SEONexus`、哪些是 `SEONexusAdmin` 2. 需要分清哪些是 `SEONexus`、哪些是 `SEONexusAdmin`
3. 需要确认后台真实页面入口现在在 Vue而不是 PHP 直出页 3. 需要确认后台真实页面入口现在在 Vue而不是 PHP 直出页
4. 需要同步今天补上的 `Spider MD 异步任务消费器``GitHub 推送``主表一键复制MD` 这些后台能力 4. 需要同步今天补上的 `Spider MD 异步任务消费器``GitHub 推送``主表一键复制MD` 这些后台能力
5. 需要同步“所有后台运行产物、工作台快照、手工导入中间文件默认落 `storage`,不要再放 `public`”这条新口径
### 1.3 AI文案与视频元数据公共规则 ### 1.3 AI文案与视频元数据公共规则