baidu tuison
This commit is contained in:
@@ -77,6 +77,7 @@ class Site extends BaseController
|
||||
'd_img_logo' => $arrRows[11],
|
||||
'd_content_encode' => $arrRows[12],
|
||||
'info_id' => $arrRows[13],
|
||||
//'d_baidu_token' => $arrRows[14],
|
||||
];
|
||||
|
||||
$TCfgTemplate = TemplatesModel::where('t_id', $arrDomain['t_id'])->find()->t_cfg_template;
|
||||
@@ -180,6 +181,7 @@ class Site extends BaseController
|
||||
"d_content_encode" => $Request->post('d_content_encode'),
|
||||
"t_cfg" => $Request->post('t_cfg'),
|
||||
"info_id" => $Request->post('info_id'),
|
||||
"d_baidu_token" => $Request->post('d_baidu_token'),
|
||||
];
|
||||
|
||||
$arrRule = [
|
||||
|
||||
@@ -128,7 +128,7 @@ class VideoCategoryModel extends MongoModel
|
||||
"children" => []
|
||||
],
|
||||
[
|
||||
'pinyin' => 'han-ju',
|
||||
'v_category_en' => 'han-ju',
|
||||
'name' => '韩剧',
|
||||
"children" => []
|
||||
],
|
||||
|
||||
@@ -21,6 +21,8 @@ class CrawlerConfig
|
||||
'斯诺克',
|
||||
'足球',
|
||||
'篮球',
|
||||
'网球',
|
||||
'LPL',
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
174
code/app/task/logic/BaiduPushVideoUrlLogic.php
Normal file
174
code/app/task/logic/BaiduPushVideoUrlLogic.php
Normal file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\task\logic;
|
||||
|
||||
use app\model\DomainModel;
|
||||
|
||||
class BaiduPushVideoUrlLogic
|
||||
{
|
||||
/**
|
||||
* SiteMap 根目录
|
||||
* @var string
|
||||
*/
|
||||
protected string $strSiteMapPath;
|
||||
|
||||
/**
|
||||
* @var DomainModel[]
|
||||
*/
|
||||
protected array $arrDomainModel = [];
|
||||
|
||||
/**
|
||||
* 每次推送条数
|
||||
*/
|
||||
protected int $limit = 10;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->strSiteMapPath = root_path('storage/SiteMap');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取域名
|
||||
*/
|
||||
public function getDomain(): array
|
||||
{
|
||||
if (empty($this->arrDomainModel)) {
|
||||
$this->arrDomainModel = DomainModel::getAllDomainOnCache();
|
||||
}
|
||||
return $this->arrDomainModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送百度 URL(任务入口)
|
||||
*/
|
||||
public function pushBaiduUrl(): void
|
||||
{
|
||||
foreach ($this->getDomain() as $DomainModel) {
|
||||
|
||||
$domain = $DomainModel->d_domain;
|
||||
$strBaiduToken = $DomainModel->d_baidu_token ?? "";
|
||||
$domainDir = $this->strSiteMapPath . DIRECTORY_SEPARATOR . $domain;
|
||||
|
||||
if (!is_dir($domainDir)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->pushDomainUrls($domain, $strBaiduToken, $domainDir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 推送单个域名
|
||||
*/
|
||||
protected function pushDomainUrls(string $domain, string $strBaiduToken, string $domainDir): void
|
||||
{
|
||||
$stateFile = $domainDir . '/baidu_state.json';
|
||||
|
||||
if(empty($strBaiduToken)){
|
||||
return ;
|
||||
}
|
||||
|
||||
$strApi = 'http://data.zz.baidu.com/urls?site=https://' . $domain . '&token=' . $strBaiduToken;
|
||||
// $strApi = 'http://data.zz.baidu.com/urls?site=https://www.aaggc.com&token=B4bzeDDBHhnoBnov';
|
||||
|
||||
// 1️⃣ 读取 txt 文件
|
||||
$txtFiles = glob($domainDir . '/*.txt');
|
||||
sort($txtFiles);
|
||||
|
||||
if (empty($txtFiles)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 2️⃣ 读取进度
|
||||
if (file_exists($stateFile)) {
|
||||
$state = json_decode(file_get_contents($stateFile), true);
|
||||
} else {
|
||||
$state = [
|
||||
'file_index' => 0,
|
||||
'line_index' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$fileIndex = (int)$state['file_index'];
|
||||
$lineIndex = (int)$state['line_index'];
|
||||
|
||||
$arrPushUrls = [];
|
||||
$newFileIndex = $fileIndex;
|
||||
$newLineIndex = $lineIndex;
|
||||
|
||||
// 3️⃣ 按顺序取 URL
|
||||
for ($i = $fileIndex; $i < count($txtFiles); $i++) {
|
||||
|
||||
$lines = file($txtFiles[$i], FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
$start = ($i === $fileIndex) ? $lineIndex : 0;
|
||||
|
||||
for ($j = $start; $j < count($lines); $j++) {
|
||||
|
||||
$url = trim($lines[$j]);
|
||||
if ($url === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$arrPushUrls[] = $url;
|
||||
$newFileIndex = $i;
|
||||
$newLineIndex = $j + 1;
|
||||
|
||||
if (count($arrPushUrls) >= $this->limit) {
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
|
||||
// 当前文件读完
|
||||
$newFileIndex = $i + 1;
|
||||
$newLineIndex = 0;
|
||||
}
|
||||
|
||||
// 4️⃣ 没有可推送 URL
|
||||
if (empty($arrPushUrls)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 5️⃣ curl 推送
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_URL => $strApi,
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POSTFIELDS => implode("\n", $arrPushUrls),
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Content-Type: text/plain; charset=utf-8'
|
||||
],
|
||||
CURLOPT_TIMEOUT => 10,
|
||||
CURLOPT_CONNECTTIMEOUT => 5,
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_SSL_VERIFYHOST => false,
|
||||
]);
|
||||
|
||||
$result = curl_exec($ch);
|
||||
|
||||
if ($result === false) {
|
||||
curl_close($ch);
|
||||
return;
|
||||
}
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
// 6️⃣ 解析结果
|
||||
$data = json_decode($result, true);
|
||||
|
||||
// 7️⃣ 成功才更新进度
|
||||
if (isset($data['success']) && $data['success'] > 0) {
|
||||
file_put_contents(
|
||||
$stateFile,
|
||||
json_encode([
|
||||
'file_index' => $newFileIndex,
|
||||
'line_index' => $newLineIndex,
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -132,24 +132,6 @@ class VideoSiteMapLogic
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
// public function generateSiteMap()
|
||||
// {
|
||||
// $arrResult = $this->VideoModel->findPaginatedWithCache([], 1, 1);
|
||||
// $this->intTotal = $arrResult['total'];
|
||||
|
||||
// $this->generateMapIndex();
|
||||
|
||||
// $this->generateMapMain();
|
||||
|
||||
// $intTotalPage = ceil($this->intTotal / $this->intPageSize);
|
||||
// for ($intPage = 1; $intPage <= $intTotalPage; $intPage++) {
|
||||
// $this->generateMapInfo($intPage);
|
||||
// }
|
||||
|
||||
// echo date('Y-m-d H:i:s') . PHP_EOL;
|
||||
// }
|
||||
|
||||
|
||||
protected function generateMapInfo(int $intPage)
|
||||
{
|
||||
$intStartPage = $intPage;
|
||||
@@ -208,6 +190,7 @@ EOF;
|
||||
$arrArgs = [
|
||||
'intVId' => $Video->v_id,
|
||||
'strPinYin' => $Video->v_name_en,
|
||||
'strPinyin' => $Video->v_name_en,
|
||||
];
|
||||
|
||||
if ($arrUrlFamily && !empty($arrUrlFamily)) {
|
||||
@@ -283,6 +266,10 @@ EOF;
|
||||
|
||||
foreach ($this->getDomain() as $DomainModel) {
|
||||
|
||||
// 用于 sitemap + txt 的 URL 去重池
|
||||
$arrUrlPool = [];
|
||||
|
||||
|
||||
$strDomainDir = $this->strSiteMapPath . $DomainModel->d_domain;
|
||||
if (is_dir($strDomainDir) == false) {
|
||||
mkdir($strDomainDir);
|
||||
@@ -316,7 +303,15 @@ EOF;
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
EOF;
|
||||
file_put_contents($strMapIndexFile, $strContent);
|
||||
|
||||
|
||||
//file_put_contents($strMapIndexFile, $strContent);
|
||||
$arrUrlPool["https://www.{$DomainModel->d_domain}/"] = [
|
||||
'lastmod' => $this->strDate,
|
||||
'changefreq' => 'daily',
|
||||
'priority' => '1.0',
|
||||
];
|
||||
|
||||
|
||||
// 分类首页 '/vodtype/{strParentCategory}',
|
||||
foreach ($this->arrVideoCategory as $strParentCategoryKey => $arrParentCategory) {
|
||||
@@ -348,10 +343,14 @@ EOF;
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
EOF;
|
||||
file_put_contents($strMapIndexFile, $strContent, FILE_APPEND);
|
||||
//file_put_contents($strMapIndexFile, $strContent, FILE_APPEND);
|
||||
$arrUrlPool[$strUrl] = [
|
||||
'lastmod' => $this->strDate,
|
||||
'changefreq' => 'weekly',
|
||||
'priority' => '0.8',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
// 分类列表 '/vodtype-{strParentCategory}/{strCategory}-{strYear}-{strArea}-{strOrder}/{strLang}-page{intPage}',
|
||||
foreach ($this->arrVideoCategory as $arrParentCategory) {
|
||||
foreach ($arrParentCategory['children'] as $arrChildrenCategory) {
|
||||
@@ -391,7 +390,12 @@ EOF;
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
EOF;
|
||||
file_put_contents($strMapIndexFile, $strContent, FILE_APPEND);
|
||||
//file_put_contents($strMapIndexFile, $strContent, FILE_APPEND);
|
||||
$arrUrlPool[$strUrl] = [
|
||||
'lastmod' => $this->strDate,
|
||||
'changefreq' => 'weekly',
|
||||
'priority' => '0.8',
|
||||
];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -432,7 +436,12 @@ EOF;
|
||||
<priority>0.8</priority>
|
||||
</url>
|
||||
EOF;
|
||||
file_put_contents($strMapIndexFile, $strContent, FILE_APPEND);
|
||||
//file_put_contents($strMapIndexFile, $strContent, FILE_APPEND);
|
||||
$arrUrlPool[$strUrl] = [
|
||||
'lastmod' => $this->strDate,
|
||||
'changefreq' => 'weekly',
|
||||
'priority' => '0.8',
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -442,7 +451,38 @@ EOF;
|
||||
$strContent = <<<EOF
|
||||
</urlset>
|
||||
EOF;
|
||||
file_put_contents($strMapIndexFile, $strContent, FILE_APPEND);
|
||||
//file_put_contents($strMapIndexFile, $strContent, FILE_APPEND);
|
||||
|
||||
|
||||
$strXml = <<<XML
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
XML;
|
||||
|
||||
foreach ($arrUrlPool as $url => $meta) {
|
||||
$strXml .= <<<XML
|
||||
|
||||
<url>
|
||||
<loc>{$url}</loc>
|
||||
<lastmod>{$meta['lastmod']}</lastmod>
|
||||
<changefreq>{$meta['changefreq']}</changefreq>
|
||||
<priority>{$meta['priority']}</priority>
|
||||
</url>
|
||||
XML;
|
||||
}
|
||||
|
||||
$strXml .= "\n</urlset>";
|
||||
|
||||
file_put_contents($strMapIndexFile, $strXml);
|
||||
|
||||
|
||||
$strTxtFile = $strDomainDir . '/sitemap-main.txt';
|
||||
|
||||
$strTxt = implode("\n", array_keys($arrUrlPool));
|
||||
|
||||
file_put_contents($strTxtFile, $strTxt);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace app\task\module;
|
||||
use app\model\PlanTaskModel;
|
||||
use app\task\logic\SiteMapLogic;
|
||||
use app\task\logic\VideoSiteMapLogic;
|
||||
use app\task\logic\BaiduPushVideoUrlLogic;
|
||||
use microserver\QueueManage;
|
||||
use microserver\ProcessSanitizer;
|
||||
|
||||
@@ -90,6 +91,11 @@ class PlanTask
|
||||
case 'GENERATE_VIDEO_SEO_WORDS':
|
||||
self::generateVideoSEOWords();
|
||||
break;
|
||||
case 'PUSH_BAIDU_VIDEO_URL':
|
||||
self::pushBaiduVideoUrl();
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -303,6 +309,22 @@ class PlanTask
|
||||
$QueueManage->set($arrTask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function pushBaiduVideoUrl()
|
||||
{
|
||||
$arrTask = [
|
||||
'callback' => [BaiduPushVideoUrlLogic::class, 'pushBaiduUrl'],
|
||||
'data' => []
|
||||
];
|
||||
|
||||
$QueueManage = new QueueManage(2);
|
||||
$QueueManage->set($arrTask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
use think\migration\Migrator;
|
||||
use think\migration\db\Column;
|
||||
|
||||
class AddBaiduTokenToVideoTable extends Migrator
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
$table = $this->table('domain');
|
||||
$table
|
||||
->addColumn(
|
||||
Column::string('d_baidu_token', 255)
|
||||
->setNullable(true)
|
||||
->setComment('百度推送token')
|
||||
)
|
||||
->update();
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
$table = $this->table('domain');
|
||||
$table
|
||||
->removeColumn('d_baidu_token')
|
||||
->update();
|
||||
}
|
||||
}
|
||||
@@ -110,12 +110,22 @@ class PlanTaskSeeder
|
||||
'pt_code' => 'PULL_DOU_BAN_SHI_PIN',
|
||||
'pt_enable' => 0,
|
||||
'pt_limit' => 1 * 24 * 3600,
|
||||
], [
|
||||
],
|
||||
[
|
||||
'pt_name' => '茅台资源库全量采集',
|
||||
'pt_code' => 'PULL_MAO_TAI_SHI_PIN',
|
||||
'pt_enable' => 0,
|
||||
'pt_limit' => 1 * 24 * 3600,
|
||||
],
|
||||
[
|
||||
'pt_name' => '推送视频url到百度收录',
|
||||
'pt_code' => 'PUSH_BAIDU_VIDEO_URL',
|
||||
'pt_enable' => 0,
|
||||
'pt_limit' => 1 * 24 * 3600,
|
||||
],
|
||||
|
||||
|
||||
|
||||
|
||||
];
|
||||
|
||||
|
||||
@@ -1,195 +1,117 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* GPT 新模板 URL Family Pool(A 方案)
|
||||
* - prefixIndex × templateIndex 生成
|
||||
* - 每套都有 id(A001…)
|
||||
* - 每个页面:1 pattern + 1 route
|
||||
* - 每套都有稳定 id(A001…)
|
||||
* - 文件被 require 时,直接返回 array
|
||||
* - task / CLI / Web 全安全
|
||||
*/
|
||||
|
||||
function buildUrlFamilyPool(): array
|
||||
{
|
||||
/** 页面定义(你给的) */
|
||||
// =====================
|
||||
// 1️⃣ 页面定义
|
||||
// =====================
|
||||
$pages = [
|
||||
'play' => [
|
||||
'sort' => 1,
|
||||
'prefix' => [
|
||||
'video', // 主
|
||||
'play', // 主
|
||||
'vodplay', // 历史
|
||||
'watch', // 英文
|
||||
'kan', // 拼音(看)
|
||||
'player', // 英文
|
||||
'bofang', // 英文
|
||||
'm3u8', // 英文
|
||||
'bf', // 英文
|
||||
'video','play','vodplay','watch','kan','player','bofang','m3u8','bf',
|
||||
],
|
||||
'type' => 'play'
|
||||
'type' => 'play',
|
||||
],
|
||||
'detail_forge' => [
|
||||
'sort' => 2,
|
||||
'prefix' => [
|
||||
'video', // 主
|
||||
'detail', // 主
|
||||
'info', // 主
|
||||
'vod', // 行业通用
|
||||
'movie', // 英文
|
||||
'film', // 英文
|
||||
'xiangqing',
|
||||
'shipin',
|
||||
'neirong',
|
||||
'dianying',
|
||||
'video','detail','info','vod','movie','film',
|
||||
'xiangqing','shipin','neirong','dianying',
|
||||
],
|
||||
'type' => 'detail_forge'
|
||||
'type' => 'detail_forge',
|
||||
],
|
||||
'detail' => [
|
||||
'sort' => 3,
|
||||
'prefix' => [
|
||||
'video', // 主
|
||||
'detail', // 主
|
||||
'info', // 主
|
||||
'vod', // 行业通用
|
||||
'movie', // 英文
|
||||
'film', // 英文
|
||||
'xiangqing',
|
||||
'shipin',
|
||||
'neirong',
|
||||
'dianying',
|
||||
'video','detail','info','vod','movie','film',
|
||||
'xiangqing','shipin','neirong','dianying',
|
||||
],
|
||||
'type' => 'detail'
|
||||
'type' => 'detail',
|
||||
],
|
||||
'category_child' => [
|
||||
'sort' => 4,
|
||||
'prefix' => [
|
||||
'fenlei', // 主
|
||||
'category', // 英文
|
||||
'class', // 主
|
||||
'type', // 主
|
||||
'genres', // 英文(类型)
|
||||
'leixing', // 拼音
|
||||
'videotype', // 拼音
|
||||
'fenlei','category','class','type','genres','leixing','videotype',
|
||||
],
|
||||
'type' => 'category_child'
|
||||
'type' => 'category_child',
|
||||
],
|
||||
'category_parent' => [
|
||||
'sort' => 5,
|
||||
'prefix' => [
|
||||
'fenlei', // 主
|
||||
'category', // 英文
|
||||
'class', // 主
|
||||
'type', // 主
|
||||
'genres', // 英文(类型)
|
||||
'leixing', // 拼音
|
||||
'videotype', // 拼音
|
||||
'fenlei','category','class','type','genres','leixing','videotype',
|
||||
],
|
||||
'type' => 'category_parent'
|
||||
'type' => 'category_parent',
|
||||
],
|
||||
'rank_list' => [
|
||||
'sort' => 6,
|
||||
'prefix' => [
|
||||
'top', // 主
|
||||
'rank', // 主
|
||||
'paihangban', // 拼音
|
||||
'ranking', // 英文
|
||||
'hot', // 热门(谨慎)
|
||||
'phb',
|
||||
'top','rank','paihangban','ranking','hot','phb',
|
||||
],
|
||||
'type' => 'rank_list'
|
||||
'type' => 'rank_list',
|
||||
],
|
||||
'category_home' => [
|
||||
'sort' => 7,
|
||||
'prefix' => [
|
||||
'fenlei', // 主
|
||||
'category', // 英文
|
||||
'class', // 主
|
||||
'type', // 主
|
||||
'genres', // 英文(类型)
|
||||
'leixing', // 拼音
|
||||
'videotype', // 拼音
|
||||
'fenlei','category','class','type','genres','leixing','videotype',
|
||||
],
|
||||
'type' => 'category_home'
|
||||
'type' => 'category_home',
|
||||
],
|
||||
'rank_index' => [
|
||||
'sort' => 8,
|
||||
'prefix' => [
|
||||
'top', // 主
|
||||
'rank', // 主
|
||||
'paihangban', // 拼音
|
||||
'ranking', // 英文
|
||||
'hot', // 热门(谨慎)
|
||||
'phb',
|
||||
'top','rank','paihangban','ranking','hot','phb',
|
||||
],
|
||||
'type' => 'rank_index'
|
||||
'type' => 'rank_index',
|
||||
],
|
||||
'search' => [
|
||||
'sort' => 9,
|
||||
'prefix' => [
|
||||
'search', // 主
|
||||
'query', // 主
|
||||
'sou', // 拼音
|
||||
'find', // 英文
|
||||
'get'
|
||||
'search','query','sou','find','get',
|
||||
],
|
||||
'type' => 'search'
|
||||
'type' => 'search',
|
||||
],
|
||||
'history' => [
|
||||
'sort' => 10,
|
||||
'prefix' => [
|
||||
'history', // 主
|
||||
'his', // 简写
|
||||
'jilu', // 拼音
|
||||
'record', // 英文
|
||||
'history','his','jilu','record',
|
||||
],
|
||||
'type' => 'history'
|
||||
'type' => 'history',
|
||||
],
|
||||
];
|
||||
|
||||
/** 每个 type 的 8 套模板(你已测试可用) */
|
||||
// =====================
|
||||
// 2️⃣ 模板定义(每类 8 套)
|
||||
// =====================
|
||||
$templates = [
|
||||
|
||||
'category_home' => [
|
||||
'pattern' => [
|
||||
'{prefix}',
|
||||
'{prefix}/index',
|
||||
'{prefix}/home',
|
||||
'{prefix}/p',
|
||||
'{prefix}/1',
|
||||
'{prefix}-1',
|
||||
'{prefix}-index',
|
||||
'{prefix}-home',
|
||||
'{prefix}','{prefix}/index','{prefix}/home','{prefix}/p',
|
||||
'{prefix}/1','{prefix}-1','{prefix}-index','{prefix}-home',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}',
|
||||
'/{prefix}/index',
|
||||
'/{prefix}/home',
|
||||
'/{prefix}/p',
|
||||
'/{prefix}/1',
|
||||
'/{prefix}/-1',
|
||||
'/{prefix}-index',
|
||||
'/{prefix}-home',
|
||||
'/{prefix}','/{prefix}/index','/{prefix}/home','/{prefix}/p',
|
||||
'/{prefix}/1','/{prefix}-1','/{prefix}-index','/{prefix}-home',
|
||||
],
|
||||
],
|
||||
|
||||
'category_parent' => [
|
||||
'pattern' => [
|
||||
'{prefix}/{strParentCategory}',
|
||||
'{prefix}/{strParentCategory}/index',
|
||||
'{prefix}/{strParentCategory}/home',
|
||||
'{prefix}/p/{strParentCategory}',
|
||||
'{prefix}/1/{strParentCategory}',
|
||||
'{prefix}/1-{strParentCategory}',
|
||||
'{prefix}/{strParentCategory}/1',
|
||||
'{prefix}/{strParentCategory}-1',
|
||||
'{prefix}/{strParentCategory}','{prefix}/{strParentCategory}/index',
|
||||
'{prefix}/{strParentCategory}/home','{prefix}/p/{strParentCategory}',
|
||||
'{prefix}/1/{strParentCategory}','{prefix}/1-{strParentCategory}',
|
||||
'{prefix}/{strParentCategory}/1','{prefix}/{strParentCategory}-1',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}/:strParentCategory',
|
||||
'/{prefix}/:strParentCategory/index',
|
||||
'/{prefix}/:strParentCategory/home',
|
||||
'/{prefix}/p/:strParentCategory',
|
||||
'/{prefix}/1/:strParentCategory',
|
||||
'/{prefix}/1-:strParentCategory',
|
||||
'/{prefix}/:strParentCategory/1',
|
||||
'/{prefix}/:strParentCategory-1',
|
||||
'/{prefix}/:strParentCategory','/{prefix}/:strParentCategory/index',
|
||||
'/{prefix}/:strParentCategory/home','/{prefix}/p/:strParentCategory',
|
||||
'/{prefix}/1/:strParentCategory','/{prefix}/1-:strParentCategory',
|
||||
'/{prefix}/:strParentCategory/1','/{prefix}/:strParentCategory-1',
|
||||
],
|
||||
],
|
||||
|
||||
@@ -218,70 +140,42 @@ function buildUrlFamilyPool(): array
|
||||
|
||||
'rank_index' => [
|
||||
'pattern' => [
|
||||
'{prefix}',
|
||||
'{prefix}/index',
|
||||
'{prefix}/all',
|
||||
'{prefix}/home',
|
||||
'{prefix}/1',
|
||||
'{prefix}-index',
|
||||
'{prefix}-all',
|
||||
'{prefix}-home',
|
||||
'{prefix}','{prefix}/index','{prefix}/all','{prefix}/home',
|
||||
'{prefix}/1','{prefix}-index','{prefix}-all','{prefix}-home',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}',
|
||||
'/{prefix}/index',
|
||||
'/{prefix}/all',
|
||||
'/{prefix}/home',
|
||||
'/{prefix}/1',
|
||||
'/{prefix}-index',
|
||||
'/{prefix}-all',
|
||||
'/{prefix}-home',
|
||||
'/{prefix}','/{prefix}/index','/{prefix}/all','/{prefix}/home',
|
||||
'/{prefix}/1','/{prefix}-index','/{prefix}-all','/{prefix}-home',
|
||||
],
|
||||
],
|
||||
|
||||
'rank_list' => [
|
||||
'pattern' => [
|
||||
'{prefix}/{strSortType}',
|
||||
'{prefix}/{strSortType}/index',
|
||||
'{prefix}/{strSortType}/home',
|
||||
'{prefix}/{strSortType}/1',
|
||||
'{prefix}/{strSortType}-1',
|
||||
'{prefix}-{strSortType}',
|
||||
'{prefix}-{strSortType}/index',
|
||||
'{prefix}-{strSortType}/1',
|
||||
'{prefix}/{strSortType}','{prefix}/{strSortType}/index',
|
||||
'{prefix}/{strSortType}/home','{prefix}/{strSortType}/1',
|
||||
'{prefix}/{strSortType}-1','{prefix}-{strSortType}',
|
||||
'{prefix}-{strSortType}/index','{prefix}-{strSortType}/1',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}/:strSortType',
|
||||
'/{prefix}/:strSortType/index',
|
||||
'/{prefix}/:strSortType/home',
|
||||
'/{prefix}/:strSortType/1',
|
||||
'/{prefix}/:strSortType-1',
|
||||
'/{prefix}-:strSortType',
|
||||
'/{prefix}-:strSortType/index',
|
||||
'/{prefix}-:strSortType/1',
|
||||
'/{prefix}/:strSortType','/{prefix}/:strSortType/index',
|
||||
'/{prefix}/:strSortType/home','/{prefix}/:strSortType/1',
|
||||
'/{prefix}/:strSortType-1','/{prefix}-:strSortType',
|
||||
'/{prefix}-:strSortType/index','/{prefix}-:strSortType/1',
|
||||
],
|
||||
],
|
||||
|
||||
'detail' => [
|
||||
'pattern' => [
|
||||
'{prefix}/{strPinyin}-{intVId}',
|
||||
'{prefix}/{intVId}-{strPinyin}',
|
||||
'{prefix}/{strPinyin}/{intVId}',
|
||||
'{prefix}/{intVId}',
|
||||
'{prefix}-{strPinyin}-{intVId}',
|
||||
'{prefix}-{intVId}-{strPinyin}',
|
||||
'{prefix}/id-{intVId}',
|
||||
'{prefix}/pinyin-{strPinyin}',
|
||||
'{prefix}/{strPinyin}-{intVId}','{prefix}/{intVId}-{strPinyin}',
|
||||
'{prefix}/{strPinyin}/{intVId}','{prefix}/{intVId}',
|
||||
'{prefix}-{strPinyin}-{intVId}','{prefix}-{intVId}-{strPinyin}',
|
||||
'{prefix}/id-{intVId}','{prefix}/pinyin-{strPinyin}',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}/:strPinyin-:intVId',
|
||||
'/{prefix}/:intVId-:strPinyin',
|
||||
'/{prefix}/:strPinyin/:intVId',
|
||||
'/{prefix}/:intVId',
|
||||
'/{prefix}-:strPinyin-:intVId',
|
||||
'/{prefix}-:intVId-:strPinyin',
|
||||
'/{prefix}/id-:intVId',
|
||||
'/{prefix}/pinyin-:strPinyin',
|
||||
'/{prefix}/:strPinyin-:intVId','/{prefix}/:intVId-:strPinyin',
|
||||
'/{prefix}/:strPinyin/:intVId','/{prefix}/:intVId',
|
||||
'/{prefix}-:strPinyin-:intVId','/{prefix}-:intVId-:strPinyin',
|
||||
'/{prefix}/id-:intVId','/{prefix}/pinyin-:strPinyin',
|
||||
],
|
||||
],
|
||||
|
||||
@@ -333,57 +227,36 @@ function buildUrlFamilyPool(): array
|
||||
|
||||
'search' => [
|
||||
'pattern' => [
|
||||
'{prefix}',
|
||||
'{prefix}.html',
|
||||
'{prefix}/index',
|
||||
'{prefix}/home',
|
||||
'{prefix}/keywords',
|
||||
'{prefix}-index',
|
||||
'{prefix}-home',
|
||||
'{prefix}-keywords',
|
||||
'{prefix}','{prefix}.html','{prefix}/index','{prefix}/home',
|
||||
'{prefix}/keywords','{prefix}-index','{prefix}-home','{prefix}-keywords',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}',
|
||||
'/{prefix}.html',
|
||||
'/{prefix}/index',
|
||||
'/{prefix}/home',
|
||||
'/{prefix}/keywords',
|
||||
'/{prefix}-index',
|
||||
'/{prefix}-home',
|
||||
'/{prefix}-keywords',
|
||||
'/{prefix}','/{prefix}.html','/{prefix}/index','/{prefix}/home',
|
||||
'/{prefix}/keywords','/{prefix}-index','/{prefix}-home','/{prefix}-keywords',
|
||||
],
|
||||
],
|
||||
|
||||
'history' => [
|
||||
'pattern' => [
|
||||
'{prefix}',
|
||||
'{prefix}.html',
|
||||
'{prefix}/index',
|
||||
'{prefix}/home',
|
||||
'{prefix}/keywords',
|
||||
'{prefix}-index',
|
||||
'{prefix}-home',
|
||||
'{prefix}-keywords',
|
||||
'{prefix}','{prefix}.html','{prefix}/index','{prefix}/home',
|
||||
'{prefix}/keywords','{prefix}-index','{prefix}-home','{prefix}-keywords',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}',
|
||||
'/{prefix}.html',
|
||||
'/{prefix}/index',
|
||||
'/{prefix}/home',
|
||||
'/{prefix}/keywords',
|
||||
'/{prefix}-index',
|
||||
'/{prefix}-home',
|
||||
'/{prefix}-keywords',
|
||||
'/{prefix}','/{prefix}.html','/{prefix}/index','/{prefix}/home',
|
||||
'/{prefix}/keywords','/{prefix}-index','/{prefix}-home','/{prefix}-keywords',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
// 🔴【新增 1】加载 index(落盘 ID)
|
||||
// =====================
|
||||
// 3️⃣ ID 索引(落盘)
|
||||
// =====================
|
||||
$indexFile = __DIR__ . '/url_family_index.php';
|
||||
$index = file_exists($indexFile) ? require $indexFile : [];
|
||||
|
||||
// 🔴【新增 2】计算当前最大 A 编号
|
||||
// =====================
|
||||
// 4️⃣ 计算当前最大 A 编号
|
||||
// =====================
|
||||
$maxId = 0;
|
||||
foreach ($index as $aid) {
|
||||
$num = (int)substr($aid, 1);
|
||||
@@ -392,33 +265,24 @@ function buildUrlFamilyPool(): array
|
||||
}
|
||||
}
|
||||
|
||||
// 页面按 sort 排序(保证路由注册顺序)
|
||||
// =====================
|
||||
// 5️⃣ 构造 families
|
||||
// =====================
|
||||
uasort($pages, fn($a, $b) => $a['sort'] <=> $b['sort']);
|
||||
|
||||
// prefix 套数
|
||||
$prefixSuiteCount = max(array_map(fn($p) => count($p['prefix']), $pages));
|
||||
|
||||
$families = [];
|
||||
|
||||
// ❌【删除】$seq = 1;
|
||||
|
||||
for ($pi = 0; $pi < $prefixSuiteCount; $pi++) {
|
||||
for ($ti = 0; $ti < 8; $ti++) {
|
||||
|
||||
/**
|
||||
* 🔴【新增 3】构造 family 唯一指纹 key
|
||||
* 只要 page / prefix / 模板索引一样,URL 身份就一样
|
||||
*/
|
||||
$familyKeyParts = [];
|
||||
|
||||
foreach ($pages as $pageKey => $page) {
|
||||
$prefix = $page['prefix'][$pi] ?? end($page['prefix']);
|
||||
$familyKeyParts[] = $pageKey . ':' . $prefix;
|
||||
}
|
||||
|
||||
$familyKey = implode('|', $familyKeyParts) . '|tpl' . $ti;
|
||||
|
||||
// 🔴【新增 4】从 index 取 A 编号(没有就新增)
|
||||
if (!isset($index[$familyKey])) {
|
||||
$maxId++;
|
||||
$index[$familyKey] = 'A' . str_pad((string)$maxId, 3, '0', STR_PAD_LEFT);
|
||||
@@ -426,14 +290,11 @@ function buildUrlFamilyPool(): array
|
||||
|
||||
$aid = $index[$familyKey];
|
||||
|
||||
// 🔴【修改】family 的 id 不再用 $seq
|
||||
$family = [
|
||||
'id' => $aid,
|
||||
'home' => [
|
||||
'pattern' => '',
|
||||
'routes' => [
|
||||
'/'
|
||||
]
|
||||
'routes' => ['/'],
|
||||
],
|
||||
];
|
||||
|
||||
@@ -444,7 +305,6 @@ function buildUrlFamilyPool(): array
|
||||
}
|
||||
|
||||
$prefix = $page['prefix'][$pi] ?? end($page['prefix']);
|
||||
|
||||
$pattern = str_replace('{prefix}', $prefix, $templates[$type]['pattern'][$ti]);
|
||||
$route = str_replace('{prefix}', $prefix, $templates[$type]['routes'][$ti]);
|
||||
|
||||
@@ -455,22 +315,18 @@ function buildUrlFamilyPool(): array
|
||||
];
|
||||
}
|
||||
|
||||
// 🔴【修改】用 A 编号做 key,避免被重排
|
||||
$families[$aid] = $family;
|
||||
}
|
||||
}
|
||||
|
||||
// 🔴【新增 5】index 落盘(只会 append)
|
||||
// =====================
|
||||
// 6️⃣ index 落盘 + 排序返回
|
||||
// =====================
|
||||
file_put_contents(
|
||||
$indexFile,
|
||||
"<?php\nreturn " . var_export($index, true) . ";\n"
|
||||
);
|
||||
|
||||
// 🔴【新增 6】按 A 编号排序,输出稳定顺序
|
||||
ksort($families);
|
||||
|
||||
return array_values($families);
|
||||
|
||||
}
|
||||
|
||||
return buildUrlFamilyPool();
|
||||
|
||||
476
code/public/initdata/video/url_family_pool_gpt_back.php
Normal file
476
code/public/initdata/video/url_family_pool_gpt_back.php
Normal file
@@ -0,0 +1,476 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* GPT 新模板 URL Family Pool(A 方案)
|
||||
* - prefixIndex × templateIndex 生成
|
||||
* - 每套都有 id(A001…)
|
||||
* - 每个页面:1 pattern + 1 route
|
||||
*/
|
||||
|
||||
function buildUrlFamilyPool(): array
|
||||
{
|
||||
/** 页面定义(你给的) */
|
||||
$pages = [
|
||||
'play' => [
|
||||
'sort' => 1,
|
||||
'prefix' => [
|
||||
'video', // 主
|
||||
'play', // 主
|
||||
'vodplay', // 历史
|
||||
'watch', // 英文
|
||||
'kan', // 拼音(看)
|
||||
'player', // 英文
|
||||
'bofang', // 英文
|
||||
'm3u8', // 英文
|
||||
'bf', // 英文
|
||||
],
|
||||
'type' => 'play'
|
||||
],
|
||||
'detail_forge' => [
|
||||
'sort' => 2,
|
||||
'prefix' => [
|
||||
'video', // 主
|
||||
'detail', // 主
|
||||
'info', // 主
|
||||
'vod', // 行业通用
|
||||
'movie', // 英文
|
||||
'film', // 英文
|
||||
'xiangqing',
|
||||
'shipin',
|
||||
'neirong',
|
||||
'dianying',
|
||||
],
|
||||
'type' => 'detail_forge'
|
||||
],
|
||||
'detail' => [
|
||||
'sort' => 3,
|
||||
'prefix' => [
|
||||
'video', // 主
|
||||
'detail', // 主
|
||||
'info', // 主
|
||||
'vod', // 行业通用
|
||||
'movie', // 英文
|
||||
'film', // 英文
|
||||
'xiangqing',
|
||||
'shipin',
|
||||
'neirong',
|
||||
'dianying',
|
||||
],
|
||||
'type' => 'detail'
|
||||
],
|
||||
'category_child' => [
|
||||
'sort' => 4,
|
||||
'prefix' => [
|
||||
'fenlei', // 主
|
||||
'category', // 英文
|
||||
'class', // 主
|
||||
'type', // 主
|
||||
'genres', // 英文(类型)
|
||||
'leixing', // 拼音
|
||||
'videotype', // 拼音
|
||||
],
|
||||
'type' => 'category_child'
|
||||
],
|
||||
'category_parent' => [
|
||||
'sort' => 5,
|
||||
'prefix' => [
|
||||
'fenlei', // 主
|
||||
'category', // 英文
|
||||
'class', // 主
|
||||
'type', // 主
|
||||
'genres', // 英文(类型)
|
||||
'leixing', // 拼音
|
||||
'videotype', // 拼音
|
||||
],
|
||||
'type' => 'category_parent'
|
||||
],
|
||||
'rank_list' => [
|
||||
'sort' => 6,
|
||||
'prefix' => [
|
||||
'top', // 主
|
||||
'rank', // 主
|
||||
'paihangban', // 拼音
|
||||
'ranking', // 英文
|
||||
'hot', // 热门(谨慎)
|
||||
'phb',
|
||||
],
|
||||
'type' => 'rank_list'
|
||||
],
|
||||
'category_home' => [
|
||||
'sort' => 7,
|
||||
'prefix' => [
|
||||
'fenlei', // 主
|
||||
'category', // 英文
|
||||
'class', // 主
|
||||
'type', // 主
|
||||
'genres', // 英文(类型)
|
||||
'leixing', // 拼音
|
||||
'videotype', // 拼音
|
||||
],
|
||||
'type' => 'category_home'
|
||||
],
|
||||
'rank_index' => [
|
||||
'sort' => 8,
|
||||
'prefix' => [
|
||||
'top', // 主
|
||||
'rank', // 主
|
||||
'paihangban', // 拼音
|
||||
'ranking', // 英文
|
||||
'hot', // 热门(谨慎)
|
||||
'phb',
|
||||
],
|
||||
'type' => 'rank_index'
|
||||
],
|
||||
'search' => [
|
||||
'sort' => 9,
|
||||
'prefix' => [
|
||||
'search', // 主
|
||||
'query', // 主
|
||||
'sou', // 拼音
|
||||
'find', // 英文
|
||||
'get'
|
||||
],
|
||||
'type' => 'search'
|
||||
],
|
||||
'history' => [
|
||||
'sort' => 10,
|
||||
'prefix' => [
|
||||
'history', // 主
|
||||
'his', // 简写
|
||||
'jilu', // 拼音
|
||||
'record', // 英文
|
||||
],
|
||||
'type' => 'history'
|
||||
],
|
||||
];
|
||||
|
||||
/** 每个 type 的 8 套模板(你已测试可用) */
|
||||
$templates = [
|
||||
|
||||
'category_home' => [
|
||||
'pattern' => [
|
||||
'{prefix}',
|
||||
'{prefix}/index',
|
||||
'{prefix}/home',
|
||||
'{prefix}/p',
|
||||
'{prefix}/1',
|
||||
'{prefix}-1',
|
||||
'{prefix}-index',
|
||||
'{prefix}-home',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}',
|
||||
'/{prefix}/index',
|
||||
'/{prefix}/home',
|
||||
'/{prefix}/p',
|
||||
'/{prefix}/1',
|
||||
'/{prefix}/-1',
|
||||
'/{prefix}-index',
|
||||
'/{prefix}-home',
|
||||
],
|
||||
],
|
||||
|
||||
'category_parent' => [
|
||||
'pattern' => [
|
||||
'{prefix}/{strParentCategory}',
|
||||
'{prefix}/{strParentCategory}/index',
|
||||
'{prefix}/{strParentCategory}/home',
|
||||
'{prefix}/p/{strParentCategory}',
|
||||
'{prefix}/1/{strParentCategory}',
|
||||
'{prefix}/1-{strParentCategory}',
|
||||
'{prefix}/{strParentCategory}/1',
|
||||
'{prefix}/{strParentCategory}-1',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}/:strParentCategory',
|
||||
'/{prefix}/:strParentCategory/index',
|
||||
'/{prefix}/:strParentCategory/home',
|
||||
'/{prefix}/p/:strParentCategory',
|
||||
'/{prefix}/1/:strParentCategory',
|
||||
'/{prefix}/1-:strParentCategory',
|
||||
'/{prefix}/:strParentCategory/1',
|
||||
'/{prefix}/:strParentCategory-1',
|
||||
],
|
||||
],
|
||||
|
||||
'category_child' => [
|
||||
'pattern' => [
|
||||
'{prefix}/{strParentCategory}/{strCategory}/page{intPage}',
|
||||
'{prefix}/{strParentCategory}/{strCategory}-page{intPage}',
|
||||
'{prefix}-{strParentCategory}/{strCategory}/page{intPage}',
|
||||
'{prefix}-{strParentCategory}/{strCategory}-page{intPage}',
|
||||
'{prefix}/{strParentCategory}/{strCategory}/{intPage}',
|
||||
'{prefix}/{strParentCategory}/{strCategory}-{intPage}',
|
||||
'{prefix}-{strParentCategory}/{strCategory}/{intPage}',
|
||||
'{prefix}-{strParentCategory}/{strCategory}-{intPage}',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}/:strParentCategory/:strCategory/page:intPage',
|
||||
'/{prefix}/:strParentCategory/:strCategory-page:intPage',
|
||||
'/{prefix}-:strParentCategory/:strCategory/page:intPage',
|
||||
'/{prefix}-:strParentCategory/:strCategory-page:intPage',
|
||||
'/{prefix}/:strParentCategory/:strCategory/:intPage',
|
||||
'/{prefix}/:strParentCategory/:strCategory-:intPage',
|
||||
'/{prefix}-:strParentCategory/:strCategory/:intPage',
|
||||
'/{prefix}-:strParentCategory/:strCategory-:intPage',
|
||||
],
|
||||
],
|
||||
|
||||
'rank_index' => [
|
||||
'pattern' => [
|
||||
'{prefix}',
|
||||
'{prefix}/index',
|
||||
'{prefix}/all',
|
||||
'{prefix}/home',
|
||||
'{prefix}/1',
|
||||
'{prefix}-index',
|
||||
'{prefix}-all',
|
||||
'{prefix}-home',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}',
|
||||
'/{prefix}/index',
|
||||
'/{prefix}/all',
|
||||
'/{prefix}/home',
|
||||
'/{prefix}/1',
|
||||
'/{prefix}-index',
|
||||
'/{prefix}-all',
|
||||
'/{prefix}-home',
|
||||
],
|
||||
],
|
||||
|
||||
'rank_list' => [
|
||||
'pattern' => [
|
||||
'{prefix}/{strSortType}',
|
||||
'{prefix}/{strSortType}/index',
|
||||
'{prefix}/{strSortType}/home',
|
||||
'{prefix}/{strSortType}/1',
|
||||
'{prefix}/{strSortType}-1',
|
||||
'{prefix}-{strSortType}',
|
||||
'{prefix}-{strSortType}/index',
|
||||
'{prefix}-{strSortType}/1',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}/:strSortType',
|
||||
'/{prefix}/:strSortType/index',
|
||||
'/{prefix}/:strSortType/home',
|
||||
'/{prefix}/:strSortType/1',
|
||||
'/{prefix}/:strSortType-1',
|
||||
'/{prefix}-:strSortType',
|
||||
'/{prefix}-:strSortType/index',
|
||||
'/{prefix}-:strSortType/1',
|
||||
],
|
||||
],
|
||||
|
||||
'detail' => [
|
||||
'pattern' => [
|
||||
'{prefix}/{strPinyin}-{intVId}',
|
||||
'{prefix}/{intVId}-{strPinyin}',
|
||||
'{prefix}/{strPinyin}/{intVId}',
|
||||
'{prefix}/{intVId}',
|
||||
'{prefix}-{strPinyin}-{intVId}',
|
||||
'{prefix}-{intVId}-{strPinyin}',
|
||||
'{prefix}/id-{intVId}',
|
||||
'{prefix}/pinyin-{strPinyin}',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}/:strPinyin-:intVId',
|
||||
'/{prefix}/:intVId-:strPinyin',
|
||||
'/{prefix}/:strPinyin/:intVId',
|
||||
'/{prefix}/:intVId',
|
||||
'/{prefix}-:strPinyin-:intVId',
|
||||
'/{prefix}-:intVId-:strPinyin',
|
||||
'/{prefix}/id-:intVId',
|
||||
'/{prefix}/pinyin-:strPinyin',
|
||||
],
|
||||
],
|
||||
|
||||
'detail_forge' => [
|
||||
'pattern' => [
|
||||
'{prefix}/{strPinyin}-{intVId}-{intVForgeId}',
|
||||
'{prefix}/{intVId}-{strPinyin}/{intVForgeId}',
|
||||
'{prefix}/{strPinyin}/{intVId}-{intVForgeId}',
|
||||
'{prefix}/{intVId}/{intVForgeId}',
|
||||
'{prefix}-{strPinyin}-{intVId}/{intVForgeId}',
|
||||
'{prefix}-{intVId}-{strPinyin}/{intVForgeId}',
|
||||
'{prefix}/id-{intVId}-{intVForgeId}',
|
||||
'{prefix}/pinyin-{strPinyin}/{intVForgeId}',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}/:strPinyin-:intVId-:intVForgeId',
|
||||
'/{prefix}/:intVId-:strPinyin/:intVForgeId',
|
||||
'/{prefix}/:strPinyin/:intVId-:intVForgeId',
|
||||
'/{prefix}/:intVId/:intVForgeId',
|
||||
'/{prefix}-:strPinyin-:intVId/:intVForgeId',
|
||||
'/{prefix}-:intVId-:strPinyin/:intVForgeId',
|
||||
'/{prefix}/id-:intVId-:intVForgeId',
|
||||
'/{prefix}/pinyin-:strPinyin/:intVForgeId',
|
||||
],
|
||||
],
|
||||
|
||||
'play' => [
|
||||
'pattern' => [
|
||||
'{prefix}/{strPinyin}-{intVId}-{strPlayType}-{intPlayIndex}',
|
||||
'{prefix}/{strPinyin}-{intVId}/{strPlayType}-{intPlayIndex}',
|
||||
'{prefix}/{intVId}-{strPlayType}-{intPlayIndex}',
|
||||
'{prefix}/{intVId}/{strPlayType}-{intPlayIndex}',
|
||||
'{prefix}-{strPinyin}-{intVId}-{strPlayType}-{intPlayIndex}',
|
||||
'{prefix}-{intVId}-{strPinyin}/{strPlayType}-{intPlayIndex}',
|
||||
'{prefix}-{intVId}-{strPlayType}-{intPlayIndex}',
|
||||
'{prefix}-{intVId}/{strPlayType}-{intPlayIndex}',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}/:strPinyin-:intVId-:strPlayType-:intPlayIndex',
|
||||
'/{prefix}/:strPinyin-:intVId/:strPlayType-:intPlayIndex',
|
||||
'/{prefix}/:intVId-:strPlayType-:intPlayIndex',
|
||||
'/{prefix}/:intVId/:strPlayType-:intPlayIndex',
|
||||
'/{prefix}-:strPinyin-:intVId-:strPlayType-:intPlayIndex',
|
||||
'/{prefix}-:intVId-:strPinyin/:strPlayType-:intPlayIndex',
|
||||
'/{prefix}-:intVId-:strPlayType-:intPlayIndex',
|
||||
'/{prefix}-:intVId/:strPlayType-:intPlayIndex',
|
||||
],
|
||||
],
|
||||
|
||||
'search' => [
|
||||
'pattern' => [
|
||||
'{prefix}',
|
||||
'{prefix}.html',
|
||||
'{prefix}/index',
|
||||
'{prefix}/home',
|
||||
'{prefix}/keywords',
|
||||
'{prefix}-index',
|
||||
'{prefix}-home',
|
||||
'{prefix}-keywords',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}',
|
||||
'/{prefix}.html',
|
||||
'/{prefix}/index',
|
||||
'/{prefix}/home',
|
||||
'/{prefix}/keywords',
|
||||
'/{prefix}-index',
|
||||
'/{prefix}-home',
|
||||
'/{prefix}-keywords',
|
||||
],
|
||||
],
|
||||
|
||||
'history' => [
|
||||
'pattern' => [
|
||||
'{prefix}',
|
||||
'{prefix}.html',
|
||||
'{prefix}/index',
|
||||
'{prefix}/home',
|
||||
'{prefix}/keywords',
|
||||
'{prefix}-index',
|
||||
'{prefix}-home',
|
||||
'{prefix}-keywords',
|
||||
],
|
||||
'routes' => [
|
||||
'/{prefix}',
|
||||
'/{prefix}.html',
|
||||
'/{prefix}/index',
|
||||
'/{prefix}/home',
|
||||
'/{prefix}/keywords',
|
||||
'/{prefix}-index',
|
||||
'/{prefix}-home',
|
||||
'/{prefix}-keywords',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
// 🔴【新增 1】加载 index(落盘 ID)
|
||||
$indexFile = __DIR__ . '/url_family_index.php';
|
||||
$index = file_exists($indexFile) ? require $indexFile : [];
|
||||
|
||||
// 🔴【新增 2】计算当前最大 A 编号
|
||||
$maxId = 0;
|
||||
foreach ($index as $aid) {
|
||||
$num = (int)substr($aid, 1);
|
||||
if ($num > $maxId) {
|
||||
$maxId = $num;
|
||||
}
|
||||
}
|
||||
|
||||
// 页面按 sort 排序(保证路由注册顺序)
|
||||
uasort($pages, fn($a, $b) => $a['sort'] <=> $b['sort']);
|
||||
|
||||
// prefix 套数
|
||||
$prefixSuiteCount = max(array_map(fn($p) => count($p['prefix']), $pages));
|
||||
|
||||
$families = [];
|
||||
|
||||
// ❌【删除】$seq = 1;
|
||||
|
||||
for ($pi = 0; $pi < $prefixSuiteCount; $pi++) {
|
||||
for ($ti = 0; $ti < 8; $ti++) {
|
||||
|
||||
/**
|
||||
* 🔴【新增 3】构造 family 唯一指纹 key
|
||||
* 只要 page / prefix / 模板索引一样,URL 身份就一样
|
||||
*/
|
||||
$familyKeyParts = [];
|
||||
|
||||
foreach ($pages as $pageKey => $page) {
|
||||
$prefix = $page['prefix'][$pi] ?? end($page['prefix']);
|
||||
$familyKeyParts[] = $pageKey . ':' . $prefix;
|
||||
}
|
||||
|
||||
$familyKey = implode('|', $familyKeyParts) . '|tpl' . $ti;
|
||||
|
||||
// 🔴【新增 4】从 index 取 A 编号(没有就新增)
|
||||
if (!isset($index[$familyKey])) {
|
||||
$maxId++;
|
||||
$index[$familyKey] = 'A' . str_pad((string)$maxId, 3, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
$aid = $index[$familyKey];
|
||||
|
||||
// 🔴【修改】family 的 id 不再用 $seq
|
||||
$family = [
|
||||
'id' => $aid,
|
||||
'home' => [
|
||||
'pattern' => '',
|
||||
'routes' => [
|
||||
'/'
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($pages as $pageKey => $page) {
|
||||
$type = $page['type'];
|
||||
if (!isset($templates[$type])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$prefix = $page['prefix'][$pi] ?? end($page['prefix']);
|
||||
|
||||
$pattern = str_replace('{prefix}', $prefix, $templates[$type]['pattern'][$ti]);
|
||||
$route = str_replace('{prefix}', $prefix, $templates[$type]['routes'][$ti]);
|
||||
|
||||
$family[$pageKey] = [
|
||||
'sort' => $page['sort'],
|
||||
'pattern' => $pattern,
|
||||
'routes' => [$route],
|
||||
];
|
||||
}
|
||||
|
||||
// 🔴【修改】用 A 编号做 key,避免被重排
|
||||
$families[$aid] = $family;
|
||||
}
|
||||
}
|
||||
|
||||
// 🔴【新增 5】index 落盘(只会 append)
|
||||
file_put_contents(
|
||||
$indexFile,
|
||||
"<?php\nreturn " . var_export($index, true) . ";\n"
|
||||
);
|
||||
|
||||
// 🔴【新增 6】按 A 编号排序,输出稳定顺序
|
||||
ksort($families);
|
||||
|
||||
return array_values($families);
|
||||
|
||||
}
|
||||
|
||||
return buildUrlFamilyPool();
|
||||
Reference in New Issue
Block a user