debug
This commit is contained in:
137
code/app/task/collection/seo/GenerateSiteMapCol.php
Normal file
137
code/app/task/collection/seo/GenerateSiteMapCol.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\task\collection\seo;
|
||||
|
||||
use app\task\collection\PullDataColBase;
|
||||
|
||||
use app\admin\model\VideoInfoModel;
|
||||
use app\admin\model\SystemConfigModel;
|
||||
use app\admin\model\VideoClassModel;
|
||||
|
||||
class GenerateSiteMapCol extends PullDataColBase
|
||||
{
|
||||
public function generate()
|
||||
{
|
||||
$strSiteDomain = SystemConfigModel::getValByCode('YONG_JIU_DOMAIN');
|
||||
|
||||
// 每个 Sitemap 包含的最大 URL 数量
|
||||
$chunkSize = 40000;
|
||||
|
||||
// 从数据库获取所有视频总数
|
||||
$totalVideoCount = VideoInfoModel::count();
|
||||
|
||||
// 获取分类信息
|
||||
$categories = VideoClassModel::getDataByCache();
|
||||
|
||||
// 生成视频详情的 Sitemap
|
||||
$videoSitemapFiles = $this->generateVideoSitemaps($chunkSize, $totalVideoCount, $strSiteDomain);
|
||||
|
||||
// 生成分类的 Sitemap
|
||||
$categorySitemapFiles = $this->generateCategorySitemaps($categories, $strSiteDomain);
|
||||
|
||||
// 合并所有 Sitemap 文件路径
|
||||
$allSitemapFiles = array_merge($videoSitemapFiles, $categorySitemapFiles);
|
||||
|
||||
// 生成 Sitemap Index 文件
|
||||
$this->buildSitemapIndex($allSitemapFiles, $strSiteDomain);
|
||||
|
||||
var_dump(['message' => '所有 Sitemap 生成成功', 'files' => $allSitemapFiles]);
|
||||
}
|
||||
|
||||
private function generateVideoSitemaps(int $chunkSize, int $totalCount, string $strSiteDomain): array
|
||||
{
|
||||
$totalFiles = ceil($totalCount / $chunkSize);
|
||||
$sitemapFiles = [];
|
||||
|
||||
for ($i = 0; $i < $totalFiles; $i++) {
|
||||
$videos = VideoInfoModel::field('v_pinyin')
|
||||
->limit($i * $chunkSize, $chunkSize)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$sitemapXml = $this->buildSitemap($videos, $strSiteDomain);
|
||||
$filePath = public_path() . "sitemap_video_{$i}.xml";
|
||||
file_put_contents($filePath, $sitemapXml);
|
||||
$sitemapFiles[] = $filePath;
|
||||
}
|
||||
|
||||
return $sitemapFiles;
|
||||
}
|
||||
|
||||
private function generateCategorySitemaps(array $categories, string $strSiteDomain): array
|
||||
{
|
||||
$sitemapFiles = [];
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$vcId = $category['vc_id'];
|
||||
$vcNicheng = $category['vc_nicheng'];
|
||||
$vcName = $category['vc_name'];
|
||||
|
||||
$videoCount = VideoInfoModel::where('vc_id', $vcId)->count();
|
||||
$totalPages = ceil($videoCount / 30);
|
||||
|
||||
$categoryUrls = [];
|
||||
$categoryUrls[] = [
|
||||
'url' => "/vodtype/{$vcNicheng}.html",
|
||||
'title' => "{$vcName} - 首页",
|
||||
'is_home' => true,
|
||||
];
|
||||
|
||||
for ($page = 2; $page <= $totalPages; $page++) {
|
||||
$categoryUrls[] = [
|
||||
'url' => "/vodshow/{$vcNicheng}--------{$page}---.html",
|
||||
'title' => "{$vcName} - 第{$page}页",
|
||||
'is_home' => false,
|
||||
];
|
||||
}
|
||||
|
||||
$sitemapXml = $this->buildSitemap($categoryUrls, $strSiteDomain, true);
|
||||
$filePath = public_path() . "sitemap_category_{$vcNicheng}.xml";
|
||||
file_put_contents($filePath, $sitemapXml);
|
||||
$sitemapFiles[] = $filePath;
|
||||
}
|
||||
|
||||
return $sitemapFiles;
|
||||
}
|
||||
|
||||
private function buildSitemap(array $items, string $strSiteDomain, bool $isCategory = false): string
|
||||
{
|
||||
$xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$urlsetStart = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
||||
$urlsetEnd = '</urlset>';
|
||||
|
||||
$urlEntries = '';
|
||||
foreach ($items as $item) {
|
||||
$urlEntries .= '<url>';
|
||||
$urlEntries .= '<loc>https://' . $strSiteDomain . ($isCategory ? $item['url'] : '/voddetail/' . htmlspecialchars($item['v_pinyin'] . '.html', ENT_QUOTES)) . '</loc>';
|
||||
$urlEntries .= '<changefreq>daily</changefreq>';
|
||||
$urlEntries .= '<priority>0.8</priority>';
|
||||
$urlEntries .= '</url>';
|
||||
}
|
||||
|
||||
return $xmlHeader . $urlsetStart . $urlEntries . $urlsetEnd;
|
||||
}
|
||||
|
||||
private function buildSitemapIndex(array $sitemapFiles, string $strSiteDomain): void
|
||||
{
|
||||
$xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$sitemapIndexStart = '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
||||
$sitemapIndexEnd = '</sitemapindex>';
|
||||
|
||||
$sitemapEntries = '';
|
||||
foreach ($sitemapFiles as $file) {
|
||||
$url = 'https://' . $strSiteDomain . '/' . basename($file);
|
||||
$sitemapEntries .= '<sitemap>';
|
||||
$sitemapEntries .= '<loc>' . htmlspecialchars($url, ENT_QUOTES) . '</loc>';
|
||||
$sitemapEntries .= '<lastmod>' . date('Y-m-d') . '</lastmod>';
|
||||
$sitemapEntries .= '</sitemap>';
|
||||
}
|
||||
|
||||
$sitemapIndexXml = $xmlHeader . $sitemapIndexStart . $sitemapEntries . $sitemapIndexEnd;
|
||||
file_put_contents(public_path() . 'sitemap_index.xml', $sitemapIndexXml);
|
||||
|
||||
var_dump(['message' => 'Sitemap Index 生成成功', 'file' => 'sitemap_index.xml']);
|
||||
}
|
||||
}
|
||||
188
code/app/task/collection/seo/GenerateSiteMapNovel.php
Normal file
188
code/app/task/collection/seo/GenerateSiteMapNovel.php
Normal file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\task\collection\seo;
|
||||
|
||||
use app\task\collection\PullDataColBase;
|
||||
|
||||
use app\admin\model\XiaoShuoXiangQingModel;
|
||||
use app\admin\model\XiaoShuoZhangJieModel;
|
||||
use app\admin\model\SystemConfigModel;
|
||||
use app\admin\model\SiteModel;
|
||||
use app\admin\model\XiaoShuoFenLeiModel;
|
||||
|
||||
class GenerateSiteMapNovel extends PullDataColBase
|
||||
{
|
||||
public function generate()
|
||||
{
|
||||
$SiteModel = SiteModel::getValById(config('app.default_app_id'));
|
||||
$strSiteDomain = $SiteModel['site_domain'];
|
||||
$strFenleiPath = $SiteModel['site_fenlei_path'];
|
||||
$strXqPath = $SiteModel['site_xiangqing_path'];
|
||||
$strRankPath = $SiteModel['site_rank_path'];
|
||||
$strTjPath = $SiteModel['site_tui_jian_path'];
|
||||
$strSeoPath = $SiteModel['site_seo_path'];
|
||||
$strZdyPath = $SiteModel['site_zdy_path'];
|
||||
$strZjPath = $SiteModel['site_zhangjie_path'];
|
||||
|
||||
// 每个 Sitemap 包含的最大 URL 数量
|
||||
$chunkSize = 40000;
|
||||
|
||||
// 从数据库获取所有总数
|
||||
$totalNovelCount = XiaoShuoXiangQingModel::count();
|
||||
|
||||
// 从数据库获取所有总数
|
||||
$totalNovelZjCount = XiaoShuoZhangJieModel::count();
|
||||
|
||||
// 获取分类信息
|
||||
$categories = XiaoShuoFenLeiModel::getDataByCache();
|
||||
|
||||
// 生成详情的 Sitemap
|
||||
$novelSitemapFiles = $this->generateNovelSitemaps($chunkSize, $totalNovelCount, $strSiteDomain);
|
||||
|
||||
// 生成章节的 Sitemap
|
||||
$novelZjSitemapFiles = $this->generateNovelZjSitemaps($chunkSize, $totalNovelZjCount, $strSiteDomain);
|
||||
|
||||
// 生成分类的 Sitemap
|
||||
$categorySitemapFiles = $this->generateCategorySitemaps($categories, $strSiteDomain);
|
||||
|
||||
// 合并所有 Sitemap 文件路径
|
||||
$allSitemapFiles = array_merge($novelSitemapFiles, $categorySitemapFiles,$novelZjSitemapFiles);
|
||||
|
||||
// 生成 Sitemap Index 文件
|
||||
$this->buildSitemapIndex($allSitemapFiles, $strSiteDomain);
|
||||
|
||||
var_dump(['message' => '所有 Sitemap 生成成功', 'files' => $allSitemapFiles]);
|
||||
}
|
||||
|
||||
private function generateNovelZjSitemaps(int $chunkSize, int $totalCount, string $strSiteDomain): array
|
||||
{
|
||||
$totalFiles = ceil($totalCount / $chunkSize);
|
||||
$sitemapFiles = [];
|
||||
|
||||
for ($i = 0; $i < $totalFiles; $i++) {
|
||||
$Novels = XiaoShuoZhangJieModel::field(['xsxq_id','xszj_id']) //intNovelId-:intNovelSourceId-:intNovelSourceSeoId
|
||||
->limit($i * $chunkSize, $chunkSize)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$sitemapXml = $this->buildZjSitemap($Novels, $strSiteDomain);
|
||||
$filePath = public_path() . "sitemap_novel_zj_{$i}.xml";
|
||||
file_put_contents($filePath, $sitemapXml);
|
||||
$sitemapFiles[] = $filePath;
|
||||
}
|
||||
|
||||
return $sitemapFiles;
|
||||
}
|
||||
|
||||
|
||||
private function generateNovelSitemaps(int $chunkSize, int $totalCount, string $strSiteDomain): array
|
||||
{
|
||||
$totalFiles = ceil($totalCount / $chunkSize);
|
||||
$sitemapFiles = [];
|
||||
|
||||
for ($i = 0; $i < $totalFiles; $i++) {
|
||||
$Novels = XiaoShuoXiangQingModel::field(['xsxq_id','xsxq_source_id','xsxq_source_seo_id']) //intNovelId-:intNovelSourceId-:intNovelSourceSeoId
|
||||
->limit($i * $chunkSize, $chunkSize)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$sitemapXml = $this->buildSitemap($Novels, $strSiteDomain);
|
||||
$filePath = public_path() . "sitemap_novel_{$i}.xml";
|
||||
file_put_contents($filePath, $sitemapXml);
|
||||
$sitemapFiles[] = $filePath;
|
||||
}
|
||||
|
||||
return $sitemapFiles;
|
||||
}
|
||||
|
||||
private function generateCategorySitemaps(array $categories, string $strSiteDomain): array
|
||||
{
|
||||
$sitemapFiles = [];
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$vcId = $category['xsfl_id'];
|
||||
$vcName = $category['xsfl_name'];
|
||||
|
||||
$intNovelCount = XiaoShuoFenLeiModel::where('xsfl_id', $vcId)->count();
|
||||
$totalPages = ceil($intNovelCount / 30);
|
||||
|
||||
$categoryUrls = [];
|
||||
for ($type = 0; $type <= 3; $type++) {
|
||||
for ($page = 1; $page <= $totalPages; $page++) {
|
||||
$categoryUrls[] = [
|
||||
// /fenlei/1-0-1.html
|
||||
'url' => "/fenlei/{$vcId}-{$type}-{$page}.html",
|
||||
'title' => "{$vcName} - 第{$page}页",
|
||||
'is_home' => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$sitemapXml = $this->buildSitemap($categoryUrls, $strSiteDomain, true);
|
||||
$filePath = public_path() . "sitemap_category_{$vcId}.xml";
|
||||
file_put_contents($filePath, $sitemapXml);
|
||||
$sitemapFiles[] = $filePath;
|
||||
}
|
||||
|
||||
return $sitemapFiles;
|
||||
}
|
||||
|
||||
private function buildZjSitemap(array $items, string $strSiteDomain, bool $isCategory = false): string
|
||||
{
|
||||
$xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$urlsetStart = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
||||
$urlsetEnd = '</urlset>';
|
||||
// zj/18648-206.html
|
||||
$urlEntries = '';
|
||||
foreach ($items as $item) {
|
||||
$urlEntries .= '<url>';
|
||||
$urlEntries .= '<loc>https://' . $strSiteDomain . ($isCategory ? $item['url'] : '/zj/' . htmlspecialchars($item['xsxq_id'].'-'.$item['xszj_id']. '.html', ENT_QUOTES)) . '</loc>';
|
||||
$urlEntries .= '<changefreq>daily</changefreq>';
|
||||
$urlEntries .= '<priority>0.8</priority>';
|
||||
$urlEntries .= '</url>';
|
||||
}
|
||||
|
||||
return $xmlHeader . $urlsetStart . $urlEntries . $urlsetEnd;
|
||||
}
|
||||
|
||||
private function buildSitemap(array $items, string $strSiteDomain, bool $isCategory = false): string
|
||||
{
|
||||
$xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$urlsetStart = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
||||
$urlsetEnd = '</urlset>';
|
||||
// /xq/20052-16107-161071.html
|
||||
$urlEntries = '';
|
||||
foreach ($items as $item) {
|
||||
$urlEntries .= '<url>';
|
||||
$urlEntries .= '<loc>https://' . $strSiteDomain . ($isCategory ? $item['url'] : '/xq/' . htmlspecialchars($item['xsxq_id'].'-'.$item['xsxq_source_id'].'-'.$item['xsxq_source_seo_id']. '.html', ENT_QUOTES)) . '</loc>';
|
||||
$urlEntries .= '<changefreq>daily</changefreq>';
|
||||
$urlEntries .= '<priority>1.0</priority>';
|
||||
$urlEntries .= '</url>';
|
||||
}
|
||||
|
||||
return $xmlHeader . $urlsetStart . $urlEntries . $urlsetEnd;
|
||||
}
|
||||
|
||||
private function buildSitemapIndex(array $sitemapFiles, string $strSiteDomain): void
|
||||
{
|
||||
$xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$sitemapIndexStart = '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
||||
$sitemapIndexEnd = '</sitemapindex>';
|
||||
|
||||
$sitemapEntries = '';
|
||||
foreach ($sitemapFiles as $file) {
|
||||
$url = 'https://' . $strSiteDomain . '/' . basename($file);
|
||||
$sitemapEntries .= '<sitemap>';
|
||||
$sitemapEntries .= '<loc>' . htmlspecialchars($url, ENT_QUOTES) . '</loc>';
|
||||
$sitemapEntries .= '<lastmod>' . date('Y-m-d') . '</lastmod>';
|
||||
$sitemapEntries .= '</sitemap>';
|
||||
}
|
||||
|
||||
$sitemapIndexXml = $xmlHeader . $sitemapIndexStart . $sitemapEntries . $sitemapIndexEnd;
|
||||
file_put_contents(public_path() . 'sitemap_index.xml', $sitemapIndexXml);
|
||||
|
||||
var_dump(['message' => 'Sitemap Index 生成成功', 'file' => 'sitemap_index.xml']);
|
||||
}
|
||||
}
|
||||
242
code/app/task/collection/seo/GenerateSiteMapNovelSk.php
Normal file
242
code/app/task/collection/seo/GenerateSiteMapNovelSk.php
Normal file
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\task\collection\seo;
|
||||
|
||||
use app\task\collection\PullDataColBase;
|
||||
|
||||
use app\admin\model\XiaoShuoXiangQingModel;
|
||||
use app\admin\model\NovelInfoSeoModel;
|
||||
use app\admin\model\XiaoShuoZhangJieModel;
|
||||
use app\admin\model\SiteModel;
|
||||
use app\admin\model\XiaoShuoFenLeiModel;
|
||||
|
||||
class GenerateSiteMapNovelSk extends PullDataColBase
|
||||
{
|
||||
public function generate()
|
||||
{
|
||||
$SiteModel = SiteModel::getValById(config('app.default_app_id'));
|
||||
// $strSiteDomain = SiteModel::getValBySiteIdByValCode('site_domain');
|
||||
$strSiteDomain = $SiteModel['site_domain'];
|
||||
$strFenleiPath = $SiteModel['site_fenlei_path'];
|
||||
$strXqPath = $SiteModel['site_xiangqing_path'];
|
||||
$strRankPath = $SiteModel['site_rank_path'];
|
||||
$strTjPath = $SiteModel['site_tui_jian_path'];
|
||||
$strSeoPath = $SiteModel['site_seo_path'];
|
||||
$strZdyPath = $SiteModel['site_zdy_path'];
|
||||
$strZjPath = $SiteModel['site_zhangjie_path'];
|
||||
|
||||
// 每个 Sitemap 包含的最大 URL 数量
|
||||
$chunkSize = 40000;
|
||||
|
||||
// 从数据库获取所有总数
|
||||
$totalNovelCount = XiaoShuoXiangQingModel::count();
|
||||
|
||||
// 从数据库获取所有总数
|
||||
$totalNovelSeoCount = NovelInfoSeoModel::count();
|
||||
|
||||
// 从数据库获取所有总数
|
||||
$totalNovelZjCount = XiaoShuoZhangJieModel::count();
|
||||
|
||||
// 获取分类信息
|
||||
$categories = XiaoShuoFenLeiModel::getDataByCache();
|
||||
|
||||
// 生成详情的 Sitemap 小说详情
|
||||
$novelSitemapFiles = $this->generateNovelSitemaps($chunkSize, $totalNovelCount, $strSiteDomain, $strXqPath);
|
||||
|
||||
// 生成详情的 Sitemap 小说seo
|
||||
$novelSeoSitemapFiles = $this->generateNovelSeoSitemaps($chunkSize, $totalNovelSeoCount, $strSiteDomain, $strSeoPath);
|
||||
|
||||
// 生成章节的 Sitemap 小说章节
|
||||
$novelZjSitemapFiles = $this->generateNovelZjSitemaps($chunkSize, $totalNovelZjCount, $strSiteDomain, $strXqPath);
|
||||
|
||||
// 生成分类的 Sitemap 小说分类
|
||||
$categorySitemapFiles = $this->generateCategorySitemaps($categories, $strSiteDomain, $strFenleiPath, $strXqPath);
|
||||
|
||||
// 合并所有 Sitemap 文件路径
|
||||
$allSitemapFiles = array_merge($novelSitemapFiles, $novelSeoSitemapFiles, $categorySitemapFiles, $novelZjSitemapFiles);
|
||||
|
||||
// 生成 Sitemap Index 文件
|
||||
$this->buildSitemapIndex($allSitemapFiles, $strSiteDomain);
|
||||
|
||||
var_dump(['message' => '所有 Sitemap 生成成功', 'files' => $allSitemapFiles]);
|
||||
}
|
||||
|
||||
# 生成小说章节 xml文件
|
||||
private function generateNovelZjSitemaps(int $chunkSize, int $totalCount, string $strSiteDomain, string $strXqPath): array
|
||||
{
|
||||
$totalFiles = ceil($totalCount / $chunkSize);
|
||||
$sitemapFiles = [];
|
||||
|
||||
for ($i = 0; $i < $totalFiles; $i++) {
|
||||
$Novels = XiaoShuoZhangJieModel::field(['xsxq_id', 'xszj_id']) //intNovelId-:intNovelSourceId-:intNovelSourceSeoId
|
||||
->limit($i * $chunkSize, $chunkSize)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$sitemapXml = $this->buildZjSitemap($Novels, $strSiteDomain, $strXqPath);
|
||||
$filePath = public_path() . "sitemap_novel_zj_{$i}.xml";
|
||||
file_put_contents($filePath, $sitemapXml);
|
||||
$sitemapFiles[] = $filePath;
|
||||
}
|
||||
|
||||
return $sitemapFiles;
|
||||
}
|
||||
|
||||
# 生成小说详情 xml文件
|
||||
private function generateNovelSitemaps(int $chunkSize, int $totalCount, string $strSiteDomain, string $strXqPath): array
|
||||
{
|
||||
$totalFiles = ceil($totalCount / $chunkSize);
|
||||
$sitemapFiles = [];
|
||||
|
||||
for ($i = 0; $i < $totalFiles; $i++) {
|
||||
$Novels = XiaoShuoXiangQingModel::field(['xsxq_id', 'xsxq_source_id', 'xsxq_source_seo_id']) //intNovelId-:intNovelSourceId-:intNovelSourceSeoId
|
||||
->limit($i * $chunkSize, $chunkSize)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$sitemapXml = $this->buildSitemap($Novels, $strSiteDomain, $strXqPath);
|
||||
$filePath = public_path() . "sitemap_novel_{$i}.xml";
|
||||
file_put_contents($filePath, $sitemapXml);
|
||||
$sitemapFiles[] = $filePath;
|
||||
}
|
||||
|
||||
return $sitemapFiles;
|
||||
}
|
||||
|
||||
# 生成小说详情 xml文件
|
||||
private function generateNovelSeoSitemaps(int $chunkSize, int $totalCount, string $strSiteDomain, string $strSeoPath): array
|
||||
{
|
||||
$totalFiles = ceil($totalCount / $chunkSize);
|
||||
$sitemapFiles = [];
|
||||
|
||||
for ($i = 0; $i < $totalFiles; $i++) {
|
||||
$Novels = NovelInfoSeoModel::field(['xsxq_id', 'nis_id']) //show/nis_id
|
||||
->limit($i * $chunkSize, $chunkSize)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$sitemapXml = $this->buildXiaoShuoSeoSitemap($Novels, $strSiteDomain, $strSeoPath);
|
||||
$filePath = public_path() . "sitemap_novel_seo_{$i}.xml";
|
||||
file_put_contents($filePath, $sitemapXml);
|
||||
$sitemapFiles[] = $filePath;
|
||||
}
|
||||
|
||||
return $sitemapFiles;
|
||||
}
|
||||
|
||||
// 生成分类链接
|
||||
private function generateCategorySitemaps(array $categories, string $strSiteDomain, string $strFenleiPath, string $strXqPath): array
|
||||
{
|
||||
$sitemapFiles = [];
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$vcId = $category['xsfl_id'];
|
||||
$vcName = $category['xsfl_name'];
|
||||
|
||||
$intNovelCount = XiaoShuoFenLeiModel::where('xsfl_id', $vcId)->count();
|
||||
$totalPages = ceil($intNovelCount / 30);
|
||||
|
||||
$categoryUrls = [];
|
||||
for ($status = 0; $status <= 2; $status++) {
|
||||
for ($sort = 0; $sort <= 4; $sort++) {
|
||||
for ($page = 1; $page <= $totalPages; $page++) {
|
||||
$categoryUrls[] = [
|
||||
// /fl/:intCId-:intSort-[:intPage]
|
||||
'url' => "/{$strFenleiPath}/{$vcId}-{$sort}-{$page}.html",
|
||||
'title' => "{$vcName} - 第{$page}页",
|
||||
'is_home' => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sitemapXml = $this->buildSitemap($categoryUrls, $strSiteDomain, $strXqPath, true);
|
||||
$filePath = public_path() . "sitemap_category_{$vcId}.xml";
|
||||
file_put_contents($filePath, $sitemapXml);
|
||||
$sitemapFiles[] = $filePath;
|
||||
}
|
||||
|
||||
return $sitemapFiles;
|
||||
}
|
||||
|
||||
//生成章节链接
|
||||
private function buildZjSitemap(array $items, string $strSiteDomain, string $strXqPath, bool $isCategory = false): string
|
||||
{
|
||||
$xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$urlsetStart = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
||||
$urlsetEnd = '</urlset>';
|
||||
// /xq/:intNovelId/:intZhangJiePaiXu-[:strSort]
|
||||
$urlEntries = '';
|
||||
foreach ($items as $item) {
|
||||
$urlEntries .= '<url>';
|
||||
$urlEntries .= '<loc>https://' . $strSiteDomain . ($isCategory ? $item['url'] : '/' . $strXqPath . '/' . htmlspecialchars($item['xsxq_id'] . '-' . $item['xszj_pai_xu']. '-' . $item['xszj_sort'] . '.html', ENT_QUOTES)) . '</loc>';
|
||||
$urlEntries .= '<changefreq>daily</changefreq>';
|
||||
$urlEntries .= '<priority>0.8</priority>';
|
||||
$urlEntries .= '</url>';
|
||||
}
|
||||
|
||||
return $xmlHeader . $urlsetStart . $urlEntries . $urlsetEnd;
|
||||
}
|
||||
|
||||
// 生成 详情链接
|
||||
private function buildSitemap(array $items, string $strSiteDomain, string $strXqPath, bool $isCategory = false): string
|
||||
{
|
||||
$xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$urlsetStart = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
||||
$urlsetEnd = '</urlset>';
|
||||
// /xq/:intNovelId
|
||||
$urlEntries = '';
|
||||
foreach ($items as $item) {
|
||||
$urlEntries .= '<url>';
|
||||
$urlEntries .= '<loc>https://' . $strSiteDomain . ($isCategory ? $item['url'] : '/' . $strXqPath . '/' . htmlspecialchars($item['xsxq_id'] . '.html', ENT_QUOTES)) . '</loc>';
|
||||
$urlEntries .= '<changefreq>daily</changefreq>';
|
||||
$urlEntries .= '<priority>1.0</priority>';
|
||||
$urlEntries .= '</url>';
|
||||
}
|
||||
|
||||
return $xmlHeader . $urlsetStart . $urlEntries . $urlsetEnd;
|
||||
}
|
||||
|
||||
// 生成详情 seo 链接
|
||||
private function buildXiaoShuoSeoSitemap(array $items, string $strSiteDomain, string $strSeoPath, bool $isCategory = false): string
|
||||
{
|
||||
$xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$urlsetStart = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
||||
$urlsetEnd = '</urlset>';
|
||||
// /show/:intNovelId
|
||||
$urlEntries = '';
|
||||
foreach ($items as $item) {
|
||||
$urlEntries .= '<url>';
|
||||
$urlEntries .= '<loc>https://' . $strSiteDomain . ($isCategory ? $item['url'] : '/' . $strSeoPath . '/' . htmlspecialchars($item['nis_id'] . '.html', ENT_QUOTES)) . '</loc>';
|
||||
$urlEntries .= '<changefreq>daily</changefreq>';
|
||||
$urlEntries .= '<priority>1.0</priority>';
|
||||
$urlEntries .= '</url>';
|
||||
}
|
||||
|
||||
return $xmlHeader . $urlsetStart . $urlEntries . $urlsetEnd;
|
||||
}
|
||||
|
||||
// 生成 xml 文件
|
||||
private function buildSitemapIndex(array $sitemapFiles, string $strSiteDomain): void
|
||||
{
|
||||
$xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$sitemapIndexStart = '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
||||
$sitemapIndexEnd = '</sitemapindex>';
|
||||
|
||||
$sitemapEntries = '';
|
||||
foreach ($sitemapFiles as $file) {
|
||||
$url = 'https://' . $strSiteDomain . '/' . basename($file);
|
||||
$sitemapEntries .= '<sitemap>';
|
||||
$sitemapEntries .= '<loc>' . htmlspecialchars($url, ENT_QUOTES) . '</loc>';
|
||||
$sitemapEntries .= '<lastmod>' . date('Y-m-d') . '</lastmod>';
|
||||
$sitemapEntries .= '</sitemap>';
|
||||
}
|
||||
|
||||
$sitemapIndexXml = $xmlHeader . $sitemapIndexStart . $sitemapEntries . $sitemapIndexEnd;
|
||||
file_put_contents(public_path() . 'sitemap_index.xml', $sitemapIndexXml);
|
||||
|
||||
var_dump(['message' => 'Sitemap Index 生成成功', 'file' => 'sitemap_index.xml']);
|
||||
}
|
||||
}
|
||||
242
code/app/task/collection/seo/GenerateSiteMapNovelZw.php
Normal file
242
code/app/task/collection/seo/GenerateSiteMapNovelZw.php
Normal file
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\task\collection\seo;
|
||||
|
||||
use app\task\collection\PullDataColBase;
|
||||
|
||||
use app\admin\model\XiaoShuoXiangQingModel;
|
||||
use app\admin\model\NovelInfoSeoModel;
|
||||
use app\admin\model\XiaoShuoZhangJieModel;
|
||||
use app\admin\model\SiteModel;
|
||||
use app\admin\model\XiaoShuoFenLeiModel;
|
||||
|
||||
class GenerateSiteMapNovelZw extends PullDataColBase
|
||||
{
|
||||
public function generate()
|
||||
{
|
||||
$SiteModel = SiteModel::getValById(config('app.default_app_id'));
|
||||
// $strSiteDomain = SiteModel::getValBySiteIdByValCode('site_domain');
|
||||
$strSiteDomain = $SiteModel['site_domain'];
|
||||
$strFenleiPath = $SiteModel['site_fenlei_path'];
|
||||
$strXqPath = $SiteModel['site_xiangqing_path'];
|
||||
$strRankPath = $SiteModel['site_rank_path'];
|
||||
$strTjPath = $SiteModel['site_tui_jian_path'];
|
||||
$strSeoPath = $SiteModel['site_seo_path'];
|
||||
$strZdyPath = $SiteModel['site_zdy_path'];
|
||||
$strZjPath = $SiteModel['site_zhangjie_path'];
|
||||
|
||||
// 每个 Sitemap 包含的最大 URL 数量
|
||||
$chunkSize = 40000;
|
||||
|
||||
// 从数据库获取所有总数
|
||||
$totalNovelCount = XiaoShuoXiangQingModel::count();
|
||||
|
||||
// 从数据库获取所有总数
|
||||
$totalNovelSeoCount = NovelInfoSeoModel::count();
|
||||
|
||||
// 从数据库获取所有总数
|
||||
$totalNovelZjCount = XiaoShuoZhangJieModel::count();
|
||||
|
||||
// 获取分类信息
|
||||
$categories = XiaoShuoFenLeiModel::getDataByCache();
|
||||
|
||||
// 生成详情的 Sitemap 小说详情
|
||||
$novelSitemapFiles = $this->generateNovelSitemaps($chunkSize, $totalNovelCount, $strSiteDomain, $strXqPath);
|
||||
|
||||
// 生成详情的 Sitemap 小说seo
|
||||
$novelSeoSitemapFiles = $this->generateNovelSeoSitemaps($chunkSize, $totalNovelSeoCount, $strSiteDomain, $strSeoPath);
|
||||
|
||||
// 生成章节的 Sitemap 小说章节
|
||||
$novelZjSitemapFiles = $this->generateNovelZjSitemaps($chunkSize, $totalNovelZjCount, $strSiteDomain, $strXqPath);
|
||||
|
||||
// 生成分类的 Sitemap 小说分类
|
||||
$categorySitemapFiles = $this->generateCategorySitemaps($categories, $strSiteDomain, $strFenleiPath, $strXqPath);
|
||||
|
||||
// 合并所有 Sitemap 文件路径
|
||||
$allSitemapFiles = array_merge($novelSitemapFiles, $novelSeoSitemapFiles, $categorySitemapFiles, $novelZjSitemapFiles);
|
||||
|
||||
// 生成 Sitemap Index 文件
|
||||
$this->buildSitemapIndex($allSitemapFiles, $strSiteDomain);
|
||||
|
||||
var_dump(['message' => '所有 Sitemap 生成成功', 'files' => $allSitemapFiles]);
|
||||
}
|
||||
|
||||
# 生成小说章节 xml文件
|
||||
private function generateNovelZjSitemaps(int $chunkSize, int $totalCount, string $strSiteDomain, string $strXqPath): array
|
||||
{
|
||||
$totalFiles = ceil($totalCount / $chunkSize);
|
||||
$sitemapFiles = [];
|
||||
|
||||
for ($i = 0; $i < $totalFiles; $i++) {
|
||||
$Novels = XiaoShuoZhangJieModel::field(['xsxq_id', 'xszj_id']) //intNovelId-:intNovelSourceId-:intNovelSourceSeoId
|
||||
->limit($i * $chunkSize, $chunkSize)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$sitemapXml = $this->buildZjSitemap($Novels, $strSiteDomain, $strXqPath);
|
||||
$filePath = public_path() . "sitemap_novel_zj_{$i}.xml";
|
||||
file_put_contents($filePath, $sitemapXml);
|
||||
$sitemapFiles[] = $filePath;
|
||||
}
|
||||
|
||||
return $sitemapFiles;
|
||||
}
|
||||
|
||||
# 生成小说详情 xml文件
|
||||
private function generateNovelSitemaps(int $chunkSize, int $totalCount, string $strSiteDomain, string $strXqPath): array
|
||||
{
|
||||
$totalFiles = ceil($totalCount / $chunkSize);
|
||||
$sitemapFiles = [];
|
||||
|
||||
for ($i = 0; $i < $totalFiles; $i++) {
|
||||
$Novels = XiaoShuoXiangQingModel::field(['xsxq_id', 'xsxq_source_id', 'xsxq_source_seo_id']) //intNovelId-:intNovelSourceId-:intNovelSourceSeoId
|
||||
->limit($i * $chunkSize, $chunkSize)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$sitemapXml = $this->buildSitemap($Novels, $strSiteDomain, $strXqPath);
|
||||
$filePath = public_path() . "sitemap_novel_{$i}.xml";
|
||||
file_put_contents($filePath, $sitemapXml);
|
||||
$sitemapFiles[] = $filePath;
|
||||
}
|
||||
|
||||
return $sitemapFiles;
|
||||
}
|
||||
|
||||
# 生成小说详情 xml文件
|
||||
private function generateNovelSeoSitemaps(int $chunkSize, int $totalCount, string $strSiteDomain, string $strSeoPath): array
|
||||
{
|
||||
$totalFiles = ceil($totalCount / $chunkSize);
|
||||
$sitemapFiles = [];
|
||||
|
||||
for ($i = 0; $i < $totalFiles; $i++) {
|
||||
$Novels = NovelInfoSeoModel::field(['xsxq_id', 'nis_id']) //show/nis_id
|
||||
->limit($i * $chunkSize, $chunkSize)
|
||||
->select()
|
||||
->toArray();
|
||||
|
||||
$sitemapXml = $this->buildXiaoShuoSeoSitemap($Novels, $strSiteDomain, $strSeoPath);
|
||||
$filePath = public_path() . "sitemap_novel_seo_{$i}.xml";
|
||||
file_put_contents($filePath, $sitemapXml);
|
||||
$sitemapFiles[] = $filePath;
|
||||
}
|
||||
|
||||
return $sitemapFiles;
|
||||
}
|
||||
|
||||
// 生成分类链接
|
||||
private function generateCategorySitemaps(array $categories, string $strSiteDomain, string $strFenleiPath, string $strXqPath): array
|
||||
{
|
||||
$sitemapFiles = [];
|
||||
|
||||
foreach ($categories as $category) {
|
||||
$vcId = $category['xsfl_id'];
|
||||
$vcName = $category['xsfl_name'];
|
||||
|
||||
$intNovelCount = XiaoShuoFenLeiModel::where('xsfl_id', $vcId)->count();
|
||||
$totalPages = ceil($intNovelCount / 30);
|
||||
|
||||
$categoryUrls = [];
|
||||
for ($status = 0; $status <= 2; $status++) {
|
||||
for ($sort = 0; $sort <= 4; $sort++) {
|
||||
for ($page = 1; $page <= $totalPages; $page++) {
|
||||
$categoryUrls[] = [
|
||||
// /fl/:intCId-:intSort-[:intPage]
|
||||
'url' => "/{$strFenleiPath}/{$vcId}-{$sort}-{$page}.html",
|
||||
'title' => "{$vcName} - 第{$page}页",
|
||||
'is_home' => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sitemapXml = $this->buildSitemap($categoryUrls, $strSiteDomain, $strXqPath, true);
|
||||
$filePath = public_path() . "sitemap_category_{$vcId}.xml";
|
||||
file_put_contents($filePath, $sitemapXml);
|
||||
$sitemapFiles[] = $filePath;
|
||||
}
|
||||
|
||||
return $sitemapFiles;
|
||||
}
|
||||
|
||||
//生成章节链接
|
||||
private function buildZjSitemap(array $items, string $strSiteDomain, string $strXqPath, bool $isCategory = false): string
|
||||
{
|
||||
$xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$urlsetStart = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
||||
$urlsetEnd = '</urlset>';
|
||||
// /xq/:intNovelId/:intZhangJiePaiXu-[:strSort]
|
||||
$urlEntries = '';
|
||||
foreach ($items as $item) {
|
||||
$urlEntries .= '<url>';
|
||||
$urlEntries .= '<loc>https://' . $strSiteDomain . ($isCategory ? $item['url'] : '/' . $strXqPath . '/' . htmlspecialchars($item['xsxq_id'] . '-' . $item['xszj_pai_xu']. '-' . $item['xszj_sort'] . '.html', ENT_QUOTES)) . '</loc>';
|
||||
$urlEntries .= '<changefreq>daily</changefreq>';
|
||||
$urlEntries .= '<priority>0.8</priority>';
|
||||
$urlEntries .= '</url>';
|
||||
}
|
||||
|
||||
return $xmlHeader . $urlsetStart . $urlEntries . $urlsetEnd;
|
||||
}
|
||||
|
||||
// 生成 详情链接
|
||||
private function buildSitemap(array $items, string $strSiteDomain, string $strXqPath, bool $isCategory = false): string
|
||||
{
|
||||
$xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$urlsetStart = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
||||
$urlsetEnd = '</urlset>';
|
||||
// /xq/:intNovelId
|
||||
$urlEntries = '';
|
||||
foreach ($items as $item) {
|
||||
$urlEntries .= '<url>';
|
||||
$urlEntries .= '<loc>https://' . $strSiteDomain . ($isCategory ? $item['url'] : '/' . $strXqPath . '/' . htmlspecialchars($item['xsxq_id'] . '.html', ENT_QUOTES)) . '</loc>';
|
||||
$urlEntries .= '<changefreq>daily</changefreq>';
|
||||
$urlEntries .= '<priority>1.0</priority>';
|
||||
$urlEntries .= '</url>';
|
||||
}
|
||||
|
||||
return $xmlHeader . $urlsetStart . $urlEntries . $urlsetEnd;
|
||||
}
|
||||
|
||||
// 生成详情 seo 链接
|
||||
private function buildXiaoShuoSeoSitemap(array $items, string $strSiteDomain, string $strSeoPath, bool $isCategory = false): string
|
||||
{
|
||||
$xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$urlsetStart = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
||||
$urlsetEnd = '</urlset>';
|
||||
// /show/:intNovelId
|
||||
$urlEntries = '';
|
||||
foreach ($items as $item) {
|
||||
$urlEntries .= '<url>';
|
||||
$urlEntries .= '<loc>https://' . $strSiteDomain . ($isCategory ? $item['url'] : '/' . $strSeoPath . '/' . htmlspecialchars($item['nis_id'] . '.html', ENT_QUOTES)) . '</loc>';
|
||||
$urlEntries .= '<changefreq>daily</changefreq>';
|
||||
$urlEntries .= '<priority>1.0</priority>';
|
||||
$urlEntries .= '</url>';
|
||||
}
|
||||
|
||||
return $xmlHeader . $urlsetStart . $urlEntries . $urlsetEnd;
|
||||
}
|
||||
|
||||
// 生成 xml 文件
|
||||
private function buildSitemapIndex(array $sitemapFiles, string $strSiteDomain): void
|
||||
{
|
||||
$xmlHeader = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$sitemapIndexStart = '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
||||
$sitemapIndexEnd = '</sitemapindex>';
|
||||
|
||||
$sitemapEntries = '';
|
||||
foreach ($sitemapFiles as $file) {
|
||||
$url = 'https://' . $strSiteDomain . '/' . basename($file);
|
||||
$sitemapEntries .= '<sitemap>';
|
||||
$sitemapEntries .= '<loc>' . htmlspecialchars($url, ENT_QUOTES) . '</loc>';
|
||||
$sitemapEntries .= '<lastmod>' . date('Y-m-d') . '</lastmod>';
|
||||
$sitemapEntries .= '</sitemap>';
|
||||
}
|
||||
|
||||
$sitemapIndexXml = $xmlHeader . $sitemapIndexStart . $sitemapEntries . $sitemapIndexEnd;
|
||||
file_put_contents(public_path() . 'sitemap_index.xml', $sitemapIndexXml);
|
||||
|
||||
var_dump(['message' => 'Sitemap Index 生成成功', 'file' => 'sitemap_index.xml']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user