feat: improve gpt import templates and seo docs
This commit is contained in:
@@ -1230,9 +1230,14 @@ class Site extends BaseController
|
|||||||
|
|
||||||
$Spreadsheet = IOFactory::load($FilePath);
|
$Spreadsheet = IOFactory::load($FilePath);
|
||||||
$Sheet = $Spreadsheet->getActiveSheet();
|
$Sheet = $Spreadsheet->getActiveSheet();
|
||||||
$arrData = $Sheet->toArray();
|
$arrData = $Sheet->toArray(null, true, true, false);
|
||||||
|
|
||||||
array_shift($arrData);
|
$arrHeaders = array_map(
|
||||||
|
static function ($strHeader): string {
|
||||||
|
return DomainBatchImportTemplateHelper::normalizeHeader(trim((string)$strHeader));
|
||||||
|
},
|
||||||
|
(array)array_shift($arrData)
|
||||||
|
);
|
||||||
|
|
||||||
$strRunRoot = DomainImportProbeRunHelper::createRunRoot($this->domainImportRunRoot(), 'excel_import');
|
$strRunRoot = DomainImportProbeRunHelper::createRunRoot($this->domainImportRunRoot(), 'excel_import');
|
||||||
$strUploadedExcelPath = $strRunRoot . '/uploaded.' . $strExt;
|
$strUploadedExcelPath = $strRunRoot . '/uploaded.' . $strExt;
|
||||||
@@ -1252,34 +1257,46 @@ class Site extends BaseController
|
|||||||
|
|
||||||
foreach ($arrData as $arrRows) {
|
foreach ($arrData as $arrRows) {
|
||||||
$intRowsTotal++;
|
$intRowsTotal++;
|
||||||
$strStrategyProfile = $this->normalizeStrategyProfile($arrRows[19] ?? DomainModel::SEO_STRATEGY_PROFILE_STANDARD);
|
$arrRowAssoc = [];
|
||||||
$strTkdMode = DomainModel::normalizeTkdMode((string)($arrRows[20] ?? ''));
|
foreach ($arrHeaders as $index => $strHeader) {
|
||||||
$strTkdProvider = DomainModel::normalizeTkdProvider((string)($arrRows[21] ?? DomainModel::TKD_PROVIDER_LOCAL));
|
if ($strHeader === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$arrRowAssoc[$strHeader] = trim((string)($arrRows[$index] ?? ''));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty(array_filter($arrRowAssoc, static fn($value): bool => trim((string)$value) !== ''))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$strStrategyProfile = $this->normalizeStrategyProfile($arrRowAssoc['strategy_profile'] ?? DomainModel::SEO_STRATEGY_PROFILE_STANDARD);
|
||||||
|
$strTkdMode = DomainModel::normalizeTkdMode((string)($arrRowAssoc['tkd_mode'] ?? ''));
|
||||||
|
$strTkdProvider = DomainModel::normalizeTkdProvider((string)($arrRowAssoc['tkd_provider'] ?? DomainModel::TKD_PROVIDER_LOCAL));
|
||||||
$arrDomain = [
|
$arrDomain = [
|
||||||
'd_domain' => $this->normalizeStoredDomain($arrRows[0] ?? '', $arrRows[14] ?? DomainModel::MATCH_TYPE_EXACT),
|
'd_domain' => $this->normalizeStoredDomain($arrRowAssoc['d_domain'] ?? '', $arrRowAssoc['d_match_type'] ?? DomainModel::MATCH_TYPE_EXACT),
|
||||||
't_id' => $arrRows[1],
|
't_id' => $arrRowAssoc['t_id'] ?? 1,
|
||||||
'd_name' => $arrRows[2],
|
'd_name' => $arrRowAssoc['d_name'] ?? '',
|
||||||
'd_keywords' => $arrRows[3],
|
'd_keywords' => $arrRowAssoc['d_keywords'] ?? '',
|
||||||
'd_index_title' => $arrRows[4],
|
'd_index_title' => $arrRowAssoc['d_index_title'] ?? '',
|
||||||
'd_index_keywords' => $arrRows[5],
|
'd_index_keywords' => $arrRowAssoc['d_index_keywords'] ?? '',
|
||||||
'd_index_description' => $arrRows[6],
|
'd_index_description' => $arrRowAssoc['d_index_description'] ?? '',
|
||||||
'd_description' => $arrRows[7],
|
'd_description' => $arrRowAssoc['d_description'] ?? '',
|
||||||
'd_statis' => $arrRows[8],
|
'd_statis' => $arrRowAssoc['d_statis'] ?? '',
|
||||||
'd_logo_type' => (int)$arrRows[9],
|
'd_logo_type' => (int)($arrRowAssoc['d_logo_type'] ?? 0),
|
||||||
'd_text_logo' => $arrRows[10],
|
'd_text_logo' => $arrRowAssoc['d_text_logo'] ?? '',
|
||||||
'd_img_logo' => $arrRows[11],
|
'd_img_logo' => $arrRowAssoc['d_img_logo'] ?? '',
|
||||||
'd_content_encode' => $arrRows[12],
|
'd_content_encode' => $arrRowAssoc['d_content_encode'] ?? 0,
|
||||||
'info_id' => $arrRows[13],
|
'info_id' => $arrRowAssoc['info_id'] ?? 0,
|
||||||
'd_match_type' => $this->normalizeMatchType($arrRows[14] ?? DomainModel::MATCH_TYPE_EXACT),
|
'd_match_type' => $this->normalizeMatchType($arrRowAssoc['d_match_type'] ?? DomainModel::MATCH_TYPE_EXACT),
|
||||||
'd_parent_domain' => $this->normalizeParentDomain($arrRows[15] ?? ''),
|
'd_parent_domain' => $this->normalizeParentDomain($arrRowAssoc['d_parent_domain'] ?? ''),
|
||||||
'd_seed_scope' => $this->normalizeSeedScope($arrRows[16] ?? DomainModel::SEED_SCOPE_DOMAIN),
|
'd_seed_scope' => $this->normalizeSeedScope($arrRowAssoc['d_seed_scope'] ?? DomainModel::SEED_SCOPE_DOMAIN),
|
||||||
'd_baidu_token' => $arrRows[17] ?? null,
|
'd_baidu_token' => $arrRowAssoc['d_baidu_token'] ?? null,
|
||||||
];
|
];
|
||||||
$arrDomain['d_seo_cfg'] = $this->applySeoStrategyProfileForDomainData($arrRows[18] ?? null, $arrDomain, $strStrategyProfile);
|
$arrDomain['d_seo_cfg'] = $this->applySeoStrategyProfileForDomainData($arrRowAssoc['d_seo_cfg'] ?? null, $arrDomain, $strStrategyProfile);
|
||||||
$arrDomain['d_seo_cfg']['tkd'] = array_merge(
|
$arrDomain['d_seo_cfg']['tkd'] = array_merge(
|
||||||
(array)($arrDomain['d_seo_cfg']['tkd'] ?? []),
|
(array)($arrDomain['d_seo_cfg']['tkd'] ?? []),
|
||||||
[
|
[
|
||||||
'mode' => $strTkdMode !== '' ? $strTkdMode : ((trim((string)($arrRows[4] ?? '')) !== '' || trim((string)($arrRows[5] ?? '')) !== '' || trim((string)($arrRows[6] ?? '')) !== '') ? DomainModel::TKD_MODE_FORCE_IMPORT : DomainModel::TKD_MODE_AUTO_GENERATE),
|
'mode' => $strTkdMode !== '' ? $strTkdMode : ((trim((string)($arrRowAssoc['d_index_title'] ?? '')) !== '' || trim((string)($arrRowAssoc['d_index_keywords'] ?? '')) !== '' || trim((string)($arrRowAssoc['d_index_description'] ?? '')) !== '') ? DomainModel::TKD_MODE_FORCE_IMPORT : DomainModel::TKD_MODE_AUTO_GENERATE),
|
||||||
'provider' => $strTkdProvider,
|
'provider' => $strTkdProvider,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
@@ -1385,11 +1402,15 @@ class Site extends BaseController
|
|||||||
try {
|
try {
|
||||||
$arrTemplate = DomainBatchImportTemplateHelper::writeTemplate($this->domainImportTemplateRoot());
|
$arrTemplate = DomainBatchImportTemplateHelper::writeTemplate($this->domainImportTemplateRoot());
|
||||||
$strRelativePath = str_replace($this->bootstrapCodeRoot() . '/public/', '', $arrTemplate['file_path']);
|
$strRelativePath = str_replace($this->bootstrapCodeRoot() . '/public/', '', $arrTemplate['file_path']);
|
||||||
|
$arrSummary = (array)($arrTemplate['summary'] ?? []);
|
||||||
|
|
||||||
return $this->success([
|
return $this->success([
|
||||||
'excel_template_path' => $strRelativePath,
|
'excel_template_path' => $strRelativePath,
|
||||||
'template_file_name' => $arrTemplate['file_name'],
|
'template_file_name' => $arrTemplate['file_name'],
|
||||||
'template_summary' => $arrTemplate['summary'],
|
'template_summary' => $arrSummary,
|
||||||
|
'template_display_headers' => array_values((array)($arrSummary['display_headers'] ?? [])),
|
||||||
|
'template_operator_notice' => array_values((array)($arrSummary['operator_notice'] ?? [])),
|
||||||
|
'template_filling_guidance' => (array)($arrSummary['filling_guidance'] ?? []),
|
||||||
]);
|
]);
|
||||||
} catch (\Throwable $Throwable) {
|
} catch (\Throwable $Throwable) {
|
||||||
return $this->error('9999', $Throwable->getMessage());
|
return $this->error('9999', $Throwable->getMessage());
|
||||||
@@ -1401,11 +1422,15 @@ class Site extends BaseController
|
|||||||
try {
|
try {
|
||||||
$arrTemplate = DomainSupplyBatchTemplateHelper::writeTemplate($this->domainSupplyTemplateRoot());
|
$arrTemplate = DomainSupplyBatchTemplateHelper::writeTemplate($this->domainSupplyTemplateRoot());
|
||||||
$strRelativePath = $this->publicRelativePath((string)$arrTemplate['file_path']);
|
$strRelativePath = $this->publicRelativePath((string)$arrTemplate['file_path']);
|
||||||
|
$arrSummary = (array)($arrTemplate['summary'] ?? []);
|
||||||
|
|
||||||
return $this->success([
|
return $this->success([
|
||||||
'excel_template_path' => $strRelativePath,
|
'excel_template_path' => $strRelativePath,
|
||||||
'template_file_name' => $arrTemplate['file_name'],
|
'template_file_name' => $arrTemplate['file_name'],
|
||||||
'template_summary' => $arrTemplate['summary'],
|
'template_summary' => $arrSummary,
|
||||||
|
'template_display_headers' => array_values((array)($arrSummary['display_headers'] ?? [])),
|
||||||
|
'template_operator_notice' => array_values((array)($arrSummary['operator_notice'] ?? [])),
|
||||||
|
'template_filling_guidance' => (array)($arrSummary['filling_guidance'] ?? []),
|
||||||
]);
|
]);
|
||||||
} catch (\Throwable $Throwable) {
|
} catch (\Throwable $Throwable) {
|
||||||
return $this->error('9999', '生成一体化供给模板失败:' . $Throwable->getMessage());
|
return $this->error('9999', '生成一体化供给模板失败:' . $Throwable->getMessage());
|
||||||
|
|||||||
@@ -10,6 +10,84 @@ use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
|||||||
|
|
||||||
class DomainBatchImportTemplateHelper
|
class DomainBatchImportTemplateHelper
|
||||||
{
|
{
|
||||||
|
public static function getHeaderLabels(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'd_domain' => '域名',
|
||||||
|
'd_name' => '站点名称',
|
||||||
|
't_id' => '模板ID',
|
||||||
|
'd_index_title' => '首页标题',
|
||||||
|
'd_index_keywords' => '首页关键词',
|
||||||
|
'd_index_description' => '首页描述',
|
||||||
|
'strategy_profile' => 'SEO策略',
|
||||||
|
'd_keywords' => '站点关键词',
|
||||||
|
'd_description' => '站点描述',
|
||||||
|
'd_baidu_token' => '百度推送Token',
|
||||||
|
'd_match_type' => '匹配类型',
|
||||||
|
'd_parent_domain' => '父域名',
|
||||||
|
'd_seed_scope' => '种子范围',
|
||||||
|
'd_logo_type' => 'LOGO类型',
|
||||||
|
'd_text_logo' => '文字LOGO',
|
||||||
|
'd_img_logo' => '图片LOGO',
|
||||||
|
'd_statis' => '统计代码',
|
||||||
|
'd_content_encode' => '内容编码',
|
||||||
|
'info_id' => '信息ID',
|
||||||
|
'd_seo_cfg' => '高级SEO配置JSON',
|
||||||
|
'tkd_mode' => 'TKD模式',
|
||||||
|
'tkd_provider' => 'TKD来源',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getHeaderAliases(): array
|
||||||
|
{
|
||||||
|
$labels = self::getHeaderLabels();
|
||||||
|
$aliases = [];
|
||||||
|
foreach ($labels as $field => $label) {
|
||||||
|
$aliases[$field] = $field;
|
||||||
|
$aliases[mb_strtolower($field)] = $field;
|
||||||
|
$aliases[$label] = $field;
|
||||||
|
$aliases[mb_strtolower($label)] = $field;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ([
|
||||||
|
'站点域名' => 'd_domain',
|
||||||
|
'域名host' => 'd_domain',
|
||||||
|
'首页SEO标题' => 'd_index_title',
|
||||||
|
'首页SEO关键词' => 'd_index_keywords',
|
||||||
|
'首页SEO描述' => 'd_index_description',
|
||||||
|
'策略' => 'strategy_profile',
|
||||||
|
'高级配置JSON' => 'd_seo_cfg',
|
||||||
|
'内容编码类型' => 'd_content_encode',
|
||||||
|
] as $alias => $field) {
|
||||||
|
$aliases[$alias] = $field;
|
||||||
|
$aliases[mb_strtolower($alias)] = $field;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aliases;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function normalizeHeader(string $header): string
|
||||||
|
{
|
||||||
|
$normalized = trim($header);
|
||||||
|
if ($normalized === '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$aliases = self::getHeaderAliases();
|
||||||
|
|
||||||
|
return $aliases[$normalized] ?? $aliases[mb_strtolower($normalized)] ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getDisplayHeaders(): array
|
||||||
|
{
|
||||||
|
$labels = self::getHeaderLabels();
|
||||||
|
|
||||||
|
return array_map(
|
||||||
|
static fn(string $field): string => $labels[$field] ?? $field,
|
||||||
|
self::getHeaders()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static function writeWorkbook(
|
public static function writeWorkbook(
|
||||||
string $filePath,
|
string $filePath,
|
||||||
string $sheetTitle,
|
string $sheetTitle,
|
||||||
@@ -65,25 +143,25 @@ class DomainBatchImportTemplateHelper
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'd_domain',
|
'd_domain',
|
||||||
't_id',
|
|
||||||
'd_name',
|
'd_name',
|
||||||
'd_keywords',
|
't_id',
|
||||||
'd_index_title',
|
'd_index_title',
|
||||||
'd_index_keywords',
|
'd_index_keywords',
|
||||||
'd_index_description',
|
'd_index_description',
|
||||||
|
'strategy_profile',
|
||||||
|
'd_keywords',
|
||||||
'd_description',
|
'd_description',
|
||||||
|
'd_baidu_token',
|
||||||
|
'd_match_type',
|
||||||
|
'd_parent_domain',
|
||||||
|
'd_seed_scope',
|
||||||
'd_statis',
|
'd_statis',
|
||||||
'd_logo_type',
|
'd_logo_type',
|
||||||
'd_text_logo',
|
'd_text_logo',
|
||||||
'd_img_logo',
|
'd_img_logo',
|
||||||
'd_content_encode',
|
'd_content_encode',
|
||||||
'info_id',
|
'info_id',
|
||||||
'd_match_type',
|
|
||||||
'd_parent_domain',
|
|
||||||
'd_seed_scope',
|
|
||||||
'd_baidu_token',
|
|
||||||
'd_seo_cfg',
|
'd_seo_cfg',
|
||||||
'strategy_profile',
|
|
||||||
'tkd_mode',
|
'tkd_mode',
|
||||||
'tkd_provider',
|
'tkd_provider',
|
||||||
];
|
];
|
||||||
@@ -92,28 +170,28 @@ class DomainBatchImportTemplateHelper
|
|||||||
public static function getColumnNotes(): array
|
public static function getColumnNotes(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'd_domain' => '必填,站点域名;wildcard 模式可填 *.example.com 或 example.com,由后端归一化。',
|
'd_domain' => '必填。填写站点正式域名,不要带 https:// 。示例:jingxifa.com。只有做泛域名时,才填 *.example.com。',
|
||||||
't_id' => '必填,模板 ID。',
|
'd_name' => '必填。填写站点前台展示名称,会用于页头、页脚和基础 SEO 文案。示例:鲸溪发影视。',
|
||||||
'd_name' => '必填,站点名称。',
|
't_id' => '通常直接填 1。只有明确知道要换模板时才改;不确定就不要改。',
|
||||||
'd_keywords' => '可选,站点关键词。',
|
'd_index_title' => '建议填写。首页给搜索引擎看的标题,尽量自然,不要堆词。建议 28 到 40 字。',
|
||||||
'd_index_title' => '可选,首页标题。',
|
'd_index_keywords' => '建议填写。首页核心关键词,多个词用逗号分隔。示例:短剧推荐,热播短剧,高清短剧。',
|
||||||
'd_index_keywords' => '可选,首页关键词。',
|
'd_index_description' => '建议填写。首页一句话简介,建议 40 到 80 字,写自然一点。',
|
||||||
'd_index_description' => '可选,首页描述。',
|
'strategy_profile' => '通常不用改,默认 standard。只有明确知道要做流量型、扩展型站点时,才改成 traffic 或 expand。',
|
||||||
'd_description' => '可选,站点描述。',
|
'd_keywords' => '可选。不填也能跑;如要补充站点级关键词,可填在这里。',
|
||||||
'd_statis' => '可选,统计代码。',
|
'd_description' => '可选。不填时系统会按站点名称自动兜底一版简介。',
|
||||||
'd_logo_type' => '必填,0 或 1。',
|
'd_baidu_token' => '可选。只有需要百度主动推送时才填写。',
|
||||||
'd_text_logo' => '可选,文字 LOGO。',
|
'd_match_type' => '可选。默认 exact。普通单域名站保持默认即可;只有泛域名场景才需要改。',
|
||||||
'd_img_logo' => '可选,图片 LOGO。',
|
'd_parent_domain' => '只有 wildcard 泛域名场景才需要填根域名。普通单域名站留空即可。',
|
||||||
'd_content_encode' => '必填,通常填 0。',
|
'd_seed_scope' => '可选。默认 domain。普通单域名站不用改;只有特殊 host 级种子策略才改。',
|
||||||
'info_id' => '可选,通常填 0。',
|
'd_statis' => '可选。统计代码区,运营通常不用填。',
|
||||||
'd_match_type' => '可选,exact 或 wildcard。',
|
'd_logo_type' => '通常填 0。普通站点不用改;如果是纯图片 LOGO 再按技术要求调整。',
|
||||||
'd_parent_domain' => 'wildcard 模式建议填写根域名。',
|
'd_text_logo' => '可选。填写前台显示的文字 LOGO;不填时可按站点名称兜底。',
|
||||||
'd_seed_scope' => '可选,domain 或 host。',
|
'd_img_logo' => '可选。只有要使用图片 LOGO 时才填写。',
|
||||||
'd_baidu_token' => '可选,百度推送 token。',
|
'd_content_encode' => '通常填 0。普通运营不用改。',
|
||||||
'd_seo_cfg' => '可选,JSON;会在 strategy_profile 默认值基础上再做覆盖。',
|
'info_id' => '通常填 0。普通运营不用改。',
|
||||||
'strategy_profile' => '可选,standard / traffic / expand / closed。',
|
'd_seo_cfg' => '可选。高级配置区,通常给技术同学使用。运营不需要填写;只有明确要覆盖默认 SEO 策略时再填 JSON。',
|
||||||
'tkd_mode' => '可选,1/auto_generate=全自动生成;2/ai_optimize=导入 TKD 后本地/AI 优化;3/force_import=强制使用导入值。',
|
'tkd_mode' => '可选。一般不用填。留空时系统会根据首页三要素是否导入自动选择模式。',
|
||||||
'tkd_provider' => '可选,local 或 openai;当前默认 local,本地优化已生效,后续可接 OpenAI API。',
|
'tkd_provider' => '可选。一般保持 local,不需要运营修改。',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,52 +199,52 @@ class DomainBatchImportTemplateHelper
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
'demo-example-com',
|
'd_domain' => 'demo-example-com',
|
||||||
1,
|
'd_name' => 'Demo Example',
|
||||||
'Demo Example',
|
't_id' => 1,
|
||||||
'Demo Example,影视推荐',
|
'd_index_title' => 'Demo Example 影视内容推荐',
|
||||||
'Demo Example 影视内容推荐',
|
'd_index_keywords' => 'Demo Example,影视推荐',
|
||||||
'Demo Example,影视推荐',
|
'd_index_description' => 'Demo Example 内容整理与推荐。',
|
||||||
'Demo Example 内容整理与推荐。',
|
'strategy_profile' => 'standard',
|
||||||
'Demo Example 内容整理与推荐。',
|
'd_keywords' => 'Demo Example,影视推荐',
|
||||||
'',
|
'd_description' => 'Demo Example 内容整理与推荐。',
|
||||||
0,
|
'd_baidu_token' => '',
|
||||||
'Demo Example',
|
'd_match_type' => 'exact',
|
||||||
'',
|
'd_parent_domain' => '',
|
||||||
0,
|
'd_seed_scope' => 'domain',
|
||||||
0,
|
'd_statis' => '',
|
||||||
'exact',
|
'd_logo_type' => 0,
|
||||||
'',
|
'd_text_logo' => 'Demo Example',
|
||||||
'domain',
|
'd_img_logo' => '',
|
||||||
'',
|
'd_content_encode' => 0,
|
||||||
'',
|
'info_id' => 0,
|
||||||
'standard',
|
'd_seo_cfg' => '',
|
||||||
'1',
|
'tkd_mode' => '1',
|
||||||
'local',
|
'tkd_provider' => 'local',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'*.traffic-example.com',
|
'd_domain' => '*.traffic-example.com',
|
||||||
1,
|
'd_name' => 'Traffic Example',
|
||||||
'Traffic Example',
|
't_id' => 1,
|
||||||
'Traffic Example,热门推荐',
|
'd_index_title' => 'Traffic Example 热门内容推荐',
|
||||||
'Traffic Example 热门内容推荐',
|
'd_index_keywords' => 'Traffic Example,热门推荐',
|
||||||
'Traffic Example,热门推荐',
|
'd_index_description' => 'Traffic Example 热门内容整理与推荐。',
|
||||||
'Traffic Example 热门内容整理与推荐。',
|
'strategy_profile' => 'traffic',
|
||||||
'Traffic Example 热门内容整理与推荐。',
|
'd_keywords' => 'Traffic Example,热门推荐',
|
||||||
'',
|
'd_description' => 'Traffic Example 热门内容整理与推荐。',
|
||||||
0,
|
'd_baidu_token' => '',
|
||||||
'Traffic Example',
|
'd_match_type' => 'wildcard',
|
||||||
'',
|
'd_parent_domain' => 'traffic-example.com',
|
||||||
0,
|
'd_seed_scope' => 'host',
|
||||||
0,
|
'd_statis' => '',
|
||||||
'wildcard',
|
'd_logo_type' => 0,
|
||||||
'traffic-example.com',
|
'd_text_logo' => 'Traffic Example',
|
||||||
'host',
|
'd_img_logo' => '',
|
||||||
'',
|
'd_content_encode' => 0,
|
||||||
'{"forge":{"route_group":"film"},"structured_data":{"organization_name":"Traffic Example Studio"}}',
|
'info_id' => 0,
|
||||||
'traffic',
|
'd_seo_cfg' => '{"forge":{"route_group":"film"},"structured_data":{"organization_name":"Traffic Example Studio"}}',
|
||||||
'2',
|
'tkd_mode' => '2',
|
||||||
'local',
|
'tkd_provider' => 'local',
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -175,8 +253,45 @@ class DomainBatchImportTemplateHelper
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'headers' => self::getHeaders(),
|
'headers' => self::getHeaders(),
|
||||||
|
'display_headers' => self::getDisplayHeaders(),
|
||||||
|
'header_labels' => self::getHeaderLabels(),
|
||||||
'column_notes' => self::getColumnNotes(),
|
'column_notes' => self::getColumnNotes(),
|
||||||
'example_rows' => self::getExampleRows(),
|
'example_rows' => self::getExampleRows(),
|
||||||
|
'template_type' => 'site_domain_import',
|
||||||
|
'filling_guidance' => [
|
||||||
|
'main_fields' => [
|
||||||
|
'd_domain',
|
||||||
|
'd_name',
|
||||||
|
't_id',
|
||||||
|
'd_index_title',
|
||||||
|
'd_index_keywords',
|
||||||
|
'd_index_description',
|
||||||
|
'strategy_profile',
|
||||||
|
],
|
||||||
|
'optional_fields' => [
|
||||||
|
'd_keywords',
|
||||||
|
'd_description',
|
||||||
|
'd_baidu_token',
|
||||||
|
'd_match_type',
|
||||||
|
'd_parent_domain',
|
||||||
|
'd_seed_scope',
|
||||||
|
'd_statis',
|
||||||
|
'd_logo_type',
|
||||||
|
'd_text_logo',
|
||||||
|
'd_img_logo',
|
||||||
|
'd_content_encode',
|
||||||
|
'info_id',
|
||||||
|
'd_seo_cfg',
|
||||||
|
'tkd_mode',
|
||||||
|
'tkd_provider',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'operator_notice' => [
|
||||||
|
'基础导入模板只负责站点基础信息,不负责 GPT 启动样本字段。',
|
||||||
|
'运营通常只需要先填写域名、站点名称、模板ID、首页标题、首页关键词、首页描述、SEO策略。',
|
||||||
|
'其余字段大多数都有默认值或属于技术配置,可留空。',
|
||||||
|
'如果要做 GPT 供料与启动包,请改用 domain-supply-batch-template.xlsx。',
|
||||||
|
],
|
||||||
'supported_strategy_profiles' => ['standard', 'traffic', 'expand', 'closed'],
|
'supported_strategy_profiles' => ['standard', 'traffic', 'expand', 'closed'],
|
||||||
'supported_match_types' => ['exact', 'wildcard'],
|
'supported_match_types' => ['exact', 'wildcard'],
|
||||||
'supported_seed_scopes' => ['domain', 'host'],
|
'supported_seed_scopes' => ['domain', 'host'],
|
||||||
@@ -189,19 +304,28 @@ class DomainBatchImportTemplateHelper
|
|||||||
$fileName = 'site-domain-import-template.xlsx';
|
$fileName = 'site-domain-import-template.xlsx';
|
||||||
$filePath = $outputRoot . '/' . $fileName;
|
$filePath = $outputRoot . '/' . $fileName;
|
||||||
$summary = self::buildSummary();
|
$summary = self::buildSummary();
|
||||||
|
$headerLabels = self::getHeaderLabels();
|
||||||
$rows = array_map(
|
$rows = array_map(
|
||||||
static function (array $row): array {
|
static function (array $row) use ($headerLabels): array {
|
||||||
return array_combine(self::getHeaders(), $row) ?: [];
|
$displayRow = [];
|
||||||
|
foreach (self::getHeaders() as $field) {
|
||||||
|
$displayRow[$headerLabels[$field] ?? $field] = (string)($row[$field] ?? '');
|
||||||
|
}
|
||||||
|
return $displayRow;
|
||||||
},
|
},
|
||||||
self::getExampleRows()
|
self::getExampleRows()
|
||||||
);
|
);
|
||||||
|
$displayNotes = [];
|
||||||
|
foreach (self::getColumnNotes() as $field => $note) {
|
||||||
|
$displayNotes[$headerLabels[$field] ?? $field] = $note;
|
||||||
|
}
|
||||||
|
|
||||||
self::writeWorkbook(
|
self::writeWorkbook(
|
||||||
$filePath,
|
$filePath,
|
||||||
'site-domain-import',
|
'site-domain-import',
|
||||||
self::getHeaders(),
|
self::getDisplayHeaders(),
|
||||||
$rows,
|
$rows,
|
||||||
self::getColumnNotes()
|
$displayNotes
|
||||||
);
|
);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -8,6 +8,92 @@ use PhpOffice\PhpSpreadsheet\IOFactory;
|
|||||||
|
|
||||||
class DomainSupplyBatchHelper
|
class DomainSupplyBatchHelper
|
||||||
{
|
{
|
||||||
|
protected static function isSampleField(string $field): bool
|
||||||
|
{
|
||||||
|
return in_array($field, [
|
||||||
|
'detail_id',
|
||||||
|
'detail_slug',
|
||||||
|
'search_keyword',
|
||||||
|
'category_parent',
|
||||||
|
'category_child',
|
||||||
|
], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function fillAutoDiscoveredSample(array $row): array
|
||||||
|
{
|
||||||
|
$host = self::hostLabelFromRow($row);
|
||||||
|
if ($host === '') {
|
||||||
|
return [
|
||||||
|
'row' => $row,
|
||||||
|
'status' => 'skipped',
|
||||||
|
'message' => 'host_empty',
|
||||||
|
'filled_fields' => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$needsSample = false;
|
||||||
|
foreach ([
|
||||||
|
'detail_id',
|
||||||
|
'detail_slug',
|
||||||
|
'search_keyword',
|
||||||
|
'category_parent',
|
||||||
|
'category_child',
|
||||||
|
] as $field) {
|
||||||
|
if (trim((string)($row[$field] ?? '')) === '') {
|
||||||
|
$needsSample = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!$needsSample) {
|
||||||
|
return [
|
||||||
|
'row' => $row,
|
||||||
|
'status' => 'not_needed',
|
||||||
|
'message' => 'sample_fields_already_present',
|
||||||
|
'filled_fields' => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$sampleResult = DomainAutoSampleHelper::discover($host, ['limit' => 80]);
|
||||||
|
if (($sampleResult['status'] ?? '') !== 'passed' || empty($sampleResult['sample']) || !is_array($sampleResult['sample'])) {
|
||||||
|
return [
|
||||||
|
'row' => $row,
|
||||||
|
'status' => 'failed',
|
||||||
|
'message' => (string)($sampleResult['message'] ?? 'auto_sample_discovery_failed'),
|
||||||
|
'filled_fields' => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$sample = (array)$sampleResult['sample'];
|
||||||
|
$filledFields = [];
|
||||||
|
$mapping = [
|
||||||
|
'detail_id' => (string)($sample['detail']['detail_id'] ?? ''),
|
||||||
|
'detail_slug' => (string)($sample['detail']['detail_slug'] ?? ''),
|
||||||
|
'search_keyword' => (string)($sample['search']['search_keyword'] ?? ''),
|
||||||
|
'category_parent' => (string)($sample['category']['category_parent'] ?? ''),
|
||||||
|
'category_child' => (string)($sample['category']['category_child'] ?? ''),
|
||||||
|
'play_type' => (string)($sample['play']['play_type'] ?? ''),
|
||||||
|
'play_index' => (string)($sample['play']['play_index'] ?? ''),
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($mapping as $field => $value) {
|
||||||
|
if ($value === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (trim((string)($row[$field] ?? '')) !== '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$row[$field] = $value;
|
||||||
|
$filledFields[] = $field;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'row' => $row,
|
||||||
|
'status' => empty($filledFields) ? 'failed' : 'filled',
|
||||||
|
'message' => empty($filledFields) ? 'auto_sample_discovery_returned_empty_fields' : 'auto_sample_discovered',
|
||||||
|
'filled_fields' => $filledFields,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
protected static function publicRelativeToAbsolutePath(string $path): string
|
protected static function publicRelativeToAbsolutePath(string $path): string
|
||||||
{
|
{
|
||||||
$path = str_replace('\\', '/', trim($path));
|
$path = str_replace('\\', '/', trim($path));
|
||||||
@@ -122,12 +208,28 @@ class DomainSupplyBatchHelper
|
|||||||
throw new \RuntimeException('Replay template rows are empty: ' . $summaryPath);
|
throw new \RuntimeException('Replay template rows are empty: ' . $summaryPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$headerLabels = DomainSupplyBatchTemplateHelper::getHeaderLabels();
|
||||||
|
$displayRows = array_map(
|
||||||
|
static function (array $row) use ($headerLabels): array {
|
||||||
|
$displayRow = [];
|
||||||
|
foreach (DomainSupplyBatchTemplateHelper::getHeaders() as $field) {
|
||||||
|
$displayRow[$headerLabels[$field] ?? $field] = (string)($row[$field] ?? '');
|
||||||
|
}
|
||||||
|
return $displayRow;
|
||||||
|
},
|
||||||
|
$rows
|
||||||
|
);
|
||||||
|
$displayNotes = [];
|
||||||
|
foreach (DomainSupplyBatchTemplateHelper::getColumnNotes() as $field => $note) {
|
||||||
|
$displayNotes[$headerLabels[$field] ?? $field] = $note;
|
||||||
|
}
|
||||||
|
|
||||||
DomainBatchImportTemplateHelper::writeWorkbook(
|
DomainBatchImportTemplateHelper::writeWorkbook(
|
||||||
$outputPath,
|
$outputPath,
|
||||||
'domain-supply-batch',
|
'domain-supply-batch',
|
||||||
DomainSupplyBatchTemplateHelper::getHeaders(),
|
DomainSupplyBatchTemplateHelper::getDisplayHeaders(),
|
||||||
$rows,
|
$displayRows,
|
||||||
DomainSupplyBatchTemplateHelper::getColumnNotes()
|
$displayNotes
|
||||||
);
|
);
|
||||||
|
|
||||||
return $outputPath;
|
return $outputPath;
|
||||||
@@ -164,7 +266,9 @@ class DomainSupplyBatchHelper
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$headers = array_map(static fn ($value): string => trim((string)$value), (array)array_shift($rows));
|
$headers = array_map(static function ($value): string {
|
||||||
|
return DomainSupplyBatchTemplateHelper::normalizeHeader(trim((string)$value));
|
||||||
|
}, (array)array_shift($rows));
|
||||||
$normalized = [];
|
$normalized = [];
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$assoc = [];
|
$assoc = [];
|
||||||
@@ -362,9 +466,19 @@ class DomainSupplyBatchHelper
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$autoSample = self::fillAutoDiscoveredSample($row);
|
||||||
|
$row = (array)($autoSample['row'] ?? $row);
|
||||||
$missing = self::validateRow($row);
|
$missing = self::validateRow($row);
|
||||||
$status = empty($missing) ? 'ready' : 'failed';
|
$status = empty($missing) ? 'ready' : 'failed';
|
||||||
$message = empty($missing) ? 'prepared' : ('missing:' . implode(',', $missing));
|
$message = empty($missing) ? 'prepared' : ('missing:' . implode(',', $missing));
|
||||||
|
if (($autoSample['status'] ?? '') === 'filled') {
|
||||||
|
$message = 'auto_sample_filled:' . implode(',', (array)($autoSample['filled_fields'] ?? []));
|
||||||
|
} elseif (($autoSample['status'] ?? '') === 'failed') {
|
||||||
|
$sampleMissing = array_values(array_filter($missing, static fn(string $field): bool => self::isSampleField($field)));
|
||||||
|
if (!empty($sampleMissing)) {
|
||||||
|
$message .= ';auto_sample_failed:' . (string)($autoSample['message'] ?? '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$siteRow = self::buildSiteImportRow($row);
|
$siteRow = self::buildSiteImportRow($row);
|
||||||
$bootstrapRow = self::buildBootstrapBatchRow($row);
|
$bootstrapRow = self::buildBootstrapBatchRow($row);
|
||||||
@@ -385,6 +499,9 @@ class DomainSupplyBatchHelper
|
|||||||
'site_domain' => (string)($siteRow['d_domain'] ?? ''),
|
'site_domain' => (string)($siteRow['d_domain'] ?? ''),
|
||||||
'bundle_host' => (string)($bootstrapRow['host'] ?? ''),
|
'bundle_host' => (string)($bootstrapRow['host'] ?? ''),
|
||||||
'missing_fields' => $missing,
|
'missing_fields' => $missing,
|
||||||
|
'auto_sample_status' => (string)($autoSample['status'] ?? ''),
|
||||||
|
'auto_sample_message' => (string)($autoSample['message'] ?? ''),
|
||||||
|
'auto_sample_filled_fields' => array_values((array)($autoSample['filled_fields'] ?? [])),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,61 +12,145 @@ class DomainSupplyBatchTemplateHelper
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'host',
|
'host',
|
||||||
'template_id',
|
|
||||||
'strategy_profile',
|
|
||||||
'match_type',
|
|
||||||
'parent_domain',
|
|
||||||
'seed_scope',
|
|
||||||
'site_name',
|
'site_name',
|
||||||
'site_keywords',
|
'template_id',
|
||||||
'site_description',
|
|
||||||
'site_index_title',
|
'site_index_title',
|
||||||
'site_index_keywords',
|
'site_index_keywords',
|
||||||
'site_index_description',
|
'site_index_description',
|
||||||
'baidu_token',
|
'strategy_profile',
|
||||||
'seo_cfg_json',
|
|
||||||
'detail_id',
|
'detail_id',
|
||||||
'detail_slug',
|
'detail_slug',
|
||||||
'search_keyword',
|
'search_keyword',
|
||||||
'category_parent',
|
'category_parent',
|
||||||
'category_child',
|
'category_child',
|
||||||
|
'site_keywords',
|
||||||
|
'site_description',
|
||||||
|
'baidu_token',
|
||||||
|
'match_type',
|
||||||
|
'parent_domain',
|
||||||
|
'seed_scope',
|
||||||
'play_type',
|
'play_type',
|
||||||
'play_index',
|
'play_index',
|
||||||
'forge_index',
|
'forge_index',
|
||||||
'rank_slug',
|
'rank_slug',
|
||||||
'base_url',
|
'base_url',
|
||||||
'bundle_name',
|
'bundle_name',
|
||||||
|
'seo_cfg_json',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getHeaderLabels(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'host' => '域名',
|
||||||
|
'site_name' => '站点名称',
|
||||||
|
'template_id' => '模板ID',
|
||||||
|
'site_index_title' => '首页标题',
|
||||||
|
'site_index_keywords' => '首页关键词',
|
||||||
|
'site_index_description' => '首页描述',
|
||||||
|
'strategy_profile' => 'SEO策略',
|
||||||
|
'detail_id' => '详情样本ID',
|
||||||
|
'detail_slug' => '详情样本Slug',
|
||||||
|
'search_keyword' => '搜索样本关键词',
|
||||||
|
'category_parent' => '父分类Slug',
|
||||||
|
'category_child' => '子分类Slug',
|
||||||
|
'site_keywords' => '站点关键词',
|
||||||
|
'site_description' => '站点描述',
|
||||||
|
'baidu_token' => '百度推送Token',
|
||||||
|
'match_type' => '匹配类型',
|
||||||
|
'parent_domain' => '父域名',
|
||||||
|
'seed_scope' => '种子范围',
|
||||||
|
'play_type' => '播放类型',
|
||||||
|
'play_index' => '播放序号',
|
||||||
|
'forge_index' => '锻造序号',
|
||||||
|
'rank_slug' => '榜单Slug',
|
||||||
|
'base_url' => '站点基础地址',
|
||||||
|
'bundle_name' => '自定义Bundle名称',
|
||||||
|
'seo_cfg_json' => '高级SEO配置JSON',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getHeaderAliases(): array
|
||||||
|
{
|
||||||
|
$labels = self::getHeaderLabels();
|
||||||
|
$aliases = [];
|
||||||
|
foreach ($labels as $field => $label) {
|
||||||
|
$aliases[$field] = $field;
|
||||||
|
$aliases[mb_strtolower($field)] = $field;
|
||||||
|
$aliases[$label] = $field;
|
||||||
|
$aliases[mb_strtolower($label)] = $field;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ([
|
||||||
|
'站点域名' => 'host',
|
||||||
|
'域名host' => 'host',
|
||||||
|
'策略' => 'strategy_profile',
|
||||||
|
'首页SEO标题' => 'site_index_title',
|
||||||
|
'首页SEO关键词' => 'site_index_keywords',
|
||||||
|
'首页SEO描述' => 'site_index_description',
|
||||||
|
'搜索关键词' => 'search_keyword',
|
||||||
|
'父分类' => 'category_parent',
|
||||||
|
'子分类' => 'category_child',
|
||||||
|
'基础地址' => 'base_url',
|
||||||
|
'高级配置JSON' => 'seo_cfg_json',
|
||||||
|
] as $alias => $field) {
|
||||||
|
$aliases[$alias] = $field;
|
||||||
|
$aliases[mb_strtolower($alias)] = $field;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $aliases;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function normalizeHeader(string $header): string
|
||||||
|
{
|
||||||
|
$normalized = trim($header);
|
||||||
|
if ($normalized === '') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$aliases = self::getHeaderAliases();
|
||||||
|
|
||||||
|
return $aliases[$normalized] ?? $aliases[mb_strtolower($normalized)] ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getDisplayHeaders(): array
|
||||||
|
{
|
||||||
|
$labels = self::getHeaderLabels();
|
||||||
|
|
||||||
|
return array_map(
|
||||||
|
static fn(string $field): string => $labels[$field] ?? $field,
|
||||||
|
self::getHeaders()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static function getColumnNotes(): array
|
public static function getColumnNotes(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'host' => '必填,域名或 wildcard 域名;会同时用于站点导入和 bundle 生成。',
|
'host' => '必填。填写站点正式域名,不要带 https:// 。示例:jingxifa.com。只有做泛域名时,才填 *.example.com。',
|
||||||
'template_id' => '必填,站点模板 ID,默认 1。',
|
'site_name' => '必填。填写站点前台展示名称,会用于页头、页脚和基础 SEO 文案。示例:鲸溪发影视。',
|
||||||
'strategy_profile' => '可选,standard / traffic / expand / closed,默认 standard。',
|
'template_id' => '通常直接填 1。只有确认要换模板时才改;不确定就不要改。',
|
||||||
'match_type' => '可选,exact 或 wildcard,默认 exact。',
|
'site_index_title' => '建议填写。首页给搜索引擎看的标题,尽量自然,不要堆词。建议 28 到 40 字。',
|
||||||
'parent_domain' => 'wildcard 模式建议填写根域名。',
|
'site_index_keywords' => '建议填写。首页核心关键词,多个词用逗号分隔。示例:短剧推荐,热播短剧,高清短剧。',
|
||||||
'seed_scope' => '可选,domain 或 host,默认 domain。',
|
'site_index_description' => '建议填写。首页一句话简介,建议 40 到 80 字,写自然一点。',
|
||||||
'site_name' => '可选,站点名称。',
|
'strategy_profile' => '通常不用改,默认 standard。只有明确知道要做流量型、扩展型站点时,才改成 traffic 或 expand。',
|
||||||
'site_keywords' => '可选,站点关键词。',
|
'detail_id' => '通常不用手填。站点部署成功后,系统会优先通过自动样本发现,从当前站点可用内容里自动提取。只有域名还没部署成功、当前只是试跑库、或自动发现失败时,才人工补填真实详情视频 ID。',
|
||||||
'site_description' => '可选,站点描述。',
|
'detail_slug' => '通常不用手填。会和详情样本 ID 一起自动获取。若人工填写,必须和详情样本 ID 对应,不能乱配。',
|
||||||
'site_index_title' => '可选,首页标题;不填时导入链按站点名称推导。',
|
'search_keyword' => '通常不用手填。系统会优先从站点名称、视频 SEO 词、视频标题里自动挑一个可搜索关键词。只有自动发现失败时,再人工填写一个能搜出结果的词。',
|
||||||
'site_index_keywords' => '可选,首页关键词;不填时导入链按站点关键词推导。',
|
'category_parent' => '通常不用手填。系统会从自动样本视频所属分类里提取一级分类 slug。只有自动发现失败时,再人工补填。示例:dian-ying。',
|
||||||
'site_index_description' => '可选,首页描述;不填时导入链按站点描述推导。',
|
'category_child' => '通常不用手填。系统会从自动样本视频所属分类里提取二级分类 slug。只有自动发现失败时,再人工补填。示例:ju-qing-pian。',
|
||||||
'baidu_token' => '可选,百度推送 token。',
|
'site_keywords' => '可选。不填也能跑;如要补充站点级关键词,可填在这里。',
|
||||||
'seo_cfg_json' => '可选,JSON;会在 strategy_profile 默认值基础上继续覆盖。',
|
'site_description' => '可选。不填时系统会按站点名称自动兜底一版简介。',
|
||||||
'detail_id' => '必填,启动包详情样本视频 ID。',
|
'baidu_token' => '可选。只有需要百度主动推送时才填写。',
|
||||||
'detail_slug' => '必填,启动包详情样本 slug。',
|
'match_type' => '可选。默认 exact。普通单域名站保持默认即可;只有泛域名场景才需要改。',
|
||||||
'search_keyword' => '必填,启动包搜索页样本关键词。',
|
'parent_domain' => '只有 wildcard 泛域名场景才需要填根域名。普通单域名站留空即可。',
|
||||||
'category_parent' => '必填,父分类 slug。',
|
'seed_scope' => '可选。默认 domain。普通单域名站不用改;只有特殊 host 级种子策略才改。',
|
||||||
'category_child' => '必填,子分类 slug。',
|
'play_type' => '可选。默认 douban。自动样本发现成功时通常也能自动带出,不需要运营关心。',
|
||||||
'play_type' => '可选,默认 douban。',
|
'play_index' => '可选。默认 1。通常不用改。',
|
||||||
'play_index' => '可选,默认 1。',
|
'forge_index' => '可选。默认 1。通常不用改。',
|
||||||
'forge_index' => '可选,默认 1。',
|
'rank_slug' => '可选。默认 daily。通常不用改。',
|
||||||
'rank_slug' => '可选,默认 daily。',
|
'base_url' => '可选。默认自动按 https://域名 生成。只有特殊环境才手填。',
|
||||||
'base_url' => '可选,默认 https://<host>。',
|
'bundle_name' => '可选。一般留空,系统会按域名自动生成 bundle 目录名。',
|
||||||
'bundle_name' => '可选,自定义 bundle 目录名。',
|
'seo_cfg_json' => '可选。高级配置区,通常给技术同学使用。运营不需要填写;只有明确要覆盖默认 SEO 策略时再填 JSON。',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,8 +218,50 @@ class DomainSupplyBatchTemplateHelper
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'headers' => self::getHeaders(),
|
'headers' => self::getHeaders(),
|
||||||
|
'display_headers' => self::getDisplayHeaders(),
|
||||||
|
'header_labels' => self::getHeaderLabels(),
|
||||||
'column_notes' => self::getColumnNotes(),
|
'column_notes' => self::getColumnNotes(),
|
||||||
'example_rows' => self::getExampleRows(),
|
'example_rows' => self::getExampleRows(),
|
||||||
|
'template_type' => 'gpt_supply_batch',
|
||||||
|
'filling_guidance' => [
|
||||||
|
'main_fields' => [
|
||||||
|
'host',
|
||||||
|
'site_name',
|
||||||
|
'template_id',
|
||||||
|
'site_index_title',
|
||||||
|
'site_index_keywords',
|
||||||
|
'site_index_description',
|
||||||
|
'strategy_profile',
|
||||||
|
],
|
||||||
|
'auto_discovery_fields' => [
|
||||||
|
'detail_id',
|
||||||
|
'detail_slug',
|
||||||
|
'search_keyword',
|
||||||
|
'category_parent',
|
||||||
|
'category_child',
|
||||||
|
],
|
||||||
|
'optional_fields' => [
|
||||||
|
'site_keywords',
|
||||||
|
'site_description',
|
||||||
|
'baidu_token',
|
||||||
|
'match_type',
|
||||||
|
'parent_domain',
|
||||||
|
'seed_scope',
|
||||||
|
'play_type',
|
||||||
|
'play_index',
|
||||||
|
'forge_index',
|
||||||
|
'rank_slug',
|
||||||
|
'base_url',
|
||||||
|
'bundle_name',
|
||||||
|
'seo_cfg_json',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'operator_notice' => [
|
||||||
|
'运营通常只需要先填写主填写区。',
|
||||||
|
'详情样本ID、详情样本Slug、搜索样本关键词、父分类Slug、子分类Slug 通常可以留空。',
|
||||||
|
'这些样本字段会在域名部署成功或试跑库有可用内容时,优先自动发现并补全。',
|
||||||
|
'只有自动发现失败时,才需要人工补填样本字段。',
|
||||||
|
],
|
||||||
'supported_strategy_profiles' => [
|
'supported_strategy_profiles' => [
|
||||||
DomainModel::SEO_STRATEGY_PROFILE_STANDARD,
|
DomainModel::SEO_STRATEGY_PROFILE_STANDARD,
|
||||||
DomainModel::SEO_STRATEGY_PROFILE_TRAFFIC,
|
DomainModel::SEO_STRATEGY_PROFILE_TRAFFIC,
|
||||||
@@ -165,12 +291,29 @@ class DomainSupplyBatchTemplateHelper
|
|||||||
$fileName = 'domain-supply-batch-template.xlsx';
|
$fileName = 'domain-supply-batch-template.xlsx';
|
||||||
$filePath = $outputRoot . '/' . $fileName;
|
$filePath = $outputRoot . '/' . $fileName;
|
||||||
|
|
||||||
|
$headerLabels = self::getHeaderLabels();
|
||||||
|
$displayHeaders = self::getDisplayHeaders();
|
||||||
|
$displayRows = array_map(
|
||||||
|
static function (array $row) use ($headerLabels): array {
|
||||||
|
$displayRow = [];
|
||||||
|
foreach (self::getHeaders() as $field) {
|
||||||
|
$displayRow[$headerLabels[$field] ?? $field] = (string)($row[$field] ?? '');
|
||||||
|
}
|
||||||
|
return $displayRow;
|
||||||
|
},
|
||||||
|
self::getExampleRows()
|
||||||
|
);
|
||||||
|
$displayNotes = [];
|
||||||
|
foreach (self::getColumnNotes() as $field => $note) {
|
||||||
|
$displayNotes[$headerLabels[$field] ?? $field] = $note;
|
||||||
|
}
|
||||||
|
|
||||||
DomainBatchImportTemplateHelper::writeWorkbook(
|
DomainBatchImportTemplateHelper::writeWorkbook(
|
||||||
$filePath,
|
$filePath,
|
||||||
'domain-supply-batch',
|
'domain-supply-batch',
|
||||||
self::getHeaders(),
|
$displayHeaders,
|
||||||
self::getExampleRows(),
|
$displayRows,
|
||||||
self::getColumnNotes()
|
$displayNotes
|
||||||
);
|
);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|||||||
Binary file not shown.
@@ -299,3 +299,73 @@
|
|||||||
2. 再补 B 组 9 站
|
2. 再补 B 组 9 站
|
||||||
3. 同时单独盯缓存滞后 4 站
|
3. 同时单独盯缓存滞后 4 站
|
||||||
4. 一旦出现首批已抓 / 已收录样本,立即回写主线文档作为样板
|
4. 一旦出现首批已抓 / 已收录样本,立即回写主线文档作为样板
|
||||||
|
|
||||||
|
## 11. 2026-04-18 当日进度判断
|
||||||
|
|
||||||
|
### 今日总判断
|
||||||
|
|
||||||
|
今天这轮蜘蛛日志,整体符合“第一阶段起量期预期”,但还没有达到理想推进速度。
|
||||||
|
|
||||||
|
更准确地说:
|
||||||
|
|
||||||
|
1. 不是偏离预期
|
||||||
|
2. 不是已经明显爆发
|
||||||
|
3. 而是“方向正确、已有 deep page 正向信号,但 sitemap 与 search 链路还没真正跑起来”
|
||||||
|
|
||||||
|
### 今日符合预期的部分
|
||||||
|
|
||||||
|
1. 多个站已经出现真实 `detail / play` 命中
|
||||||
|
- `jingxifa.com`
|
||||||
|
- `codohealth.com`
|
||||||
|
- `lgyz.net`
|
||||||
|
- `jpjdxs.com`
|
||||||
|
- `gxhongzhuang.com`
|
||||||
|
- `leici1940.com`
|
||||||
|
- `oronorent.com`
|
||||||
|
2. 当前主问题不再是“大面积基础链路失效”
|
||||||
|
3. 旧硬 `404` 没有成为这轮主旋律
|
||||||
|
4. 说明这批 GPT 模板修复已经开始被蜘蛛侧真实吃到
|
||||||
|
|
||||||
|
### 今日未达理想预期的部分
|
||||||
|
|
||||||
|
1. `sitemap` 命中仍偏弱
|
||||||
|
2. 搜索页真实回访仍不够,很多还是测试探针
|
||||||
|
3. 仍有一批站停在首页层 / robots 层
|
||||||
|
4. 缓存滞后站还没有完全收口
|
||||||
|
|
||||||
|
### 当前阶段结论
|
||||||
|
|
||||||
|
如果按 7 天主线节奏看:
|
||||||
|
|
||||||
|
1. Day 1 到 Day 2 的目标,当前基本达标
|
||||||
|
2. Day 3 到 Day 4 想看到的 `sitemap -> detail` 与 `search -> detail`,现在只完成了一半
|
||||||
|
|
||||||
|
因此,今天的正式结论定为:
|
||||||
|
|
||||||
|
> SEO 进度总体符合“修复后开始进入正向回访期”的预期,但还不符合“sitemap 与搜索链路快速放量”的理想预期。
|
||||||
|
|
||||||
|
### 今日最值得继续追的站
|
||||||
|
|
||||||
|
1. `jingxifa.com`
|
||||||
|
2. `codohealth.com`
|
||||||
|
3. `lgyz.net`
|
||||||
|
4. `jpjdxs.com`
|
||||||
|
|
||||||
|
### 今日最需要警惕的站
|
||||||
|
|
||||||
|
1. `cnzhenbang.com`
|
||||||
|
2. `lcdchq.com`
|
||||||
|
3. `oronorent.com`
|
||||||
|
4. `jxxgygy.com`
|
||||||
|
5. `liangzuan.net`
|
||||||
|
|
||||||
|
### 明日优先动作
|
||||||
|
|
||||||
|
1. 继续盯缓存滞后 4 站:
|
||||||
|
- `jingxifa.com`
|
||||||
|
- `lcdchq.com`
|
||||||
|
- `cnzhenbang.com`
|
||||||
|
- `oronorent.com`
|
||||||
|
2. 单独复核 `jxxgygy.com` 的 `/sitemap.xml => 444`
|
||||||
|
3. 看 `cnzhenbang.com` 是否开始进入 `detail`
|
||||||
|
4. 看 `lgyz.net`、`jpjdxs.com` 是否继续扩大 `detail -> play`
|
||||||
|
|||||||
@@ -147,3 +147,62 @@
|
|||||||
|
|
||||||
- GPT 模板线今天没有新增结构性故障,重点仍在缓存收口和深页回访扩张。
|
- GPT 模板线今天没有新增结构性故障,重点仍在缓存收口和深页回访扩张。
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 2026-04-18 正式复盘
|
||||||
|
|
||||||
|
- 日期:2026-04-18
|
||||||
|
- 复盘人:Codex / 团队
|
||||||
|
- 今日处理域名:A组6站 + B组9站
|
||||||
|
- 今日查看日志时间窗口:2026-04-17 09:10:03 ~ 2026-04-17 22:20:02
|
||||||
|
- 今日是否执行清缓存:部分已列优先执行单,尚未全部收口
|
||||||
|
- 今日是否执行 `curl` 对照:已对部分缓存滞后站做过对照
|
||||||
|
|
||||||
|
## 今日新增日志结论
|
||||||
|
|
||||||
|
1. GPT 模板线已经出现多站 `detail / play` 正向回访,说明修复方向正确。
|
||||||
|
2. `jingxifa.com`、`codohealth.com`、`lgyz.net`、`jpjdxs.com` 是当前最明显的正向样本。
|
||||||
|
3. `sitemap` 命中整体仍偏弱,搜索页真实回访不足,链路还没有完全跑通。
|
||||||
|
4. `cnzhenbang.com`、`lcdchq.com`、`oronorent.com` 仍受缓存或浅层抓取影响。
|
||||||
|
5. `jxxgygy.com` 出现 `/sitemap.xml => 444`,属于需要单独复核的风险项。
|
||||||
|
|
||||||
|
## 今日缓存复查结论
|
||||||
|
|
||||||
|
### 已恢复一致
|
||||||
|
|
||||||
|
1. 暂未把任何站正式降级为“完全恢复一致”
|
||||||
|
|
||||||
|
### 仍需继续跟缓存
|
||||||
|
|
||||||
|
1. `jingxifa.com`
|
||||||
|
2. `lcdchq.com`
|
||||||
|
3. `cnzhenbang.com`
|
||||||
|
4. `oronorent.com`
|
||||||
|
|
||||||
|
### 疑似不是缓存问题
|
||||||
|
|
||||||
|
1. `jxxgygy.com` 的 sitemap 异常更像链路或规则问题
|
||||||
|
2. `liangzuan.net` 当前窗口无明显蜘蛛信号,不属于缓存结论
|
||||||
|
|
||||||
|
## 今日新增正向信号
|
||||||
|
|
||||||
|
1. `jingxifa.com` 已有稳定 `detail + play`
|
||||||
|
2. `codohealth.com` 已有 `detail + play-like`
|
||||||
|
3. `lgyz.net` 已有 `detail + play`
|
||||||
|
|
||||||
|
## 今日风险项
|
||||||
|
|
||||||
|
1. `sitemap` 整体抓取信号仍弱
|
||||||
|
2. 搜索页真实回访不足,测试探针仍在干扰判断
|
||||||
|
3. 缓存滞后 4 站尚未完成收口
|
||||||
|
|
||||||
|
## 明日优先处理
|
||||||
|
|
||||||
|
1. 继续盯 `jingxifa.com`
|
||||||
|
2. 继续盯 `lcdchq.com`
|
||||||
|
3. 继续盯 `cnzhenbang.com`
|
||||||
|
4. 继续盯 `oronorent.com`
|
||||||
|
5. 复核 `jxxgygy.com` 的 `/sitemap.xml => 444`
|
||||||
|
|
||||||
|
## 一句话复盘
|
||||||
|
|
||||||
|
- 今天的 SEO 进度总体符合“修复后进入正向回访期”的预期,但还未达到 sitemap 和搜索链路快速放量的理想状态。
|
||||||
|
|||||||
@@ -84,6 +84,37 @@
|
|||||||
2. GPT 专属目录负责做节奏管理、跟踪板和阶段汇总
|
2. GPT 专属目录负责做节奏管理、跟踪板和阶段汇总
|
||||||
3. 每日复盘优先写到 [03-GPT模板每日复盘模板-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/03-GPT模板每日复盘模板-2026-04-18.md)
|
3. 每日复盘优先写到 [03-GPT模板每日复盘模板-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/03-GPT模板每日复盘模板-2026-04-18.md)
|
||||||
|
|
||||||
|
## 2026-04-18 当日结论
|
||||||
|
|
||||||
|
### 总判断
|
||||||
|
|
||||||
|
今天这轮 GPT 模板蜘蛛进度属于:
|
||||||
|
|
||||||
|
1. 总体正向
|
||||||
|
2. 符合第一阶段预期
|
||||||
|
3. 但尚未达到理想放量速度
|
||||||
|
|
||||||
|
### 已确认的正向样本
|
||||||
|
|
||||||
|
1. `jingxifa.com`
|
||||||
|
2. `codohealth.com`
|
||||||
|
3. `lgyz.net`
|
||||||
|
4. `jpjdxs.com`
|
||||||
|
|
||||||
|
### 当前主要卡点
|
||||||
|
|
||||||
|
1. `sitemap` 命中偏弱
|
||||||
|
2. 搜索页真实回访偏少
|
||||||
|
3. 缓存滞后站尚未完全收口
|
||||||
|
4. 部分弱站仍停在首页层 / robots 层
|
||||||
|
|
||||||
|
### 明日执行重点
|
||||||
|
|
||||||
|
1. P0 继续盯缓存滞后 4 站
|
||||||
|
2. P1 继续追 `codohealth.com`、`lgyz.net`、`jpjdxs.com`
|
||||||
|
3. 单独复核 `jxxgygy.com` 的 sitemap 风险
|
||||||
|
4. 观察 `cnzhenbang.com` 是否开始进入 detail 层
|
||||||
|
|
||||||
## 当前全局优先级
|
## 当前全局优先级
|
||||||
|
|
||||||
### P0
|
### P0
|
||||||
|
|||||||
219
docs/gpt-template-seo/09-GPT模板次日蜘蛛日志判读模板-2026-04-19.md
Normal file
219
docs/gpt-template-seo/09-GPT模板次日蜘蛛日志判读模板-2026-04-19.md
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
# 09 GPT模板次日蜘蛛日志判读模板 2026-04-19
|
||||||
|
|
||||||
|
这份文档是给明天继续看 GPT 模板蜘蛛日志时直接套用的。
|
||||||
|
|
||||||
|
目标很简单:
|
||||||
|
|
||||||
|
1. 不重新发明判读口径
|
||||||
|
2. 先看最关键的站,再看其余样本站
|
||||||
|
3. 把“是否符合预期”快速落成统一结论
|
||||||
|
|
||||||
|
建议和下面几份文档一起开着看:
|
||||||
|
|
||||||
|
- [01-GPT模板7天SEO执行主线-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/01-GPT模板7天SEO执行主线-2026-04-18.md)
|
||||||
|
- [03-GPT模板每日复盘模板-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/03-GPT模板每日复盘模板-2026-04-18.md)
|
||||||
|
- [04-GPT模板A-B组日志跟踪板-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/04-GPT模板A-B组日志跟踪板-2026-04-18.md)
|
||||||
|
- [2026-04-18-7天推收录执行主线.md](/www/wwwroot/diff-maccms/SEONexus/docs/2026-04-18-7天推收录执行主线.md)
|
||||||
|
|
||||||
|
## 明日先看什么
|
||||||
|
|
||||||
|
先看 P0,再看 P1,最后补 P2。
|
||||||
|
|
||||||
|
### P0 缓存与深页突破优先站
|
||||||
|
|
||||||
|
1. `jingxifa.com`
|
||||||
|
2. `lcdchq.com`
|
||||||
|
3. `cnzhenbang.com`
|
||||||
|
4. `oronorent.com`
|
||||||
|
|
||||||
|
### P1 已出现正向信号、需要确认是否扩大
|
||||||
|
|
||||||
|
1. `codohealth.com`
|
||||||
|
2. `lgyz.net`
|
||||||
|
3. `jpjdxs.com`
|
||||||
|
|
||||||
|
### P2 风险或弱信号观察站
|
||||||
|
|
||||||
|
1. `liangzuan.net`
|
||||||
|
2. `jxxgygy.com`
|
||||||
|
3. `gxhongzhuang.com`
|
||||||
|
4. `leici1940.com`
|
||||||
|
5. `pcslcl.com`
|
||||||
|
6. `sdxtwnc.com`
|
||||||
|
7. `gz-yxsw.com`
|
||||||
|
8. `glae.cc`
|
||||||
|
|
||||||
|
## 明日判读顺序
|
||||||
|
|
||||||
|
### 第 1 步:先判断整体方向有没有继续向前
|
||||||
|
|
||||||
|
先回答这 3 个问题:
|
||||||
|
|
||||||
|
1. 今天有没有新增 `detail / play` 命中站点
|
||||||
|
2. 昨天已有正向信号的站,今天是否继续重复回访
|
||||||
|
3. `sitemap / search` 是否比昨天更强
|
||||||
|
|
||||||
|
如果这 3 个问题里有 2 个以上是正向,就可以先判为:
|
||||||
|
|
||||||
|
- 总体继续向前
|
||||||
|
|
||||||
|
如果只有第 1 条或第 2 条成立,但 `sitemap / search` 仍弱,就判为:
|
||||||
|
|
||||||
|
- 仍符合预期,但推进速度一般
|
||||||
|
|
||||||
|
如果 3 条都没有改善,就判为:
|
||||||
|
|
||||||
|
- 进度偏慢,需要怀疑缓存、入口链路或站点质量问题
|
||||||
|
|
||||||
|
### 第 2 步:逐站看是不是“浅层”还是“深层”
|
||||||
|
|
||||||
|
优先按这个层级判断:
|
||||||
|
|
||||||
|
1. `robots.txt` / `/`
|
||||||
|
2. `category`
|
||||||
|
3. `detail`
|
||||||
|
4. `play`
|
||||||
|
5. `search`
|
||||||
|
6. `sitemap`
|
||||||
|
|
||||||
|
原则:
|
||||||
|
|
||||||
|
1. 只停留在 `robots` / 首页,不算明显进展
|
||||||
|
2. 进入 `detail`,才算真正开始吃内容页
|
||||||
|
3. 出现 `play`,说明深层链路更进一步
|
||||||
|
4. `search` 和 `sitemap` 增强,才代表放量基础变好
|
||||||
|
|
||||||
|
### 第 3 步:逐站判断是不是缓存问题
|
||||||
|
|
||||||
|
对 4 个 P0 站,统一问这 3 个问题:
|
||||||
|
|
||||||
|
1. 普通访问是否仍落后于 `?__nocache=1`
|
||||||
|
2. 普通访问 `title / h1 / canonical` 是否已经追平
|
||||||
|
3. 蜘蛛日志里的深页访问,是否和前台当前页输出相互印证
|
||||||
|
|
||||||
|
如果第 1 条仍成立,就继续归类为:
|
||||||
|
|
||||||
|
- 缓存滞后未收口
|
||||||
|
|
||||||
|
如果第 1 条不成立,但蜘蛛仍只打浅层,就归类为:
|
||||||
|
|
||||||
|
- 已不主要是缓存问题,转为抓取层问题
|
||||||
|
|
||||||
|
## 明日快速填写模板
|
||||||
|
|
||||||
|
- 复盘日期:2026-04-19
|
||||||
|
- 日志时间窗口:
|
||||||
|
- 复盘人:
|
||||||
|
- 今日先看组别:A组 / B组 / 全量
|
||||||
|
|
||||||
|
## 一、整体判断
|
||||||
|
|
||||||
|
- 今日总判断:
|
||||||
|
- 是否符合预期:
|
||||||
|
- 是否比 2026-04-18 更进一步:
|
||||||
|
|
||||||
|
可直接三选一:
|
||||||
|
|
||||||
|
1. 明显变好
|
||||||
|
2. 基本符合预期,但速度一般
|
||||||
|
3. 明显低于预期
|
||||||
|
|
||||||
|
## 二、P0 四站逐站判读
|
||||||
|
|
||||||
|
### 1. `jingxifa.com`
|
||||||
|
|
||||||
|
- 今日新增信号:
|
||||||
|
- 当前层级:
|
||||||
|
- 是否仍有缓存滞后:
|
||||||
|
- 明日动作:
|
||||||
|
|
||||||
|
### 2. `lcdchq.com`
|
||||||
|
|
||||||
|
- 今日新增信号:
|
||||||
|
- 当前层级:
|
||||||
|
- 是否仍有缓存滞后:
|
||||||
|
- 明日动作:
|
||||||
|
|
||||||
|
### 3. `cnzhenbang.com`
|
||||||
|
|
||||||
|
- 今日新增信号:
|
||||||
|
- 当前层级:
|
||||||
|
- 是否仍停留在浅层:
|
||||||
|
- 明日动作:
|
||||||
|
|
||||||
|
### 4. `oronorent.com`
|
||||||
|
|
||||||
|
- 今日新增信号:
|
||||||
|
- 当前层级:
|
||||||
|
- 是否仍有缓存滞后:
|
||||||
|
- 明日动作:
|
||||||
|
|
||||||
|
## 三、P1 正向样本站判读
|
||||||
|
|
||||||
|
### `codohealth.com`
|
||||||
|
|
||||||
|
- 是否继续有 `detail / play-like`:
|
||||||
|
- 是否扩大:
|
||||||
|
- 判断:
|
||||||
|
|
||||||
|
### `lgyz.net`
|
||||||
|
|
||||||
|
- 是否继续有 `detail / play`:
|
||||||
|
- 是否扩大:
|
||||||
|
- 判断:
|
||||||
|
|
||||||
|
### `jpjdxs.com`
|
||||||
|
|
||||||
|
- 是否继续有 `detail / play`:
|
||||||
|
- 是否出现 `search`:
|
||||||
|
- 判断:
|
||||||
|
|
||||||
|
## 四、P2 风险与弱站观察
|
||||||
|
|
||||||
|
### `liangzuan.net`
|
||||||
|
|
||||||
|
- 是否出现新信号:
|
||||||
|
- 是否有异常页面:
|
||||||
|
- 判断:
|
||||||
|
|
||||||
|
### `jxxgygy.com`
|
||||||
|
|
||||||
|
- `/sitemap.xml` 是否恢复:
|
||||||
|
- 是否仍有 `444`:
|
||||||
|
- 判断:
|
||||||
|
|
||||||
|
### 其余弱站
|
||||||
|
|
||||||
|
只写有变化的:
|
||||||
|
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
|
||||||
|
## 五、明日最关键的 5 个判断句
|
||||||
|
|
||||||
|
直接写结论,不写长文。
|
||||||
|
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
4.
|
||||||
|
5.
|
||||||
|
|
||||||
|
## 六、一句话总复盘
|
||||||
|
|
||||||
|
-
|
||||||
|
|
||||||
|
## 建议用词
|
||||||
|
|
||||||
|
如果明天情况继续温和改善,可以直接用:
|
||||||
|
|
||||||
|
> GPT 模板线今天继续保持正向回访,整体仍符合修复后的收录推进预期,但 `sitemap` 与搜索链路仍未进入理想放量阶段。
|
||||||
|
|
||||||
|
如果明天出现明显推进,可以直接用:
|
||||||
|
|
||||||
|
> GPT 模板线今天较昨天更进一步,已有更多站点从浅层访问进入 `detail / play`,开始接近第一阶段目标。
|
||||||
|
|
||||||
|
如果明天表现偏弱,可以直接用:
|
||||||
|
|
||||||
|
> GPT 模板线今天新增有效蜘蛛信号有限,整体低于理想节奏,下一步要优先排除缓存未收口和入口链路偏弱的问题。
|
||||||
136
docs/gpt-template-seo/10-GPT模板运营导入模板使用说明-2026-04-18.md
Normal file
136
docs/gpt-template-seo/10-GPT模板运营导入模板使用说明-2026-04-18.md
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
# 10 GPT模板运营导入模板使用说明 2026-04-18
|
||||||
|
|
||||||
|
这份文档只解决一个问题:
|
||||||
|
|
||||||
|
运营下载模板后,到底该用哪一份,哪些字段必须填,哪些字段通常可以留空。
|
||||||
|
|
||||||
|
## 先记结论
|
||||||
|
|
||||||
|
当前有两类模板:
|
||||||
|
|
||||||
|
1. 基础站点导入模板
|
||||||
|
2. GPT 供料模板
|
||||||
|
|
||||||
|
不要混着用。
|
||||||
|
|
||||||
|
## 一、基础站点导入模板是干什么的
|
||||||
|
|
||||||
|
适用场景:
|
||||||
|
|
||||||
|
1. 先把站点基础信息导入系统
|
||||||
|
2. 先建站、先落基础 SEO 信息
|
||||||
|
3. 还没开始做 GPT 启动包和供料
|
||||||
|
|
||||||
|
这份模板主要管:
|
||||||
|
|
||||||
|
1. 域名
|
||||||
|
2. 站点名称
|
||||||
|
3. 模板ID
|
||||||
|
4. 首页标题
|
||||||
|
5. 首页关键词
|
||||||
|
6. 首页描述
|
||||||
|
7. SEO策略
|
||||||
|
|
||||||
|
下载接口对应:
|
||||||
|
|
||||||
|
- `getDomainImportTemplate`
|
||||||
|
|
||||||
|
## 二、GPT 供料模板是干什么的
|
||||||
|
|
||||||
|
适用场景:
|
||||||
|
|
||||||
|
1. 已经要做 GPT 模板启动包
|
||||||
|
2. 要生成 bundle
|
||||||
|
3. 要继续跑 bootstrap / probe / 供料链
|
||||||
|
|
||||||
|
这份模板除了基础信息,还会带:
|
||||||
|
|
||||||
|
1. 详情样本ID
|
||||||
|
2. 详情样本Slug
|
||||||
|
3. 搜索样本关键词
|
||||||
|
4. 父分类Slug
|
||||||
|
5. 子分类Slug
|
||||||
|
|
||||||
|
下载接口对应:
|
||||||
|
|
||||||
|
- `getDomainSupplyTemplate`
|
||||||
|
|
||||||
|
## 三、运营通常该怎么填
|
||||||
|
|
||||||
|
### 基础站点导入模板
|
||||||
|
|
||||||
|
运营通常先填这 7 项:
|
||||||
|
|
||||||
|
1. 域名
|
||||||
|
2. 站点名称
|
||||||
|
3. 模板ID
|
||||||
|
4. 首页标题
|
||||||
|
5. 首页关键词
|
||||||
|
6. 首页描述
|
||||||
|
7. SEO策略
|
||||||
|
|
||||||
|
其余字段:
|
||||||
|
|
||||||
|
1. 大多数有默认值
|
||||||
|
2. 大多数属于技术配置
|
||||||
|
3. 不确定就先留空
|
||||||
|
|
||||||
|
### GPT 供料模板
|
||||||
|
|
||||||
|
运营通常先填这 7 项:
|
||||||
|
|
||||||
|
1. 域名
|
||||||
|
2. 站点名称
|
||||||
|
3. 模板ID
|
||||||
|
4. 首页标题
|
||||||
|
5. 首页关键词
|
||||||
|
6. 首页描述
|
||||||
|
7. SEO策略
|
||||||
|
|
||||||
|
下面这 5 项通常可以先留空:
|
||||||
|
|
||||||
|
1. 详情样本ID
|
||||||
|
2. 详情样本Slug
|
||||||
|
3. 搜索样本关键词
|
||||||
|
4. 父分类Slug
|
||||||
|
5. 子分类Slug
|
||||||
|
|
||||||
|
原因:
|
||||||
|
|
||||||
|
1. 系统会优先尝试自动样本发现
|
||||||
|
2. 域名部署成功后,可从当前站点真实内容自动提取
|
||||||
|
3. 如果当前只是试跑库,只要库里有可用视频内容,也会优先自动补全
|
||||||
|
4. 只有自动发现失败时,才需要人工补填
|
||||||
|
|
||||||
|
## 四、什么时候样本字段不能完全指望自动化
|
||||||
|
|
||||||
|
下面这几种情况,要提前有心理预期:
|
||||||
|
|
||||||
|
1. 域名还没部署成功
|
||||||
|
2. 当前站点还没有可访问的首页 / 搜索 / 详情链路
|
||||||
|
3. 试跑库里没有合适的视频样本
|
||||||
|
4. 分类 slug 数据本身不完整
|
||||||
|
|
||||||
|
这时系统可能自动补不全,才需要人工补:
|
||||||
|
|
||||||
|
1. 详情样本ID
|
||||||
|
2. 详情样本Slug
|
||||||
|
3. 搜索样本关键词
|
||||||
|
4. 父分类Slug
|
||||||
|
5. 子分类Slug
|
||||||
|
|
||||||
|
## 五、给运营的一句话规则
|
||||||
|
|
||||||
|
可以直接这么记:
|
||||||
|
|
||||||
|
1. 只建站,用基础站点导入模板
|
||||||
|
2. 要跑 GPT 启动包和供料,用 GPT 供料模板
|
||||||
|
3. 两个模板里,前面主填写区优先填
|
||||||
|
4. GPT 供料模板里的样本字段,通常先留空,系统自动补
|
||||||
|
5. 自动补失败,再找技术补样本字段
|
||||||
|
|
||||||
|
## 六、给接手 Codex 的一句话规则
|
||||||
|
|
||||||
|
1. 不要再要求运营手工理解 `detail_id / detail_slug / search_keyword / category_parent / category_child`
|
||||||
|
2. 优先让自动样本发现补全
|
||||||
|
3. 只有自动发现失败,才让人工介入
|
||||||
224
docs/gpt-template-seo/11-GPT模板导入模板中文化与自动样本补全交接-2026-04-18.md
Normal file
224
docs/gpt-template-seo/11-GPT模板导入模板中文化与自动样本补全交接-2026-04-18.md
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
# 11 GPT模板导入模板中文化与自动样本补全交接 2026-04-18
|
||||||
|
|
||||||
|
这份文档用于交接本轮“模板中文化 + 上传兼容 + 自动样本补全”改动。
|
||||||
|
|
||||||
|
目标不是讲所有历史,而是让接手同学快速知道:
|
||||||
|
|
||||||
|
1. 这轮改了什么
|
||||||
|
2. 为什么要改
|
||||||
|
3. 现在运营该怎么用
|
||||||
|
4. 后续如果继续改,应该从哪里接
|
||||||
|
|
||||||
|
## 一、本轮改动目标
|
||||||
|
|
||||||
|
本轮主要解决两个问题:
|
||||||
|
|
||||||
|
1. 运营下载的 Excel 模板字段太技术化,英文字段不易理解
|
||||||
|
2. GPT 供料模板中的样本字段原本看起来像“必须人工填写”,但系统其实已经具备自动发现能力
|
||||||
|
|
||||||
|
因此这轮统一做了三件事:
|
||||||
|
|
||||||
|
1. 下载模板中文化
|
||||||
|
2. 上传解析兼容中文表头
|
||||||
|
3. GPT 供料模板支持样本字段留空后自动补全
|
||||||
|
|
||||||
|
## 二、已经完成的改动
|
||||||
|
|
||||||
|
### 1. 基础站点导入模板中文化
|
||||||
|
|
||||||
|
文件:
|
||||||
|
|
||||||
|
- [DomainBatchImportTemplateHelper.php](/www/wwwroot/diff-maccms/SEONexus/code/app/common/helper/DomainBatchImportTemplateHelper.php)
|
||||||
|
|
||||||
|
已完成:
|
||||||
|
|
||||||
|
1. 模板表头改为中文
|
||||||
|
2. 字段顺序重排为“主填写区在前”
|
||||||
|
3. `notes` 改为运营可理解的人话说明
|
||||||
|
4. `template_summary` 补充:
|
||||||
|
- `template_type`
|
||||||
|
- `filling_guidance`
|
||||||
|
- `operator_notice`
|
||||||
|
|
||||||
|
### 2. 基础站点导入上传兼容中文表头
|
||||||
|
|
||||||
|
文件:
|
||||||
|
|
||||||
|
- [Site.php](/www/wwwroot/diff-maccms/SEONexus/code/app/admin/controller/Site.php)
|
||||||
|
|
||||||
|
已完成:
|
||||||
|
|
||||||
|
1. `uploadDomain` 不再死绑固定列号
|
||||||
|
2. 现在会先读取首行表头
|
||||||
|
3. 再通过 `normalizeHeader(...)` 映射回内部字段
|
||||||
|
4. 因此中文表头和旧英文字段都能兼容
|
||||||
|
|
||||||
|
### 3. GPT 供料模板中文化
|
||||||
|
|
||||||
|
文件:
|
||||||
|
|
||||||
|
- [DomainSupplyBatchTemplateHelper.php](/www/wwwroot/diff-maccms/SEONexus/code/app/common/helper/DomainSupplyBatchTemplateHelper.php)
|
||||||
|
|
||||||
|
已完成:
|
||||||
|
|
||||||
|
1. 模板表头改为中文
|
||||||
|
2. 字段顺序重排为:
|
||||||
|
- 运营主填写区
|
||||||
|
- 自动样本区
|
||||||
|
- 技术参数区
|
||||||
|
3. `notes` 明确说明:
|
||||||
|
- 哪些字段通常先填
|
||||||
|
- 哪些字段通常可以留空
|
||||||
|
- 哪些字段只有技术同学需要关心
|
||||||
|
|
||||||
|
### 4. GPT 供料模板支持自动样本补全
|
||||||
|
|
||||||
|
文件:
|
||||||
|
|
||||||
|
- [DomainSupplyBatchHelper.php](/www/wwwroot/diff-maccms/SEONexus/code/app/common/helper/DomainSupplyBatchHelper.php)
|
||||||
|
|
||||||
|
已完成:
|
||||||
|
|
||||||
|
1. 供料模板上传后,如果以下字段为空:
|
||||||
|
- `detail_id`
|
||||||
|
- `detail_slug`
|
||||||
|
- `search_keyword`
|
||||||
|
- `category_parent`
|
||||||
|
- `category_child`
|
||||||
|
2. 系统会优先调用自动样本发现
|
||||||
|
3. 若自动发现成功,则回填并继续处理
|
||||||
|
4. 若自动发现失败,才把这些字段继续记为缺失
|
||||||
|
|
||||||
|
## 三、自动样本补全依赖什么
|
||||||
|
|
||||||
|
自动样本补全不是凭空猜,它依赖现有自动化能力:
|
||||||
|
|
||||||
|
### 自动样本发现
|
||||||
|
|
||||||
|
文件:
|
||||||
|
|
||||||
|
- [DomainAutoSampleHelper.php](/www/wwwroot/diff-maccms/SEONexus/code/app/common/helper/DomainAutoSampleHelper.php)
|
||||||
|
|
||||||
|
会自动产出:
|
||||||
|
|
||||||
|
1. `detail_id`
|
||||||
|
2. `detail_slug`
|
||||||
|
3. `search_keyword`
|
||||||
|
4. `category_parent`
|
||||||
|
5. `category_child`
|
||||||
|
6. `play_type`
|
||||||
|
7. `play_index`
|
||||||
|
|
||||||
|
### 轨迹探针
|
||||||
|
|
||||||
|
文件:
|
||||||
|
|
||||||
|
- [DomainTrajectoryProbeHelper.php](/www/wwwroot/diff-maccms/SEONexus/code/app/common/helper/DomainTrajectoryProbeHelper.php)
|
||||||
|
|
||||||
|
会用自动样本继续验证:
|
||||||
|
|
||||||
|
1. 首页
|
||||||
|
2. 搜索
|
||||||
|
3. 详情
|
||||||
|
4. 播放
|
||||||
|
|
||||||
|
## 四、现在运营应该怎么用
|
||||||
|
|
||||||
|
### 1. 只做基础建站
|
||||||
|
|
||||||
|
使用:
|
||||||
|
|
||||||
|
- 基础站点导入模板
|
||||||
|
|
||||||
|
优先填写:
|
||||||
|
|
||||||
|
1. 域名
|
||||||
|
2. 站点名称
|
||||||
|
3. 模板ID
|
||||||
|
4. 首页标题
|
||||||
|
5. 首页关键词
|
||||||
|
6. 首页描述
|
||||||
|
7. SEO策略
|
||||||
|
|
||||||
|
### 2. 要做 GPT 启动包和供料
|
||||||
|
|
||||||
|
使用:
|
||||||
|
|
||||||
|
- GPT 供料模板
|
||||||
|
|
||||||
|
优先填写:
|
||||||
|
|
||||||
|
1. 域名
|
||||||
|
2. 站点名称
|
||||||
|
3. 模板ID
|
||||||
|
4. 首页标题
|
||||||
|
5. 首页关键词
|
||||||
|
6. 首页描述
|
||||||
|
7. SEO策略
|
||||||
|
|
||||||
|
下面 5 个字段通常先留空:
|
||||||
|
|
||||||
|
1. 详情样本ID
|
||||||
|
2. 详情样本Slug
|
||||||
|
3. 搜索样本关键词
|
||||||
|
4. 父分类Slug
|
||||||
|
5. 子分类Slug
|
||||||
|
|
||||||
|
原因:
|
||||||
|
|
||||||
|
1. 域名部署成功后可从真实站点链路自动发现
|
||||||
|
2. 若当前只是试跑库,只要库里有可用视频,也会优先自动提取
|
||||||
|
3. 只有自动发现失败时才人工补
|
||||||
|
|
||||||
|
## 五、当前边界
|
||||||
|
|
||||||
|
这轮虽然已经大幅改善体验,但还要明确边界:
|
||||||
|
|
||||||
|
1. 如果域名未部署成功,自动样本不一定能从前台链路补全
|
||||||
|
2. 如果试跑库本身缺少有效视频样本,也可能自动失败
|
||||||
|
3. 如果分类 slug 数据本身缺失,`category_parent / category_child` 可能补不全
|
||||||
|
|
||||||
|
所以正确口径不是“永远不用填”,而是:
|
||||||
|
|
||||||
|
1. 通常先留空
|
||||||
|
2. 系统优先自动补
|
||||||
|
3. 自动失败再人工补
|
||||||
|
|
||||||
|
## 六、当前推荐口径
|
||||||
|
|
||||||
|
以后对运营和接手同学统一这么说:
|
||||||
|
|
||||||
|
1. 基础站点导入模板:先做站点基础信息
|
||||||
|
2. GPT 供料模板:做 GPT 启动包与供料
|
||||||
|
3. GPT 供料模板里的样本字段通常先留空
|
||||||
|
4. 系统会优先自动样本发现
|
||||||
|
5. 只有自动发现失败时,才需要人工补样本字段
|
||||||
|
|
||||||
|
## 七、后续如果继续改,优先从哪里接
|
||||||
|
|
||||||
|
### 优先级 P1
|
||||||
|
|
||||||
|
1. 在后台下载模板按钮旁增加一句提示文案
|
||||||
|
2. 在上传结果页把 `operator_notice` 更明显展示出来
|
||||||
|
|
||||||
|
### 优先级 P2
|
||||||
|
|
||||||
|
1. 让基础导入成功后,直接给出“下一步请使用 GPT 供料模板”的入口
|
||||||
|
2. 在供料模板执行结果页,把“自动样本已补全哪些字段”展示得更直观
|
||||||
|
|
||||||
|
### 优先级 P3
|
||||||
|
|
||||||
|
1. 如果后续还有别的模板线,也统一改成中文表头 + 人话 notes
|
||||||
|
2. 把所有模板下载入口的摘要口径统一化
|
||||||
|
|
||||||
|
## 八、关联文档
|
||||||
|
|
||||||
|
建议接手时一起看:
|
||||||
|
|
||||||
|
1. [README.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/README.md)
|
||||||
|
2. [10-GPT模板运营导入模板使用说明-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/10-GPT模板运营导入模板使用说明-2026-04-18.md)
|
||||||
|
3. [08-GPT模板其它服务器更新交接-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/08-GPT模板其它服务器更新交接-2026-04-18.md)
|
||||||
|
|
||||||
|
## 一句话交接
|
||||||
|
|
||||||
|
> 本轮已经把 GPT 模板线的导入模板从“技术字段驱动”改成“运营可填写驱动”,并把样本字段从“看起来必须手填”收口成“系统优先自动补全、失败才人工补填”的新口径。
|
||||||
96
docs/gpt-template-seo/12-GPT模板导入模板改造交付清单-2026-04-18.md
Normal file
96
docs/gpt-template-seo/12-GPT模板导入模板改造交付清单-2026-04-18.md
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
# 12 GPT模板导入模板改造交付清单 2026-04-18
|
||||||
|
|
||||||
|
这份文档只做一件事:
|
||||||
|
|
||||||
|
把本轮“导入模板中文化 + 自动样本补全”改造的交付边界一次性钉住。
|
||||||
|
|
||||||
|
## 一、本轮已交付
|
||||||
|
|
||||||
|
### 代码
|
||||||
|
|
||||||
|
1. [DomainBatchImportTemplateHelper.php](/www/wwwroot/diff-maccms/SEONexus/code/app/common/helper/DomainBatchImportTemplateHelper.php)
|
||||||
|
2. [DomainSupplyBatchTemplateHelper.php](/www/wwwroot/diff-maccms/SEONexus/code/app/common/helper/DomainSupplyBatchTemplateHelper.php)
|
||||||
|
3. [DomainSupplyBatchHelper.php](/www/wwwroot/diff-maccms/SEONexus/code/app/common/helper/DomainSupplyBatchHelper.php)
|
||||||
|
4. [Site.php](/www/wwwroot/diff-maccms/SEONexus/code/app/admin/controller/Site.php)
|
||||||
|
|
||||||
|
### 文档
|
||||||
|
|
||||||
|
1. [10-GPT模板运营导入模板使用说明-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/10-GPT模板运营导入模板使用说明-2026-04-18.md)
|
||||||
|
2. [11-GPT模板导入模板中文化与自动样本补全交接-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/11-GPT模板导入模板中文化与自动样本补全交接-2026-04-18.md)
|
||||||
|
3. [README.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/README.md)
|
||||||
|
|
||||||
|
## 二、本轮实现结果
|
||||||
|
|
||||||
|
### 基础站点导入模板
|
||||||
|
|
||||||
|
已实现:
|
||||||
|
|
||||||
|
1. 中文表头
|
||||||
|
2. 中文 `notes`
|
||||||
|
3. 主填写区前置
|
||||||
|
4. 上传兼容中文表头
|
||||||
|
5. 上传兼容旧英文字段表头
|
||||||
|
|
||||||
|
### GPT 供料模板
|
||||||
|
|
||||||
|
已实现:
|
||||||
|
|
||||||
|
1. 中文表头
|
||||||
|
2. 中文 `notes`
|
||||||
|
3. 主填写区前置
|
||||||
|
4. 样本字段单独收口
|
||||||
|
5. 样本字段留空时优先自动补全
|
||||||
|
|
||||||
|
### 后台接口返回
|
||||||
|
|
||||||
|
已实现:
|
||||||
|
|
||||||
|
1. `template_summary`
|
||||||
|
2. `template_display_headers`
|
||||||
|
3. `template_operator_notice`
|
||||||
|
4. `template_filling_guidance`
|
||||||
|
|
||||||
|
这意味着后端已经把“模板怎么展示、怎么提示运营”所需的数据准备好了。
|
||||||
|
|
||||||
|
## 三、当前统一口径
|
||||||
|
|
||||||
|
以后统一按这句话对外:
|
||||||
|
|
||||||
|
> 基础站点导入模板先做建站基础信息,GPT 供料模板再做启动包和供料;GPT 供料模板中的样本字段通常可留空,系统会优先自动补全,只有自动发现失败时才人工补填。
|
||||||
|
|
||||||
|
## 四、本轮不再继续做的内容
|
||||||
|
|
||||||
|
本轮先不继续做这些:
|
||||||
|
|
||||||
|
1. 不继续改 GPT 前台模板
|
||||||
|
2. 不继续扩写更多老模板导入逻辑
|
||||||
|
3. 不继续做前端页面 UI 大改
|
||||||
|
4. 不继续把所有后台页面提示都改成统一样式
|
||||||
|
|
||||||
|
原因:
|
||||||
|
|
||||||
|
1. 当前最大问题已经不是 GPT 前台模板结构
|
||||||
|
2. 本轮目标是把导入模板和执行入口收口
|
||||||
|
3. 继续扩大会把当前改动边界搞散
|
||||||
|
|
||||||
|
## 五、如果下一个人继续接
|
||||||
|
|
||||||
|
优先顺序建议:
|
||||||
|
|
||||||
|
1. 先确认下载接口返回的 `template_operator_notice` 和 `template_filling_guidance` 是否已在前端页面展示
|
||||||
|
2. 若页面还没展示,再补页面提示文案
|
||||||
|
3. 若运营仍觉得模板复杂,再继续缩减主填写区,但不要破坏自动样本补全逻辑
|
||||||
|
|
||||||
|
## 六、验收标准
|
||||||
|
|
||||||
|
本轮到此为止,满足以下标准即可视为收口完成:
|
||||||
|
|
||||||
|
1. 运营下载模板看到的是中文表头
|
||||||
|
2. 运营上传中文表头模板不会报错
|
||||||
|
3. GPT 供料模板样本字段留空时能自动补全则自动补全
|
||||||
|
4. 自动补全失败时才提示缺字段
|
||||||
|
5. 后续接手人能通过文档快速知道怎么继续
|
||||||
|
|
||||||
|
## 一句话交付结论
|
||||||
|
|
||||||
|
> 这轮改造已经把“模板难懂、字段太技术化、样本看起来必须手填”的问题,收口成了“中文模板 + 中文说明 + 中文上传兼容 + 样本自动补全优先”的可交付状态。
|
||||||
@@ -32,6 +32,14 @@
|
|||||||
3. [07-GPT模板交接说明-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/07-GPT模板交接说明-2026-04-18.md)
|
3. [07-GPT模板交接说明-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/07-GPT模板交接说明-2026-04-18.md)
|
||||||
4. [08-GPT模板其它服务器更新交接-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/08-GPT模板其它服务器更新交接-2026-04-18.md)
|
4. [08-GPT模板其它服务器更新交接-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/08-GPT模板其它服务器更新交接-2026-04-18.md)
|
||||||
作用:给“原本也是 GPT 模板、现在要对齐到最新版”的其它服务器接手使用。
|
作用:给“原本也是 GPT 模板、现在要对齐到最新版”的其它服务器接手使用。
|
||||||
|
5. [09-GPT模板次日蜘蛛日志判读模板-2026-04-19.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/09-GPT模板次日蜘蛛日志判读模板-2026-04-19.md)
|
||||||
|
作用:给第二天继续看蜘蛛日志时直接套用,快速判断进度是否符合预期。
|
||||||
|
6. [10-GPT模板运营导入模板使用说明-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/10-GPT模板运营导入模板使用说明-2026-04-18.md)
|
||||||
|
作用:告诉运营和接手同学“基础导入模板”和“GPT 供料模板”分别怎么用、哪些字段通常可留空。
|
||||||
|
7. [11-GPT模板导入模板中文化与自动样本补全交接-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/11-GPT模板导入模板中文化与自动样本补全交接-2026-04-18.md)
|
||||||
|
作用:给后续 Codex 或技术接手同学,快速说明这轮模板中文化与自动补全到底改了什么。
|
||||||
|
8. [12-GPT模板导入模板改造交付清单-2026-04-18.md](/www/wwwroot/diff-maccms/SEONexus/docs/gpt-template-seo/12-GPT模板导入模板改造交付清单-2026-04-18.md)
|
||||||
|
作用:把本轮模板改造的交付边界、统一口径和验收标准一次性钉住。
|
||||||
|
|
||||||
首批 4 站的执行材料也全部放在本目录:
|
首批 4 站的执行材料也全部放在本目录:
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user