This commit is contained in:
make
2025-04-16 11:00:28 +08:00
64 changed files with 2461 additions and 1681 deletions

View File

@@ -6,7 +6,7 @@ DEFAULT_LANG = zh-cn
# 数据库 # 数据库
DB_TYPE = mysql DB_TYPE = mysql
DB_HOST = 127.0.0.1 DB_HOST = 127.0.0.1
DB_NAME = seo DB_NAME = novel
DB_USER = root DB_USER = root
DB_PASS = qq123123 DB_PASS = qq123123
DB_PORT = 3306 DB_PORT = 3306
@@ -51,7 +51,14 @@ VIEW_TPL_CACHE = false
VIEW_DATA_CACHE = false VIEW_DATA_CACHE = false
# PROXY # PROXY
PROXY_STATUS = false PROXY_STATUS = true
PROXY_CODE = XIONGMAO # PROXY_CODE = XIONGMAO
PROXY_ORDER = DT20250413204710pFcgjMR9 # PROXY_HOST = dtbf.xiongmaodaili.com:8089
PROXY_SECRET = 583b141edcf65ce94f83591c5cb592ed # PROXY_KEY = DT20250413204710pFcgjMR9
# PROXY_SECRET = 583b141edcf65ce94f83591c5cb592ed
PROXY_CODE = KUAI
#PROXY_HOST = w739.kdltps.com
PROXY_HOST = w740.kdltps.com
PROXY_KEY = t14468368981914
PROXY_SECRET = 03xvfdc0

View File

@@ -1,4 +1,5 @@
<?php <?php
declare(strict_types=1); declare(strict_types=1);
// 应用公共文件 // 应用公共文件
@@ -750,6 +751,10 @@ namespace {
*/ */
function zhToPinYin(string $strZh): string function zhToPinYin(string $strZh): string
{ {
if (empty($strZh)) {
return $strZh;
}
$strPinYinToolsPath = root_path() . '/extend/tools/pinyin-tool'; $strPinYinToolsPath = root_path() . '/extend/tools/pinyin-tool';
$strPinYin = shell_exec(sprintf("%s %s", $strPinYinToolsPath, escapeshellcmd($strZh))); $strPinYin = shell_exec(sprintf("%s %s", $strPinYinToolsPath, escapeshellcmd($strZh)));
@@ -803,6 +808,4 @@ namespace {
} }
} }
} }
} }

View File

@@ -44,6 +44,8 @@ class Index extends BaseController
break; break;
case 'kuangYu': case 'kuangYu':
$strKey = sprintf('%s:H5:INDEX:ZUIJIAN:SEX:%s:%s', $Request->DomainModel->d_domain, 0, 8);
$arrNewsNovel = $NovelModel->getCommonNovelOnCache($strKey, $intTTL, 8, 0, NULL, ['n_update_time' => -1]);
$strKey = sprintf('%s:H5:INDEX:RANK:%s:SEX:%s', $Request->DomainModel->d_domain, 'daily', 0); $strKey = sprintf('%s:H5:INDEX:RANK:%s:SEX:%s', $Request->DomainModel->d_domain, 'daily', 0);
$arrDayRankNovel = $NovelModel->getRankNovelOnCache($strKey, 10, 0, 'daily'); $arrDayRankNovel = $NovelModel->getRankNovelOnCache($strKey, 10, 0, 'daily');
@@ -156,7 +158,8 @@ class Index extends BaseController
$intRecommendEndNovel = 12; $intRecommendEndNovel = 12;
// 男生频道,最新的 随机5个小说 // 男生频道,最新的 随机5个小说
$strKey = sprintf('%s:PC:INDEX:ZUIJIAN:SEX:%s:%s', $Request->DomainModel->d_domain, 1, 5); $strKey = sprintf('%s:PC:INDEX:ZUIJIAN:SEX:%s:%s', $Request->DomainModel->d_domain, 1, 5);
$arrBoyNewsNovel = $NovelModel->getCommonNovelOnCache($strKey, $intTTL, 5, 1, NULL, ['og_novel_update_time' => -1]); $arrBoyNewsNovel = $NovelModel->getCommonNovelOnCache($strKey, $intTTL, 5, 1, NULL, ['n_update_time' => -1]);
// 男生频道,周排行榜 随机10个小说 // 男生频道,周排行榜 随机10个小说
$strKey = sprintf('%s:PC:INDEX:RANK:%s:SEX:%s', $Request->DomainModel->d_domain, 'weekly', 1); $strKey = sprintf('%s:PC:INDEX:RANK:%s:SEX:%s', $Request->DomainModel->d_domain, 'weekly', 1);
@@ -172,7 +175,7 @@ class Index extends BaseController
// 女生频道,最新的 随机5个小说 // 女生频道,最新的 随机5个小说
$strKey = sprintf('%s:PC:INDEX:ZUIJIAN:SEX:%s:%s', $Request->DomainModel->d_domain, 2, 5); $strKey = sprintf('%s:PC:INDEX:ZUIJIAN:SEX:%s:%s', $Request->DomainModel->d_domain, 2, 5);
$arrGirlNewsNovel = $NovelModel->getCommonNovelOnCache($strKey, $intTTL, 5, 2, NULL, ['og_novel_update_time' => -1]); $arrGirlNewsNovel = $NovelModel->getCommonNovelOnCache($strKey, $intTTL, 5, 2, NULL, ['n_update_time' => -1]);
// 女生频道,周排行榜 随机10个小说 // 女生频道,周排行榜 随机10个小说
$strKey = sprintf('%s:PC:INDEX:RANK:%s:SEX:%s', $Request->DomainModel->d_domain, 'weekly', 2); $strKey = sprintf('%s:PC:INDEX:RANK:%s:SEX:%s', $Request->DomainModel->d_domain, 'weekly', 2);
@@ -203,12 +206,12 @@ class Index extends BaseController
$arrRecommendSerializationNovel = $NovelModel->getCommonNovelOnCache($strKey, $intTTL, $intRecommendSerializationNovel, 0, NULL); $arrRecommendSerializationNovel = $NovelModel->getCommonNovelOnCache($strKey, $intTTL, $intRecommendSerializationNovel, 0, NULL);
// 推荐等级为9的完结的 随机12个小说 // 推荐等级为9的完结的 随机12个小说
$strKey = sprintf('%s:PC:INDEX:TUIJIAN:WANJIE:%s', $Request->DomainModel->d_domain, $intRecommendEndNovel); $strKey = sprintf('%s:PC:INDEX:TUIJIAN:WANJIE:%s', $Request->DomainModel->d_domain, 12);
$arrRecommendEndNovel = $NovelModel->getCommonNovelOnCache($strKey, $intTTL, $intRecommendEndNovel, 0, "已完结"); $arrRecommendEndNovel = $NovelModel->getCommonNovelOnCache($strKey, $intTTL, 12, 0, "已完结");
// 最近更新-随机50 // 最近更新-随机50
$strKey = sprintf('%s:PC:INDEX:ZUIJIAN:SEX:%s:%s', $Request->DomainModel->d_domain, 0, 50); $strKey = sprintf('%s:PC:INDEX:ZUIJIAN:SEX:%s:%s', $Request->DomainModel->d_domain, 0, 50);
$arrNewsUpdateNovel = $NovelModel->getCommonNovelOnCache($strKey, $intTTL, 50, 0, NULL, ['og_novel_update_time' => -1]); $arrNewsUpdateNovel = $NovelModel->getCommonNovelOnCache($strKey, $intTTL, 50, 0, NULL, ['n_update_time' => -1]);
// Title 模板 // Title 模板
ConverterMovel::setVal([ ConverterMovel::setVal([

View File

@@ -248,11 +248,11 @@ class Novel extends BaseController
// 模拟数据-最近更新-随机50 // 模拟数据-最近更新-随机50
$strKey = sprintf('%s:PC:Novel:Channel:Latest:%s', $Request->DomainModel->d_domain, $intType); $strKey = sprintf('%s:PC:Novel:Channel:Latest:%s', $Request->DomainModel->d_domain, $intType);
$intCount = 20; $intCount = 20;
$arrNewsUpdateNovel = $NovelModel->getCommonNovelOnCache($strKey, $intLifeTime, $intCount, $intType, NULL, ['og_novel_update_time' => -1]); $arrNewsUpdateNovel = $NovelModel->getCommonNovelOnCache($strKey, $intLifeTime, $intCount, $intType, NULL, ['n_update_time' => -1]);
// echo "<pre>"; // echo "<pre>";
// var_dump($arrNewsUpdateNovel);exit; // var_dump($arrNewsUpdateNovel);exit;
// TODO og_description 改成 og_description // TODO n_description 改成 n_description
// 更新值 // 更新值
ConverterMovel::setVal([ ConverterMovel::setVal([
'intPage' => 1, 'intPage' => 1,
@@ -388,14 +388,14 @@ class Novel extends BaseController
foreach ($arrNovel['n_forge_novel'] as $arrForgeNovel) { foreach ($arrNovel['n_forge_novel'] as $arrForgeNovel) {
if ($arrForgeNovel['n_forge_id'] == $intForgeId) { if ($arrForgeNovel['n_forge_id'] == $intForgeId) {
$arrNovel['og_novel_book_name'] = $arrForgeNovel['n_forge_title']; $arrNovel['n_name'] = $arrForgeNovel['n_forge_title'];
break; break;
} }
} }
// 分类拼音 // 分类拼音
$arrNovel['category_pinyin'] = CategoryModel::getPinYinByZh($arrNovel['og_novel_category']); $arrNovel['n_category_pinyin'] = CategoryModel::getPinYin($arrNovel['n_category']);
$arrNovel['category_sex'] = $arrNovel['category_sex'] ?? 'man'; $arrNovel['n_category_sex_en'] = $arrNovel['n_category_sex_en'] ?? 'man';
// 最后章节 // 最后章节
$ChapterModel = ChapterModel::getInstance(); $ChapterModel = ChapterModel::getInstance();
@@ -411,7 +411,7 @@ class Novel extends BaseController
$strFocus = ''; $strFocus = '';
// 要点 // 要点
if ($arrLatestChapter) { if ($arrLatestChapter) {
$strFocus = strip_tags($arrLatestChapter['content']); $strFocus = strip_tags($arrLatestChapter['c_content']);
$intCount = mb_strlen($strFocus); $intCount = mb_strlen($strFocus);
if ($intCount > 300) { if ($intCount > 300) {
$intPos = mt_rand(0, $intCount - 300); $intPos = mt_rand(0, $intCount - 300);
@@ -439,12 +439,12 @@ class Novel extends BaseController
// 更新值 // 更新值
ConverterMovel::setVal([ ConverterMovel::setVal([
'intPage' => 1, 'intPage' => 1,
'strNovelName' => $arrNovel['og_novel_book_name'], 'strNovelName' => $arrNovel['n_name'],
'strNovelAuthor' => $arrNovel['og_novel_author'], 'strNovelAuthor' => $arrNovel['n_author'],
'strNovelCategoryName' => $arrNovel['og_novel_category'], 'strNovelCategoryName' => $arrNovel['n_category'],
'strNovelSex' => $arrNovel['category_sex'] == 'man' ? '男生' : '女生', 'strNovelSex' => $arrNovel['n_category_sex_en'] == 'man' ? '男生' : '女生',
'strNovelStatus' => $arrNovel['og_novel_status'], 'strNovelStatus' => $arrNovel['n_status'],
'strNovelDescription' => $arrNovel['og_description'], 'strNovelDescription' => $arrNovel['n_description'],
]); ]);
$strTitleTemplate = $Request->DomainModel->getFomartSubject('NOVEL@GETNOVELINFO@TITLE',$intForgeId); $strTitleTemplate = $Request->DomainModel->getFomartSubject('NOVEL@GETNOVELINFO@TITLE',$intForgeId);
@@ -457,7 +457,7 @@ class Novel extends BaseController
// js使用到 // js使用到
$arrNovelJs = $arrNovel; $arrNovelJs = $arrNovel;
unset($arrNovelJs['n_related_novel'], $arrNovelJs['n_forge_novel'], $arrNovelJs['og_description']); unset($arrNovelJs['n_related_novel'], $arrNovelJs['n_forge_novel'], $arrNovelJs['n_description']);
View::assign([ View::assign([
'arrRelateveNovel' => $arrRelateveNovel, 'arrRelateveNovel' => $arrRelateveNovel,
@@ -498,8 +498,8 @@ class Novel extends BaseController
$arrNovel = $NovelModel->getNovelByNId($intNId); $arrNovel = $NovelModel->getNovelByNId($intNId);
// 分类拼音 // 分类拼音
$arrNovel['category_pinyin'] = CategoryModel::getPinYinByZh($arrNovel['og_novel_category']); $arrNovel['n_category_pinyin'] = CategoryModel::getPinYin($arrNovel['n_category']);
$arrNovel['category_sex'] = $arrNovel['category_sex'] ?? 'man'; $arrNovel['n_category_sex_en'] = $arrNovel['n_category_sex_en'] ?? 'man';
// 最后章节 // 最后章节
$ChapterModel = ChapterModel::getInstance(); $ChapterModel = ChapterModel::getInstance();
@@ -515,7 +515,7 @@ class Novel extends BaseController
$strFocus = ''; $strFocus = '';
// 要点 // 要点
if ($arrLatestChapter) { if ($arrLatestChapter) {
$strFocus = strip_tags($arrLatestChapter['content']); $strFocus = strip_tags($arrLatestChapter['c_content']);
$intCount = mb_strlen($strFocus); $intCount = mb_strlen($strFocus);
if ($intCount > 300) { if ($intCount > 300) {
$intPos = mt_rand(0, $intCount - 300); $intPos = mt_rand(0, $intCount - 300);
@@ -543,12 +543,12 @@ class Novel extends BaseController
// 更新值 // 更新值
ConverterMovel::setVal([ ConverterMovel::setVal([
'intPage' => 1, 'intPage' => 1,
'strNovelName' => $arrNovel['og_novel_book_name'], 'strNovelName' => $arrNovel['n_name'],
'strNovelAuthor' => $arrNovel['og_novel_author'], 'strNovelAuthor' => $arrNovel['n_author'],
'strNovelCategoryName' => $arrNovel['og_novel_category'], 'strNovelCategoryName' => $arrNovel['n_category'],
'strNovelSex' => $arrNovel['category_sex'] == 'man' ? '男生' : '女生', 'strNovelSex' => $arrNovel['n_category_sex_en'] == 'man' ? '男生' : '女生',
'strNovelStatus' => $arrNovel['og_novel_status'], 'strNovelStatus' => $arrNovel['n_status'],
'strNovelDescription' => $arrNovel['og_description'], 'strNovelDescription' => $arrNovel['n_description'],
]); ]);
$strTitleTemplate = $Request->DomainModel->getFomartSubject(getFomartSubjectKey(__METHOD__) . '@TITLE',$intNId); $strTitleTemplate = $Request->DomainModel->getFomartSubject(getFomartSubjectKey(__METHOD__) . '@TITLE',$intNId);
@@ -595,8 +595,8 @@ class Novel extends BaseController
$NovelModel = NovelModel::getInstance(); $NovelModel = NovelModel::getInstance();
$arrNovel = $NovelModel->getNovelByNId($intNId); $arrNovel = $NovelModel->getNovelByNId($intNId);
$arrNovel['category_pinyin'] = $arrNovel['category_pinyin'] ?? 'all'; $arrNovel['n_category_pinyin'] = $arrNovel['n_category_pinyin'] ?? 'all';
$arrNovel['category_sex'] = $arrNovel['category_sex'] ?? 'man'; $arrNovel['n_category_sex_en'] = $arrNovel['n_category_sex_en'] ?? 'man';
// 最新章节 // 最新章节
$ChapterModel = ChapterModel::getInstance(); $ChapterModel = ChapterModel::getInstance();
@@ -611,9 +611,11 @@ class Novel extends BaseController
$arrNextChapter = $ChapterModel->getNextChapter($arrChapter['n_id'], $arrChapter['c_sort_num'], $arrChapter['c_page']); $arrNextChapter = $ChapterModel->getNextChapter($arrChapter['n_id'], $arrChapter['c_sort_num'], $arrChapter['c_page']);
// 要点-先从章节随机截取后面如果用上ai看看使用ai 提炼 精简内容 // 要点-先从章节随机截取后面如果用上ai看看使用ai 提炼 精简内容
$strChapterDescription = strip_tags($arrChapter['content']); $strChapterDescription = strip_tags($arrChapter['c_content']);
$intCount = mb_strlen($strChapterDescription); $intCount = mb_strlen($strChapterDescription);
$strChapterDescription = ($intCount > 50) ? mb_substr($strChapterDescription, 0, 50) : $strChapterDescription; $strChapterDescription = ($intCount > 50) ? mb_substr($strChapterDescription, 0, 50) : $strChapterDescription;
$arrChapter['c_content'] = base64_encode($arrChapter['c_content']);
} }
$arrCategoryAll = CategoryModel::$arrCategoryAll; $arrCategoryAll = CategoryModel::$arrCategoryAll;
@@ -621,13 +623,13 @@ class Novel extends BaseController
// 更新值 // 更新值
ConverterMovel::setVal([ ConverterMovel::setVal([
'intPage' => 1, 'intPage' => 1,
'strNovelName' => $arrNovel['og_novel_book_name'], 'strNovelName' => $arrNovel['n_name'],
'strNovelAuthor' => $arrNovel['og_novel_author'], 'strNovelAuthor' => $arrNovel['n_author'],
'strNovelCategoryName' => $arrNovel['og_novel_category'], 'strNovelCategoryName' => $arrNovel['n_category'],
'strNovelStatus' => $arrNovel['og_novel_status'], 'strNovelStatus' => $arrNovel['n_status'],
'strNovelDescription' => $arrNovel['og_description'], 'strNovelDescription' => $arrNovel['n_description'],
'strChapterDescription' => $strChapterDescription, 'strChapterDescription' => $strChapterDescription,
'strNovelChapterName' => $arrChapter['name'] ?? '', 'strNovelChapterName' => $arrChapter['c_name'] ?? '',
'strNovelChapterSort' => $arrChapter['c_sort_num'] ?? '', 'strNovelChapterSort' => $arrChapter['c_sort_num'] ?? '',
]); ]);
@@ -640,6 +642,7 @@ class Novel extends BaseController
$strKeywords = ConverterMovel::convert($strKeywordsTemplate); $strKeywords = ConverterMovel::convert($strKeywordsTemplate);
$strDescription = ConverterMovel::convert($strDescriptionTemplate); $strDescription = ConverterMovel::convert($strDescriptionTemplate);
View::assign([ View::assign([
'arrNovel' => $arrNovel, 'arrNovel' => $arrNovel,
'arrCategoryAll' => $arrCategoryAll, 'arrCategoryAll' => $arrCategoryAll,
@@ -679,8 +682,8 @@ class Novel extends BaseController
$intNId = $intNovelId; $intNId = $intNovelId;
$arrNovel = $NovelModel->getNovelByNId($intNId); $arrNovel = $NovelModel->getNovelByNId($intNId);
$arrNovel['category_pinyin'] = $arrNovel['category_pinyin'] ?? 'all'; $arrNovel['n_category_pinyin'] = $arrNovel['n_category_pinyin'] ?? 'all';
$arrNovel['category_sex'] = $arrNovel['category_sex'] ?? 'man'; $arrNovel['n_category_sex_en'] = $arrNovel['n_category_sex_en'] ?? 'man';
// 章节 // 章节
$ChapterModel = ChapterModel::getInstance(); $ChapterModel = ChapterModel::getInstance();
@@ -697,11 +700,11 @@ class Novel extends BaseController
$arrNextChapter = $ChapterModel->getNextChapter($arrChapter['n_id'], $arrChapter['c_sort_num'], $arrChapter['c_page']); $arrNextChapter = $ChapterModel->getNextChapter($arrChapter['n_id'], $arrChapter['c_sort_num'], $arrChapter['c_page']);
// 要点-先从章节随机截取后面如果用上ai看看使用ai 提炼 精简内容 // 要点-先从章节随机截取后面如果用上ai看看使用ai 提炼 精简内容
$strChapterDescription = strip_tags($arrChapter['content']); $strChapterDescription = strip_tags($arrChapter['c_content']);
$intCount = mb_strlen($strChapterDescription); $intCount = mb_strlen($strChapterDescription);
$strChapterDescription = ($intCount > 50) ? mb_substr($strChapterDescription, 0, 50) : $strChapterDescription; $strChapterDescription = ($intCount > 50) ? mb_substr($strChapterDescription, 0, 50) : $strChapterDescription;
$arrChapter['content'] = base64_encode($arrChapter['content']); $arrChapter['c_content'] = base64_encode($arrChapter['c_content']);
} }
$arrCategoryAll = CategoryModel::$arrCategoryAll; $arrCategoryAll = CategoryModel::$arrCategoryAll;
@@ -709,13 +712,13 @@ class Novel extends BaseController
// 更新值 // 更新值
ConverterMovel::setVal([ ConverterMovel::setVal([
'intPage' => 1, 'intPage' => 1,
'strNovelName' => $arrNovel['og_novel_book_name'], 'strNovelName' => $arrNovel['n_name'],
'strNovelAuthor' => $arrNovel['og_novel_author'], 'strNovelAuthor' => $arrNovel['n_author'],
'strNovelCategoryName' => $arrNovel['og_novel_category'], 'strNovelCategoryName' => $arrNovel['n_category'],
'strNovelStatus' => $arrNovel['og_novel_status'], 'strNovelStatus' => $arrNovel['n_status'],
'strNovelDescription' => $arrNovel['og_description'], 'strNovelDescription' => $arrNovel['n_description'],
'strChapterDescription' => $strChapterDescription, 'strChapterDescription' => $strChapterDescription,
'strNovelChapterName' => $arrChapter['name'], 'strNovelChapterName' => $arrChapter['c_name'],
'strNovelChapterSort' => $arrChapter['c_sort_num'], 'strNovelChapterSort' => $arrChapter['c_sort_num'],
]); ]);
@@ -765,8 +768,8 @@ class Novel extends BaseController
$intNId = $intNovelId; $intNId = $intNovelId;
$arrNovel = $NovelModel->getNovelByNId($intNId); $arrNovel = $NovelModel->getNovelByNId($intNId);
$arrNovel['category_pinyin'] = $arrNovel['category_pinyin'] ?? 'all'; $arrNovel['n_category_pinyin'] = $arrNovel['n_category_pinyin'] ?? 'all';
$arrNovel['category_sex'] = $arrNovel['category_sex'] ?? 'man'; $arrNovel['n_category_sex_en'] = $arrNovel['n_category_sex_en'] ?? 'man';
$ChapterModel = ChapterModel::getInstance(); $ChapterModel = ChapterModel::getInstance();
@@ -789,18 +792,18 @@ class Novel extends BaseController
$intButtomNum = 10; $intButtomNum = 10;
} }
$strBaseUrl = sprintf('/pc/xiaoshuo/%s-%s/mulu/%s/{page}', $arrNovel['og_novel_pin_yin'], $intNId, $strOrder); $strBaseUrl = sprintf('/pc/xiaoshuo/%s-%s/mulu/%s/{page}', $arrNovel['n_name_pinyin'], $intNId, $strOrder);
$arrPaginator = CusteomPage02::generate($intPage, $arrPage['total'], $intLimit, $strBaseUrl, $intButtomNum); $arrPaginator = CusteomPage02::generate($intPage, $arrPage['total'], $intLimit, $strBaseUrl, $intButtomNum);
// 更新值 // 更新值
ConverterMovel::setVal([ ConverterMovel::setVal([
'intPage' => $intPage, 'intPage' => $intPage,
'strNovelSex' => $arrNovel['category_sex'] == 'man' ? '男生' : '女生', 'strNovelSex' => $arrNovel['n_category_sex_en'] == 'man' ? '男生' : '女生',
'strNovelName' => $arrNovel['og_novel_book_name'], 'strNovelName' => $arrNovel['n_name'],
'strNovelAuthor' => $arrNovel['og_novel_author'], 'strNovelAuthor' => $arrNovel['n_author'],
'strNovelCategoryName' => $arrNovel['og_novel_category'], 'strNovelCategoryName' => $arrNovel['n_category'],
'strNovelStatus' => $arrNovel['og_novel_status'], 'strNovelStatus' => $arrNovel['n_status'],
'strNovelDescription' => $arrNovel['og_description'], 'strNovelDescription' => $arrNovel['n_description'],
]); ]);
$strTitleTemplate = $Request->DomainModel->getFomartSubject(getFomartSubjectKey(__METHOD__) . '@TITLE',$intNId); $strTitleTemplate = $Request->DomainModel->getFomartSubject(getFomartSubjectKey(__METHOD__) . '@TITLE',$intNId);
@@ -861,10 +864,10 @@ class Novel extends BaseController
$arrFilter = [ $arrFilter = [
'$or' => [ '$or' => [
['og_novel_book_name' => ['$regex' => $strSearchKeywords, '$options' => 'i']], ['n_name' => ['$regex' => $strSearchKeywords, '$options' => 'i']],
['og_novel_author' => ['$regex' => $strSearchKeywords, '$options' => 'i']], ['n_author' => ['$regex' => $strSearchKeywords, '$options' => 'i']],
['og_novel_category' => ['$regex' => $strSearchKeywords, '$options' => 'i']], ['n_category' => ['$regex' => $strSearchKeywords, '$options' => 'i']],
['og_description' => ['$regex' => $strSearchKeywords, '$options' => 'i']], ['n_description' => ['$regex' => $strSearchKeywords, '$options' => 'i']],
] ]
]; ];

View File

@@ -16,15 +16,15 @@
{foreach $arrRecommendNovel as $key=>$Novel } {foreach $arrRecommendNovel as $key=>$Novel }
<dl class="rec-focus-book"> <dl class="rec-focus-book">
<dt class="book-img"> <dt class="book-img">
<a href='{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'> <a href='{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>
<img height="100" width="80" alt="{$Novel.og_novel_book_name ?? ''} - {$Novel.og_novel_category ?? ''}最新章节在线免费阅读" <img height="100" width="80" alt="{$Novel.n_name ?? ''} - {$Novel.n_category ?? ''}最新章节在线免费阅读"
src="{$Novel.n_cover_path ?? ''}" > src="{$Novel.n_cover_path ?? ''}" >
</a> </a>
</dt> </dt>
<dd class="book-info"> <dd class="book-info">
<h2><a href='{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'>{$Novel.og_novel_book_name}</a></h2> <h2><a href='{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>{$Novel.n_name}</a></h2>
<p>作者:{$Novel.og_novel_author}</p> <p>作者:{$Novel.n_author}</p>
<p>{$Novel.og_description}</p> <p>{$Novel.n_description}</p>
</dd> </dd>
</dl> </dl>
{/foreach} {/foreach}

View File

@@ -30,21 +30,21 @@
{foreach $arrRecommendSerializationNovel as $key=>$Novel } {foreach $arrRecommendSerializationNovel as $key=>$Novel }
<div class="item"> <div class="item">
<div class="image"> <div class="image">
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'> <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>
<img style="min-height:120px;" class="lazyload-img" <img style="min-height:120px;" class="lazyload-img"
src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}" src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}"
alt="{$Novel.og_novel_book_name ?? ''} - {$Novel.og_novel_category ?? ''}最新章节在线免费阅读"> alt="{$Novel.n_name ?? ''} - {$Novel.n_category ?? ''}最新章节在线免费阅读">
</a> </a>
</div> </div>
<dl> <dl>
<dt> <dt>
<span>{$Novel.og_novel_author ?? ''}</span> <span>{$Novel.n_author ?? ''}</span>
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'>{$Novel.og_novel_book_name ?? ''}</a> <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>{$Novel.n_name ?? ''}</a>
</dt> </dt>
<dd style="height:90px"> <dd style="height:90px">
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'
style="color: #555"> style="color: #555">
{$Novel.og_description ?? ''} {$Novel.n_description ?? ''}
</a> </a>
</dd> </dd>
</dl> </dl>
@@ -56,9 +56,9 @@
<ul class="txt-list txt-list-row3"> <ul class="txt-list txt-list-row3">
{foreach $arrRecommendEndNovel as $key=>$Novel } {foreach $arrRecommendEndNovel as $key=>$Novel }
<li> <li>
<span class="s1">[{$Novel->og_novel_category ?? ''}</span> <span class="s1">[{$Novel->n_category ?? ''}</span>
<span class="s2"><a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'>{$Novel->og_novel_book_name}</a></span> <span class="s2"><a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>{$Novel->n_name}</a></span>
<span class="s5"><a href='{site:souurl key="$Novel->og_novel_author" p="1"/}'>{$Novel->og_novel_author}</a></span> <span class="s5"><a href='{site:souurl key="$Novel->n_author" p="1"/}'>{$Novel->n_author}</a></span>
</li> </li>
{/foreach} {/foreach}
</ul> </ul>
@@ -74,15 +74,15 @@
{foreach $arrNovels[$category.xsfl_source_id] as $key2 => $Novel} {foreach $arrNovels[$category.xsfl_source_id] as $key2 => $Novel}
{if $key2 == 0} {if $key2 == 0}
<div class="image"> <div class="image">
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'> <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>
<img class="lazyload-img" <img class="lazyload-img"
src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}" src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}"
alt="{$Novel.og_novel_book_name ?? ''} - {$Novel.og_novel_category ?? ''}最新章节在线免费阅读"> alt="{$Novel.n_name ?? ''} - {$Novel.n_category ?? ''}最新章节在线免费阅读">
</a> </a>
</div> </div>
<dl> <dl>
<dt><a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'>{$Novel->og_novel_book_name}</a></dt> <dt><a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>{$Novel->n_name}</a></dt>
<dd><a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' style="color: #555">{$Novel.og_description ?? ''}</a></dd> <dd><a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' style="color: #555">{$Novel.n_description ?? ''}</a></dd>
</dl> </dl>
{/if} {/if}
{/foreach} {/foreach}
@@ -90,7 +90,7 @@
<ul> <ul>
{foreach $arrNovels[$category.xsfl_source_id] as $key2 => $Novel} {foreach $arrNovels[$category.xsfl_source_id] as $key2 => $Novel}
{if $key2 >= 1} {if $key2 >= 1}
<li><a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'>{$Novel->og_novel_book_name}</a>/<a href='{site:souurl key="$Novel->og_novel_author" p="1"/}'>{$Novel->og_novel_author}</a></li> <li><a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>{$Novel->n_name}</a>/<a href='{site:souurl key="$Novel->n_author" p="1"/}'>{$Novel->n_author}</a></li>
{/if} {/if}
{/foreach} {/foreach}
</ul> </ul>
@@ -105,9 +105,9 @@
<ul class="txt-list txt-list-row3"> <ul class="txt-list txt-list-row3">
{foreach $arrNewsNovel as $key=>$Novel } {foreach $arrNewsNovel as $key=>$Novel }
<li> <li>
<span class="s1">[{$Novel->og_novel_category ?? ''}]</span> <span class="s1">[{$Novel->n_category ?? ''}]</span>
<span class="s2"><a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'>{$Novel->og_novel_book_name}</a></span> <span class="s2"><a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>{$Novel->n_name}</a></span>
<span class="s5"><a href='{site:souurl key="$Novel->og_novel_author" p="1"/}'>{$Novel->og_novel_author}</a></span> <span class="s5"><a href='{site:souurl key="$Novel->n_author" p="1"/}'>{$Novel->n_author}</a></span>
</li> </li>
{/foreach} {/foreach}
</ul> </ul>
@@ -117,10 +117,10 @@
<ul class="txt-list txt-list-row5"> <ul class="txt-list txt-list-row5">
{foreach $arrNewsUpdateNovel as $key=>$Novel } {foreach $arrNewsUpdateNovel as $key=>$Novel }
<li> <li>
<span class="s1">[{$Novel->og_novel_category ?? ''}]</span> <span class="s1">[{$Novel->n_category ?? ''}]</span>
<span class="s2"><a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'>{$Novel->og_novel_book_name}</a></span> <span class="s2"><a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>{$Novel->n_name}</a></span>
<span class="s5"><a href='{site:souurl key="$Novel->og_novel_author" p="1"/}'>{$Novel->og_novel_author}</a></span> <span class="s5"><a href='{site:souurl key="$Novel->n_author" p="1"/}'>{$Novel->n_author}</a></span>
<span class="s4">{$Novel.og_novel_author ?? ''}</span> <span class="s4">{$Novel.n_author ?? ''}</span>
<span class="s5">{:date('m-d')}</span> <span class="s5">{:date('m-d')}</span>
</li> </li>
{/foreach} {/foreach}

View File

@@ -67,8 +67,8 @@
<div class="wrap-box"> <div class="wrap-box">
<h3 class="wrap-title"><span>最新标签</span></h3> <h3 class="wrap-title"><span>最新标签</span></h3>
<div class="rec-focus" style="font-size:12px;"> <div class="rec-focus" style="font-size:12px;">
{foreach $arrNewsNovel as $key=>$Novel } {foreach $arrRecommendNovel as $key=>$vo }
<a href='{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'>{$Novel.og_novel_book_name}</a>&nbsp;&nbsp; <a href="/">{$vo.n_name}</a>&nbsp;&nbsp;
{/foreach} {/foreach}
<a href="/sitemap_index.xml">XML地图</a>&nbsp;&nbsp; <a href="/sitemap_index.xml">XML地图</a>&nbsp;&nbsp;
</div> </div>

View File

@@ -67,7 +67,7 @@
<h2 class="layout-tit">最新标签</h2> <h2 class="layout-tit">最新标签</h2>
<ul class="txt-list txt-list-row5 tag_news"> <ul class="txt-list txt-list-row5 tag_news">
{foreach $arrNewsNovel as $key=>$Novel } {foreach $arrNewsNovel as $key=>$Novel }
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'>{$Novel.og_novel_book_name}</a>&nbsp;&nbsp; <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>{$Novel.n_name}</a>&nbsp;&nbsp;
{/foreach} {/foreach}
<a href="/sitemap_index.xml">XML地图</a> <a href="/sitemap_index.xml">XML地图</a>
</ul> </ul>

View File

@@ -4,26 +4,26 @@
{block name="description"}{$strDescription??''}{/block} {block name="description"}{$strDescription??''}{/block}
{block name="head"} {block name="head"}
<!-- 社交媒体标签 --> <!-- 社交媒体标签 -->
<meta property="og:title" content="{$arrNovel['og_novel_book_name']??'未知小说'}章节目录 - {$DomainModel->d_name} 第{$intPage}页 " /> <meta property="og:title" content="{$arrNovel['n_name']??'未知小说'}章节目录 - {$DomainModel->d_name} 第{$intPage}页 " />
<meta property="og:description" content="{$strDescription??'暂无简介'}" /> <meta property="og:description" content="{$strDescription??'暂无简介'}" />
<meta property="og:url" <meta property="og:url"
content='https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' /> content='https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}' />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:image" content="{$arrNovel.n_cover_path ?? ''}" /> <meta property="og:image" content="{$arrNovel.n_cover_path ?? ''}" />
<meta property="og:site_name" content="{$DomainModel->d_name}" /> <meta property="og:site_name" content="{$DomainModel->d_name}" />
<meta property="og:novel:category" content="{$arrNovel.og_novel_category ?? ''}"> <meta property="og:novel:category" content="{$arrNovel.n_category ?? ''}">
<meta property="og:novel:author" content="{$arrNovel.og_novel_author ?? ''}"> <meta property="og:novel:author" content="{$arrNovel.n_author ?? ''}">
<meta property="og:novel:book_name" content="{$arrNovel.og_novel_book_name ?? ''}"> <meta property="og:novel:book_name" content="{$arrNovel.n_name ?? ''}">
<meta property="og:novel:read_url" <meta property="og:novel:read_url"
content='https://{$DomainModel->d_domain}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$intFirstChapterSort"/}'> content='https://{$DomainModel->d_domain}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$intFirstChapterSort"/}'>
<meta property="og:novel:status" content="{$arrNovel.og_novel_status ?? ''}"> <meta property="og:novel:status" content="{$arrNovel.n_status ?? ''}">
<meta property="og:novel:update_time" content="{$arrNovel.og_novel_update_time ?? ''}"> <meta property="og:novel:update_time" content="{$arrNovel.n_update_time ?? ''}">
<meta property="og:novel:latest_chapter_name" content="{$arrLatestChapter.name ?? ''}"> <meta property="og:novel:latest_chapter_name" content="{$arrLatestChapter.c_name ?? ''}">
<meta property="og:novel:latest_chapter_url" <meta property="og:novel:latest_chapter_url"
content='https://{$DomainModel->d_domain}{site:lcpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}'> content='https://{$DomainModel->d_domain}{site:lcpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'>
<!-- 可选:支持 Twitter Card --> <!-- 可选:支持 Twitter Card -->
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="{$arrNovel['og_novel_book_name'] ?? '未知小说'}" /> <meta name="twitter:title" content="{$arrNovel['n_name'] ?? '未知小说'}" />
<meta name="twitter:description" content="{$strDescription ?? '暂无简介'}" /> <meta name="twitter:description" content="{$strDescription ?? '暂无简介'}" />
<meta name="twitter:image" content="{$arrNovel.n_cover_path ?? ''}" /> <meta name="twitter:image" content="{$arrNovel.n_cover_path ?? ''}" />
@@ -33,23 +33,23 @@
{ {
"@context": "https://schema.org", "@context": "https://schema.org",
"@type": "Book", "@type": "Book",
"name": "{$arrNovel['og_novel_book_name'] ?? '未知小说'}", "name": "{$arrNovel['n_name'] ?? '未知小说'}",
"author": { "author": {
"@type": "Person", "@type": "Person",
"name": "{$arrNovel['og_novel_author'] ??'佚名'}" "name": "{$arrNovel['n_author'] ??'佚名'}"
}, },
"publisher": { "publisher": {
"@type": "Organization", "@type": "Organization",
"name": "{$DomainModel->d_name}", "name": "{$DomainModel->d_name}",
"url": "https://{$DomainModel->d_domain}" "url": "https://{$DomainModel->d_domain}"
}, },
"url": 'https://{$DomainModel->d_domain}{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" order="zheng" page="$intPage"/}', "url": 'https://{$DomainModel->d_domain}{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" order="zheng" page="$intPage"/}',
"inLanguage": "zh-CN", "inLanguage": "zh-CN",
"genre": "{$arrNovel['og_novel_category'] ?? '未知分类'}", "genre": "{$arrNovel['n_category'] ?? '未知分类'}",
"hasPart": { "hasPart": {
"@type": "WebPage", "@type": "WebPage",
"name": "{$arrNovel['og_novel_book_name'] ?? '未知小说'}章节目录 第{$intPage}页", "name": "{$arrNovel['n_name'] ?? '未知小说'}章节目录 第{$intPage}页",
"url": 'https://{$DomainModel->d_domain}{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" order="zheng" page="$intPage"/}' "url": 'https://{$DomainModel->d_domain}{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" order="zheng" page="$intPage"/}'
} }
} }
</script> </script>
@@ -72,15 +72,15 @@
<meta itemprop="position" content="1" /> <meta itemprop="position" content="1" />
</li> </li>
<li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<?php $arrNovel['category_pinyin'] ?? $arrNovel['category_pinyin'] = 'all'?> <?php $arrNovel['n_category_pinyin'] ?? $arrNovel['n_category_pinyin'] = 'all'?>
<a href='{site:nflurl gender="all" category="$arrNovel[category_pinyin]" status="all" page="1"/}' itemprop="item"> <a href='{site:nflurl gender="all" category="$arrNovel[n_category_pinyin]" status="all" page="1"/}' itemprop="item">
<span itemprop="name">{$arrNovel.og_novel_category}</span> <span itemprop="name">{$arrNovel.n_category}</span>
</a> </a>
<meta itemprop="position" content="2" /> <meta itemprop="position" content="2" />
</li> </li>
<li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a href='{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' itemprop="item"> <a href='{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}' itemprop="item">
<span itemprop="name">{$arrNovel['og_novel_book_name']}</span> <span itemprop="name">{$arrNovel['n_name']}</span>
</a> </a>
<meta itemprop="position" content="3" /> <meta itemprop="position" content="3" />
</li> </li>
@@ -91,7 +91,7 @@
<div class="mod mod-attentions"> <div class="mod mod-attentions">
{$arrGRM[0]|raw} {$arrGRM[0]|raw}
<div class="mod-head"> <div class="mod-head">
<h1>{$arrNovel['og_novel_book_name']}章节目录 - {$arrNovel['og_novel_author']} - {$DomainModel->d_name} 第{$intPage}页</h1> <h1>{$arrNovel['n_name']}章节目录 - {$arrNovel['n_author']} - {$DomainModel->d_name} 第{$intPage}页</h1>
</div> </div>
@@ -103,8 +103,8 @@
{volist name="arrPage.data" id="Chapter" key="key"} {volist name="arrPage.data" id="Chapter" key="key"}
<li> <li>
{$arrGRM[$key]|raw} {$arrGRM[$key]|raw}
<a href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$Chapter[c_sort_num]" c_page="0"/}' <a href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$Chapter[c_sort_num]" c_page="0"/}'
title="{$arrNovel['og_novel_book_name']} {$Chapter.name}">{$Chapter.name}</a> title="{$arrNovel['n_name']} {$Chapter.c_name}">{$Chapter.c_name}</a>
</li> </li>
{/volist} {/volist}
</ul> </ul>

View File

@@ -20,26 +20,26 @@
<script src="/public/js/yueduqsbs.js"></script> <script src="/public/js/yueduqsbs.js"></script>
<!-- 社交媒体标签 --> <!-- 社交媒体标签 -->
<meta property="og:title" content="{$arrNovel['og_novel_book_name']??'未知小说'} {$arrChapter.name} - {$DomainModel->d_name}" /> <meta property="og:title" content="{$arrNovel['n_name']??'未知小说'} {$arrChapter.c_name} - {$DomainModel->d_name}" />
<meta property="og:description" content="{$strDescription??'暂无简介'}" /> <meta property="og:description" content="{$strDescription??'暂无简介'}" />
<meta property="og:url" <meta property="og:url"
content='https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' /> content='https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}' />
<meta property="og:type" content="book" /> <meta property="og:type" content="book" />
<meta property="og:image" content="{$arrNovel.n_cover_path ?? ''}" /> <meta property="og:image" content="{$arrNovel.n_cover_path ?? ''}" />
<meta property="og:site_name" content="{$DomainModel->d_name}" /> <meta property="og:site_name" content="{$DomainModel->d_name}" />
<meta property="og:novel:category" content="{$arrNovel.og_novel_category ?? ''}"> <meta property="og:novel:category" content="{$arrNovel.n_category ?? ''}">
<meta property="og:novel:author" content="{$arrNovel.og_novel_author ?? ''}"> <meta property="og:novel:author" content="{$arrNovel.n_author ?? ''}">
<meta property="og:novel:book_name" content="{$arrNovel.og_novel_book_name ?? ''}"> <meta property="og:novel:book_name" content="{$arrNovel.n_name ?? ''}">
<meta property="og:novel:read_url" <meta property="og:novel:read_url"
content='https://{$DomainModel->d_domain}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$$arrChapter[c_sort_num]"/}'> content='https://{$DomainModel->d_domain}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$$arrChapter[c_sort_num]"/}'>
<meta property="og:novel:status" content="{$arrNovel.og_novel_status ?? ''}"> <meta property="og:novel:status" content="{$arrNovel.n_status ?? ''}">
<meta property="og:novel:update_time" content="{$arrNovel.og_novel_update_time ?? ''}"> <meta property="og:novel:update_time" content="{$arrNovel.n_update_time ?? ''}">
<meta property="og:novel:latest_chapter_name" content="{$arrChapter.name}"> <meta property="og:novel:latest_chapter_name" content="{$arrChapter.c_name}">
<meta property="og:novel:latest_chapter_url" <meta property="og:novel:latest_chapter_url"
content='https://{$DomainModel->d_domain}{site:lcpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}'> content='https://{$DomainModel->d_domain}{site:lcpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'>
<!-- 可选:支持 Twitter Card --> <!-- 可选:支持 Twitter Card -->
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="{$arrNovel['og_novel_book_name']??'未知小说'} {$arrChapter.name} - {$DomainModel->d_name}" /> <meta name="twitter:title" content="{$arrNovel['n_name']??'未知小说'} {$arrChapter.c_name} - {$DomainModel->d_name}" />
<meta name="twitter:description" content="{$strDescription ?? '暂无简介'}" /> <meta name="twitter:description" content="{$strDescription ?? '暂无简介'}" />
<meta name="twitter:image" content="{$arrNovel.n_cover_path ?? ''}" /> <meta name="twitter:image" content="{$arrNovel.n_cover_path ?? ''}" />
<!-- 结构化数据 --> <!-- 结构化数据 -->
@@ -47,10 +47,10 @@
{ {
"@context": "https://schema.org", "@context": "https://schema.org",
"@type": "Book", "@type": "Book",
"name": "{$arrNovel['og_novel_book_name'] ?? '未知小说'}", "name": "{$arrNovel['n_name'] ?? '未知小说'}",
"author": { "author": {
"@type": "Person", "@type": "Person",
"name": "{$arrNovel['og_novel_author'] ??'佚名'}" "name": "{$arrNovel['n_author'] ??'佚名'}"
}, },
"publisher": { "publisher": {
"@type": "Organization", "@type": "Organization",
@@ -58,14 +58,14 @@
"url": "https://{$DomainModel->d_domain}" "url": "https://{$DomainModel->d_domain}"
}, },
"image": "{$arrNovel.n_cover_path ?? ''}", "image": "{$arrNovel.n_cover_path ?? ''}",
"url":'https://{$DomainModel->d_domain}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}', "url":'https://{$DomainModel->d_domain}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}',
"inLanguage": "zh-CN", "inLanguage": "zh-CN",
"genre": "{$arrNovel.og_novel_category ??''}", "genre": "{$arrNovel.n_category ??''}",
"datePublished": "{$arrNovel['og_novel_update_time'] ?? time()}", "datePublished": "{$arrNovel['n_update_time'] ?? time()}",
"hasPart": { "hasPart": {
"@type": "CreativeWork", "@type": "CreativeWork",
"name": "{$arrChapter.name ?? ''}", "name": "{$arrChapter.c_name ?? ''}",
"url":'https://{$DomainModel->d_domain}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}', "url":'https://{$DomainModel->d_domain}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}',
"description": "{$strDescription}" "description": "{$strDescription}"
} }
} }
@@ -104,12 +104,12 @@
<a href="javascript:" class="btn-normal red" data-size="14" role="button">上一章</a> <a href="javascript:" class="btn-normal red" data-size="14" role="button">上一章</a>
{else} {else}
{$arrGRM[4]|raw} {$arrGRM[4]|raw}
<a href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$arrPreChapter[c_sort_num]" c_page="0"/}' <a href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$arrPreChapter[c_sort_num]" c_page="0"/}'
class="btn-normal red" data-size="14" role="button">上一章</a> class="btn-normal red" data-size="14" role="button">上一章</a>
{/if} {/if}
{if $arrNextChapter && $arrNextChapter.c_sort_num} {if $arrNextChapter && $arrNextChapter.c_sort_num}
<a href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$arrNextChapter[c_sort_num]" c_page="0"/}' <a href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$arrNextChapter[c_sort_num]" c_page="0"/}'
class="btn-normal red" data-size="14" role="button">下一章</a> class="btn-normal red" data-size="14" role="button">下一章</a>
{/if} {/if}
<a href="#" class="btn-blank blue" style="display:none">已经是最后一章了 »</a> <a href="#" class="btn-blank blue" style="display:none">已经是最后一章了 »</a>
@@ -117,7 +117,7 @@
<article id="chapterContent" class="read-article" style="font-size: 1.125rem"> <article id="chapterContent" class="read-article" style="font-size: 1.125rem">
<section class="read-section jsChapterWrapper" data-chapter-id="4b2d5aab58d71"> <section class="read-section jsChapterWrapper" data-chapter-id="4b2d5aab58d71">
<script>document.writeln(qsbs.bb('{$arrChapter.content}'));</script> <script>document.writeln(qsbs.bb('{$arrChapter.c_content}'));</script>
</section> </section>
</article> </article>
{$arrGRM[5]|raw} {$arrGRM[5]|raw}
@@ -126,12 +126,12 @@
<!-- <a id="j_chapterPrev" href="javascript:void(0);">上一章</a> --> <!-- <a id="j_chapterPrev" href="javascript:void(0);">上一章</a> -->
<a href="javascript:" class="btn-normal red" data-size="14" role="button">上一章</a> <a href="javascript:" class="btn-normal red" data-size="14" role="button">上一章</a>
{else} {else}
<a href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$arrPreChapter[c_sort_num]" c_page="0"/}' <a href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$arrPreChapter[c_sort_num]" c_page="0"/}'
class="btn-normal red" data-size="14" role="button">上一章</a> class="btn-normal red" data-size="14" role="button">上一章</a>
{/if} {/if}
{if $arrNextChapter && $arrNextChapter.c_sort_num} {if $arrNextChapter && $arrNextChapter.c_sort_num}
<a href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$arrNextChapter[c_sort_num]" c_page="0"/}' <a href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$arrNextChapter[c_sort_num]" c_page="0"/}'
class="btn-normal red" data-size="14" role="button">下一章</a> class="btn-normal red" data-size="14" role="button">下一章</a>
{/if} {/if}
@@ -150,25 +150,25 @@
<meta itemprop="position" content="1" /> <meta itemprop="position" content="1" />
</li> </li>
<li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<?php $arrNovel['category_pinyin'] ?? $arrNovel['category_pinyin'] = 'all'?> <?php $arrNovel['n_category_pinyin'] ?? $arrNovel['n_category_pinyin'] = 'all'?>
<a href='{site:nflurl gender="all" category="$arrNovel[category_pinyin]" status="all" page="1"/}' itemprop="item"> <a href='{site:nflurl gender="all" category="$arrNovel[n_category_pinyin]" status="all" page="1"/}' itemprop="item">
<span itemprop="name">{$arrNovel.og_novel_category}</span> <span itemprop="name">{$arrNovel.n_category}</span>
</a> </a>
<meta itemprop="position" content="2" /> <meta itemprop="position" content="2" />
</li> </li>
<li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a href='{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' itemprop="item"> <a href='{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}' itemprop="item">
<span itemprop="name">{$arrNovel.og_novel_book_name}</span> <span itemprop="name">{$arrNovel.n_name}</span>
</a> </a>
<meta itemprop="position" content="2" /> <meta itemprop="position" content="2" />
</li> </li>
</ol> </ol>
</nav> </nav>
<h1 id="chapterTitle" class="read-book-name"> <h1 id="chapterTitle" class="read-book-name">
<a href='{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}'> <a href='{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'>
{$arrNovel.og_novel_book_name} {$arrNovel.n_name}
</a> </a>
<a href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}'>{$arrChapter.name}</a> <a href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}'>{$arrChapter.c_name}</a>
</h1> </h1>
</div> </div>
@@ -202,7 +202,7 @@
<i class="iconfont icon-lixianxiazai"></i> <i class="iconfont icon-lixianxiazai"></i>
离线章节 离线章节
</a> --> </a> -->
<a href='{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' class="read-opt-a"> <a href='{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}' class="read-opt-a">
<i class="iconfont icon-SU"></i> <i class="iconfont icon-SU"></i>
书籍详情 书籍详情
</a> </a>
@@ -299,7 +299,7 @@
<footer class="read-opt-footer"> <footer class="read-opt-footer">
<div class="btn-group"> <div class="btn-group">
<!-- id="readBtnChapter" --> <!-- id="readBtnChapter" -->
<a href='{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" order="zheng" page="1"/}' class="btn-group-cell" <a href='{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" order="zheng" page="1"/}' class="btn-group-cell"
data-rel="asideChapter" role="button" aria-haspopup="true"> data-rel="asideChapter" role="button" aria-haspopup="true">
<i class="iconfont icon-mulu"></i> <i class="iconfont icon-mulu"></i>
<h4 class="read-opt-footer-h">目录</h4> <h4 class="read-opt-footer-h">目录</h4>
@@ -339,28 +339,28 @@
const strNovelId = `{$arrNovel.n_id}`; const strNovelId = `{$arrNovel.n_id}`;
const arrNovel = { const arrNovel = {
'n_id' : `{$arrNovel['n_id']}`, 'n_id' : `{$arrNovel['n_id']}`,
'og_novel_pin_yin' : `{$arrNovel['og_novel_pin_yin']}`, 'n_name_pinyin' : `{$arrNovel['n_name_pinyin']}`,
'n_cover_path' : `{$arrNovel['n_cover_path']}`, 'n_cover_path' : `{$arrNovel['n_cover_path']}`,
'og_novel_book_name' : `{$arrNovel['og_novel_book_name']}`, 'n_name' : `{$arrNovel['n_name']}`,
'og_novel_author' : `{$arrNovel['og_novel_author']}`, 'n_author' : `{$arrNovel['n_author']}`,
'og_novel_status' : `{$arrNovel['og_novel_status']}`, 'n_status' : `{$arrNovel['n_status']}`,
'c_sort_num' : `{$arrChapter.c_sort_num}`, 'c_sort_num' : `{$arrChapter.c_sort_num}`,
'c_name' : `{$arrChapter.name}`, 'c_name' : `{$arrChapter.c_name}`,
}; };
</script> </script>
<script type="text/javascript"> <script type="text/javascript">
var book = {}; var book = {};
book.Info = { book.Info = {
"Id": `{$arrNovel['n_id']}`, "Id": `{$arrNovel['n_id']}`,
"Name": `{$arrNovel['og_novel_book_name']}`, "Name": `{$arrNovel['n_name']}`,
"authorName": `{$arrNovel['og_novel_author']}` "authorName": `{$arrNovel['n_author']}`
}; };
book.chapter = { book.chapter = {
//页面进入加载的章节id //页面进入加载的章节id
id: '{$arrPreChapter.c_sort_num ?? 1}', id: '{$arrPreChapter.c_sort_num ?? 1}',
//章节源id //章节源id
source_id: '{$arrPreChapter.c_sort_num ?? 1}', source_id: '{$arrPreChapter.c_sort_num ?? 1}',
title: '{$arrPreChapter.name ?? 1}', title: '{$arrPreChapter.c_name ?? 1}',
content: '', content: '',
//章节vip标识 //章节vip标识
vipStatus: 0, vipStatus: 0,
@@ -369,8 +369,8 @@
//下一章id //下一章id
nextId: '{$arrNextChapter.c_sort_num ?? 1}' nextId: '{$arrNextChapter.c_sort_num ?? 1}'
}; };
book.chapterUrl = '{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}' ; book.chapterUrl = '{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}' ;
book.url = '{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' book.url = '{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'
book.nextChapterVip = 0; book.nextChapterVip = 0;
book.uid = 0; book.uid = 0;
</script> </script>

View File

@@ -4,26 +4,26 @@
{block name="description"}{$strDescription??''}{/block} {block name="description"}{$strDescription??''}{/block}
{block name="head"} {block name="head"}
<!-- 社交媒体标签 --> <!-- 社交媒体标签 -->
<meta property="og:title" content="{$arrNovel['og_novel_book_name']??'未知小说'}" /> <meta property="og:title" content="{$arrNovel['n_name']??'未知小说'}" />
<meta property="og:description" content="{$strDescription??'暂无简介'}" /> <meta property="og:description" content="{$strDescription??'暂无简介'}" />
<meta property="og:url" <meta property="og:url"
content='https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' /> content='https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}' />
<meta property="og:type" content="book" /> <meta property="og:type" content="book" />
<meta property="og:image" content="{$arrNovel.n_cover_path ?? ''}" /> <meta property="og:image" content="{$arrNovel.n_cover_path ?? ''}" />
<meta property="og:site_name" content="{$DomainModel->d_name}" /> <meta property="og:site_name" content="{$DomainModel->d_name}" />
<meta property="og:novel:category" content="{$arrNovel.og_novel_category ?? ''}"> <meta property="og:novel:category" content="{$arrNovel.n_category ?? ''}">
<meta property="og:novel:author" content="{$arrNovel.og_novel_author ?? ''}"> <meta property="og:novel:author" content="{$arrNovel.n_author ?? ''}">
<meta property="og:novel:book_name" content="{$arrNovel.og_novel_book_name ?? ''}"> <meta property="og:novel:book_name" content="{$arrNovel.n_name ?? ''}">
<meta property="og:novel:read_url" <meta property="og:novel:read_url"
content='https://{$DomainModel->d_domain}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$intFirstChapterSort"/}'> content='https://{$DomainModel->d_domain}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$intFirstChapterSort"/}'>
<meta property="og:novel:status" content="{$arrNovel.og_novel_status ?? ''}"> <meta property="og:novel:status" content="{$arrNovel.n_status ?? ''}">
<meta property="og:novel:update_time" content="{$arrNovel.og_novel_update_time ?? ''}"> <meta property="og:novel:update_time" content="{$arrNovel.n_update_time ?? ''}">
<meta property="og:novel:latest_chapter_name" content="{$arrLatestChapter.name ?? ''}"> <meta property="og:novel:latest_chapter_name" content="{$arrLatestChapter.c_name ?? ''}">
<meta property="og:novel:latest_chapter_url" <meta property="og:novel:latest_chapter_url"
content='https://{$DomainModel->d_domain}{site:lcpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}'> content='https://{$DomainModel->d_domain}{site:lcpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'>
<!-- 可选:支持 Twitter Card --> <!-- 可选:支持 Twitter Card -->
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="{$arrNovel['og_novel_book_name'] ?? '未知小说'}" /> <meta name="twitter:title" content="{$arrNovel['n_name'] ?? '未知小说'}" />
<meta name="twitter:description" content="{$strDescription ?? '暂无简介'}" /> <meta name="twitter:description" content="{$strDescription ?? '暂无简介'}" />
<meta name="twitter:image" content="{$arrNovel.n_cover_path ?? ''}" /> <meta name="twitter:image" content="{$arrNovel.n_cover_path ?? ''}" />
<!-- 结构化数据 --> <!-- 结构化数据 -->
@@ -31,21 +31,21 @@
{ {
"@context": "https://schema.org", "@context": "https://schema.org",
"@type": "Book", "@type": "Book",
"name": "{$arrNovel['og_novel_book_name'] ?? '未知小说'}", "name": "{$arrNovel['n_name'] ?? '未知小说'}",
"description": "{$arrNovel['og_description'] ??'暂无简介'}", "description": "{$arrNovel['n_description'] ??'暂无简介'}",
"author": { "author": {
"@type": "Person", "@type": "Person",
"name": "{$arrNovel['og_novel_author'] ??'佚名'}" "name": "{$arrNovel['n_author'] ??'佚名'}"
}, },
"publisher": { "publisher": {
"@type": "Organization", "@type": "Organization",
"name": "{$DomainModel->d_name}", "name": "{$DomainModel->d_name}",
"url": "https://{$DomainModel->d_domain}" "url": "https://{$DomainModel->d_domain}"
}, },
"datePublished": "{$arrNovel['og_novel_update_time'] ?? time()}", "datePublished": "{$arrNovel['n_update_time'] ?? time()}",
"image": "{$arrNovel.n_cover_path ?? ''}", "image": "{$arrNovel.n_cover_path ?? ''}",
"url": 'https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}', "url": 'https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}',
"genre": "{$arrNovel.og_novel_category ??''}", "genre": "{$arrNovel.n_category ??''}",
"inLanguage": "zh-CN", "inLanguage": "zh-CN",
"bookFormat": "https://{$DomainModel->d_domain}/EBook", "bookFormat": "https://{$DomainModel->d_domain}/EBook",
"aggregateRating": { "aggregateRating": {
@@ -78,20 +78,20 @@
<meta itemprop="position" content="1" /> <meta itemprop="position" content="1" />
</li> </li>
<li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<?php $arrNovel['category_pinyin'] ?? $arrNovel['category_pinyin'] = 'all'?> <?php $arrNovel['n_category_pinyin'] ?? $arrNovel['n_category_pinyin'] = 'all'?>
<a href='{site:nflurl gender="all" category="$arrNovel[category_pinyin]" status="all" page="1"/}' itemprop="item"> <a href='{site:nflurl gender="all" category="$arrNovel[n_category_pinyin]" status="all" page="1"/}' itemprop="item">
<span itemprop="name">{$arrNovel.og_novel_category}</span> <span itemprop="name">{$arrNovel.n_category}</span>
</a> </a>
<meta itemprop="position" content="2" /> <meta itemprop="position" content="2" />
</li> </li>
<li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a href='{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' itemprop="item"> <a href='{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}' itemprop="item">
<span itemprop="name">{$arrNovel['og_novel_book_name']}</span> <span itemprop="name">{$arrNovel['n_name']}</span>
</a> </a>
<meta itemprop="position" content="3" /> <meta itemprop="position" content="3" />
</li> </li>
</ol> </ol>
<h1 class="site-description ">{$arrNovel['og_novel_book_name']}最新章节 - {$arrNovel['og_novel_author']} - {$DomainModel->d_name}</h1> <h1 class="site-description ">{$arrNovel['n_name']}最新章节 - {$arrNovel['n_author']} - {$DomainModel->d_name}</h1>
</nav> </nav>
<!--info--> <!--info-->
@@ -101,15 +101,15 @@
<dl class="base clearfix"> <dl class="base clearfix">
<dt> <dt>
<img src="/static/img/default.jpg" data-src="{$arrNovel.n_cover_path ?? ''}" <img src="/static/img/default.jpg" data-src="{$arrNovel.n_cover_path ?? ''}"
alt="{$arrNovel['og_novel_book_name'] ?? ''}小说封面 - {$arrNovel.og_novel_author}最新章节" class="lazy lazyload-img" /> alt="{$arrNovel['n_name'] ?? ''}小说封面 - {$arrNovel.n_author}最新章节" class="lazy lazyload-img" />
<i class='{eq name="arrNovel.og_novel_status" value="连载中"}serial{else}finish {/eq}'>已完结</i> <i class='{eq name="arrNovel.n_status" value="连载中"}serial{else}finish {/eq}'>已完结</i>
</dt> </dt>
<dd> <dd>
<h2>{$arrNovel['og_novel_book_name']}</h2> <h2>{$arrNovel['n_name']}</h2>
<p class="info"> <p class="info">
<span>分类:{$arrNovel.og_novel_category}</span> <span>分类:{$arrNovel.n_category}</span>
<span>作者:<a href='{site:souurl key="$arrNovel[og_novel_author]" p="1"/}'>{$arrNovel.og_novel_author}</a></span> <span>作者:<a href='{site:souurl key="$arrNovel[n_author]" p="1"/}'>{$arrNovel.n_author}</a></span>
<!-- <span>字数54.20万字</span> --> <!-- <span>字数54.20万字</span> -->
<span>阅读:{$arrNovelClicks.total}</span> <span>阅读:{$arrNovelClicks.total}</span>
</p> </p>
@@ -121,7 +121,7 @@
{if !empty($intFirstChapterSort)} {if !empty($intFirstChapterSort)}
<li> <li>
{$arrGRM[2]|raw} {$arrGRM[2]|raw}
<a class="read-online reading" href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$intFirstChapterSort"/}' <a class="read-online reading" href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$intFirstChapterSort"/}'
>点击阅读</a> >点击阅读</a>
</li> </li>
{/if} {/if}
@@ -134,7 +134,7 @@
{$arrGRM[3]|raw} {$arrGRM[3]|raw}
<div class="content"> <div class="content">
<p> <p>
{$arrNovel.og_description ?? ''} {$arrNovel.n_description ?? ''}
</p> </p>
</div> </div>
</div> </div>
@@ -157,7 +157,7 @@
{volist name="arrNovel.n_forge_novel" id="ForgeNovel" key="key"} {volist name="arrNovel.n_forge_novel" id="ForgeNovel" key="key"}
{$arrGRM[$key+20]|raw} {$arrGRM[$key+20]|raw}
<a <a
href='{site:nnurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" n_fid="$ForgeNovel[n_forge_id]"/}'>{$ForgeNovel.n_forge_title}</a> href='{site:nnurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" n_fid="$ForgeNovel[n_forge_id]"/}'>{$ForgeNovel.n_forge_title}</a>
{/volist} {/volist}
</p> </p>
</div> </div>
@@ -170,23 +170,23 @@
<!-- hot-book --> <!-- hot-book -->
<div class="mod mod-attentions"> <div class="mod mod-attentions">
<div class="mod-head"> <div class="mod-head">
<h3>{$arrNovel.og_novel_book_name}最新章节</h3> <h3>{$arrNovel.n_name}最新章节</h3>
</div> </div>
<div class="attentions"> <div class="attentions">
<ul class="clearfix"> <ul class="clearfix">
{volist name="arrChapter" id="Chapter" key="key"} {volist name="arrChapter" id="Chapter" key="key"}
<li> <li>
{$arrGRM[$key]|raw} {$arrGRM[$key]|raw}
<a href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$Chapter[c_sort_num]" c_page="0"/}' <a href='{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$Chapter[c_sort_num]" c_page="0"/}'
title="{$arrNovel.og_novel_book_name}-{$Chapter.name}">{$Chapter.name}</a> title="{$arrNovel.n_name}-{$Chapter.c_name}">{$Chapter.c_name}</a>
</li> </li>
{/volist} {/volist}
</ul> </ul>
<div class="chapters-more"> <div class="chapters-more">
<a href='{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" order="zheng" page="1"/}' <a href='{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" order="zheng" page="1"/}'
class="reading btn-bookshelf">{$arrNovel.og_novel_book_name}更多章节</a> class="reading btn-bookshelf">{$arrNovel.n_name}更多章节</a>
</div> </div>
</div> </div>
</div> </div>
@@ -200,12 +200,12 @@
{foreach $arrRelateveNovel as $Novel} {foreach $arrRelateveNovel as $Novel}
<li> <li>
{$arrGRM[$key+10]|raw} {$arrGRM[$key+10]|raw}
<a href='{site:nurl n_id="Novel.n_id" n_py="Novel.og_novel_pin_yin"/}'> <a href='{site:nurl n_id="Novel.n_id" n_py="Novel.n_name_pinyin"/}'>
<img class="lazy lazyload-img" data-encrypted="false" src="/static/img/default.jpg" <img class="lazy lazyload-img" data-encrypted="false" src="/static/img/default.jpg"
data-src="{$Novel.n_cover_path ?? ''}" alt="{$Novel.og_novel_book_name ?? ''}" /> data-src="{$Novel.n_cover_path ?? ''}" alt="{$Novel.n_name ?? ''}" />
<span>{$Novel.og_novel_book_name ?? ''}</span> <span>{$Novel.n_name ?? ''}</span>
<em> <em>
<aria>作者:</aria>{$Novel.og_novel_author ?? ''} <aria>作者:</aria>{$Novel.n_author ?? ''}
</em> </em>
</a> </a>
</li> </li>
@@ -220,12 +220,12 @@
const strNovelId = `{$arrNovel.n_id}`; const strNovelId = `{$arrNovel.n_id}`;
const arrNovel = { const arrNovel = {
'n_id' : `{$arrNovel['n_id']}`, 'n_id' : `{$arrNovel['n_id']}`,
'og_novel_pin_yin' : `{$arrNovel['og_novel_pin_yin']}`, 'n_name_pinyin' : `{$arrNovel['n_name_pinyin']}`,
'n_cover_path' : `{$arrNovel['n_cover_path']}`, 'n_cover_path' : `{$arrNovel['n_cover_path']}`,
'og_novel_book_name' : `{$arrNovel['og_novel_book_name']}`, 'n_name' : `{$arrNovel['n_name']}`,
'og_novel_author' : `{$arrNovel['og_novel_author']}`, 'n_author' : `{$arrNovel['n_author']}`,
'og_novel_status' : `{$arrNovel['og_novel_status']}`, 'n_status' : `{$arrNovel['n_status']}`,
'og_novel_update_time' : `{$arrNovel['og_novel_update_time']}`, 'n_update_time' : `{$arrNovel['n_update_time']}`,
'c_sort_num' : 1, 'c_sort_num' : 1,
'c_name' : `第一章`, 'c_name' : `第一章`,
}; };

View File

@@ -22,7 +22,7 @@
"url": "https://{$DomainModel->d_name}{site:souurl key='$strSearchKeywords' p='1'/}", "url": "https://{$DomainModel->d_name}{site:souurl key='$strSearchKeywords' p='1'/}",
"name": "{$DomainModel->d_name} - {$DomainModel->d_name}搜索 第{$intPage}页", "name": "{$DomainModel->d_name} - {$DomainModel->d_name}搜索 第{$intPage}页",
"description": "搜索‘{$strSearchKeywords}’结果第{$intPage}页,提供{$strSearchKeywords}创作的小说免费阅读。", "description": "搜索‘{$strSearchKeywords}’结果第{$intPage}页,提供{$strSearchKeywords}创作的小说免费阅读。",
"datePublished": "{$arrNovel['og_novel_update_time'] ?? time()}", "datePublished": "{$arrNovel['n_update_time'] ?? time()}",
"mainEntity": { "mainEntity": {
"@type": "Book", "@type": "Book",
"name": "{$DomainModel->d_name}", "name": "{$DomainModel->d_name}",

View File

@@ -4,48 +4,48 @@
{block name="description"}{$strDescription??''}{/block} {block name="description"}{$strDescription??''}{/block}
{block name="head"} {block name="head"}
<!-- 社交媒体标签 --> <!-- 社交媒体标签 -->
<meta property="og:title" content="{$arrNovel['og_novel_book_name']??'未知小说'}" /> <meta property="og:title" content="{$arrNovel['n_name']??'未知小说'}" />
<meta property="og:description" content="{$strDescription??'暂无简介'}" /> <meta property="og:description" content="{$strDescription??'暂无简介'}" />
<meta property="og:url" <meta property="og:url"
content='https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' /> content='https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}' />
<meta property="og:type" content="book" /> <meta property="og:type" content="book" />
<meta property="og:image" content="{$arrNovel.n_cover_path ?? ''}" /> <meta property="og:image" content="{$arrNovel.n_cover_path ?? ''}" />
<meta property="og:site_name" content="{$DomainModel->d_name}" /> <meta property="og:site_name" content="{$DomainModel->d_name}" />
<meta property="og:novel:category" content="{$arrNovel.og_novel_category ?? ''}"> <meta property="og:novel:category" content="{$arrNovel.n_category ?? ''}">
<meta property="og:novel:author" content="{$arrNovel.og_novel_author ?? ''}"> <meta property="og:novel:author" content="{$arrNovel.n_author ?? ''}">
<meta property="og:novel:book_name" content="{$arrNovel.og_novel_book_name ?? ''}"> <meta property="og:novel:book_name" content="{$arrNovel.n_name ?? ''}">
<meta property="og:novel:read_url" <meta property="og:novel:read_url"
content="https://{$DomainModel->d_domain}{$strPcPath}/xiaoshuo/{$arrNovel.og_novel_pin_yin}-{$arrNovel.n_id}/zhang-1"> content="https://{$DomainModel->d_domain}{$strPcPath}/xiaoshuo/{$arrNovel.n_name_pinyin}-{$arrNovel.n_id}/zhang-1">
<meta property="og:novel:status" content="{$arrNovel.og_novel_status ?? ''}"> <meta property="og:novel:status" content="{$arrNovel.n_status ?? ''}">
<meta property="og:novel:update_time" content="{$arrNovel.og_novel_update_time ?? ''}"> <meta property="og:novel:update_time" content="{$arrNovel.n_update_time ?? ''}">
<meta property="og:novel:latest_chapter_name" content="{$arrLatestChapter.name ?? ''}"> <meta property="og:novel:latest_chapter_name" content="{$arrLatestChapter.c_name ?? ''}">
<meta property="og:novel:latest_chapter_url" <meta property="og:novel:latest_chapter_url"
content="https://{$DomainModel->d_domain}{$strPcPath}/xiaoshuo/{$arrNovel.og_novel_pin_yin}-{$arrNovel.n_id}/zhang-{$arrLatestChapter.c_sort_num ?? 1}"> content="https://{$DomainModel->d_domain}{$strPcPath}/xiaoshuo/{$arrNovel.n_name_pinyin}-{$arrNovel.n_id}/zhang-{$arrLatestChapter.c_sort_num ?? 1}">
<!-- 可选:支持 Twitter Card --> <!-- 可选:支持 Twitter Card -->
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="{$arrNovel['og_novel_book_name'] ?? '未知小说'}" /> <meta name="twitter:title" content="{$arrNovel['n_name'] ?? '未知小说'}" />
<meta name="twitter:description" content="{$strDescription ?? '暂无简介'}" /> <meta name="twitter:description" content="{$strDescription ?? '暂无简介'}" />
<meta name="twitter:image" content="{$arrNovel.n_cover_path ?? ''}" /> <meta name="twitter:image" content="{$arrNovel.n_cover_path ?? ''}" />
<!-- 结构化数据 --> <!-- 结构化数据 -->
<script type="application/ld+json"> <script type="application/ld+json">
{ {
"@context": 'https://{$DomainModel->d_domain}/{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}', "@context": 'https://{$DomainModel->d_domain}/{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}',
"@type": "book", "@type": "book",
"name": "{$arrNovel['og_novel_book_name'] ?? '未知小说'}", "name": "{$arrNovel['n_name'] ?? '未知小说'}",
"description": "{$arrNovel['og_description'] ??'暂无简介'}", "description": "{$arrNovel['n_description'] ??'暂无简介'}",
"author": { "author": {
"@type": "Person", "@type": "Person",
"name": "{$arrNovel['og_novel_author'] ??'佚名'}" "name": "{$arrNovel['n_author'] ??'佚名'}"
}, },
"publisher": { "publisher": {
"@type": "Organization", "@type": "Organization",
"name": "{$DomainModel->d_name}", "name": "{$DomainModel->d_name}",
"url": "https://{$DomainModel->d_domain}" "url": "https://{$DomainModel->d_domain}"
}, },
"datePublished": "{$arrNovel['og_novel_update_time'] ?? time()}", "datePublished": "{$arrNovel['n_update_time'] ?? time()}",
"image": "{$Novel.n_cover_path ?? ''}", "image": "{$Novel.n_cover_path ?? ''}",
"url": '{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}', "url": '{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}',
"genre": "{$arrNovel.og_novel_category ??''}", "genre": "{$arrNovel.n_category ??''}",
"inLanguage": "zh-CN", "inLanguage": "zh-CN",
"bookFormat": "https://{$DomainModel->d_domain}/EBook", "bookFormat": "https://{$DomainModel->d_domain}/EBook",
"aggregateRating": { "aggregateRating": {
@@ -59,7 +59,7 @@
{/block} {/block}
{block name="head-css"} {block name="head-css"}
<link rel="canonical" <link rel="canonical"
href='{$DomainModel->d_domain}/{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}'> href='{$DomainModel->d_domain}/{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'>
{/block} {/block}
{block name="logo-html"} {block name="logo-html"}
<h2> <h2>
@@ -79,15 +79,15 @@
<meta itemprop="position" content="1" /> <meta itemprop="position" content="1" />
</li> </li>
<li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<?php $arrNovel['category_pinyin'] ?? $arrNovel['category_pinyin'] = 'all'?> <?php $arrNovel['n_category_pinyin'] ?? $arrNovel['n_category_pinyin'] = 'all'?>
<a href="{$strPcPath}/shuku/all/{$arrNovel.category_pinyin}/all/page1" itemprop="item"> <a href="{$strPcPath}/shuku/all/{$arrNovel.n_category_pinyin}/all/page1" itemprop="item">
<span itemprop="name">{$arrNovel.og_novel_category}</span> <span itemprop="name">{$arrNovel.n_category}</span>
</a> </a>
<meta itemprop="position" content="2" /> <meta itemprop="position" content="2" />
</li> </li>
<li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' itemprop="item"> <a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}' itemprop="item">
<span itemprop="name">{$arrNovel['og_novel_book_name']}</span> <span itemprop="name">{$arrNovel['n_name']}</span>
</a> </a>
<meta itemprop="position" content="3" /> <meta itemprop="position" content="3" />
</li> </li>
@@ -97,11 +97,11 @@
<div class="info"> <div class="info">
<div class="info_box"> <div class="info_box">
<div class="info_L"> <div class="info_L">
<a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' <a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'
title="{$arrNovel['og_novel_book_name']}" class="book_cov"> title="{$arrNovel['n_name']}" class="book_cov">
<img src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}" <img src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}"
alt="{$Novel->og_novel_book_name ?? ''}封面" class="lazyload_book_cover lazyload-img"> alt="{$Novel->n_name ?? ''}封面" class="lazyload_book_cover lazyload-img">
<i class="serial">{$arrNovel.og_novel_status ?? ''}</i> <i class="serial">{$arrNovel.n_status ?? ''}</i>
</a> </a>
<div class="btn"> <div class="btn">
<a href="javascript:;" class="sc" onclick="addBookshelfFun()"> <a href="javascript:;" class="sc" onclick="addBookshelfFun()">
@@ -114,19 +114,19 @@
<div class="info_C book_inf"> <div class="info_C book_inf">
<div class="c01"> <div class="c01">
<h3><a <h3><a
href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}'>{$arrNovel['og_novel_book_name']}</a> href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'>{$arrNovel['n_name']}</a>
</h3> </h3>
<!-- <span id="mod_book_star">0分</span> --> <!-- <span id="mod_book_star">0分</span> -->
</div> </div>
<p class="c02"> <p class="c02">
<span class="zz">作者:{$arrNovel.og_novel_author}</span> <span class="zz">作者:{$arrNovel.n_author}</span>
<span>创建日期:{$arrNovel.og_novel_update_time}</span> <span>创建日期:{$arrNovel.n_update_time}</span>
</p> </p>
<div class="c03"> <div class="c03">
<p class="jianjie">简介</p> <p class="jianjie">简介</p>
<div class="c03_box"> <div class="c03_box">
<p class="jj_con" id="book_desc"> <p class="jj_con" id="book_desc">
{$arrNovel.og_description}</p> {$arrNovel.n_description}</p>
<span class="zk_btn" style="">展开<s></s></span> <span class="zk_btn" style="">展开<s></s></span>
<span class="sq_btn" style="display: none;">收起<s></s></span> <span class="sq_btn" style="display: none;">收起<s></s></span>
</div> </div>
@@ -142,8 +142,8 @@
</div> </div>
<div class="c04"> <div class="c04">
{if !empty($arrChapter)} {if !empty($arrChapter)}
<a href="{$strPcPath}/xiaoshuo/{$arrNovel.og_novel_pin_yin}-{$arrNovel.n_id}/zhang-1" class="read">立即阅读</a> <a href="{$strPcPath}/xiaoshuo/{$arrNovel.n_name_pinyin}-{$arrNovel.n_id}/zhang-1" class="read">立即阅读</a>
<a href="{$strPcPath}/xiaoshuo/{$arrNovel.og_novel_pin_yin}-{$arrNovel.n_id}/mulu/zheng" class="mulu">目录</a> <a href="{$strPcPath}/xiaoshuo/{$arrNovel.n_name_pinyin}-{$arrNovel.n_id}/mulu/zheng" class="mulu">目录</a>
{/if} {/if}
</div> </div>
<!-- <div class="c05"> <!-- <div class="c05">
@@ -159,9 +159,9 @@
<div class="inf02"> <div class="inf02">
<h4>小说信息</h4> <h4>小说信息</h4>
<p>类别: <p>类别:
<?php $arrNovel['category_pinyin'] ?? $arrNovel['category_pinyin'] = 'all'?> <?php $arrNovel['n_category_pinyin'] ?? $arrNovel['n_category_pinyin'] = 'all'?>
<a href='{$strPcPath}/shuku/all/{$arrNovel.category_pinyin}/all/page1' title="{$arrNovel.og_novel_category}"> <a href='{$strPcPath}/shuku/all/{$arrNovel.n_category_pinyin}/all/page1' title="{$arrNovel.n_category}">
{$arrNovel.og_novel_category} {$arrNovel.n_category}
</a> </a>
</p> </p>
<!-- <p>总字数54.20万+</p> --> <!-- <p>总字数54.20万+</p> -->
@@ -184,8 +184,8 @@
<div class="zj_con"> <div class="zj_con">
{volist name="arrChapter" id="Chapter" key="key"} {volist name="arrChapter" id="Chapter" key="key"}
<p> <p>
<a href="{$strPcPath}/xiaoshuo/{$arrNovel.og_novel_pin_yin}-{$Chapter.n_id}/zhang-{$Chapter.c_sort_num}" <a href="{$strPcPath}/xiaoshuo/{$arrNovel.n_name_pinyin}-{$Chapter.n_id}/zhang-{$Chapter.c_sort_num}"
class="zj">{$Chapter.name}</a> class="zj">{$Chapter.c_name}</a>
<span class="time">{$Chapter.created_at ?? '1天前'}</span> <span class="time">{$Chapter.created_at ?? '1天前'}</span>
<!-- <span class="time">3天前</span>--> <!-- <span class="time">3天前</span>-->
</p> </p>
@@ -199,7 +199,7 @@
<div class="pl_con"> <div class="pl_con">
{volist name="arrNovel.n_forge_novel" id="ForgeNovel" key="key"} {volist name="arrNovel.n_forge_novel" id="ForgeNovel" key="key"}
<!-- n_forge_id --> <!-- n_forge_id -->
<a href='{$strPcPath}/kan-xiaoshuo/{$arrNovel.og_novel_pin_yin}-{$arrNovel.n_id}-{$ForgeNovel.n_forge_id}' <a href='{$strPcPath}/kan-xiaoshuo/{$arrNovel.n_name_pinyin}-{$arrNovel.n_id}-{$ForgeNovel.n_forge_id}'
class="red">{$ForgeNovel.n_forge_title}</a> class="red">{$ForgeNovel.n_forge_title}</a>
{/volist} {/volist}
@@ -213,23 +213,23 @@
{volist name="arrRelateveNovel" id="Novel" key="key"} {volist name="arrRelateveNovel" id="Novel" key="key"}
<li> <li>
<h3> <h3>
<a href='{$strPcPath}{site:nurl n_id="$Novel[n_id]" n_py="$Novel[og_novel_pin_yin]" /}' <a href='{$strPcPath}{site:nurl n_id="$Novel[n_id]" n_py="$Novel[n_name_pinyin]" /}'
title="{$Novel['og_novel_book_name'] ?? ''}"> title="{$Novel['n_name'] ?? ''}">
{$Novel['og_novel_book_name'] ?? ''} {$Novel['n_name'] ?? ''}
</a> </a>
</h3> </h3>
<div> <div>
<a href='{$strPcPath}{site:nurl n_id="$Novel[n_id]" n_py="$Novel[og_novel_pin_yin]" /}' <a href='{$strPcPath}{site:nurl n_id="$Novel[n_id]" n_py="$Novel[n_name_pinyin]" /}'
title="$Novel['og_novel_book_name'] ?? ''}" class="book_cov"> title="$Novel['n_name'] ?? ''}" class="book_cov">
<img src="/template/kuangyu/home/bai_web/images/default.png" <img src="/template/kuangyu/home/bai_web/images/default.png"
data-src="{$Novel['n_cover_path'] ?? ''}" class="lazyload_book_cover lazyload-img" data-src="{$Novel['n_cover_path'] ?? ''}" class="lazyload_book_cover lazyload-img"
alt="{$Novel['og_novel_book_name'] ?? ''}"> alt="{$Novel['n_name'] ?? ''}">
</a> </a>
<div class="book_inf"> <div class="book_inf">
<span class="aut">{$Novel['og_novel_author'] ?? ''}</span> <span class="aut">{$Novel['n_author'] ?? ''}</span>
<span class="tag"><a href="/">{$Novel['og_novel_category'] ?? ''}</a></span> <span class="tag"><a href="/">{$Novel['n_category'] ?? ''}</a></span>
<p class="int"> <p class="int">
{$Novel['og_description'] ?? ''}</p> {$Novel['n_description'] ?? ''}</p>
</div> </div>
</div> </div>
</li> </li>
@@ -244,11 +244,11 @@
const strNovelId = `{$arrNovel.n_id}`; const strNovelId = `{$arrNovel.n_id}`;
const arrNovel = { const arrNovel = {
'n_id' : `{$arrNovel['n_id']}`, 'n_id' : `{$arrNovel['n_id']}`,
'og_novel_pin_yin' : `{$arrNovel['og_novel_pin_yin']}`, 'n_name_pinyin' : `{$arrNovel['n_name_pinyin']}`,
'n_cover_path' : `{$arrNovel['n_cover_path']}`, 'n_cover_path' : `{$arrNovel['n_cover_path']}`,
'og_novel_book_name' : `{$arrNovel['og_novel_book_name']}`, 'n_name' : `{$arrNovel['n_name']}`,
'og_novel_author' : `{$arrNovel['og_novel_author']}`, 'n_author' : `{$arrNovel['n_author']}`,
'og_novel_status' : `{$arrNovel['og_novel_status']}`, 'n_status' : `{$arrNovel['n_status']}`,
'c_sort_num' : 1, 'c_sort_num' : 1,
'c_name' : `第一章`, 'c_name' : `第一章`,
}; };

View File

@@ -4,26 +4,26 @@
{block name="description"}{$strDescription??''}{/block} {block name="description"}{$strDescription??''}{/block}
{block name="head"} {block name="head"}
<!-- 社交媒体标签 --> <!-- 社交媒体标签 -->
<meta property="og:title" content="{$arrNovel['og_novel_book_name']??'未知小说'}" /> <meta property="og:title" content="{$arrNovel['n_name']??'未知小说'}" />
<meta property="og:description" content="{$strDescription??'暂无简介'}" /> <meta property="og:description" content="{$strDescription??'暂无简介'}" />
<meta property="og:url" <meta property="og:url"
content='https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' /> content='https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}' />
<meta property="og:type" content="book" /> <meta property="og:type" content="book" />
<meta property="og:image" content="{$arrNovel.n_cover_path ?? ''}" /> <meta property="og:image" content="{$arrNovel.n_cover_path ?? ''}" />
<meta property="og:site_name" content="{$DomainModel->d_name}" /> <meta property="og:site_name" content="{$DomainModel->d_name}" />
<meta property="og:novel:category" content="{$arrNovel.og_novel_category ?? ''}"> <meta property="og:novel:category" content="{$arrNovel.n_category ?? ''}">
<meta property="og:novel:author" content="{$arrNovel.og_novel_author ?? ''}"> <meta property="og:novel:author" content="{$arrNovel.n_author ?? ''}">
<meta property="og:novel:book_name" content="{$arrNovel.og_novel_book_name ?? ''}"> <meta property="og:novel:book_name" content="{$arrNovel.n_name ?? ''}">
<meta property="og:novel:read_url" <meta property="og:novel:read_url"
content='https://{$DomainModel->d_domain}{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$intFirstChapterSort"/}'> content='https://{$DomainModel->d_domain}{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$intFirstChapterSort"/}'>
<meta property="og:novel:status" content="{$arrNovel.og_novel_status ?? ''}"> <meta property="og:novel:status" content="{$arrNovel.n_status ?? ''}">
<meta property="og:novel:update_time" content="{$arrNovel.og_novel_update_time ?? ''}"> <meta property="og:novel:update_time" content="{$arrNovel.n_update_time ?? ''}">
<meta property="og:novel:latest_chapter_name" content="{$arrLatestChapter.name}"> <meta property="og:novel:latest_chapter_name" content="{$arrLatestChapter.c_name}">
<meta property="og:novel:latest_chapter_url" <meta property="og:novel:latest_chapter_url"
content='https://{$DomainModel->d_domain}{$strPcPath}{site:lcpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}'> content='https://{$DomainModel->d_domain}{$strPcPath}{site:lcpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'>
<!-- 可选:支持 Twitter Card --> <!-- 可选:支持 Twitter Card -->
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="{$arrNovel['og_novel_book_name'] ?? '未知小说'}" /> <meta name="twitter:title" content="{$arrNovel['n_name'] ?? '未知小说'}" />
<meta name="twitter:description" content="{$strDescription ?? '暂无简介'}" /> <meta name="twitter:description" content="{$strDescription ?? '暂无简介'}" />
<meta name="twitter:image" content="{$arrNovel.n_cover_path ?? ''}" /> <meta name="twitter:image" content="{$arrNovel.n_cover_path ?? ''}" />
<!-- 结构化数据 --> <!-- 结构化数据 -->
@@ -31,28 +31,28 @@
{ {
"@context": "https://schema.org", "@context": "https://schema.org",
"@type": "Book", "@type": "Book",
"name": "{$arrNovel['og_novel_book_name'] ?? '未知小说'}", "name": "{$arrNovel['n_name'] ?? '未知小说'}",
"author": { "author": {
"@type": "Person", "@type": "Person",
"name": "{$arrNovel['og_novel_author'] ??'佚名'}" "name": "{$arrNovel['n_author'] ??'佚名'}"
}, },
"publisher": { "publisher": {
"@type": "Organization", "@type": "Organization",
"name": "{$DomainModel->d_name}", "name": "{$DomainModel->d_name}",
"url": "https://{$DomainModel->d_domain}" "url": "https://{$DomainModel->d_domain}"
}, },
"url": 'https://{$DomainModel->d_domain}{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" order="zheng" page="$intPage"/}', "url": 'https://{$DomainModel->d_domain}{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" order="zheng" page="$intPage"/}',
"inLanguage": "zh-CN", "inLanguage": "zh-CN",
"genre": "{$arrNovel['og_novel_category'] ?? '未知分类'}", "genre": "{$arrNovel['n_category'] ?? '未知分类'}",
"hasPart": { "hasPart": {
"@type": "WebPage", "@type": "WebPage",
"name": "{$arrNovel['og_novel_book_name'] ?? '未知小说'}章节目录 第{$intPage}页", "name": "{$arrNovel['n_name'] ?? '未知小说'}章节目录 第{$intPage}页",
"url": 'https://{$DomainModel->d_domain}{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" order="zheng" page="$intPage"/}' "url": 'https://{$DomainModel->d_domain}{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" order="zheng" page="$intPage"/}'
} }
} }
</script> </script>
{block name="head-css"} {block name="head-css"}
<link rel="canonical" href='https://{$DomainModel->d_domain}{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" order="zheng" page="$intPage"/}'> <link rel="canonical" href='https://{$DomainModel->d_domain}{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" order="zheng" page="$intPage"/}'>
{/block} {/block}
{block name="head-js"}{/block} {block name="head-js"}{/block}
@@ -75,15 +75,15 @@
<meta itemprop="position" content="1" /> <meta itemprop="position" content="1" />
</li> </li>
<li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<?php $arrNovel['category_pinyin'] ?? $arrNovel['category_pinyin'] = 'all'?> <?php $arrNovel['n_category_pinyin'] ?? $arrNovel['n_category_pinyin'] = 'all'?>
<a href='{$strPcPath}{site:nflurl gender="all" category="$arrNovel[category_pinyin]" status="all" page="1"/}' itemprop="item"> <a href='{$strPcPath}{site:nflurl gender="all" category="$arrNovel[n_category_pinyin]" status="all" page="1"/}' itemprop="item">
<span itemprop="name">{$arrNovel.og_novel_category}</span> <span itemprop="name">{$arrNovel.n_category}</span>
</a> </a>
<meta itemprop="position" content="2" /> <meta itemprop="position" content="2" />
</li> </li>
<li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' itemprop="item"> <a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}' itemprop="item">
<span itemprop="name">{$arrNovel['og_novel_book_name']}</span> <span itemprop="name">{$arrNovel['n_name']}</span>
</a> </a>
<meta itemprop="position" content="3" /> <meta itemprop="position" content="3" />
</li> </li>
@@ -100,11 +100,11 @@
<div class="top"> <div class="top">
{$arrGRM[0]|raw} {$arrGRM[0]|raw}
<h1> <h1>
<a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' > <a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}' >
{$arrNovel['og_novel_book_name']}章节目录 - {$arrNovel['og_novel_author']} - {$DomainModel->d_name} 第{$intPage}页 {$arrNovel['n_name']}章节目录 - {$arrNovel['n_author']} - {$DomainModel->d_name} 第{$intPage}页
</a> </a>
</h1> </h1>
<p>作者:{$arrNovel.og_novel_author}</p> <p>作者:{$arrNovel.n_author}</p>
</div> </div>
<div class="fenlei"> <div class="fenlei">
@@ -119,7 +119,7 @@
<li> <li>
{$arrGRM[$key]|raw} {$arrGRM[$key]|raw}
<h2> <h2>
<a href='{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$Chapter[c_sort_num]" c_page="0"/}' >{$Chapter.name}</a> <a href='{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$Chapter[c_sort_num]" c_page="0"/}' >{$Chapter.c_name}</a>
</h2> </h2>
</li> </li>
{/foreach} {/foreach}

View File

@@ -12,30 +12,30 @@
<link rel="stylesheet" href="/public/layer/need/layer.css" type="text/css"> <link rel="stylesheet" href="/public/layer/need/layer.css" type="text/css">
{block name="head-css"} {block name="head-css"}
<link rel="canonical" <link rel="canonical"
href='https://{$DomainModel->d_domain}{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$arrChapter[c_sort_num]"/}'> href='https://{$DomainModel->d_domain}{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$arrChapter[c_sort_num]"/}'>
{/block} {/block}
<!-- 社交媒体标签 --> <!-- 社交媒体标签 -->
<meta property="og:title" content="{$arrNovel['og_novel_book_name']??'未知小说'} {$arrChapter.name} - {$DomainModel->d_name}" /> <meta property="og:title" content="{$arrNovel['n_name']??'未知小说'} {$arrChapter.c_name} - {$DomainModel->d_name}" />
<meta property="og:description" content="{$strDescription??'暂无简介'}" /> <meta property="og:description" content="{$strDescription??'暂无简介'}" />
<meta property="og:url" <meta property="og:url"
content='https://{$DomainModel->d_domain}{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' /> content='https://{$DomainModel->d_domain}{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}' />
<meta property="og:type" content="book" /> <meta property="og:type" content="book" />
<meta property="og:image" content="{$arrNovel.n_cover_path ?? ''}" /> <meta property="og:image" content="{$arrNovel.n_cover_path ?? ''}" />
<meta property="og:site_name" content="{$DomainModel->d_name}" /> <meta property="og:site_name" content="{$DomainModel->d_name}" />
<meta property="og:novel:category" content="{$arrNovel.og_novel_category ?? ''}"> <meta property="og:novel:category" content="{$arrNovel.n_category ?? ''}">
<meta property="og:novel:author" content="{$arrNovel.og_novel_author ?? ''}"> <meta property="og:novel:author" content="{$arrNovel.n_author ?? ''}">
<meta property="og:novel:book_name" content="{$arrNovel.og_novel_book_name ?? ''}"> <meta property="og:novel:book_name" content="{$arrNovel.n_name ?? ''}">
<meta property="og:novel:read_url" <meta property="og:novel:read_url"
content='https://{$DomainModel->d_domain}{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$$arrChapter[c_sort_num]"/}'> content='https://{$DomainModel->d_domain}{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$$arrChapter[c_sort_num]"/}'>
<meta property="og:novel:status" content="{$arrNovel.og_novel_status ?? ''}"> <meta property="og:novel:status" content="{$arrNovel.n_status ?? ''}">
<meta property="og:novel:update_time" content="{$arrNovel.og_novel_update_time ?? ''}"> <meta property="og:novel:update_time" content="{$arrNovel.n_update_time ?? ''}">
<meta property="og:novel:latest_chapter_name" content="{$arrChapter.name}"> <meta property="og:novel:latest_chapter_name" content="{$arrChapter.c_name}">
<meta property="og:novel:latest_chapter_url" <meta property="og:novel:latest_chapter_url"
content='https://{$DomainModel->d_domain}{$strPcPath}{site:lcpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}'> content='https://{$DomainModel->d_domain}{$strPcPath}{site:lcpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'>
<!-- 可选:支持 Twitter Card --> <!-- 可选:支持 Twitter Card -->
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="{$arrNovel['og_novel_book_name']??'未知小说'} {$arrChapter.name} - {$DomainModel->d_name}" /> <meta name="twitter:title" content="{$arrNovel['n_name']??'未知小说'} {$arrChapter.c_name} - {$DomainModel->d_name}" />
<meta name="twitter:description" content="{$strDescription ?? '暂无简介'}" /> <meta name="twitter:description" content="{$strDescription ?? '暂无简介'}" />
<meta name="twitter:image" content="{$arrNovel.n_cover_path ?? ''}" /> <meta name="twitter:image" content="{$arrNovel.n_cover_path ?? ''}" />
<!-- 结构化数据 --> <!-- 结构化数据 -->
@@ -43,10 +43,10 @@
{ {
"@context": "https://schema.org", "@context": "https://schema.org",
"@type": "Book", "@type": "Book",
"name": "{$arrNovel['og_novel_book_name'] ?? '未知小说'}", "name": "{$arrNovel['n_name'] ?? '未知小说'}",
"author": { "author": {
"@type": "Person", "@type": "Person",
"name": "{$arrNovel['og_novel_author'] ??'佚名'}" "name": "{$arrNovel['n_author'] ??'佚名'}"
}, },
"publisher": { "publisher": {
"@type": "Organization", "@type": "Organization",
@@ -54,14 +54,14 @@
"url": "https://{$DomainModel->d_domain}" "url": "https://{$DomainModel->d_domain}"
}, },
"image": "{$arrNovel.n_cover_path ?? ''}", "image": "{$arrNovel.n_cover_path ?? ''}",
"url":'https://{$DomainModel->d_domain}{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}', "url":'https://{$DomainModel->d_domain}{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}',
"inLanguage": "zh-CN", "inLanguage": "zh-CN",
"genre": "{$arrNovel.og_novel_category ??''}", "genre": "{$arrNovel.n_category ??''}",
"datePublished": "{$arrNovel['og_novel_update_time'] ?? time()}", "datePublished": "{$arrNovel['n_update_time'] ?? time()}",
"hasPart": { "hasPart": {
"@type": "CreativeWork", "@type": "CreativeWork",
"name": "{$arrChapter.name ?? ''}", "name": "{$arrChapter.c_name ?? ''}",
"url":'https://{$DomainModel->d_domain}{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}', "url":'https://{$DomainModel->d_domain}{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}',
"description": "{$strDescription}" "description": "{$strDescription}"
} }
} }
@@ -159,26 +159,26 @@
<div class="crumbs-nav"> <div class="crumbs-nav">
<a href="{$strPcPath}/">首页</a> <a href="{$strPcPath}/">首页</a>
<em class="iconfont"></em> <em class="iconfont"></em>
{if $arrNovel.category_sex && $arrNovel.category_sex == 'man'} {if $arrNovel.n_category_sex_en && $arrNovel.n_category_sex_en == 'man'}
{$arrGRM[15]|raw} {$arrGRM[15]|raw}
<a href='{$strPcPath}{site:nflurl gender="$strNanUrlTemp" category="all" status="all" page="1"/}'>男生</a> <a href='{$strPcPath}{site:nflurl gender="$strNanUrlTemp" category="all" status="all" page="1"/}'>男生</a>
<em class="iconfont"></em> <em class="iconfont"></em>
{$arrGRM[14]|raw} {$arrGRM[14]|raw}
<?php $arrNovel['category_pinyin'] ?? $arrNovel['category_pinyin'] = 'all'?> <?php $arrNovel['n_category_pinyin'] ?? $arrNovel['n_category_pinyin'] = 'all'?>
<a <a
href='{$strPcPath}{site:nflurl gender="$strNanUrlTemp" category="$arrNovel[category_pinyin]" status="all" page="1"/}'>{$arrNovel.og_novel_category}</a> href='{$strPcPath}{site:nflurl gender="$strNanUrlTemp" category="$arrNovel[n_category_pinyin]" status="all" page="1"/}'>{$arrNovel.n_category}</a>
{else} {else}
<a href='{$strPcPath}{site:nflurl gender="$strNvUrlTemp" category="all" status="all" page="1"/}'>女生</a> <a href='{$strPcPath}{site:nflurl gender="$strNvUrlTemp" category="all" status="all" page="1"/}'>女生</a>
<em class="iconfont"></em> <em class="iconfont"></em>
{$arrGRM[13]|raw} {$arrGRM[13]|raw}
<a href='{$strPcPath}{site:nflurl gender="$strNvUrlTemp" category="$arrNovel[category_pinyin]" status="all" page="1"/}'>{$arrNovel.og_novel_category}</a> <a href='{$strPcPath}{site:nflurl gender="$strNvUrlTemp" category="$arrNovel[n_category_pinyin]" status="all" page="1"/}'>{$arrNovel.n_category}</a>
{/if} {/if}
<em class="iconfont"></em> <em class="iconfont"></em>
{$arrGRM[12]|raw} {$arrGRM[12]|raw}
<a <a
href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}'>{$arrNovel.og_novel_book_name}</a> href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'>{$arrNovel.n_name}</a>
</div> </div>
<div class="read-main-wrap font-family01" style="font-size:18px" id="j_readMainWrap"> <div class="read-main-wrap font-family01" style="font-size:18px" id="j_readMainWrap">
<div id="j_chapterBox"> <div id="j_chapterBox">
@@ -188,19 +188,19 @@
<div class="main-text-wrap"> <div class="main-text-wrap">
<div class="text-head"> <div class="text-head">
<h1 class="j_chapterName"> <h1 class="j_chapterName">
<a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}'> <a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'>
{$arrNovel.og_novel_book_name} {$arrNovel.n_name}
</a> </a>
<a href='{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}' <a href='{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}'
>{$arrChapter.name}</a> >{$arrChapter.c_name}</a>
</h1> </h1>
<div class="text-info cf"> <div class="text-info cf">
<div class="info fl"> <div class="info fl">
{$arrGRM[11]|raw} {$arrGRM[11]|raw}
<a <a
href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}'> href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'>
<em class="iconfont"></em> {$arrNovel.og_novel_book_name}</a> <em class="iconfont"></em> {$arrNovel.n_name}</a>
<a href="javascript:"> <em class="iconfont"></em> {$arrNovel.og_novel_author}</a> <a href="javascript:"> <em class="iconfont"></em> {$arrNovel.n_author}</a>
<i><em class="iconfont"></em><span class="j_chapterWordCut">2000</span></i> <i><em class="iconfont"></em><span class="j_chapterWordCut">2000</span></i>
<i><em class="iconfont"></em><span class="j_updateTime">{$arrChapter.created_at ?? <i><em class="iconfont"></em><span class="j_updateTime">{$arrChapter.created_at ??
''}</span></i> ''}</span></i>
@@ -208,8 +208,8 @@
</div> </div>
</div> </div>
<div class="read-content j_readContent"> <div class="read-content j_readContent">
{if $arrChapter && $arrChapter.content} {if $arrChapter && $arrChapter.c_content}
<script>document.writeln(qsbs.bb('{$arrChapter.content}'));</script> <script>document.writeln(qsbs.bb('{$arrChapter.c_content}'));</script>
{/if} {/if}
</div> </div>
</div> </div>
@@ -227,13 +227,13 @@
{else} {else}
{$arrGRM[10]|raw} {$arrGRM[10]|raw}
<a id="j_chapterPrev" <a id="j_chapterPrev"
href='{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$arrPreChapter[c_sort_num]" c_page="0"/}'>上一章</a> href='{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$arrPreChapter[c_sort_num]" c_page="0"/}'>上一章</a>
{/if} {/if}
<span>|</span> <span>|</span>
{if $arrNextChapter && $arrNextChapter.c_sort_num} {if $arrNextChapter && $arrNextChapter.c_sort_num}
{$arrGRM[9]|raw} {$arrGRM[9]|raw}
<a id="j_chapterNext" <a id="j_chapterNext"
href='{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$arrNextChapter[c_sort_num]" c_page="0"/}'>下一章</a> href='{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$arrNextChapter[c_sort_num]" c_page="0"/}'>下一章</a>
{/if} {/if}
</div> </div>
</div> </div>
@@ -243,7 +243,7 @@
<dl> <dl>
<dd id="j_navCatalogBtn"> <dd id="j_navCatalogBtn">
{$arrGRM[8]|raw} {$arrGRM[8]|raw}
<a href='{$strPcPath}{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" order="zheng" page="1"/}'> <a href='{$strPcPath}{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" order="zheng" page="1"/}'>
<i><em class="iconfont"></em><span>目录</span></i> <i><em class="iconfont"></em><span>目录</span></i>
</a> </a>
</dd> </dd>
@@ -260,7 +260,7 @@
</dd> </dd>
<dd> <dd>
{$arrGRM[6]|raw} {$arrGRM[6]|raw}
<a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}'> <a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'>
<i><em class="iconfont"></em><span>详情</span></i> <i><em class="iconfont"></em><span>详情</span></i>
</a> </a>
</dd> </dd>
@@ -375,13 +375,13 @@
const strNovelId = `{$arrNovel.n_id}`; const strNovelId = `{$arrNovel.n_id}`;
const arrNovel = { const arrNovel = {
'n_id' : `{$arrNovel['n_id']}`, 'n_id' : `{$arrNovel['n_id']}`,
'og_novel_pin_yin' : `{$arrNovel['og_novel_pin_yin']}`, 'n_name_pinyin' : `{$arrNovel['n_name_pinyin']}`,
'n_cover_path' : `{$arrNovel['n_cover_path']}`, 'n_cover_path' : `{$arrNovel['n_cover_path']}`,
'og_novel_book_name' : `{$arrNovel['og_novel_book_name']}`, 'n_name' : `{$arrNovel['n_name']}`,
'og_novel_author' : `{$arrNovel['og_novel_author']}`, 'n_author' : `{$arrNovel['n_author']}`,
'og_novel_status' : `{$arrNovel['og_novel_status']}`, 'n_status' : `{$arrNovel['n_status']}`,
'c_sort_num' : `{$arrChapter.c_sort_num}`, 'c_sort_num' : `{$arrChapter.c_sort_num}`,
'c_name' : `{$arrChapter.name}`, 'c_name' : `{$arrChapter.c_name}`,
}; };
</script> </script>
@@ -390,8 +390,8 @@
var book = {}; var book = {};
book.Info = { book.Info = {
"Id": `{$arrNovel['n_id']}`, "Id": `{$arrNovel['n_id']}`,
"Name": `{$arrNovel['og_novel_book_name']}`, "Name": `{$arrNovel['n_name']}`,
"authorName": `{$arrNovel['og_novel_author']}` "authorName": `{$arrNovel['n_author']}`
}; };
book.chapter = { book.chapter = {
//页面进入加载的章节id //页面进入加载的章节id
@@ -405,7 +405,7 @@
//下一章id //下一章id
nextId: '{$arrNextChapter.c_sort_num ?? 1}' nextId: '{$arrNextChapter.c_sort_num ?? 1}'
}; };
book.chapterUrl = '{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}' ; book.chapterUrl = '{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$arrChapter[c_sort_num]" c_page="0"/}' ;
book.nextChapterVip = 0; book.nextChapterVip = 0;
</script> </script>
<script type="text/javascript" src="/template/kuangyu/reader/web/js/global.js"></script> <script type="text/javascript" src="/template/kuangyu/reader/web/js/global.js"></script>

View File

@@ -4,26 +4,26 @@
{block name="description"}{$strDescription??''}{/block} {block name="description"}{$strDescription??''}{/block}
{block name="head"} {block name="head"}
<!-- 社交媒体标签 --> <!-- 社交媒体标签 -->
<meta property="og:title" content="{$arrNovel['og_novel_book_name']??'未知小说'}" /> <meta property="og:title" content="{$arrNovel['n_name']??'未知小说'}" />
<meta property="og:description" content="{$strDescription??'暂无简介'}" /> <meta property="og:description" content="{$strDescription??'暂无简介'}" />
<meta property="og:url" <meta property="og:url"
content='https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' /> content='https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}' />
<meta property="og:type" content="book" /> <meta property="og:type" content="book" />
<meta property="og:image" content="{$arrNovel.n_cover_path ?? ''}" /> <meta property="og:image" content="{$arrNovel.n_cover_path ?? ''}" />
<meta property="og:site_name" content="{$DomainModel->d_name}" /> <meta property="og:site_name" content="{$DomainModel->d_name}" />
<meta property="og:novel:category" content="{$arrNovel.og_novel_category ?? ''}"> <meta property="og:novel:category" content="{$arrNovel.n_category ?? ''}">
<meta property="og:novel:author" content="{$arrNovel.og_novel_author ?? ''}"> <meta property="og:novel:author" content="{$arrNovel.n_author ?? ''}">
<meta property="og:novel:book_name" content="{$arrNovel.og_novel_book_name ?? ''}"> <meta property="og:novel:book_name" content="{$arrNovel.n_name ?? ''}">
<meta property="og:novel:read_url" <meta property="og:novel:read_url"
content='https://{$DomainModel->d_domain}{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$intFirstChapterSort"/}'> content='https://{$DomainModel->d_domain}{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$intFirstChapterSort"/}'>
<meta property="og:novel:status" content="{$arrNovel.og_novel_status ?? ''}"> <meta property="og:novel:status" content="{$arrNovel.n_status ?? ''}">
<meta property="og:novel:update_time" content="{$arrNovel.og_novel_update_time ?? ''}"> <meta property="og:novel:update_time" content="{$arrNovel.n_update_time ?? ''}">
<meta property="og:novel:latest_chapter_name" content="{$arrLatestChapter.name ?? ''}"> <meta property="og:novel:latest_chapter_name" content="{$arrLatestChapter.c_name ?? ''}">
<meta property="og:novel:latest_chapter_url" <meta property="og:novel:latest_chapter_url"
content='https://{$DomainModel->d_domain}{$strPcPath}{site:lcpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}'> content='https://{$DomainModel->d_domain}{$strPcPath}{site:lcpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'>
<!-- 可选:支持 Twitter Card --> <!-- 可选:支持 Twitter Card -->
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="{$arrNovel['og_novel_book_name'] ?? '未知小说'}" /> <meta name="twitter:title" content="{$arrNovel['n_name'] ?? '未知小说'}" />
<meta name="twitter:description" content="{$strDescription ?? '暂无简介'}" /> <meta name="twitter:description" content="{$strDescription ?? '暂无简介'}" />
<meta name="twitter:image" content="{$arrNovel.n_cover_path ?? ''}" /> <meta name="twitter:image" content="{$arrNovel.n_cover_path ?? ''}" />
<!-- 结构化数据 --> <!-- 结构化数据 -->
@@ -31,21 +31,21 @@
{ {
"@context": "https://schema.org", "@context": "https://schema.org",
"@type": "Book", "@type": "Book",
"name": "{$arrNovel['og_novel_book_name'] ?? '未知小说'}", "name": "{$arrNovel['n_name'] ?? '未知小说'}",
"description": "{$arrNovel['og_description'] ??'暂无简介'}", "description": "{$arrNovel['n_description'] ??'暂无简介'}",
"author": { "author": {
"@type": "Person", "@type": "Person",
"name": "{$arrNovel['og_novel_author'] ??'佚名'}" "name": "{$arrNovel['n_author'] ??'佚名'}"
}, },
"publisher": { "publisher": {
"@type": "Organization", "@type": "Organization",
"name": "{$DomainModel->d_name}", "name": "{$DomainModel->d_name}",
"url": "https://{$DomainModel->d_domain}" "url": "https://{$DomainModel->d_domain}"
}, },
"datePublished": "{$arrNovel['og_novel_update_time'] ?? time()}", "datePublished": "{$arrNovel['n_update_time'] ?? time()}",
"image": "{$arrNovel.n_cover_path ?? ''}", "image": "{$arrNovel.n_cover_path ?? ''}",
"url": 'https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}', "url": 'https://{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}',
"genre": "{$arrNovel.og_novel_category ??''}", "genre": "{$arrNovel.n_category ??''}",
"inLanguage": "zh-CN", "inLanguage": "zh-CN",
"bookFormat": "https://{$DomainModel->d_domain}/EBook", "bookFormat": "https://{$DomainModel->d_domain}/EBook",
"aggregateRating": { "aggregateRating": {
@@ -60,7 +60,7 @@
{/block} {/block}
{block name="head-css"} {block name="head-css"}
<link rel="canonical" <link rel="canonical"
href='{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}'> href='{$DomainModel->d_domain}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'>
{/block} {/block}
{block name="logo-html"} {block name="logo-html"}
<h2> <h2>
@@ -70,7 +70,7 @@
</h2> </h2>
{/block} {/block}
{block name="main"} {block name="main"}
<?php $arrNovel['category_pinyin'] ?? $arrNovel['category_pinyin'] = 'all'?> <?php $arrNovel['n_category_pinyin'] ?? $arrNovel['n_category_pinyin'] = 'all'?>
<div class="content"> <div class="content">
<nav class="breadcrumb" aria-label="breadcrumb"> <nav class="breadcrumb" aria-label="breadcrumb">
<ol itemscope itemtype="https://schema.org/BreadcrumbList"> <ol itemscope itemtype="https://schema.org/BreadcrumbList">
@@ -81,33 +81,33 @@
<meta itemprop="position" content="1" /> <meta itemprop="position" content="1" />
</li> </li>
<li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a href='{$strPcPath}{site:nflurl gender="all" category="$arrNovel[category_pinyin]" status="all" page="1"/}' <a href='{$strPcPath}{site:nflurl gender="all" category="$arrNovel[n_category_pinyin]" status="all" page="1"/}'
itemprop="item"> itemprop="item">
<span itemprop="name">{$arrNovel.og_novel_category}</span> <span itemprop="name">{$arrNovel.n_category}</span>
</a> </a>
<meta itemprop="position" content="2" /> <meta itemprop="position" content="2" />
</li> </li>
<li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <li class="breadcrumb-item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' <a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'
itemprop="item"> itemprop="item">
<span itemprop="name">{$arrNovel['og_novel_book_name']}</span> <span itemprop="name">{$arrNovel['n_name']}</span>
</a> </a>
<meta itemprop="position" content="3" /> <meta itemprop="position" content="3" />
</li> </li>
</ol> </ol>
<h1 class="site-description ">{$arrNovel['og_novel_book_name']}最新章节 - {$arrNovel['og_novel_author']} - <h1 class="site-description ">{$arrNovel['n_name']}最新章节 - {$arrNovel['n_author']} -
{$DomainModel->d_name}</h1> {$DomainModel->d_name}</h1>
</nav> </nav>
<div class="info"> <div class="info">
<div class="info_box"> <div class="info_box">
<div class="info_L"> <div class="info_L">
<a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}' <a href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'
title="{$arrNovel['og_novel_book_name']}" class="book_cov"> title="{$arrNovel['n_name']}" class="book_cov">
<img src="/static/img/default.jpg" data-src="{$arrNovel.n_cover_path ?? ''}" <img src="/static/img/default.jpg" data-src="{$arrNovel.n_cover_path ?? ''}"
alt="{$arrNovel['og_novel_book_name'] ?? ''}小说封面 - {$arrNovel.og_novel_author}最新章节" alt="{$arrNovel['n_name'] ?? ''}小说封面 - {$arrNovel.n_author}最新章节"
class="lazyload_book_cover lazyload-img"> class="lazyload_book_cover lazyload-img">
<i class="serial">{$arrNovel.og_novel_status ?? ''}</i> <i class="serial">{$arrNovel.n_status ?? ''}</i>
</a> </a>
<div class="btn"> <div class="btn">
<a href="javascript:;" class="sc" onclick="addBookshelfFun()"> <a href="javascript:;" class="sc" onclick="addBookshelfFun()">
@@ -120,19 +120,19 @@
<div class="info_C book_inf"> <div class="info_C book_inf">
<div class="c01"> <div class="c01">
<h2><a <h2><a
href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" /}'>{$arrNovel['og_novel_book_name']}</a> href='{$strPcPath}{site:nurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" /}'>{$arrNovel['n_name']}</a>
</h2> </h2>
<!-- <span id="mod_book_star">0分</span> --> <!-- <span id="mod_book_star">0分</span> -->
</div> </div>
<p class="c02"> <p class="c02">
<span class="zz">作者:{$arrNovel.og_novel_author}</span> <span class="zz">作者:{$arrNovel.n_author}</span>
<span>创建日期:{$arrNovel.og_novel_update_time}</span> <span>创建日期:{$arrNovel.n_update_time}</span>
</p> </p>
<div class="c03"> <div class="c03">
<p class="jianjie">简介</p> <p class="jianjie">简介</p>
<div class="c03_box"> <div class="c03_box">
<p class="jj_con" id="book_desc"> <p class="jj_con" id="book_desc">
{$arrNovel.og_description ?? ''}</p> {$arrNovel.n_description ?? ''}</p>
<span class="zk_btn">展开<s></s></span> <span class="zk_btn">展开<s></s></span>
<span class="sq_btn" style="display: none;">收起<s></s></span> <span class="sq_btn" style="display: none;">收起<s></s></span>
</div> </div>
@@ -148,9 +148,9 @@
</div> </div>
<div class="c04"> <div class="c04">
{if !empty($arrChapter)} {if !empty($arrChapter)}
<a href='{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$intFirstChapterSort"/}' <a href='{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$intFirstChapterSort"/}'
class="read">立即阅读</a> class="read">立即阅读</a>
<a href='{$strPcPath}{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" order="zheng" page="1"/}' <a href='{$strPcPath}{site:nclurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" order="zheng" page="1"/}'
class="mulu">目录</a> class="mulu">目录</a>
{/if} {/if}
</div> </div>
@@ -167,9 +167,9 @@
<div class="inf02"> <div class="inf02">
<h4>小说信息</h4> <h4>小说信息</h4>
<p>类别: <p>类别:
<a href='{$strPcPath}{site:nflurl gender="all" category="$arrNovel[category_pinyin]" status="all" page="1"/}' <a href='{$strPcPath}{site:nflurl gender="all" category="$arrNovel[n_category_pinyin]" status="all" page="1"/}'
title="{$arrNovel.og_novel_category}"> title="{$arrNovel.n_category}">
{$arrNovel.og_novel_category} {$arrNovel.n_category}
</a> </a>
</p> </p>
<!-- <p>总字数54.20万+</p> --> <!-- <p>总字数54.20万+</p> -->
@@ -193,8 +193,8 @@
{volist name="arrChapter" id="Chapter" key="key"} {volist name="arrChapter" id="Chapter" key="key"}
<p> <p>
{$arrGRM[$key]|raw} {$arrGRM[$key]|raw}
<a href='{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" c_sort="$Chapter[c_sort_num]" c_page="0"/}' <a href='{$strPcPath}{site:cpurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" c_sort="$Chapter[c_sort_num]" c_page="0"/}'
title="{$arrNovel.og_novel_book_name}-{$Chapter.name}" class="zj">{$Chapter.name}</a> title="{$arrNovel.n_name}-{$Chapter.c_name}" class="zj">{$Chapter.c_name}</a>
<span class="time">{$Chapter.created_at ?? '1天前'}</span> <span class="time">{$Chapter.created_at ?? '1天前'}</span>
<!-- <span class="time">3天前</span>--> <!-- <span class="time">3天前</span>-->
</p> </p>
@@ -208,7 +208,7 @@
<div class="pl_con"> <div class="pl_con">
{volist name="arrNovel.n_forge_novel" id="ForgeNovel" key="key"} {volist name="arrNovel.n_forge_novel" id="ForgeNovel" key="key"}
{if $key<20 } {$arrGRM[$key+20]|raw} {/if} <a {if $key<20 } {$arrGRM[$key+20]|raw} {/if} <a
href='{$strPcPath}{site:nnurl n_id="$arrNovel[n_id]" n_py="$arrNovel[og_novel_pin_yin]" n_fid="$ForgeNovel[n_forge_id]"/}' href='{$strPcPath}{site:nnurl n_id="$arrNovel[n_id]" n_py="$arrNovel[n_name_pinyin]" n_fid="$ForgeNovel[n_forge_id]"/}'
class="red">{$ForgeNovel.n_forge_title}</a> class="red">{$ForgeNovel.n_forge_title}</a>
{/volist} {/volist}
@@ -223,23 +223,23 @@
<li> <li>
<h3> <h3>
{$arrGRM[$key+10]|raw} {$arrGRM[$key+10]|raw}
<a href='{$strPcPath}{site:nurl n_id="$Novel[n_id]" n_py="$Novel[og_novel_pin_yin]" /}' <a href='{$strPcPath}{site:nurl n_id="$Novel[n_id]" n_py="$Novel[n_name_pinyin]" /}'
title="{$Novel['og_novel_book_name'] ?? ''}"> title="{$Novel['n_name'] ?? ''}">
{$Novel['og_novel_book_name'] ?? ''} {$Novel['n_name'] ?? ''}
</a> </a>
</h3> </h3>
<div> <div>
<a href='{$strPcPath}{site:nurl n_id="$Novel[n_id]" n_py="$Novel[og_novel_pin_yin]" /}' <a href='{$strPcPath}{site:nurl n_id="$Novel[n_id]" n_py="$Novel[n_name_pinyin]" /}'
title="$Novel['og_novel_book_name'] ?? ''}" class="book_cov"> title="$Novel['n_name'] ?? ''}" class="book_cov">
<img src="/template/kuangyu/home/bai_web/images/default.png" <img src="/template/kuangyu/home/bai_web/images/default.png"
data-src="{$Novel['n_cover_path'] ?? ''}" class="lazyload_book_cover lazyload-img" data-src="{$Novel['n_cover_path'] ?? ''}" class="lazyload_book_cover lazyload-img"
alt="{$Novel['og_novel_book_name'] ?? ''}"> alt="{$Novel['n_name'] ?? ''}">
</a> </a>
<div class="book_inf"> <div class="book_inf">
<span class="aut">{$Novel['og_novel_author'] ?? ''}</span> <span class="aut">{$Novel['n_author'] ?? ''}</span>
<span class="tag"><a href="/">{$Novel['og_novel_category'] ?? ''}</a></span> <span class="tag"><a href="/">{$Novel['n_category'] ?? ''}</a></span>
<p class="int"> <p class="int">
{$Novel['og_description'] ?? ''}</p> {$Novel['n_description'] ?? ''}</p>
</div> </div>
</div> </div>
</li> </li>
@@ -253,12 +253,12 @@
const strNovelId = `{$arrNovel.n_id}`; const strNovelId = `{$arrNovel.n_id}`;
const arrNovel = { const arrNovel = {
'n_id': `{$arrNovel['n_id']}`, 'n_id': `{$arrNovel['n_id']}`,
'og_novel_pin_yin': `{$arrNovel['og_novel_pin_yin']}`, 'n_name_pinyin': `{$arrNovel['n_name_pinyin']}`,
'n_cover_path': `{$arrNovel['n_cover_path']}`, 'n_cover_path': `{$arrNovel['n_cover_path']}`,
'og_novel_book_name': `{$arrNovel['og_novel_book_name']}`, 'n_name': `{$arrNovel['n_name']}`,
'og_novel_author': `{$arrNovel['og_novel_author']}`, 'n_author': `{$arrNovel['n_author']}`,
'og_novel_status': `{$arrNovel['og_novel_status']}`, 'n_status': `{$arrNovel['n_status']}`,
'og_novel_update_time': `{$arrNovel['og_novel_update_time']}`, 'n_update_time': `{$arrNovel['n_update_time']}`,
'c_sort_num': 1, 'c_sort_num': 1,
'c_name': `第一章`, 'c_name': `第一章`,
}; };

View File

@@ -21,7 +21,7 @@
"url": "https://{$DomainModel->d_name}{site:souurl key='$strSearchKeywords' p='1'/}", "url": "https://{$DomainModel->d_name}{site:souurl key='$strSearchKeywords' p='1'/}",
"name": "{$DomainModel->d_name} - {$DomainModel->d_name}搜索 第{$intPage}页", "name": "{$DomainModel->d_name} - {$DomainModel->d_name}搜索 第{$intPage}页",
"description": "搜索‘{$strSearchKeywords}’结果第{$intPage}页,提供{$strSearchKeywords}创作的小说免费阅读。", "description": "搜索‘{$strSearchKeywords}’结果第{$intPage}页,提供{$strSearchKeywords}创作的小说免费阅读。",
"datePublished": "{$arrNovel['og_novel_update_time'] ?? time()}", "datePublished": "{$arrNovel['n_update_time'] ?? time()}",
"mainEntity": { "mainEntity": {
"@type": "Book", "@type": "Book",
"name": "{$DomainModel->d_name}", "name": "{$DomainModel->d_name}",

View File

@@ -62,13 +62,13 @@
{if $key == 1} {if $key == 1}
<h3> <h3>
{$arrGRM[1]|raw} {$arrGRM[1]|raw}
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'
title="{$Novel.og_novel_book_name ?? ''}" title="{$Novel.n_name ?? ''}"
class="zdz"> class="zdz">
{$Novel.og_novel_book_name ?? ''} {$Novel.n_name ?? ''}
</a> </a>
</h3> </h3>
<p class="int"> {$Novel.og_description ?? ''}</p> <p class="int"> {$Novel.n_description ?? ''}</p>
{/if} {/if}
{/volist} {/volist}
</div> </div>

View File

@@ -1,14 +1,14 @@
<li> <li>
{$arrGRM[$key+[start]]|raw} {$arrGRM[$key+[start]]|raw}
<h3> <h3>
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' title="{$Novel->og_novel_book_name ?? ''}" class="book_cov"> <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' title="{$Novel->n_name ?? ''}" class="book_cov">
<img class="lazyload_book_cover lazyload-img" <img class="lazyload_book_cover lazyload-img"
src="/static/img/default.jpg" data-src="{$Novel->n_cover_path ?? ''}" src="/static/img/default.jpg" data-src="{$Novel->n_cover_path ?? ''}"
alt="{$Novel->og_novel_book_name ?? ''}- {$Novel.og_novel_category ?? ''}最新章节在线免费阅读"> alt="{$Novel->n_name ?? ''}- {$Novel.n_category ?? ''}最新章节在线免费阅读">
</a> </a>
</h3> </h3>
<div class="book_inf"> <div class="book_inf">
<h3><a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' title="{$Novel->og_novel_book_name ?? ''}" >{$Novel->og_novel_book_name ?? ''}</a></h3> <h3><a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' title="{$Novel->n_name ?? ''}" >{$Novel->n_name ?? ''}</a></h3>
<span class="aut">{$Novel->og_novel_author ?? ''}</span> <span class="aut">{$Novel->n_author ?? ''}</span>
</div> </div>
</li> </li>

View File

@@ -1,14 +1,14 @@
<div class="bookLink"> <div class="bookLink">
{$arrGRM[$key+[start]]|raw} {$arrGRM[$key+[start]]|raw}
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' > <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' >
<div class="bookImg"> <div class="bookImg">
<img class="lazyload-img" <img class="lazyload-img"
src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}" alt="{$Novel.og_novel_book_name ?? ''} - {$Novel.og_novel_category ?? ''}最新章节在线免费阅读"> src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}" alt="{$Novel.n_name ?? ''} - {$Novel.n_category ?? ''}最新章节在线免费阅读">
</div> </div>
<div> <div>
<h2>{$Novel.og_novel_book_name ?? ''}</h2> <h2>{$Novel.n_name ?? ''}</h2>
<span>{$Novel->og_novel_author ?? ''}</span> <span>{$Novel->n_author ?? ''}</span>
<p>{$Novel.og_description ?? ''}</p> <p>{$Novel.n_description ?? ''}</p>
</div> </div>
</a> </a>
</div> </div>

View File

@@ -1,7 +1,7 @@
<div class="bookLink oneLine"> <div class="bookLink oneLine">
{$arrGRM[$key+[start]]|raw} {$arrGRM[$key+[start]]|raw}
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' > <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' >
<em>「{$Novel->og_novel_category ?? ''}」</em> <em>「{$Novel->n_category ?? ''}」</em>
{$Novel.og_novel_book_name ?? ''} {$Novel.n_name ?? ''}
</a> </a>
</div> </div>

View File

@@ -1,19 +1,19 @@
<li> <li>
<?php $Novel['category_pinyin'] ?? $Novel['category_pinyin'] = 'all'?> <?php $Novel['n_category_pinyin'] ?? $Novel['n_category_pinyin'] = 'all'?>
<h3> <h3>
{$arrGRM[$key+[start]]|raw} {$arrGRM[$key+[start]]|raw}
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' title="{$Novel->og_novel_book_name ?? ''}" > <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' title="{$Novel->n_name ?? ''}" >
{$Novel->og_novel_book_name ?? ''} {$Novel->n_name ?? ''}
</a> </a>
</h3> </h3>
<div class="book_inf"> <div class="book_inf">
<span class="aut">{$Novel->og_novel_author ?? ''}</span> <span class="aut">{$Novel->n_author ?? ''}</span>
<span class="tag"><a href="{$strPcPath}/shuku/all/{$Novel->category_pinyin}/all/page1" >{$Novel->og_novel_category ?? ''}</a></span> <span class="tag"><a href="{$strPcPath}/shuku/all/{$Novel->n_category_pinyin}/all/page1" >{$Novel->n_category ?? ''}</a></span>
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' title="{$Novel->og_novel_book_name ?? ''}" class="book_cov"> <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' title="{$Novel->n_name ?? ''}" class="book_cov">
<img class="lazyload_book_cover lazyload-img" <img class="lazyload_book_cover lazyload-img"
src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}" src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}"
alt="{$Novel->og_novel_book_name ?? ''} - {$Novel.og_novel_category ?? ''}最新章节在线免费阅读"> alt="{$Novel->n_name ?? ''} - {$Novel.n_category ?? ''}最新章节在线免费阅读">
</a> </a>
<p class="int"> {$Novel->og_description ?? ''}</p> <p class="int"> {$Novel->n_description ?? ''}</p>
</div> </div>
</li> </li>

View File

@@ -1,22 +1,24 @@
<div class="f3_L"> <div class="f3_L">
<?php $Novel['category_pinyin'] ?? $Novel['category_pinyin'] = 'all'?> <?php $Novel['n_category_pinyin'] ?? $Novel['n_category_pinyin'] = 'all'?>
<h3> <h3>
{$arrGRM[$key+[start]]|raw} {$arrGRM[$key+[start]]|raw}
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' title="{$Novel.og_novel_book_name ?? ''}" > <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' title="{$Novel.n_name ?? ''}" >
{$Novel.og_novel_book_name ?? ''}</a></h3> {$Novel.n_name ?? ''}</a></h3>
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' title="{$Novel.og_novel_book_name ?? ''}" class="book_cov"> <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' title="{$Novel.n_name ?? ''}" class="book_cov">
<img class="lazyload_book_cover lazyload-img" <img class="lazyload_book_cover lazyload-img"
src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}" src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}"
alt="{$Novel.og_novel_book_name ?? ''} - {$Novel.og_novel_category ?? ''}最新章节在线免费阅读"> alt="{$Novel.n_name ?? ''} - {$Novel.n_category ?? ''}最新章节在线免费阅读">
</a> </a>
<div class="book_inf"> <div class="book_inf">
<div class="book_inf01"> <div class="book_inf01">
<span class="aut">作者:{$Novel->og_novel_author ?? ''}</span> <span class="aut">作者:{$Novel->n_author ?? ''}</span>
<span class="fr">分类:<a href='{$strPcPath}{site:nflurl gender="all" category="$Novel->category_pinyin" status="all" page="1"/}' >{$Novel->og_novel_category ?? ''}</a></span> <span class="fr">分类:
<a href='{$strPcPath}{site:nflurl gender="all" category="$Novel->n_category_pinyin" status="all" page="1"/}' >{$Novel->n_category ?? ''}</a>
</span>
<!-- <span>字数24.20万字+</span> --> <!-- <span>字数24.20万字+</span> -->
<span class="fr">进度:{$Novel->og_novel_status ?? ''}</span> <span class="fr">进度:{$Novel->n_status ?? ''}</span>
<span>总点击:{$Novel->og_novel_click ?? 0}</span> <span>总点击:{$Novel->og_novel_click ?? 0}</span>
</div> </div>
<p class="int"> {$Novel->og_description ?? ''}</p> <p class="int"> {$Novel->n_description ?? ''}</p>
</div> </div>
</div> </div>

View File

@@ -1,21 +1,23 @@
<li> <li>
<?php $Novel['category_pinyin'] ?? $Novel['category_pinyin'] = 'all'?> <?php $Novel['n_category_pinyin'] ?? $Novel['n_category_pinyin'] = 'all'?>
<em class="red_bg">{$key+=1}</em> <em class="red_bg">{$key+=1}</em>
<h3 class="name"> <h3 class="name">
{$arrGRM[$key+[start]]|raw} {$arrGRM[$key+[start]]|raw}
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' title="{$Novel.og_novel_book_name ?? ''}" > <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' title="{$Novel.n_name ?? ''}" >
{$Novel.og_novel_book_name ?? ''} {$Novel.n_name ?? ''}
</a> </a>
</h3> </h3>
<div class="open"> <div class="open">
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' title="{$Novel.og_novel_book_name ?? ''}" class="book_cov"> <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' title="{$Novel.n_name ?? ''}" class="book_cov">
<img class="lazyload_book_cover lazyload-img" <img class="lazyload_book_cover lazyload-img"
src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}" alt="{$Novel.og_novel_book_name ?? ''}"> src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}" alt="{$Novel.n_name ?? ''}">
</a> </a>
<div class="book_inf"> <div class="book_inf">
<span class="aut">作者:{$Novel->og_novel_author ?? ''}</span> <span class="aut">作者:{$Novel->n_author ?? ''}</span>
<span>类别:<a href='{$strPcPath}{site:nflurl gender="all" category="$Novel->category_pinyin" status="all" page="1"/}' >{$Novel->og_novel_category ?? ''}</a></span> <span>类别:
<p class="int"> {$Novel->og_description ?? ''}</p> <a href='{$strPcPath}{site:nflurl gender="all" category="$Novel->n_category_pinyin" status="all" page="1"/}' >{$Novel->n_category ?? ''}</a>
</span>
<p class="int"> {$Novel->n_description ?? ''}</p>
</div> </div>
</div> </div>
</li> </li>

View File

@@ -1,19 +1,21 @@
<li class="lis_sh"> <li class="lis_sh">
<?php $Novel['category_pinyin'] ?? $Novel['category_pinyin'] = 'all'?> <?php $Novel['n_category_pinyin'] ?? $Novel['n_category_pinyin'] = 'all'?>
<em class="red_bg">1</em> <em class="red_bg">1</em>
<h3 class="name"> <h3 class="name">
{$arrGRM[$key+[start]]|raw} {$arrGRM[$key+[start]]|raw}
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' title="{$Novel.og_novel_book_name ?? ''}" >{$Novel.og_novel_book_name ?? ''}</a> <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' title="{$Novel.n_name ?? ''}" >{$Novel.n_name ?? ''}</a>
</h3> </h3>
<div class="open"> <div class="open">
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' title="{$Novel.og_novel_book_name ?? ''}" class="book_cov"> <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' title="{$Novel.n_name ?? ''}" class="book_cov">
<img class="lazyload_book_cover lazyload-img" <img class="lazyload_book_cover lazyload-img"
src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}" alt="{$Novel.og_novel_book_name ?? ''} - {$Novel.og_novel_category ?? ''}最新章节在线免费阅读"> src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}" alt="{$Novel.n_name ?? ''} - {$Novel.n_category ?? ''}最新章节在线免费阅读">
</a> </a>
<div class="book_inf"> <div class="book_inf">
<span class="aut">作者:{$Novel.og_novel_author ?? ''}</span> <span class="aut">作者:{$Novel.n_author ?? ''}</span>
<span>类别:<a href='{$strPcPath}{site:nflurl gender="all" category="$Novel[category_pinyin]" status="all" page="1"/}' >{$Novel.og_novel_category ?? ''}</a></span> <span>类别:
<p class="int"> {$Novel.og_description ?? ''}</p> <a href='{$strPcPath}{site:nflurl gender="all" category="$Novel[n_category_pinyin]" status="all" page="1"/}' >{$Novel.n_category ?? ''}</a>
</span>
<p class="int"> {$Novel.n_description ?? ''}</p>
</div> </div>
</div> </div>
</li> </li>

View File

@@ -1,20 +1,20 @@
<li> <li>
<ul> <ul>
<li class="lb"> <li class="lb">
<?php $Novel['category_pinyin'] ?? $Novel['category_pinyin'] = 'all'?> <?php $Novel['n_category_pinyin'] ?? $Novel['n_category_pinyin'] = 'all'?>
<a href='{$strPcPath}{site:nflurl gender="all" category="$Novel[category_pinyin]" status="all" page="1"/}' >{$Novel->og_novel_category ?? ''}</a></li> <a href='{$strPcPath}{site:nflurl gender="all" category="$Novel[n_category_pinyin]" status="all" page="1"/}' >{$Novel->n_category ?? ''}</a></li>
<li class="sm"> <li class="sm">
<h3> <h3>
{$arrGRM[$key+[start]]|raw} {$arrGRM[$key+[start]]|raw}
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' title="{$Novel.og_novel_book_name ?? ''}" > <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' title="{$Novel.n_name ?? ''}" >
{$Novel.og_novel_book_name ?? ''}</a> {$Novel.n_name ?? ''}</a>
</h3> </h3>
</li> </li>
<li class="gx"> <li class="gx">
<a href='{$strPcPath}{site:lcpurl n_id="$Novel[n_id]" n_py="$Novel[og_novel_pin_yin]" /}' <a href='{$strPcPath}{site:lcpurl n_id="$Novel[n_id]" n_py="$Novel[n_name_pinyin]" /}'
title="{$Novel->og_novel_latest_chapter_name ?? 'null'}" title="{$Novel->n_latest_chapter_name ?? 'null'}"
>{$Novel->og_novel_latest_chapter_name ?? 'null'}</a></li> >{$Novel->n_latest_chapter_name ?? 'null'}</a></li>
<li class="zz"><a href="{$strPcPath}{site:souurl key='$Novel[og_novel_author]' p='1'/}">{$Novel->og_novel_author ?? 'null'}</a></li> <li class="zz"><a href="{$strPcPath}{site:souurl key='$Novel[n_author]' p='1'/}">{$Novel->n_author ?? 'null'}</a></li>
<li class="sj">{$Novel->og_novel_update_time ?? 'null'}</li> <li class="sj">{$Novel->n_update_time ?? 'null'}</li>
</ul> </ul>
</li> </li>

View File

@@ -0,0 +1,27 @@
<li>
{$arrGRM[$key+[start]]|raw}
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id ?? 1" n_py="$Novel->n_name_pinyin"/}' class="book_cov" title="{$Novel->n_name ?? ''}">
<img class="lazyload_book_cover lazyload-img"
src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}" alt="{$Novel->n_name ?? ''} - {$Novel.n_category ?? ''}最新章节在线免费阅读">
</a>
<div class="book_inf">
<h3><a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' title="{$Novel->n_name ?? ''}" >{$Novel->n_name ?? ''}</a></h3>
<p>
<span>作者:<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' title="{$Novel->n_author ?? ''}">{$Novel->n_author ?? ''}</a></span>
<span>分类:<a href="/lists/4.html" title="{$Novel->n_category ?? ''}">{$Novel->n_category ?? ''}</a></span>
<span>状态:{$Novel->n_status ?? ''}</span>
<!-- <span>总字数43.80万字+</span> -->
</p>
<p class="tags">
<i>标签:</i>
<i></i>
</p>
<p><b>最近更新:</b><a href="{$strPcPath}/chapter/1-1-1.html" title="219 桃花酿" >219 桃花酿</a>
</p>
<p class="int"> {$Novel->n_description ?? ''}</p>
</div>
<div class="right">
<span>更新时间2025-03-20 23:59</span>
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' class="read_btn btn">立即阅读</a>
</div>
</li>

View File

@@ -1,10 +1,10 @@
<li> <li>
{$arrGRM[$key+[start]]|raw} {$arrGRM[$key+[start]]|raw}
<h3> <h3>
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}' title="{$Novel.og_novel_book_name}" class="book_cov"> <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}' title="{$Novel.n_name}" class="book_cov">
<img class="lazyload_lb_nv lazyload-img" <img class="lazyload_lb_nv lazyload-img"
src="/static/img/default.jpg" data-src="{$Novel->n_cover_path ?? '/static/img/default.jpg'}" src="/static/img/default.jpg" data-src="{$Novel->n_cover_path ?? '/static/img/default.jpg'}"
alt="{$Novel->og_novel_book_name ?? ''} - {$Novel.og_novel_category ?? ''}最新章节在线免费阅读"> alt="{$Novel->n_name ?? ''} - {$Novel.n_category ?? ''}最新章节在线免费阅读">
</a> </a>
</h3> </h3>
</li> </li>

View File

@@ -1,5 +1,5 @@
<li data-desc=" {$Novel.og_description ?? ''}" class="on"> <li data-desc=" {$Novel.n_description ?? ''}" class="on">
<s class="arr"></s> <s class="arr"></s>
<s class="xh">{$key}</s> <s class="xh">{$key}</s>
<i>{$Novel.og_novel_book_name ?? ''}</i> <i>{$Novel.n_name ?? ''}</i>
</li> </li>

View File

@@ -76,19 +76,19 @@
{volist name="arrRecommendEndNovel" id="Novel" key="key"} {volist name="arrRecommendEndNovel" id="Novel" key="key"}
{$arrGRM[$key]|raw} {$arrGRM[$key]|raw}
<li> <li>
<a href='{$strPcPath}{site:nurl n_id="$Novel[n_id]" n_py="$Novel[og_novel_pin_yin]"/}' <a href='{$strPcPath}{site:nurl n_id="$Novel[n_id]" n_py="$Novel[n_name_pinyin]"/}'
title="{$Novel.og_novel_book_name ?? ''}"> title="{$Novel.n_name ?? ''}">
<img src="{$Novel.n_cover_path ?? ''}" alt="{$Novel.og_novel_book_name ?? ''}"> <img src="{$Novel.n_cover_path ?? ''}" alt="{$Novel.n_name ?? ''}">
</a> </a>
<p> <p>
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'> <a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>
<span class="bookName other">{$Novel.og_novel_book_name ?? ''}</span> <span class="bookName other">{$Novel.n_name ?? ''}</span>
</a> </a>
<a href='{$strPcPath}{site:souurl key="$Novel[og_novel_author]" p="1"/}'> <a href='{$strPcPath}{site:souurl key="$Novel[n_author]" p="1"/}'>
<span class="bookStatus other">{$Novel->og_novel_author ?? ''}</span> <span class="bookStatus other">{$Novel->n_author ?? ''}</span>
</a> </a>
<span class="bookBrief"> <span class="bookBrief">
{$Novel.og_description ?? ''}</span> {$Novel.n_description ?? ''}</span>
</p> </p>
</li> </li>
{/volist} {/volist}
@@ -125,31 +125,31 @@
const DomBookshelfContainer = document.getElementById('bookshelf-ul'); const DomBookshelfContainer = document.getElementById('bookshelf-ul');
DomBookshelfContainer.innerHTML = '' DomBookshelfContainer.innerHTML = ''
arrBookshelf.forEach(book => { arrBookshelf.forEach(book => {
let strNovelUrl = formatNovelUrl(book.og_novel_pin_yin, book.n_id) let strNovelUrl = formatNovelUrl(book.n_name_pinyin, book.n_id)
let strNovelChapterUrl = formatNovelChapterUrl(book.og_novel_pin_yin, book.n_id, book.c_sort_num) let strNovelChapterUrl = formatNovelChapterUrl(book.n_name_pinyin, book.n_id, book.c_sort_num)
let strSearchUrl = formatSearchUrl(book.og_novel_author, 1) let strSearchUrl = formatSearchUrl(book.n_author, 1)
const bookElement = document.createElement('li'); const bookElement = document.createElement('li');
if (isMobile()) { if (isMobile()) {
bookElement.innerHTML = ` bookElement.innerHTML = `
<a href="${strNovelUrl}" alt="${book.og_novel_book_name}" title="${book.og_novel_book_name}"> <a href="${strNovelUrl}" alt="${book.n_name}" title="${book.n_name}">
<img src="${book.n_cover_path}"> <img src="${book.n_cover_path}">
</a> </a>
<p> <p>
<a href="${strNovelUrl}" > <a href="${strNovelUrl}" >
<span class="bookName">${book.og_novel_book_name}</span> <span class="bookName">${book.n_name}</span>
</a> </a>
<span class="bookStatus"> <span class="bookStatus">
<b class="authorSt"><em>${book.og_novel_status}</em> <b class="authorSt"><em>${book.n_status}</em>
<a href='${strSearchUrl}'> <a href='${strSearchUrl}'>
<em class="none">${book.og_novel_author}</em> <em class="none">${book.n_author}</em>
</a> </a>
</b> </b>
<b class="authorSt chapterSt"> <b class="authorSt chapterSt">
<a href="${strNovelChapterUrl}" > <a href="${strNovelChapterUrl}" >
<em class="ct">${book.c_name}</em> <em class="ct">${book.c_name}</em>
</a> </a>
<em class="time">${book.og_novel_update_time}</em></b> <em class="time">${book.n_update_time}</em></b>
</span> </span>
<a href="${strNovelChapterUrl}" > <a href="${strNovelChapterUrl}" >
<i class="goon">阅读</i> <i class="goon">阅读</i>
@@ -158,24 +158,24 @@
`; `;
} else { } else {
bookElement.innerHTML = ` bookElement.innerHTML = `
<a href="${strPcPath}${strNovelUrl}" alt="${book.og_novel_book_name}" title="${book.og_novel_book_name}"> <a href="${strPcPath}${strNovelUrl}" alt="${book.n_name}" title="${book.n_name}">
<img src="${book.n_cover_path}"> <img src="${book.n_cover_path}">
</a> </a>
<p> <p>
<a href="${strPcPath}${strNovelUrl}" > <a href="${strPcPath}${strNovelUrl}" >
<span class="bookName">${book.og_novel_book_name}</span> <span class="bookName">${book.n_name}</span>
</a> </a>
<span class="bookStatus"> <span class="bookStatus">
<b class="authorSt"><em>${book.og_novel_status}</em> <b class="authorSt"><em>${book.n_status}</em>
<a href='${strPcPath}${strSearchUrl}'> <a href='${strPcPath}${strSearchUrl}'>
<em class="none">${book.og_novel_author}</em> <em class="none">${book.n_author}</em>
</a> </a>
</b> </b>
<b class="authorSt chapterSt"> <b class="authorSt chapterSt">
<a href="${strPcPath}${strNovelChapterUrl}" > <a href="${strPcPath}${strNovelChapterUrl}" >
<em class="ct">${book.c_name}</em> <em class="ct">${book.c_name}</em>
</a> </a>
<em class="time">${book.og_novel_update_time}</em></b> <em class="time">${book.n_update_time}</em></b>
</span> </span>
<a href="${strPcPath}${strNovelChapterUrl}" > <a href="${strPcPath}${strNovelChapterUrl}" >
<i class="goon">阅读</i> <i class="goon">阅读</i>
@@ -203,30 +203,30 @@
const DomBookshelfContainer = document.getElementById('history-ul'); const DomBookshelfContainer = document.getElementById('history-ul');
DomBookshelfContainer.innerHTML = '' DomBookshelfContainer.innerHTML = ''
arrBookshelf.forEach(book => { arrBookshelf.forEach(book => {
let strNovelUrl = formatNovelUrl(book.og_novel_pin_yin, book.n_id) let strNovelUrl = formatNovelUrl(book.n_name_pinyin, book.n_id)
let strNovelChapterUrl = formatNovelChapterUrl(book.og_novel_pin_yin, book.n_id, book.c_sort_num) let strNovelChapterUrl = formatNovelChapterUrl(book.n_name_pinyin, book.n_id, book.c_sort_num)
let strSearchUrl = formatSearchUrl(book.og_novel_author, 1) let strSearchUrl = formatSearchUrl(book.n_author, 1)
const bookElement = document.createElement('li'); const bookElement = document.createElement('li');
if (isMobile()) { if (isMobile()) {
bookElement.innerHTML = ` bookElement.innerHTML = `
<a href="${strNovelUrl}" alt="${book.og_novel_book_name}" title="${book.og_novel_book_name}"> <a href="${strNovelUrl}" alt="${book.n_name}" title="${book.n_name}">
<img src="${book.n_cover_path}"> <img src="${book.n_cover_path}">
</a> </a>
<p> <p>
<a href="${strNovelUrl}" > <a href="${strNovelUrl}" >
<span class="bookName">${book.og_novel_book_name}</span> <span class="bookName">${book.n_name}</span>
</a> </a>
<span class="bookStatus"> <span class="bookStatus">
<b class="authorSt"><em>${book.og_novel_status}</em> <b class="authorSt"><em>${book.n_status}</em>
<a href='${strSearchUrl}'> <a href='${strSearchUrl}'>
<em class="none">${book.og_novel_author}</em> <em class="none">${book.n_author}</em>
</a> </a>
</b> </b>
<b class="authorSt chapterSt"> <b class="authorSt chapterSt">
<a href="${strNovelChapterUrl}" > <a href="${strNovelChapterUrl}" >
<em class="ct">${book.c_name}</em> <em class="ct">${book.c_name}</em>
</a> </a>
<em class="time">${book.og_novel_update_time}</em></b> <em class="time">${book.n_update_time}</em></b>
</span> </span>
<a href="${strNovelChapterUrl}" > <a href="${strNovelChapterUrl}" >
<i class="goon">阅读</i> <i class="goon">阅读</i>
@@ -235,24 +235,24 @@
`; `;
} else { } else {
bookElement.innerHTML = ` bookElement.innerHTML = `
<a href="${strPcPath}${strNovelUrl}" alt="${book.og_novel_book_name}" title="${book.og_novel_book_name}"> <a href="${strPcPath}${strNovelUrl}" alt="${book.n_name}" title="${book.n_name}">
<img src="${book.n_cover_path}"> <img src="${book.n_cover_path}">
</a> </a>
<p> <p>
<a href="${strPcPath}${strNovelUrl}" > <a href="${strPcPath}${strNovelUrl}" >
<span class="bookName">${book.og_novel_book_name}</span> <span class="bookName">${book.n_name}</span>
</a> </a>
<span class="bookStatus"> <span class="bookStatus">
<b class="authorSt"><em>${book.og_novel_status}</em> <b class="authorSt"><em>${book.n_status}</em>
<a href='${strSearchUrl}'> <a href='${strSearchUrl}'>
<em class="none">${book.og_novel_author}</em> <em class="none">${book.n_author}</em>
</a> </a>
</b> </b>
<b class="authorSt chapterSt"> <b class="authorSt chapterSt">
<a href="${strPcPath}${strNovelChapterUrl}" > <a href="${strPcPath}${strNovelChapterUrl}" >
<em class="ct">${book.c_name}</em> <em class="ct">${book.c_name}</em>
</a> </a>
<em class="time">${book.og_novel_update_time}</em></b> <em class="time">${book.n_update_time}</em></b>
</span> </span>
<a href="${strPcPath}${strNovelChapterUrl}" > <a href="${strPcPath}${strNovelChapterUrl}" >
<i class="goon">阅读</i> <i class="goon">阅读</i>

View File

@@ -1,5 +1,5 @@
<li class="s2"> <li class="s2">
<h5 class="tit"> <h5 class="tit">
<a href='{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'>我真是一条龙</a> <a href='{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>我真是一条龙</a>
</h5> <i class="num"><em>{$key+=1}</em></i> </h5> <i class="num"><em>{$key+=1}</em></i>
</li> </li>

View File

@@ -1,18 +1,18 @@
<li class="s1"> <li class="s1">
<img class="pic lazy lazyload-img" data-encrypted="false" <img class="pic lazy lazyload-img" data-encrypted="false"
src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}" src="/static/img/default.jpg" data-src="{$Novel.n_cover_path ?? ''}"
alt="{$Novel.og_novel_book_name ?? ''} - {$Novel.og_novel_category ?? ''}最新章节在线免费阅读" /> alt="{$Novel.n_name ?? ''} - {$Novel.n_category ?? ''}最新章节在线免费阅读" />
{$arrGRM[$key+[start]]|raw} {$arrGRM[$key+[start]]|raw}
<h3> <h3>
<a class="tit" href='{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'>{$Novel.og_novel_book_name ?? ''}</a> <a class="tit" href='{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>{$Novel.n_name ?? ''}</a>
</h3> </h3>
<p class="intro">{$Novel.og_description ?? ''}</p> <p class="intro">{$Novel.n_description ?? ''}</p>
<p class="info"> <p class="info">
<span> <span>
<aria>作者:</aria>{$Novel.og_novel_author ?? ''} <aria>作者:</aria>{$Novel.n_author ?? ''}
</span> </span>
<em class="type">{$Novel->og_novel_category ?? ''}</em> <em class="type">{$Novel->n_category ?? ''}</em>
<em class='{eq name="$Novel->og_novel_status ?? null " value="连载中"}serial{else}finish {/eq}'>{$Novel->og_novel_status ?? ''}</em> <em class='{eq name="$Novel->n_status ?? null " value="连载中"}serial{else}finish {/eq}'>{$Novel->n_status ?? ''}</em>
</p> </p>
</li> </li>

View File

@@ -1,6 +1,6 @@
<li class="s2"> <li class="s2">
<h5 class="tit"> <h5 class="tit">
{$arrGRM[$key+[start]]|raw} {$arrGRM[$key+[start]]|raw}
<a href='{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'>{$Novel.og_novel_book_name ?? ''}</a> <a href='{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>{$Novel.n_name ?? ''}</a>
</h5> <i class="num"><em>{$key}</em></i> </h5> <i class="num"><em>{$key}</em></i>
</li> </li>

View File

@@ -1,12 +1,12 @@
<li> <li>
{$arrGRM[$key+[start]]|raw} {$arrGRM[$key+[start]]|raw}
<a href='{site:nurl n_id="$Novel->n_id" n_py="$Novel->og_novel_pin_yin"/}'> <a href='{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>
<img class="lazy lazyload-img" data-encrypted="false" src="/static/img/default.jpg" <img class="lazy lazyload-img" data-encrypted="false" src="/static/img/default.jpg"
data-src="{$Novel.n_cover_path ?? ''}" data-src="{$Novel.n_cover_path ?? ''}"
alt="{$Novel.og_novel_book_name ?? ''} - {$Novel.og_novel_category ?? ''}最新章节在线免费阅读" /> alt="{$Novel.n_name ?? ''} - {$Novel.n_category ?? ''}最新章节在线免费阅读" />
<h3>{$Novel.og_novel_book_name ?? ''}</h3> <h3>{$Novel.n_name ?? ''}</h3>
<em> <em>
<aria>作者:</aria>{$Novel.og_novel_author ?? ''} <aria>作者:</aria>{$Novel.n_author ?? ''}
</em> </em>
</a> </a>
</li> </li>

View File

@@ -139,7 +139,7 @@ class CategoryModel extends MongoModel
* @param string $strZh * @param string $strZh
* @return string * @return string
*/ */
static public function getPinYinByZh(string $strZh) static public function getPinYin(string $strZh)
{ {
$intKey = array_search($strZh, self::$arrCategory); $intKey = array_search($strZh, self::$arrCategory);
return self::$arrCategoryPinYin[$intKey]; return self::$arrCategoryPinYin[$intKey];
@@ -151,7 +151,7 @@ class CategoryModel extends MongoModel
* @param string $strName * @param string $strName
* @return string * @return string
*/ */
static public function checkSex(string $strName): string static public function getSexEn(string $strName): string
{ {
return in_array($strName, self::$arrMan) ? 'man' : 'women'; return in_array($strName, self::$arrMan) ? 'man' : 'women';
} }
@@ -162,7 +162,7 @@ class CategoryModel extends MongoModel
* @param string $strName * @param string $strName
* @return string * @return string
*/ */
static public function checkSexZh(string $strName): string static public function getSexZh(string $strName): string
{ {
return in_array($strName, self::$arrMan) ? '男生' : '女生'; return in_array($strName, self::$arrMan) ? '男生' : '女生';
} }

View File

@@ -37,7 +37,7 @@ class ChapterModel extends MongoModel
'_id' => 0, '_id' => 0,
'c_source_id' => 0, 'c_source_id' => 0,
'c_site_code' => 0, 'c_site_code' => 0,
'c_site_uuid' => 0, 'c_source_uuid' => 0,
], ],
]; ];
@@ -120,12 +120,18 @@ class ChapterModel extends MongoModel
$arrChapter = $this->getOne($arrFilter, $arrOptions); $arrChapter = $this->getOne($arrFilter, $arrOptions);
if (!empty($arrChapter)) { if (!empty($arrChapter)) {
applyToKeys($arrChapter, ['created_at', 'updated_at'], 'formatMongoDate'); try {
applyToKeys($arrChapter, ['created_at', 'updated_at'], 'formatMongoDate');
} catch (\Exception $e) {
var_dump($arrChapter);
throw $e;
}
if ($boolReadContent) { if ($boolReadContent) {
$arrChapter['content'] = StorageCore::getInstance()->read($arrChapter['c_content_path']); $arrChapter['c_content'] = StorageCore::getInstance()->read($arrChapter['c_content_path']);
} else { } else {
$arrChapter['content'] = ''; $arrChapter['c_content'] = '';
} }
} }
@@ -194,9 +200,9 @@ class ChapterModel extends MongoModel
foreach ($arrResult as &$arrItem) { foreach ($arrResult as &$arrItem) {
applyToKeys($arrItem, ['created_at', 'updated_at'], 'formatMongoDate'); applyToKeys($arrItem, ['created_at', 'updated_at'], 'formatMongoDate');
$arrItem['content'] = ''; $arrItem['c_content'] = '';
if ($boolReadContent) { if ($boolReadContent) {
$arrItem['content'] = StorageCore::getInstance()->read($arrItem['c_content_path']); $arrItem['c_content'] = StorageCore::getInstance()->read($arrItem['c_content_path']);
} }
} }

View File

@@ -70,7 +70,7 @@ class NovelClicksModel extends MongoModel
], ],
[ [
'$inc' => ['nc_clicks' => 1], '$inc' => ['nc_clicks' => 1],
'$set' => ['n_category' => $Novel->og_novel_category] '$set' => ['n_category' => $Novel->n_category]
], ],
[ [
'upsert' => true 'upsert' => true

View File

@@ -44,7 +44,7 @@ class NovelModel extends MongoModel
'projection' => [ 'projection' => [
'_id' => 0, '_id' => 0,
'n_site_code' => 0, 'n_site_code' => 0,
'n_site_uuid' => 0, 'n_source_uuid' => 0,
'n_source_id' => 0, 'n_source_id' => 0,
], ],
]; ];
@@ -63,7 +63,7 @@ class NovelModel extends MongoModel
try { try {
$arrConditions = array_map(function ($strKeyword) { $arrConditions = array_map(function ($strKeyword) {
return ['og_novel_book_name' => ['$regex' => trim($strKeyword), '$options' => 'i']]; return ['n_name' => ['$regex' => trim($strKeyword), '$options' => 'i']];
}, $arrKeywords); }, $arrKeywords);
$UpdateResult = $this->getCol()->updateMany( $UpdateResult = $this->getCol()->updateMany(
@@ -305,16 +305,16 @@ class NovelModel extends MongoModel
switch ($intType) { switch ($intType) {
case 1: case 1:
$arrCategory = array_values(CategoryModel::getManCategory()); $arrCategory = array_values(CategoryModel::getManCategory());
$arrFilter['og_novel_category'] = ['$in' => $arrCategory]; $arrFilter['n_category'] = ['$in' => $arrCategory];
break; break;
case 2: case 2:
$arrCategory = array_values(CategoryModel::getWomenCategory()); $arrCategory = array_values(CategoryModel::getWomenCategory());
$arrFilter['og_novel_category'] = ['$in' => $arrCategory]; $arrFilter['n_category'] = ['$in' => $arrCategory];
break; break;
} }
if ($strStatus !== NULL) { if ($strStatus !== NULL) {
$arrFilter['og_novel_status'] = $strStatus; $arrFilter['n_status'] = $strStatus;
} }
return $this->findPaginatedWithCache($arrFilter, $intPage, $intLimit, $arrSort, $strKey, $intLifeTime,); return $this->findPaginatedWithCache($arrFilter, $intPage, $intLimit, $arrSort, $strKey, $intLifeTime,);
} }
@@ -394,11 +394,11 @@ class NovelModel extends MongoModel
$arrFilter = []; $arrFilter = [];
if (in_array($intType, [1, 2])) { if (in_array($intType, [1, 2])) {
$arrFilter['og_novel_category'] = ['$in' => CategoryModel::getCategoryByType($intType)]; $arrFilter['n_category'] = ['$in' => CategoryModel::getCategoryByType($intType)];
} }
if ($strStatus !== NULL) { if ($strStatus !== NULL) {
$arrFilter['og_novel_status'] = $strStatus; $arrFilter['n_status'] = $strStatus;
} }
return $this->findManyShuffledWithCache($arrFilter, $intCount, $arrSort, $strKey, $intLifeTime); return $this->findManyShuffledWithCache($arrFilter, $intCount, $arrSort, $strKey, $intLifeTime);
@@ -434,11 +434,11 @@ class NovelModel extends MongoModel
]; ];
if ($strStatus !== NULL) { if ($strStatus !== NULL) {
$arrFilter['og_novel_status'] = $strStatus; $arrFilter['n_status'] = $strStatus;
} }
if (in_array($intType, [1, 2])) { if (in_array($intType, [1, 2])) {
$arrFilter['og_novel_category'] = ['$in' => CategoryModel::getCategoryByType($intType)]; $arrFilter['n_category'] = ['$in' => CategoryModel::getCategoryByType($intType)];
} }
$arrOptions = [ $arrOptions = [

View File

@@ -0,0 +1,319 @@
<?php
declare(strict_types=1);
namespace app\task\crawler\zw;
use app\model\ChapterModel;
use app\task\crawler\zw\page\Site;
use microserver\QueueManage;
use storage\StorageCore;
/**
* @mixin think\Model
*/
class Scheduler
{
protected $intSlice = 8;
protected $intStartNSourceId = 1;
protected $intEndNSourceId = 1000;
/**
* Undocumented variable
*
* @var \microserver\QueueManage
*/
protected $QueueManage = NULL;
/**
* Undocumented function
*/
public function __construct()
{
$this->QueueManage = new QueueManage();
$this->init();
}
/**
* Undocumented function
*
* @return void
*/
public function init()
{
$this->intSlice = 8;
}
/**
* create a site-wide craw task
*
* @return void
*/
public function crawlFull()
{
$intSliceSize = $this->intSlice;
$arrFilter = [];
for ($intNId = $this->intStartNSourceId; $intNId <= $this->intEndNSourceId; $intNId++) {
$arrFilter[] = [
'n_source_id' => $intNId,
'page' => 0,
];
if ($intNId % $intSliceSize == 0) {
$this->fetchNovel($arrFilter);
$arrFilter = [];
}
}
if (!empty($arrFilter)) {
$this->fetchNovel($arrFilter);
}
}
/**
* Undocumented function
*
* @param array $arrFilter
* @return void
*/
public function fetchNovel(array $arrFilter)
{
$arrTask = [
'callback' => [static::class, 'getNovelInfo'],
'data' => $arrFilter,
];
$this->QueueManage->set($arrTask);
}
/**
* Undocumented function
*
* @param array $arrFilter
* @return void
*/
public function getNovelInfo(array $arrFilter)
{
$Site = $this->getSite();
$arrNovelPageList = $Site->getNovelPageList($arrFilter);
$arrCover = [];
foreach ($arrNovelPageList as $NovelPage) {
// $arrNovel = $NovelPage->getNovelInfo();
$boolResult = $NovelPage->saveNovelInfo();
// return;
if ($boolResult == false) {
continue;
}
$arrNextPageData = $NovelPage->getNextPageArgs();
if (!empty($arrNextPageData)) {
$this->fetchNovel([
[
'n_source_id' => $arrNextPageData['n_source_id'],
'page' => $arrNextPageData['page'],
]
]);
}
$arrCoverItem = $NovelPage->getDownCoverInfo();
if (!StorageCore::getInstance()->has($arrCoverItem['local_path'])) {
$arrCover[] = $arrCoverItem;
}
$arrChapterList = $NovelPage->getChapters();
$this->fetchChapter($NovelPage->intNId, $NovelPage->getData()['page'], $arrChapterList);
}
if ($arrCover) {
$Site->downRemoteImgToLocal($arrCover);
}
}
/**
* create a task to craw the latest chapter
*
* @return void
*/
public function crawLatest()
{
$intSliceSize = $this->intSlice;
$arrUri = [];
$strUri = '/list/lastupdate_%s_0_0_%s.html';
$intEndCategory = $intEndPage = 10;
for ($intCategoryKey = 0; $intCategoryKey < $intEndCategory; $intCategoryKey++) {
for ($intPage = 1; $intPage <= $intEndPage; $intPage++) {
$arrUri[] = sprintf($strUri, $intCategoryKey, $intPage);
}
}
$arrUri = array_chunk($arrUri, $intSliceSize);
$arrTask = [
'callback' => [static::class, 'getLatestChapter'],
'data' => [],
];
foreach ($arrUri as $arrUriSlice) {
$arrTask['data'] = $arrUriSlice;
$this->QueueManage->set($arrTask);
}
}
/**
* Undocumented function
*
* @param array $arrData
* @return void
*/
public function getLatestChapter(array $arrFilter)
{
$Site = $this->getSite();
$arrLatestListPageList = $Site->getLatestListPageList($arrFilter);
$arrNSourceId = [];
foreach ($arrLatestListPageList as $LatestListPage) {
$arrResult = $LatestListPage->getNovelFilter();
$arrNSourceId = array_merge($arrNSourceId, $arrResult);
}
$arrNSourceId = array_unique($arrNSourceId);
$arrNSourceId = array_values($arrNSourceId);
$intSliceSize = $this->intSlice;
$arrFilter = [];
foreach ($arrNSourceId as $intKey => $intNSourceId) {
$arrFilter[] = [
'n_source_id' => $intNSourceId,
'page' => 0,
];
if ($intKey % $intSliceSize == 0) {
$this->fetchNovel($arrFilter);
$arrFilter = [];
}
}
if (!empty($arrFilter)) {
$this->fetchNovel($arrFilter);
}
}
/**
* Undocumented function
*
* @param integer $intNId
* @param integer $intPage
* @param array $arrChapterList
* @return void
*/
public function fetchChapter(int $intNId, int $intPage, array $arrChapterList = [])
{
$intSliceSize = $this->intSlice;
$intPageSize = 100;
$arrTask = [
'callback' => [static::class, 'getChapterInfo'],
'data' => [
'n_id' => $intNId,
]
];
$arrFilter = [];
foreach ($arrChapterList as $intKey => $arrChapter) {
$arrChapter['c_sort_num'] = $intPage * $intPageSize + $intKey + 1;
$arrChapter['c_source_id'] = supperExtractFilename($arrChapter['uri']);
$arrChapter['c_page'] = 0;
$arrFilter[] = $arrChapter;
if ($intKey % $intSliceSize == 0) {
$arrTask['data']['filter'] = $arrFilter;
$this->QueueManage->set($arrTask);
$arrFilter = [];
}
}
if (!empty($arrFilter)) {
$arrTask['data']['filter'] = $arrFilter;
$this->QueueManage->set($arrTask);
}
}
/**
* Undocumented variable
*
* @var Site
*/
public $Site;
/**
* Undocumented function
*
* @return Site
*/
public function getSite()
{
if ($this->Site == NULL) {
$this->Site = new Site;
}
return $this->Site;
}
/**
* Undocumented function
*
* @param array $arrData
* @return void
*/
public function getChapterInfo(array $arrData)
{
$Site = $this->getSite();
$ChapterModel = ChapterModel::getInstance();
foreach ($arrData['filter'] as $intKey => $arrChapterFilter) {
$strUUId = sprintf('%s-chapter-%s-%s', $Site->getSiteCode(), $arrChapterFilter['c_source_id'], $arrChapterFilter['c_page']);
$arrChapter = $ChapterModel->findOne(['c_source_uuid' => $strUUId]);
if (!empty($arrChapter) && !empty($arrChapter['content'])) {
unset($arrData['filter'][$intKey]);
}
}
$arrData['filter'] = array_values($arrData['filter']);
$arrChapterPageList = $Site->getChapterPageList($arrData['filter']);
$arrNextPageFilterList = [];
foreach ($arrChapterPageList as $ChapterPage) {
$ChapterPage->saveChapter($arrData['n_id']);
$arrNextPageFilter = $ChapterPage->getNextPage();
if (!empty($arrNextPageFilter)) {
$arrNextPageFilterList[] = $arrNextPageFilter;
}
}
if (!empty($arrNextPageFilterList)) {
$arrTask = $arrData;
$arrTask['filter'] = $arrNextPageFilterList;
$arrTask = [
'callback' => [static::class, 'getChapterInfo'],
'data' => $arrTask
];
$this->QueueManage->set($arrTask);
}
}
}

View File

@@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace app\task\crawler\zw630\page; namespace app\task\crawler\zw\page;
use db\mongo\MongoBase; use db\mongo\MongoBase;
use ddl\DDLManage; use ddl\DDLManage;
@@ -100,7 +100,7 @@ abstract class BasePage
* *
* @param string $strUri * @param string $strUri
*/ */
public function __construct(Site $Site, string $strUri) public function __construct($Site, string $strUri)
{ {
$this->setSite($Site); $this->setSite($Site);

View File

@@ -0,0 +1,226 @@
<?php
declare(strict_types=1);
namespace app\task\crawler\zw\page;
use app\model\ChapterModel;
use storage\StorageCore;
class ChapterPage extends BasePage
{
/**
* Undocumented variable
*
* @var string
*/
protected $strChapterContent = '';
/**
* Undocumented variable
*
* @var ChapterModel
*/
protected $ChapterModel;
/**
* Undocumented function
*
* @return ChapterModel
*/
public function getChapterModel(): ChapterModel
{
if ($this->ChapterModel == NULL) {
$this->ChapterModel = ChapterModel::getInstance();
}
return $this->ChapterModel;
}
public $arrOptions = [
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array',
],
];
/**
* Undocumented function
*
* @return array
*/
public function getChapterInfo(): array
{
if ($this->arrChapterInfo === NULL) {
$this->arrChapterInfo = [];
$strPattern = "/qsbs\.bb\('([^']*)'\)/";
preg_match_all($strPattern, $this->getContent(), $arrMatches);
$strContent = '';
foreach ($arrMatches[1] as $str) {
$strContent .= base64_decode($str);
}
$this->strChapterContent = $strContent;
$this->arrChapterInfo['c_page_title'] = $this->getQueryList()->find('title')->text();
$this->arrChapterInfo['c_page_keywords'] = $this->getQueryList()->find('meta[name="keywords"]')->attr('content');
$this->arrChapterInfo['c_page_description'] = $this->getQueryList()->find('meta[name="description"]')->attr('content');
$strPattern = "/lastread\.set\((.*?)\);/";
if (preg_match($strPattern, $this->getContent(), $arrMatches)) {
$strMatch = $arrMatches[1]; // 提取括号内的内容
$arrData = array_map('trim', explode(",", $strMatch));
$arrData = array_map(function ($item) {
return trim($item, "'");
}, $arrData);
$this->arrChapterInfo['c_page_data'] = $arrData;
} else {
$this->arrChapterInfo['c_page_data'] = NULL;
}
}
return $this->arrChapterInfo;
}
/**
* Undocumented variable
*
* @var array
*/
protected $arrChapterInfo;
/**
* Undocumented function
*
* @param integer $intNId
* @return boolean
*/
public function saveChapter(int $intNId): bool
{
$arrPageChapter = $this->getChapterInfo();
if (
empty($arrPageChapter) ||
empty($arrPageChapter['c_page_title']) ||
empty($arrPageChapter['c_page_data']) ||
count($arrPageChapter['c_page_data']) < 5
) {
return false;
}
$strUUId = $this->getSite()->getSiteUUId('chapter-' . $this->arrData['c_source_id'] . '-' . $this->arrData['c_page']);
$arrChapter = [
'n_id' => $intNId,
'c_name' => $arrPageChapter['c_page_data'][3],
'c_sort_num' => $this->arrData['c_sort_num'],
'c_page' => $this->arrData['c_page'],
'c_source_id' => $this->arrData['c_source_id'],
'c_site_code' => $this->getSite()->getSiteCode(),
'c_source_uuid' => $strUUId,
];
$arrExistsChapter = $this->getChapterModel()->findOne(['c_source_uuid' => $strUUId], $this->arrOptions);
if ($arrExistsChapter) {
$arrExistsChapter = (array) $arrExistsChapter;
$arrUpdate = [
'updated_at' => new \MongoDB\BSON\UTCDateTime(),
];
$this->getChapterModel()->updateOne(
['c_source_uuid' => $strUUId],
['$set' => $arrUpdate],
);
$this->strCContentPath = $arrExistsChapter['c_content_path'];
} else {
$arrInsertNovel = $arrChapter;
$arrInsertNovel['c_content_path'] = '/novel/' . ($intNId % 100) . '/' . $intNId . '/' . $arrChapter['c_sort_num'] . '_' . $arrChapter['c_page'] . '.txt';
$arrInsertNovel['created_at'] = new \MongoDB\BSON\UTCDateTime();
try {
$this->getChapterModel()->insert($arrInsertNovel);
$this->updateNovelHaveChapter($intNId);
$this->strCContentPath = $arrInsertNovel['c_content_path'];
} catch (\Exception $e) {
if ($e->getCode() === 11000) {
return $this->saveChapter($intNId);
} else {
throw $e;
}
}
}
StorageCore::getInstance()->put($this->strCContentPath, $this->strChapterContent);
return true;
}
public $strCContentPath;
/**
* Undocumented function
*
* @param integer $intNId
* @return void
*/
protected function updateNovelHaveChapter(int $intNId)
{
$arrFilter = [
'n_id' => $intNId,
];
$ChapterModel = ChapterModel::getInstance();
$arrLasteChapter = $ChapterModel->getLatestChapterByNId($intNId, false);
if (!empty($arrLasteChapter)) {
$arrUpdate['$set']['n_have_chapter'] = 1;
$arrUpdate['$set']['n_latest_chapter_name'] = $arrLasteChapter['c_name'];
$this->getMongoBase()->updateOne('novel', $arrFilter, $arrUpdate);
}
}
protected $arrNextPage;
/**
* Undocumented function
*
* @return array
*/
public function getNextPage(): array
{
if ($this->arrNextPage === NULL) {
$this->arrNextPage = [];
if ($this->isMobile()) {
$strPattern = "/var\s+hhekgsv\s*=\s*['\"](.*?)['\"]/";
preg_match_all($strPattern, $this->getContent(), $arrMatches);
$strNextPageUri = end($arrMatches[1]) ?: '';
} else {
$strHref = $this->getQueryList()->find('.read_btn a:contains("下一章")')->attr('href');
$strNextPageUri = $strHref ?: '';
}
if (is_numeric(strpos($strNextPageUri, '_'))) {
$this->arrNextPage = $this->arrData;
$this->arrNextPage['c_page'] += 1;
$this->arrNextPage['uri'] = $strNextPageUri;
}
}
return $this->arrNextPage;
}
}

View File

@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace app\task\crawler\zw\page;
use app\model\NovelModel;
class LatestListPage extends BasePage
{
/**
* Undocumented variable
*
* @var NovelModel
*/
protected $NovelModel;
/**
* Undocumented function
*
* @return NovelModel
*/
public function getNovelModel(): NovelModel
{
if ($this->NovelModel == NULL) {
$this->NovelModel = NovelModel::getInstance();
}
return $this->NovelModel;
}
static public $arrOptions = [
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array',
],
];
/**
* Undocumented function
*
* @return array
*/
public function getNovelFilter(): array
{
$arrFilter = [];
if ($this->isMobile()) {
$arrFilter = $this->getQueryList()->find('div.wrap-box')->eq(0)->find('ul.sort_list li')->map(function ($li) {
$strUri = $li->find('a')->eq(0)->attr('href');
return supperExtractFilename($strUri);
})->filter()->all();
} else {
$arrFilter = $this->getQueryList()->find('div.layout.layout2.layout-col2.fl ul.txt-list li')->map(function ($li) {
$strUri = $li->find('a')->eq(0)->attr('href');
return supperExtractFilename($strUri);
})->filter()->all();
}
return $arrFilter;
}
}

View File

@@ -0,0 +1,418 @@
<?php
declare(strict_types=1);
namespace app\task\crawler\zw\page;
use app\model\CategoryModel;
use app\model\CountersModel;
use app\model\NovelModel;
use storage\StorageCore;
class NovelPage extends BasePage
{
/**
* Undocumented variable
*
* @var array
*/
protected $arrNovelInfo = [];
/**
* Undocumented variable
*
* @var array
*/
protected $arrRelatedNovel = [];
/**
* Undocumented variable
*
* @var array
*/
protected $arrForgeNovel = [];
/**
* Undocumented variable
*
* @var NovelModel
*/
protected $NovelModel;
/**
* Undocumented function
*
* @return NovelModel
*/
public function getNovelModel(): NovelModel
{
if ($this->NovelModel == NULL) {
$this->NovelModel = NovelModel::getInstance();
}
return $this->NovelModel;
}
public $arrOptions = [
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array',
],
];
/**
* 查询看的小说
*
* @param integer $intNSourceId
* @param string $strName
* @return array
*/
protected function findOrCreateNovel(int $intNSourceId, string $strName): array
{
$strUUId = $this->getSite()->getSiteUUId($intNSourceId);
$arrExistsNovel = $this->getNovelModel()->findOne(['n_source_uuid' => $strUUId], $this->arrOptions);
if ($arrExistsNovel) {
$arrNovelInfo = (array) $arrExistsNovel;
} else {
$arrNovelInfo = [
'n_id' => CountersModel::getInstance()->getNextSequence('novel'),
'n_name' => $strName,
'n_name_pinyin' => zhToPinYin($strName),
'n_site_code' => $this->getSite()->getSiteCode(),
'n_source_uuid' => $strUUId,
'n_source_id' => $intNSourceId,
'n_level' => 1,
'n_have_chapter' => 0,
'created_at' => new \MongoDB\BSON\UTCDateTime(),
];
try {
$this->getNovelModel()->insert($arrNovelInfo);
} catch (\Exception $e) {
if ($e->getCode() === 11000) {
return $this->findOrCreateNovel($intNSourceId, $strName);
} else {
throw $e;
}
}
}
return $arrNovelInfo;
}
/**
* 分析关联数据
*
* @return void
*/
public function getReletedNovel() {}
/**
* Undocumented function
*
* @return array
*/
public function getNovelInfo(): array
{
if (empty($this->arrNovelInfo)) {
# 获取head字段
$this->getQueryList()->find('meta[property]')->each(function ($Item) {
$strKey = str_replace(':', '_', $Item->attr('property'));
$this->arrNovelInfo[$strKey] = $Item->attr('content');
});
$this->getReletedNovel();
}
return $this->arrNovelInfo;
}
/**
* Undocumented function
*
* @param string $strName
* @return string
*/
public function generateCoverPath($strName): string
{
$intTime = time() - mt_rand(1, 2 * 24 * 3600 * 360);
return sprintf('/img/%s/%s.jpg', date('Y/m/d/H', $intTime), $strName);
}
public function filterOtherFields(&$arrNovel)
{
$arrFields = [
'n_id',
'n_name',
'n_name_pinyin',
'n_status',
'n_author',
'n_description',
'n_category',
'n_category_pinyin',
'n_category_sex_en',
'n_category_sex_zh',
'n_cover_path',
'n_latest_chapter_name',
'n_update_time',
'n_forge_novel',
'n_related_novel',
'n_site_code',
'n_source_uuid',
'n_source_id',
'n_have_chapter',
'created_at',
'updated_at',
];
foreach ($arrNovel as $strKey => $strVal) {
if (!in_array($strKey, $arrFields)) {
unset($arrNovel[$strKey]);
}
}
}
/**
* Undocumented function
*
* @return bool
*/
public function saveNovelInfo(): bool
{
$arrPageInfo = $this->getNovelInfo();
if (
empty($arrPageInfo) ||
empty($arrPageInfo['og_title']) ||
empty($arrPageInfo['og_image']) ||
empty($arrPageInfo['og_novel_category'])
) {
return false;
}
$arrNovelInfo = [
// 'n_id'=> $arrPageInfo['xxxxx'],
'n_name' => $arrPageInfo['og_title'],
'n_name_pinyin' => zhToPinYin($arrPageInfo['og_title']),
'n_status' => $arrPageInfo['og_novel_status'],
'n_author' => $arrPageInfo['og_novel_author'],
'n_description' => $arrPageInfo['og_description'],
'n_category' => $arrPageInfo['og_novel_category'],
// 'n_category_pinyin' => $arrPageInfo['xxxxx'],
// 'n_category_sex_en' => $arrPageInfo['xxxxx'],
// 'n_category_sex_zh' => $arrPageInfo['xxxxx'],
// 'n_cover_path' => $arrPageInfo['xxxxx'],
'n_latest_chapter_name' => $arrPageInfo['og_novel_latest_chapter_name'],
'n_update_time' => $arrPageInfo['og_novel_update_time'],
'n_forge_novel' => $this->arrForgeNovel,
'n_related_novel' => $this->arrRelatedNovel,
'n_site_code' => $this->getSite()->getSiteCode(),
'n_source_id' => $this->arrData['n_source_id'],
'n_source_uuid' => $this->getSite()->getSiteUUId($this->arrData['n_source_id']),
// 'n_have_chapter' => $arrPageInfo['xxxxx'],
// 'created_at' => $arrPageInfo['xxxxx'],
// 'updated_at' => $arrPageInfo['xxxxx'],
];
$arrExistsNovel = $this->getNovelModel()->findOne(['n_source_uuid' => $arrNovelInfo['n_source_uuid']], $this->arrOptions);
if ($arrExistsNovel) {
$arrExistsNovel = (array) $arrExistsNovel;
$arrUpdate = [
'n_latest_chapter_name' => $arrNovelInfo['n_latest_chapter_name'],
'n_update_time' => $arrNovelInfo['n_update_time'],
'updated_at' => new \MongoDB\BSON\UTCDateTime(),
];
# 如果没有分类说明这条数据是最初从关联shu那里采集的需要补全全部信息
if (empty($arrExistsNovel['n_category'])) {
$arrUpdate = array_merge($arrUpdate, $arrNovelInfo);
$arrUpdate['n_related_novel'] = $this->arrRelatedNovel;
$arrUpdate['n_forge_novel'] = $this->arrForgeNovel;
$arrUpdate['n_category_pinyin'] = CategoryModel::getPinYin($this->arrNovelInfo['og_novel_category']);
$arrUpdate['n_category_sex_en'] = CategoryModel::getSexEn($this->arrNovelInfo['og_novel_category']);
$arrUpdate['n_category_sex_zh'] = CategoryModel::getSexZh($this->arrNovelInfo['og_novel_category']);
$arrUpdate['n_related_novel'] = $this->arrRelatedNovel;
$arrUpdate['n_forge_novel'] = $this->arrForgeNovel;
}
# 图片不存在的时候,需要重新生成
if (
!isset($arrExistsNovel['n_cover_path']) ||
empty($arrExistsNovel['n_cover_path']) ||
!StorageCore::getInstance()->has($arrExistsNovel['n_cover_path']) ||
(basename($arrExistsNovel['n_cover_path']) == '.jpg')
) {
$arrUpdate['n_cover_path'] = $this->generateCoverPath($arrNovelInfo['n_name_pinyin']);
$this->strCoverLocalPath = $arrUpdate['n_cover_path'];
} else {
$this->strCoverLocalPath = $arrExistsNovel['n_cover_path'];
}
$this->getNovelModel()->updateOne(
['n_source_uuid' => $arrNovelInfo['n_source_uuid']],
['$set' => $arrUpdate],
);
$this->intNId = $arrExistsNovel['n_id'];
} else {
$arrNovelInfo['n_category_pinyin'] = CategoryModel::getPinYin($this->arrNovelInfo['og_novel_category']);
$arrNovelInfo['n_category_sex_en'] = CategoryModel::getSexEn($this->arrNovelInfo['og_novel_category']);
$arrNovelInfo['n_category_sex_zh'] = CategoryModel::getSexZh($this->arrNovelInfo['og_novel_category']);
$arrNovelInfo['n_id'] = CountersModel::getInstance()->getNextSequence('novel');
$arrNovelInfo['n_level'] = 1;
$arrNovelInfo['n_have_chapter'] = 0;
$arrNovelInfo['n_cover_path'] = $this->generateCoverPath($arrNovelInfo['n_name_pinyin']);
$arrNovelInfo['n_related_novel'] = $this->arrRelatedNovel;
$arrNovelInfo['n_forge_novel'] = $this->arrForgeNovel;
$arrNovelInfo['created_at'] = new \MongoDB\BSON\UTCDateTime();
try {
$this->getNovelModel()->insert($arrNovelInfo);
$this->intNId = $arrNovelInfo['n_id'];
$this->strCoverLocalPath = $arrNovelInfo['n_cover_path'];
} catch (\Exception $e) {
if ($e->getCode() === 11000) {
return $this->saveNovelInfo();
} else {
throw $e;
}
}
}
return true;
}
public $strCoverLocalPath = '';
public $intNId;
/**
* Undocumented function
*
* @return array
*/
public function getDownCoverInfo(): array
{
return [
'uri' => $this->arrNovelInfo['og_image'],
'local_path' => $this->strCoverLocalPath,
];
}
/**
* Undocumented variable
*
* @var array
*/
protected $arrLatestChapters = NULL;
/**
* Undocumented variable
*
* @var array
*/
protected $arrChapters = NULL;
public function getLatestChapterByNIdsList(): array
{
if ($this->arrLatestChapters === NULL) {
$this->arrLatestChapters = [];
if ($this->isMobile()) {
$strClass = '.chapter-list';
} else {
$strClass = '.section-list';
}
if ($this->arrData['page'] == 0) {
$this->getQueryList()->find($strClass)->eq(0)->find("a")->map(function ($A) {
$this->arrLatestChapters[] = [
'name' => $A->text(),
'uri' => $A->attr('href'),
];
});
}
}
return $this->arrLatestChapters;
}
/**
* Undocumented function
*
* @return array
*/
public function getChapters(): array
{
if ($this->arrChapters === NULL) {
$this->arrChapters = [];
if ($this->isMobile()) {
$strClass = '.chapter-list';
} else {
$strClass = '.section-list';
}
$intDivIndex = 0;
if ($this->arrData['page'] == 0) {
$intDivIndex = 1;
}
$this->getQueryList()->find($strClass)->eq($intDivIndex)->find("a")->map(function ($A) {
$this->arrChapters[] = [
'name' => $A->text(),
'uri' => $A->attr('href'),
];
});
}
return $this->arrChapters;
}
protected $arrNextPageArgs = NULL;
/**
* Undocumented function
*
* @return array
*/
public function getNextPageArgs(): array
{
$this->arrNextPageArgs = [];
if ($this->arrData['page'] == 0) {
$this->getLatestChapterByNIdsList();
$this->getChapters();
$arrLatestChapterFirstBlock = count($this->arrLatestChapters) > 0 ? $this->arrLatestChapters[0] : null;
$arrLatestChapterSecondBlock = count($this->arrChapters) > 0 ? $this->arrChapters[count($this->arrChapters) - 1] : null;
if (
!empty($arrLatestChapterFirstBlock) && !empty($arrLatestChapterSecondBlock)
&& ($arrLatestChapterFirstBlock['uri'] != $arrLatestChapterSecondBlock['uri'])
) {
$this->arrNextPageArgs = [
'n_source_id' => $this->arrData['n_source_id'],
'page' => $this->arrData['page'] + 1,
];
}
} else {
$strLastUri = $this->getQueryList()->find('select:first option:last')->attr('value');
if ($strLastUri != '' && $strLastUri != $this->strUri) {
$this->arrNextPageArgs = [
'n_source_id' => $this->arrData['n_source_id'],
'page' => $this->arrData['page'] + 1,
];
}
}
return $this->arrNextPageArgs;
}
}

View File

@@ -0,0 +1,347 @@
<?php
declare(strict_types=1);
namespace app\task\crawler\zw\page;
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
use storage\StorageCore;
/**
* @mixin think\Model
*/
class Site
{
/**
* Undocumented variable
*
* @var Client
*/
protected $Client;
/**
* Undocumented variable
*
* @var string
*/
protected $strDomain = '';
/**
* Undocumented variable
*
* @var string
*/
protected $strSiteCode = '';
/**
* Undocumented function
*/
public function __construct()
{
$this->initClient();
}
/**
* Undocumented function
*/
public function initClient()
{
$arrConfig = [
'http_version' => '1.1', // 强制用 HTTP/1.1,已有,保持
'base_uri' => $this->strDomain, // 基础域名,已有,保持
'http_errors' => false, // 不抛 HTTP 错误,已有,保持
'timeout' => 60, // 从 160 秒改为 60 秒
'connect_timeout' => 10, // 从 30 秒改为 10 秒
'curl' => [
CURLOPT_TCP_KEEPALIVE => 1, // 启用 TCP Keep-Alive已有保持
CURLOPT_TCP_KEEPIDLE => 120, // Keep-Alive 空闲时间
CURLOPT_TCP_KEEPINTVL => 60, // Keep-Alive 探测间隔
// CURLOPT_SSL_VERIFYPEER => true, // 验证 SSL已有保持
],
'headers' => [
'User-Agent' => 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36',
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Language' => 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Referer' => $this->strDomain,
'Connection' => 'keep-alive',
'sec-ch-ua' => '"Not/A)Brand";v="8", "Chromium";v="130", "Google Chrome";v="130"',
'sec-ch-ua-mobile' => '?1',
'sec-ch-ua-platform' => '"Android"',
'sec-fetch-dest' => 'document',
'sec-fetch-mode' => 'navigate',
'sec-fetch-site' => 'same-origin',
'sec-fetch-user' => '?1',
'upgrade-insecure-requests' => '1',
],
'pool_size' => 10,
'verify' => false,
];
$arrProxy = config('proxy');
if ($arrProxy['proxy_status']) {
$strCode = $arrProxy['proxy_code'];
$strProxyHost = $arrProxy['proxy_host'];
$strKey = $arrProxy['proxy_key'];
$strSecret = $arrProxy['proxy_secret'];
switch ($strCode) {
case 'XIONGMAO':
$intTime = time();
$strTxt = "orderno=" . $strKey . ",secret=" . $strSecret . ",timestamp=" . $intTime;
$strSign = strtoupper(md5($strTxt));
$strAuth = 'sign=' . $strSign . '&orderno=' . $strKey . '&timestamp=' . $intTime;
$arrConfig['proxy'] = $strProxyHost;
$arrConfig['headers']['Proxy-Authorization'] = $strAuth;
break;
case 'KUAI':
$arrConfig['proxy'] = $strProxyHost;
$arrConfig['curl'][CURLOPT_PROXYAUTH] = CURLAUTH_BASIC;
$arrConfig['curl'][CURLOPT_PROXYUSERPWD] = "$strKey:$strSecret";
break;
}
}
$this->Client = new Client($arrConfig);
}
/**
* Undocumented function
*
* @return string
*/
public function getSiteCode(): string
{
return $this->strSiteCode;
}
/**
* Undocumented function
*
* @param integer|string $strSign
* @return string
*/
public function getSiteUUId(int|string $strSign): string
{
return $this->getSiteCode() . '-' . $strSign;
}
/**
* Undocumented function
*
* @return Client
*/
public function getClient(): Client
{
return $this->Client;
}
public function getNovelPageUri($intNSourceId, $intPage): string
{
$intUriFirst = intdiv($intNSourceId, 1000);
$strUri = '';
if ($intPage == 0) {
$strUri = sprintf('/%s/%s/', $intUriFirst, $intNSourceId);
} else {
$strUri = sprintf('/book/%s/list%s.html', $intNSourceId, $intPage);
}
return $strUri;
}
/**
* retrieve multiple novel page model
*
* @param string $strUri
* @return NovelPage[]
*/
public function getNovelPageList(array $arrFilter): array
{
/** @var NovelPage[] */
$arrNovelPage = [];
foreach ($arrFilter as $intKey => $arrItem) {
$arrFilter[$intKey]['uri'] = $this->getNovelPageUri($arrItem['n_source_id'], $arrItem['page']);
$arrPromises[$intKey] = $this->getClient()->getAsync($arrFilter[$intKey]['uri']);
}
$arrResults = Promise\Utils::settle($arrPromises)->wait();
$arrSuccessfulResults = array_filter($arrResults, function ($arrResult) {
return $arrResult['state'] === 'fulfilled';
});
foreach ($arrSuccessfulResults as $intKey => $arrResult) {
$Response = $arrResult['value'];
$strContent = $Response->getBody()->getContents();
if ($strContent == '索引文件不存在!') {
continue;
}
$NovelPage = $this->getNovelPage($this, $arrFilter[$intKey]['uri']);
$NovelPage->setContent($strContent);
$NovelPage->setData($arrFilter[$intKey]);
$arrNovelPage[] = $NovelPage;
}
return $arrNovelPage;
}
/**
* retrieve multiple chapter page model
*
* @param string $strUri
* @return ChapterPage[]
*/
public function getChapterPageList(array $arrFilter): array
{
/** @var ChapterPage[] */
$arrChapterPage = [];
$arrPromises = [];
foreach ($arrFilter as $intKey => $arrItem) {
$arrPromises[$intKey] = $this->getClient()->getAsync($arrItem['uri']);
}
$arrResults = Promise\Utils::settle($arrPromises)->wait();
$arrSuccessfulResults = array_filter($arrResults, function ($arrResult) {
return $arrResult['state'] === 'fulfilled';
});
foreach ($arrSuccessfulResults as $intKey => $arrResult) {
$Response = $arrResult['value'];
$strContent = $Response->getBody()->getContents();;
$ChapterPage = $this->getChapterPage($this, $arrFilter[$intKey]['uri']);
$ChapterPage->setContent($strContent);
$ChapterPage->setData($arrFilter[$intKey]);
$arrChapterPage[] = $ChapterPage;
}
return $arrChapterPage;
}
/**
* retrieve multiple chapter page model
*
* @param string $strUri
* @return LatestListPage[]
*/
public function getLatestListPageList(array $arrFilter): array
{
/** @var LatestListPage[] */
$arrLatestListPage = [];
$arrPromises = [];
foreach ($arrFilter as $intKey => $strUri) {
$arrPromises[$intKey] = $this->getClient()->getAsync($strUri);
}
$arrResults = Promise\Utils::settle($arrPromises)->wait();
$arrSuccessfulResults = array_filter($arrResults, function ($arrResult) {
return $arrResult['state'] === 'fulfilled';
});
foreach ($arrSuccessfulResults as $intKey => $arrResult) {
$Response = $arrResult['value'];
$strContent = $Response->getBody()->getContents();;
$LatestListPage = $this->getLatestListPage($this, $arrFilter[$intKey]);
$LatestListPage->setContent($strContent);
$arrLatestListPage[] = $LatestListPage;
}
return $arrLatestListPage;
}
/**
* download the image to the local system
*
* @param array $arrFilter
* @return void
*/
public function downRemoteImgToLocal(array $arrFilter)
{
$StorageCore = StorageCore::getInstance();
$arrPromises = [];
foreach ($arrFilter as $intKey => $arrItem) {
if (!$StorageCore->has($arrItem['local_path'])) {
$arrPromises[$intKey] = $this->getClient()->getAsync($arrItem['uri']);
}
}
$arrResults = Promise\Utils::settle($arrPromises)->wait();
$arrSuccessfulResults = array_filter($arrResults, function ($arrResult) {
return $arrResult['state'] === 'fulfilled';
});
foreach ($arrSuccessfulResults as $intKey => $arrResult) {
$Response = $arrResult['value'];
$StorageCore->writeStream($arrFilter[$intKey]['local_path'], $Response->getBody()->detach());;
}
}
/**
* Undocumented function
*
* @param object $Site
* @param string $strUri
* @return NovelPage
*/
public function getNovelPage($Site, $strUri)
{
return new NovelPage($Site, $strUri);
}
/**
* Undocumented function
*
* @param object $Site
* @param string $strUri
* @return ChapterPage
*/
public function getChapterPage($Site, $strUri)
{
return new ChapterPage($Site, $strUri);
}
/**
* Undocumented function
*
* @param object $Site
* @param string $strUri
* @return LatestListPage
*/
public function getLatestListPage($Site, $strUri)
{
return new LatestListPage($Site, $strUri);
}
}

View File

@@ -4,278 +4,34 @@ declare(strict_types=1);
namespace app\task\crawler\zw630; namespace app\task\crawler\zw630;
use app\model\ChapterModel;
use app\task\crawler\zw630\page\NovelPage;
use app\task\crawler\zw630\page\Site; use app\task\crawler\zw630\page\Site;
use microserver\QueueManage; use app\task\crawler\zw\Scheduler as ZwScheduler;
use storage\StorageCore;
/** /**
* @mixin think\Model * @mixin think\Model
*/ */
class Scheduler class Scheduler extends ZwScheduler
{ {
static $intSlice = 3;
/** /**
* Undocumented variable * Undocumented function
*
* @var \microserver\QueueManage
*/
protected $QueueManage = NULL;
public function __construct()
{
$this->QueueManage = new QueueManage();
}
/**
* create a site-wide craw task
* *
* @return void * @return void
*/ */
public function crawlFull() public function init()
{ {
$intSliceSize = self::$intSlice; $this->intSlice = 8;
$arrFilter = [];
for ($intNId = 1; $intNId <= 531208; $intNId++) {
// for ($intNId = 1; $intNId <= 10000; $intNId++) {
// for ($intNId = 1; $intNId <= 1; $intNId++) {
$arrFilter[] = [
'n_source_id' => $intNId,
'page' => 0,
];
if ($intNId % $intSliceSize == 0) {
$this->fetchNovel($arrFilter);
$arrFilter = [];
}
}
if (!empty($arrFilter)) {
$this->fetchNovel($arrFilter);
}
}
/**
* create a task to craw the latest chapter
*
* @return void
*/
public function crawLatest()
{
$intSliceSize = self::$intSlice;
$arrUri = [];
$strUri = '/list/lastupdate_%s_0_0_%s.html';
$intEndCategory = $intEndPage = 10;
for ($intCategoryKey = 0; $intCategoryKey < $intEndCategory; $intCategoryKey++) {
for ($intPage = 1; $intPage <= $intEndPage; $intPage++) {
$arrUri[] = sprintf($strUri, $intCategoryKey, $intPage);
}
}
$arrUri = array_chunk($arrUri, $intSliceSize);
$arrTask = [
'callback' => [self::class, 'getLatestChapter'],
'data' => [],
];
foreach ($arrUri as $arrUriSlice) {
$arrTask['data'] = $arrUriSlice;
$this->QueueManage->set($arrTask);
}
} }
/** /**
* Undocumented function * Undocumented function
* *
* @param array $arrData * @return Site
* @return void
*/ */
public function getLatestChapter(array $arrFilter) public function getSite()
{ {
$Site = new Site; if ($this->Site == NULL) {
$this->Site = new Site;
$arrLatestListPageList = $Site->getLatestListPageList($arrFilter);
$arrNSourceId = [];
foreach ($arrLatestListPageList as $LatestListPage) {
$arrResult = $LatestListPage->getNovelFilter();
$arrNSourceId = array_merge($arrNSourceId, $arrResult);
}
$arrNSourceId = array_unique($arrNSourceId);
$arrNSourceId = array_values($arrNSourceId);
$intSliceSize = self::$intSlice;
$arrFilter = [];
foreach ($arrNSourceId as $intKey => $intNSourceId) {
$arrFilter[] = [
'n_source_id' => $intNSourceId,
'page' => 0,
];
if ($intKey % $intSliceSize == 0) {
$this->fetchNovel($arrFilter);
$arrFilter = [];
}
}
if (!empty($arrFilter)) {
$this->fetchNovel($arrFilter);
}
}
/**
* Undocumented function
*
* @param array $arrFilter
* @return void
*/
public function fetchNovel(array $arrFilter)
{
$arrTask = [
'callback' => [self::class, 'getNovelInfo'],
'data' => $arrFilter,
];
$this->QueueManage->set($arrTask);
}
/**
* Undocumented function
*
* @param integer $intNId
* @param integer $intPage
* @param array $arrChapterList
* @return void
*/
public function fetchChapter(int $intNId, int $intPage, array $arrChapterList = [])
{
$intSliceSize = self::$intSlice;
$intPageSize = 100;
$arrTask = [
'callback' => [self::class, 'getChapterInfo'],
'data' => [
'n_id' => $intNId,
]
];
$arrFilter = [];
foreach ($arrChapterList as $intKey => $arrChapter) {
$arrChapter['c_sort_num'] = $intPage * $intPageSize + $intKey + 1;
$arrChapter['c_source_id'] = supperExtractFilename($arrChapter['uri']);
$arrChapter['c_page'] = 0;
$arrFilter[] = $arrChapter;
if ($intKey % $intSliceSize == 0) {
$arrTask['data']['filter'] = $arrFilter;
$this->QueueManage->set($arrTask);
$arrFilter = [];
}
}
if (!empty($arrFilter)) {
$arrTask['data']['filter'] = $arrFilter;
$this->QueueManage->set($arrTask);
}
}
/**
* Undocumented function
*
* @param array $arrFilter
* @return void
*/
public function getNovelInfo(array $arrFilter)
{
$Site = new Site;
$arrNovelPageList = $Site->getNovelPageList($arrFilter);
$arrCover = [];
foreach ($arrNovelPageList as $NovelPage) {
$arrNovel = $NovelPage->getNovelInfo();
if (empty($arrNovel)) {
continue;
}
$arrNextPageData = $NovelPage->getNextPageArgs();
if (!empty($arrNextPageData)) {
$this->fetchNovel([
[
'n_source_id' => $arrNextPageData['n_source_id'],
'page' => $arrNextPageData['page'],
]
]);
}
$arrCoverItem = $NovelPage->getDownCoverInfo();
if (!StorageCore::getInstance()->has($arrCoverItem['local_path'])) {
$arrCover[] = $arrCoverItem;
}
$arrChapterList = $NovelPage->getChapters();
$this->fetchChapter($arrNovel['n_id'], $NovelPage->getData()['page'], $arrChapterList);
}
if ($arrCover) {
$Site->downRemoteImgToLocal($arrCover);
}
}
/**
* Undocumented function
*
* @param array $arrData
* @return void
*/
public function getChapterInfo(array $arrData)
{
$Site = new Site;
$ChapterModel = ChapterModel::getInstance();
foreach ($arrData['filter'] as $intKey => $arrChapterFilter) {
$strUUId = sprintf('%s-chapter-%s-%s', $Site->getSiteCode(), $arrChapterFilter['c_source_id'], $arrChapterFilter['c_page']);
$arrChapter = $ChapterModel->findOne(['c_site_uuid' => $strUUId]);
if (!empty($arrChapter) && !empty($arrChapter['content'])) {
unset($arrData['filter'][$intKey]);
}
}
$arrData['filter'] = array_values($arrData['filter']);
$arrChapterPageList = $Site->getChapterPageList($arrData['filter']);
$arrNextPageFilterList = [];
foreach ($arrChapterPageList as $ChapterPage) {
$ChapterPage->saveChapter($arrData['n_id']);
$arrNextPageFilter = $ChapterPage->getNextPage();
if (!empty($arrNextPageFilter)) {
$arrNextPageFilterList[] = $arrNextPageFilter;
}
}
if (!empty($arrNextPageFilterList)) {
$arrTask = $arrData;
$arrTask['filter'] = $arrNextPageFilterList;
$arrTask = [
'callback' => [self::class, 'getChapterInfo'],
'data' => $arrTask
];
$this->QueueManage->set($arrTask);
} }
return $this->Site;
} }
} }

View File

@@ -4,214 +4,6 @@ declare(strict_types=1);
namespace app\task\crawler\zw630\page; namespace app\task\crawler\zw630\page;
use app\model\ChapterModel; use app\task\crawler\zw\page\ChapterPage as ZwChapterPage;
use storage\StorageCore;
class ChapterPage extends BasePage class ChapterPage extends ZwChapterPage {}
{
/**
* Undocumented variable
*
* @var string
*/
protected $strChapterContent = '';
/**
* Undocumented variable
*
* @var ChapterModel
*/
protected $ChapterModel;
/**
* Undocumented function
*
* @return ChapterModel
*/
public function getChapterModel(): ChapterModel
{
if ($this->ChapterModel == NULL) {
$this->ChapterModel = ChapterModel::getInstance();
}
return $this->ChapterModel;
}
static public $arrOptions = [
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array',
],
];
/**
* Undocumented function
*
* @return array
*/
public function getChapterInfo(): array
{
if ($this->arrChapterInfo === NULL) {
$this->arrChapterInfo = [];
$strPattern = "/qsbs\.bb\('([^']*)'\)/";
preg_match_all($strPattern, $this->getContent(), $arrMatches);
$strContent = '';
foreach ($arrMatches[1] as $str) {
$strContent .= base64_decode($str);
}
$this->strChapterContent = $strContent;
$this->arrChapterInfo['c_page_title'] = $this->getQueryList()->find('title')->text();
$this->arrChapterInfo['c_page_keywords'] = $this->getQueryList()->find('meta[name="keywords"]')->attr('content');
$this->arrChapterInfo['c_page_description'] = $this->getQueryList()->find('meta[name="description"]')->attr('content');
}
return $this->arrChapterInfo;
}
/**
* Undocumented variable
*
* @var array
*/
protected $arrChapterInfo;
public function filterOtherFields(&$arrChapter)
{
$arrFields = [
'n_id',
'name',
'c_sort_num',
'c_page',
'c_source_id',
'c_site_code',
'c_site_uuid',
'c_content_path',
'created_at',
'updated_at',
];
foreach ($arrChapter as $strKey => $strVal) {
if (!in_array($strKey, $arrFields)) {
unset($arrChapter[$strKey]);
}
}
}
public function saveChapter(int $intNId): array
{
try {
$this->getChapterInfo();
$strUUId = $this->getSite()->getSiteUUId('chapter-' . $this->arrData['c_source_id'] . '-' . $this->arrData['c_page']);
$arrExisting = $this->getChapterModel()->findOne(['c_site_uuid' => $strUUId], self::$arrOptions);
if ($arrExisting) {
$arrExisting = (array) $arrExisting;
$this->arrChapterInfo = array_merge($arrExisting, $this->getChapterInfo());
$this->arrChapterInfo['updated_at'] = new \MongoDB\BSON\UTCDateTime();
$arrUpdate = $this->arrChapterInfo;
$this->filterOtherFields($arrUpdate);
$this->getChapterModel()->updateOne(
['c_site_uuid' => $strUUId],
['$set' => $arrUpdate],
);
} else {
$this->arrChapterInfo['n_id'] = $intNId;
$this->arrChapterInfo['name'] = $this->arrData['name'];
$this->arrChapterInfo['c_sort_num'] = $this->arrData['c_sort_num'];
$this->arrChapterInfo['c_page'] = $this->arrData['c_page'];
$this->arrChapterInfo['c_source_id'] = $this->arrData['c_source_id'];
$this->arrChapterInfo['c_site_code'] = $this->getSite()->getSiteCode();
$this->arrChapterInfo['c_site_uuid'] = $strUUId;
$this->arrChapterInfo['c_content_path'] = '/novel/' . ($intNId % 100) . '/' . $intNId . '/' . $this->arrChapterInfo['c_sort_num'] . '_' . $this->arrChapterInfo['c_page'] . '.txt';
$this->arrChapterInfo['created_at'] = new \MongoDB\BSON\UTCDateTime();
$arrInsert = $this->arrChapterInfo;
$this->filterOtherFields($arrInsert);
$this->getChapterModel()->insert($arrInsert);
$this->updateNovelHaveChapter($intNId);
}
if (mb_strlen($this->strChapterContent) > 20) {
if (!StorageCore::getInstance()->has($this->arrChapterInfo['c_content_path'])) {
StorageCore::getInstance()->set($this->arrChapterInfo['c_content_path'], $this->strChapterContent);
}
}
return $this->arrChapterInfo;
} catch (\Exception $e) {
throw new \Exception("Upsert failed: " . $e->getMessage());
}
}
/**
* Undocumented function
*
* @param integer $intNId
* @return void
*/
protected function updateNovelHaveChapter(int $intNId)
{
$arrFilter = [
'n_id' => $intNId,
];
$ChapterModel = ChapterModel::getInstance();
$arrLasteChapter = $ChapterModel->getLatestChapterByNId($intNId, false);
if (!empty($arrLasteChapter)) {
$arrUpdate['$set']['n_have_chapter'] = 1;
$arrUpdate['$set']['og_novel_latest_chapter_name'] = $arrLasteChapter['name'];
$this->getMongoBase()->updateOne('novel', $arrFilter, $arrUpdate);
}
}
protected $arrNextPage;
/**
* Undocumented function
*
* @return array
*/
public function getNextPage(): array
{
if ($this->arrNextPage === NULL) {
$this->arrNextPage = [];
if ($this->isMobile()) {
$strPattern = "/var\s+hhekgsv\s*=\s*['\"](.*?)['\"]/";
preg_match_all($strPattern, $this->getContent(), $arrMatches);
$strNextPageUri = end($arrMatches[1]) ?: '';
} else {
$strHref = $this->getQueryList()->find('.read_btn a:contains("下一章")')->attr('href');
$strNextPageUri = $strHref ?: '';
}
if (is_numeric(strpos($strNextPageUri, '_'))) {
$this->arrNextPage = $this->arrData;
$this->arrNextPage['c_page'] += 1;
$this->arrNextPage['uri'] = $strNextPageUri;
}
}
return $this->arrNextPage;
}
}

View File

@@ -4,63 +4,8 @@ declare(strict_types=1);
namespace app\task\crawler\zw630\page; namespace app\task\crawler\zw630\page;
use app\model\CategoryModel;
use app\model\CountersModel;
use app\model\NovelModel; use app\model\NovelModel;
use app\task\crawler\zw\page\LatestListPage as ZwLatestListPage;
class LatestListPage extends ZwLatestListPage {}
class LatestListPage extends BasePage
{
/**
* Undocumented variable
*
* @var NovelModel
*/
protected $NovelModel;
/**
* Undocumented function
*
* @return NovelModel
*/
public function getNovelModel(): NovelModel
{
if ($this->NovelModel == NULL) {
$this->NovelModel = NovelModel::getInstance();
}
return $this->NovelModel;
}
static public $arrOptions = [
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array',
],
];
/**
* Undocumented function
*
* @return array
*/
public function getNovelFilter(): array
{
$arrFilter = [];
if ($this->isMobile()) {
$arrFilter = $this->getQueryList()->find('div.wrap-box')->eq(0)->find('ul.sort_list li')->map(function ($li) {
$strUri = $li->find('a')->eq(0)->attr('href');
return supperExtractFilename($strUri);
})->filter()->all();
} else {
$arrFilter = $this->getQueryList()->find('div.layout.layout2.layout-col2.fl ul.txt-list li')->map(function ($li) {
$strUri = $li->find('a')->eq(0)->attr('href');
return supperExtractFilename($strUri);
})->filter()->all();
}
return $arrFilter;
}
}

View File

@@ -4,120 +4,31 @@ declare(strict_types=1);
namespace app\task\crawler\zw630\page; namespace app\task\crawler\zw630\page;
use app\model\CategoryModel;
use app\model\CountersModel;
use app\model\NovelModel;
class NovelPage extends BasePage use app\task\crawler\zw\page\NovelPage as ZwNovelPage;
class NovelPage extends ZwNovelPage
{ {
/** /**
* Undocumented variable * 分析关联数据
* *
* @var array * @return void
*/ */
protected $arrNovelInfo = []; public function getReletedNovel()
/**
* Undocumented variable
*
* @var array
*/
protected $arrRelatedNovel = [];
/**
* Undocumented variable
*
* @var array
*/
protected $arrForgeNovel = [];
/**
* Undocumented variable
*
* @var NovelModel
*/
protected $NovelModel;
/**
* Undocumented function
*
* @return NovelModel
*/
public function getNovelModel(): NovelModel
{ {
if ($this->NovelModel == NULL) { if (empty($this->arrRelatedNovel) || empty($this->arrForgeNovel)) {
$this->NovelModel = NovelModel::getInstance();
}
return $this->NovelModel;
}
static public $arrOptions = [
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array',
],
];
/**
* 查询看的小说
*
* @param integer $intNSourceId
* @param string $strName
* @return array
*/
private function findOrCreateNovel(int $intNSourceId, string $strName): array
{
$strUUId = $this->getSite()->getSiteUUId($intNSourceId);
$arrExisting = $this->getNovelModel()->findOne(['n_site_uuid' => $strUUId], self::$arrOptions);
if ($arrExisting) {
$arrNovelInfo = (array) $arrExisting;
} else {
$arrNovelInfo = [
'og_novel_book_name' => $strName,
'og_novel_pin_yin' => zhToPinYin($strName),
'n_site_code' => $this->getSite()->getSiteCode(),
'n_site_uuid' => $strUUId,
'n_source_id' => $intNSourceId,
'n_level' => 1,
'n_have_chapter' => 0,
'n_id' => CountersModel::getInstance()->getNextSequence('novel'),
];
$this->getNovelModel()->insert($arrNovelInfo);
}
return $arrNovelInfo;
}
/**
* Undocumented function
*
* @return array
*/
public function getNovelInfo($boolSave = true): array
{
if (empty($this->arrNovelInfo)) {
# 获取head字段
$this->getQueryList()->find('meta[property]')->each(function ($Item) {
$strKey = str_replace(':', '_', $Item->attr('property'));
$this->arrNovelInfo[$strKey] = $Item->attr('content');
});
# 获取 kan 和 shu 的关联数据
$this->getQueryList()->find('.first_txt')->eq(0)->find("a")->map(function ($A) { $this->getQueryList()->find('.first_txt')->eq(0)->find("a")->map(function ($A) {
$strName = $A->text(); $strName = $A->text();
$strUri = $A->attr('href'); $strUri = $A->attr('href');
if (is_numeric(strpos($strUri, 'shu'))) { if (is_numeric(strpos($strUri, 'shu'))) {
$intNSourceId = (int)supperExtractFilename($strUri); $intNSourceId = (int)supperExtractFilename($strUri);
$arrNovelInfo = $this->findOrCreateNovel($intNSourceId, $strName); $arrNovelInfo = $this->findOrCreateNovel($intNSourceId, $strName);
$this->arrRelatedNovel[] = [ $this->arrRelatedNovel[] = [
"n_id" => $arrNovelInfo["n_id"], "n_id" => $arrNovelInfo["n_id"],
"n_source_id" => $arrNovelInfo["n_source_id"], "n_source_id" => $arrNovelInfo["n_source_id"],
"og_novel_book_name" => $arrNovelInfo["og_novel_book_name"], "n_name" => $arrNovelInfo["n_name"],
]; ];
} elseif (is_numeric(strpos($strUri, 'kan'))) { } elseif (is_numeric(strpos($strUri, 'kan'))) {
$intNForgeId = (int)supperExtractFilename($strUri); $intNForgeId = (int)supperExtractFilename($strUri);
@@ -127,244 +38,6 @@ class NovelPage extends BasePage
]; ];
} }
}); });
$this->arrNovelInfo['n_related_novel'] = $this->arrRelatedNovel;
$this->arrNovelInfo['n_forge_novel'] = $this->arrForgeNovel;
$this->arrNovelInfo['og_novel_pin_yin'] = zhToPinYin($this->arrNovelInfo['og_novel_book_name'] ?? '');
if (!empty($this->arrNovelInfo['og_novel_category'])) {
$this->arrNovelInfo['category_pinyin'] = CategoryModel::getPinYinByZh($this->arrNovelInfo['og_novel_category']);
$this->arrNovelInfo['category_sex'] = CategoryModel::checkSex($this->arrNovelInfo['og_novel_category']);
$this->arrNovelInfo['category_sex_zh'] = CategoryModel::checkSexZh($this->arrNovelInfo['og_novel_category']);
}
$this->arrNovelInfo['n_site_code'] = $this->getSite()->getSiteCode();
$this->arrNovelInfo['n_source_id'] = $this->arrData['n_source_id'];
} }
if ($boolSave && !empty($this->arrNovelInfo)) {
$this->saveNovelInfo();
}
return $this->arrNovelInfo;
}
/**
* Undocumented function
*
* @param string $strName
* @return string
*/
public function generateCoverPath($strName): string
{
return sprintf('/img/%s/%s.jpg', date('Y/m/d', time() - 24 * 3600 * 14), $strName);
}
public function filterOtherFields(&$arrNovel)
{
$arrFields = [
'n_id',
'og_novel_book_name',
'og_novel_pin_yin',
'og_novel_status',
'og_novel_author',
'og_description',
'og_novel_category',
'category_pinyin',
'category_sex',
'category_sex_zh',
'n_cover_path',
'og_novel_latest_chapter_name',
'og_novel_update_time',
'n_forge_novel',
'n_related_novel',
'og_site_code',
'n_site_uuid',
'n_source_id',
'n_have_chapter',
'created_at',
'updated_at',
];
foreach ($arrNovel as $strKey => $strVal) {
if (!in_array($strKey, $arrFields)) {
unset($arrNovel[$strKey]);
}
}
}
/**
* Undocumented function
*
* @return void
*/
public function saveNovelInfo()
{
try {
$strUUId = $this->getSite()->getSiteUUId($this->arrData['n_source_id']);
$arrExisting = $this->getNovelModel()->findOne(['n_site_uuid' => $strUUId], self::$arrOptions);
if ($arrExisting) {
$arrExisting = (array) $arrExisting;
$this->arrNovelInfo = array_merge($arrExisting, $this->arrNovelInfo);
if (
!isset($this->arrNovelInfo['n_cover_path']) ||
empty($this->arrNovelInfo['n_cover_path']) ||
!file_exists($this->arrNovelInfo['n_cover_path']) ||
(basename($this->arrNovelInfo['n_cover_path']) == '.jpg')
) {
$this->arrNovelInfo['n_cover_path'] = $this->generateCoverPath($this->arrNovelInfo['og_novel_pin_yin']);
}
$this->arrNovelInfo['updated_at'] = new \MongoDB\BSON\UTCDateTime();
$arrUpdate = $this->arrNovelInfo;
$this->filterOtherFields($arrUpdate);
$this->getNovelModel()->updateOne(
['n_site_uuid' => $strUUId],
['$set' => $arrUpdate],
);
} else {
$this->arrNovelInfo['n_site_uuid'] = $strUUId;
$this->arrNovelInfo['n_id'] = CountersModel::getInstance()->getNextSequence('novel');
$this->arrNovelInfo['n_level'] = 1;
$this->arrNovelInfo['n_have_chapter'] = 0;
$this->arrNovelInfo['n_cover_path'] = $this->generateCoverPath($this->arrNovelInfo['og_novel_pin_yin']);
$arrInsert = $this->arrNovelInfo;
$this->filterOtherFields($arrInsert);
$this->getNovelModel()->insert($arrInsert);
}
return $this->arrNovelInfo;
} catch (\Exception $e) {
throw new \Exception("Upsert failed: " . $e->getMessage());
}
}
/**
* Undocumented function
*
* @return array
*/
public function getDownCoverInfo(): array
{
return [
'uri' => $this->arrNovelInfo['og_image'],
'local_path' => $this->arrNovelInfo['n_cover_path'],
];
}
/**
* Undocumented variable
*
* @var array
*/
protected $arrLatestChapters = NULL;
/**
* Undocumented variable
*
* @var array
*/
protected $arrChapters = NULL;
public function getLatestChapterByNIdsList(): array
{
if ($this->arrLatestChapters === NULL) {
$this->arrLatestChapters = [];
if ($this->isMobile()) {
$strClass = '.chapter-list';
} else {
$strClass = '.section-list';
}
if ($this->arrData['page'] == 0) {
$this->getQueryList()->find($strClass)->eq(0)->find("a")->map(function ($A) {
$this->arrLatestChapters[] = [
'name' => $A->text(),
'uri' => $A->attr('href'),
];
});
}
}
return $this->arrLatestChapters;
}
/**
* Undocumented function
*
* @return array
*/
public function getChapters(): array
{
if ($this->arrChapters === NULL) {
$this->arrChapters = [];
if ($this->isMobile()) {
$strClass = '.chapter-list';
} else {
$strClass = '.section-list';
}
$intDivIndex = 0;
if ($this->arrData['page'] == 0) {
$intDivIndex = 1;
}
$this->getQueryList()->find($strClass)->eq($intDivIndex)->find("a")->map(function ($A) {
$this->arrChapters[] = [
'name' => $A->text(),
'uri' => $A->attr('href'),
];
});
}
return $this->arrChapters;
}
protected $arrNextPageArgs = NULL;
/**
* Undocumented function
*
* @return array
*/
public function getNextPageArgs(): array
{
$this->arrNextPageArgs = [];
if ($this->arrData['page'] == 0) {
$this->getLatestChapterByNIdsList();
$this->getChapters();
$arrLatestChapterFirstBlock = count($this->arrLatestChapters) > 0 ? $this->arrLatestChapters[0] : null;
$arrLatestChapterSecondBlock = count($this->arrChapters) > 0 ? $this->arrChapters[count($this->arrChapters) - 1] : null;
if (
!empty($arrLatestChapterFirstBlock) && !empty($arrLatestChapterSecondBlock)
&& ($arrLatestChapterFirstBlock['uri'] != $arrLatestChapterSecondBlock['uri'])
) {
$this->arrNextPageArgs = [
'n_source_id' => $this->arrData['n_source_id'],
'page' => $this->arrData['page'] + 1,
];
}
} else {
$strLastUri = $this->getQueryList()->find('select:first option:last')->attr('value');
if ($strLastUri != '' && $strLastUri != $this->strUri) {
$this->arrNextPageArgs = [
'n_source_id' => $this->arrData['n_source_id'],
'page' => $this->arrData['page'] + 1,
];
}
}
return $this->arrNextPageArgs;
} }
} }

View File

@@ -4,22 +4,14 @@ declare(strict_types=1);
namespace app\task\crawler\zw630\page; namespace app\task\crawler\zw630\page;
use GuzzleHttp\Client; use app\task\crawler\zw\page\Site as ZwSite;
use GuzzleHttp\Promise; use GuzzleHttp\Promise;
use storage\StorageCore; use GuzzleHttp\Client;
/** /**
* @mixin think\Model * @mixin think\Model
*/ */
class Site class Site extends ZwSite
{ {
/**
* Undocumented variable
*
* @var Client
*/
private $Client;
/** /**
* Undocumented variable * Undocumented variable
* *
@@ -27,33 +19,17 @@ class Site
*/ */
protected $strDomain = 'https://www.630zw.com'; protected $strDomain = 'https://www.630zw.com';
/**
* Undocumented variable
*
* @var string
*/
protected $strSiteCode = 'zw630'; protected $strSiteCode = 'zw630';
/** /**
* Undocumented function * Undocumented function
*
* @return string
*/ */
public function getSiteCode(): string public function initClient()
{
return $this->strSiteCode;
}
/**
* Undocumented function
*
* @param integer|string $strSign
* @return string
*/
public function getSiteUUId(int|string $strSign): string
{
return $this->getSiteCode() . '-' . $strSign;
}
/**
* Undocumented function
*/
public function __construct()
{ {
$arrConfig = [ $arrConfig = [
'http_version' => '1.1', // 强制用 HTTP/1.1,已有,保持 'http_version' => '1.1', // 强制用 HTTP/1.1,已有,保持
@@ -82,208 +58,90 @@ class Site
'sec-fetch-user' => '?1', 'sec-fetch-user' => '?1',
'upgrade-insecure-requests' => '1', 'upgrade-insecure-requests' => '1',
], ],
'pool_size' => 5, 'pool_size' => 10,
'verify' => false, 'verify' => false,
]; ];
$arrProxy = config('proxy'); $arrProxy = config('proxy');
if ($arrProxy['proxy_status']) { if ($arrProxy['proxy_status']) {
$intTime = time();
$strOrderNo = $arrProxy['proxy_order']; $strCode = $arrProxy['proxy_code'];
$strProxyHost = $arrProxy['proxy_host'];
$strKey = $arrProxy['proxy_key'];
$strSecret = $arrProxy['proxy_secret']; $strSecret = $arrProxy['proxy_secret'];
$strTxt = "orderno=" . $strOrderNo . ",secret=" . $strSecret . ",timestamp=" . $intTime;
$strSign = strtoupper(md5($strTxt));
$strAuth = 'sign=' . $strSign . '&orderno=' . $strOrderNo . '&timestamp=' . $intTime;
$arrConfig['proxy'] = 'http://dtbf.xiongmaodaili.com:8089'; switch ($strCode) {
$arrConfig['headers']['Proxy-Authorization'] = $strAuth; case 'XIONGMAO':
$intTime = time();
$strTxt = "orderno=" . $strKey . ",secret=" . $strSecret . ",timestamp=" . $intTime;
$strSign = strtoupper(md5($strTxt));
$strAuth = 'sign=' . $strSign . '&orderno=' . $strKey . '&timestamp=' . $intTime;
$arrConfig['proxy'] = $strProxyHost;
$arrConfig['headers']['Proxy-Authorization'] = $strAuth;
break;
case 'KUAI':
$arrConfig['proxy'] = $strProxyHost;
$arrConfig['curl'][CURLOPT_PROXYAUTH] = CURLAUTH_BASIC;
$arrConfig['curl'][CURLOPT_PROXYUSERPWD] = "$strKey:$strSecret";
break;
}
} }
$this->Client = new Client($arrConfig); $this->Client = new Client($arrConfig);
} }
public function getNovelPageUri($intNSourceId, $intPage): string
{
$strUri = '';
if ($intPage == 0) {
$arrItem['uri'] = sprintf('/shu/%s.html', $intNSourceId);
} else {
$arrItem['uri'] = sprintf('/shu/%s_%s.html', $intNSourceId, $intPage);
}
return $strUri;
}
/** /**
* Undocumented function * Undocumented function
* *
* @return Client * @param object $Site
*/
public function getClient(): Client
{
return $this->Client;
}
/**
* retrieve novel page model
*
* @param string $strUri * @param string $strUri
* @return NovelPage * @return NovelPage
*/ */
public function getNovelPage(string $strUri): NovelPage public function getNovelPage($Site, $strUri)
{ {
return new NovelPage($this, $strUri); return new NovelPage($Site, $strUri);
} }
/** /**
* retrieve multiple novel page model * Undocumented function
* *
* @param object $Site
* @param string $strUri * @param string $strUri
* @return NovelPage[] * @return ChapterPage
*/ */
public function getNovelPageList(array $arrFilter): array public function getChapterPage($Site, $strUri)
{ {
return new ChapterPage($Site, $strUri);
/** @var NovelPage[] */
$arrNovelPage = [];
foreach ($arrFilter as $intKey => $arrItem) {
if ($arrItem['page'] == 0) {
$arrItem['uri'] = sprintf('/shu/%s.html', $arrItem['n_source_id']);
} else {
$arrItem['uri'] = sprintf('/shu/%s_%s.html', $arrItem['n_source_id'], $arrItem['page']);
}
$arrFilter[$intKey]['uri'] = $arrItem['uri'];
$arrPromises[$intKey] = $this->getClient()->getAsync($arrItem['uri']);
}
$arrResults = Promise\Utils::settle($arrPromises)->wait();
$arrSuccessfulResults = array_filter($arrResults, function ($arrResult) {
return $arrResult['state'] === 'fulfilled';
});
foreach ($arrSuccessfulResults as $intKey => $arrResult) {
$Response = $arrResult['value'];
$strContent = $Response->getBody()->getContents();
if ($strContent == '索引文件不存在!') {
continue;
}
$NovelPage = new NovelPage($this, $arrFilter[$intKey]['uri']);
$NovelPage->setContent($strContent);
$NovelPage->setData($arrFilter[$intKey]);
$arrNovelPage[] = $NovelPage;
}
return $arrNovelPage;
} }
/** /**
* retrieve multiple chapter page model * Undocumented function
* *
* @param object $Site
* @param string $strUri * @param string $strUri
* @return ChapterPage[] * @return LatestListPage
*/ */
public function getChapterPageList(array $arrFilter): array public function getLatestListPage($Site, $strUri)
{ {
return new LatestListPage($Site, $strUri);
/** @var ChapterPage[] */
$arrChapterPage = [];
$arrPromises = [];
foreach ($arrFilter as $intKey => $arrItem) {
$arrPromises[$intKey] = $this->getClient()->getAsync($arrItem['uri']);
}
$arrResults = Promise\Utils::settle($arrPromises)->wait();
$arrSuccessfulResults = array_filter($arrResults, function ($arrResult) {
return $arrResult['state'] === 'fulfilled';
});
foreach ($arrSuccessfulResults as $intKey => $arrResult) {
$Response = $arrResult['value'];
$strContent = $Response->getBody()->getContents();;
$ChapterPage = new ChapterPage($this, $arrFilter[$intKey]['uri']);
$ChapterPage->setContent($strContent);
$ChapterPage->setData($arrFilter[$intKey]);
$arrChapterPage[] = $ChapterPage;
}
return $arrChapterPage;
}
/**
* retrieve multiple chapter page model
*
* @param string $strUri
* @return LatestListPage[]
*/
public function getLatestListPageList(array $arrFilter): array
{
/** @var LatestListPage[] */
$arrLatestListPage = [];
$arrPromises = [];
foreach ($arrFilter as $intKey => $strUri) {
$arrPromises[$intKey] = $this->getClient()->getAsync($strUri);
}
$arrResults = Promise\Utils::settle($arrPromises)->wait();
$arrSuccessfulResults = array_filter($arrResults, function ($arrResult) {
return $arrResult['state'] === 'fulfilled';
});
foreach ($arrSuccessfulResults as $intKey => $arrResult) {
$Response = $arrResult['value'];
$strContent = $Response->getBody()->getContents();;
$LatestListPage = new LatestListPage($this, $arrFilter[$intKey]);
$LatestListPage->setContent($strContent);
$arrLatestListPage[] = $LatestListPage;
}
return $arrLatestListPage;
}
/**
* download the image to the local system
*
* @param array $arrFilter
* @return void
*/
public function downRemoteImgToLocal(array $arrFilter)
{
$StorageCore = StorageCore::getInstance();
$arrPromises = [];
foreach ($arrFilter as $intKey => $arrItem) {
if (!$StorageCore->has($arrItem['local_path'])) {
$arrPromises[$intKey] = $this->getClient()->getAsync($arrItem['uri']);
}
}
$arrResults = Promise\Utils::settle($arrPromises)->wait();
$arrSuccessfulResults = array_filter($arrResults, function ($arrResult) {
return $arrResult['state'] === 'fulfilled';
});
foreach ($arrSuccessfulResults as $intKey => $arrResult) {
$Response = $arrResult['value'];
$StorageCore->writeStream($arrFilter[$intKey]['local_path'], $Response->getBody()->detach());;
}
} }
} }

View File

@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace app\task\crawler\zw74;
use app\task\crawler\zw74\page\Site;
use app\task\crawler\zw\Scheduler as ZwScheduler;
/**
* @mixin think\Model
*/
class Scheduler extends ZwScheduler
{
/**
* Undocumented function
*
* @return void
*/
public function init()
{
$this->intSlice = 8;
}
/**
* Undocumented function
*
* @return Site
*/
public function getSite()
{
if ($this->Site == NULL) {
$this->Site = new Site;
}
return $this->Site;
}
}

View File

@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);
namespace app\task\crawler\zw74\page;
use app\task\crawler\zw\page\ChapterPage as ZwChapterPage;
class ChapterPage extends ZwChapterPage {}

View File

@@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace app\task\crawler\zw74\page;
use app\model\NovelModel;
use app\task\crawler\zw\page\LatestListPage as ZwLatestListPage;
class LatestListPage extends ZwLatestListPage {}

View File

@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace app\task\crawler\zw74\page;
use app\task\crawler\zw\page\NovelPage as ZwNovelPage;
class NovelPage extends ZwNovelPage
{
/**
* 分析关联数据
*
* @return void
*/
public function getReletedNovel()
{
if (empty($this->arrRelatedNovel) || empty($this->arrForgeNovel)) {
$this->getQueryList()->find('.first_txt')->eq(0)->find("a")->map(function ($A) {
$strName = $A->text();
$strUri = $A->attr('href');
if (is_numeric(strpos($strUri, 'http'))) {
return;
}
$strPattern = '#^/\d+/(\d+)/$#';
if (is_numeric(strpos($strUri, 'info'))) {
$intNForgeId = (int)supperExtractFilename($strUri);
$this->arrForgeNovel[] = [
"n_forge_id" => $intNForgeId,
"n_forge_title" => $strName,
];
} elseif (preg_match($strPattern, $strUri, $arrMatches)) {
$intNSourceId = (int)$arrMatches[1];
$arrNovelInfo = $this->findOrCreateNovel($intNSourceId, $strName);
$this->arrRelatedNovel[] = [
"n_id" => $arrNovelInfo["n_id"],
"n_source_id" => $arrNovelInfo["n_source_id"],
"n_name" => $arrNovelInfo["n_name"],
];
}
});
}
}
}

View File

@@ -0,0 +1,152 @@
<?php
declare(strict_types=1);
namespace app\task\crawler\zw74\page;
use app\task\crawler\zw\page\Site as ZwSite;
use GuzzleHttp\Client;
/**
* @mixin think\Model
*/
class Site extends ZwSite
{
/**
* Undocumented variable
*
* @var string
*/
protected $strDomain = 'https://www.74zw.cc';
/**
* Undocumented variable
*
* @var string
*/
protected $strSiteCode = 'zw';
/**
* Undocumented function
*/
public function initClient()
{
$arrConfig = [
'http_version' => '1.1', // 强制用 HTTP/1.1,已有,保持
'base_uri' => $this->strDomain, // 基础域名,已有,保持
'http_errors' => false, // 不抛 HTTP 错误,已有,保持
'timeout' => 60, // 从 160 秒改为 60 秒
'connect_timeout' => 10, // 从 30 秒改为 10 秒
'curl' => [
CURLOPT_TCP_KEEPALIVE => 1, // 启用 TCP Keep-Alive已有保持
CURLOPT_TCP_KEEPIDLE => 120, // Keep-Alive 空闲时间
CURLOPT_TCP_KEEPINTVL => 60, // Keep-Alive 探测间隔
// CURLOPT_SSL_VERIFYPEER => true, // 验证 SSL已有保持
],
'headers' => [
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0',
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Accept-Language' => 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'Referer' => $this->strDomain,
'Connection' => 'keep-alive',
'sec-ch-ua' => '"Microsoft Edge";v="135", "Not-A.Brand";v="8", "Chromium";v="135"',
'sec-ch-ua-mobile' => '?0',
'sec-ch-ua-platform' => '"Windows"',
'sec-fetch-dest' => 'document',
'sec-fetch-mode' => 'navigate',
'sec-fetch-site' => 'same-origin',
'sec-fetch-user' => '?1',
'upgrade-insecure-requests' => '1',
],
'pool_size' => 10,
'verify' => false,
];
$arrProxy = config('proxy');
if ($arrProxy['proxy_status']) {
$strCode = $arrProxy['proxy_code'];
$strProxyHost = $arrProxy['proxy_host'];
$strKey = $arrProxy['proxy_key'];
$strSecret = $arrProxy['proxy_secret'];
switch ($strCode) {
case 'XIONGMAO':
$intTime = time();
$strTxt = "orderno=" . $strKey . ",secret=" . $strSecret . ",timestamp=" . $intTime;
$strSign = strtoupper(md5($strTxt));
$strAuth = 'sign=' . $strSign . '&orderno=' . $strKey . '&timestamp=' . $intTime;
$arrConfig['proxy'] = $strProxyHost;
$arrConfig['headers']['Proxy-Authorization'] = $strAuth;
break;
case 'KUAI':
$arrConfig['proxy'] = $strProxyHost;
$arrConfig['curl'][CURLOPT_PROXYAUTH] = CURLAUTH_BASIC;
$arrConfig['curl'][CURLOPT_PROXYUSERPWD] = "$strKey:$strSecret";
break;
}
}
$this->Client = new Client($arrConfig);
}
/**
* Undocumented function
*
* @param int $intNSourceId
* @param int $intPage
* @return string
*/
public function getNovelPageUri($intNSourceId, $intPage): string
{
$intUriFirst = intdiv($intNSourceId, 1000);
$strUri = '';
if ($intPage == 0) {
$strUri = sprintf('/%s/%s/', $intUriFirst, $intNSourceId);
} else {
$strUri = sprintf('/book/%s/list%s.html', $intNSourceId, $intPage);
}
return $strUri;
}
/**
* Undocumented function
*
* @param object $Site
* @param string $strUri
* @return NovelPage
*/
public function getNovelPage($Site, $strUri)
{
return new NovelPage($Site, $strUri);
}
/**
* Undocumented function
*
* @param object $Site
* @param string $strUri
* @return ChapterPage
*/
public function getChapterPage($Site, $strUri)
{
return new ChapterPage($Site, $strUri);
}
/**
* Undocumented function
*
* @param object $Site
* @param string $strUri
* @return LatestListPage
*/
public function getLatestListPage($Site, $strUri)
{
return new LatestListPage($Site, $strUri);
}
}

View File

@@ -6,6 +6,7 @@ namespace app\task\module;
use app\model\PlanTaskModel; use app\model\PlanTaskModel;
use app\task\crawler\zw630\Scheduler as Zw630Scheduler; use app\task\crawler\zw630\Scheduler as Zw630Scheduler;
use app\task\crawler\zw74\Scheduler as Zw74Scheduler;
use microserver\QueueManage; use microserver\QueueManage;
use microserver\ProcessSanitizer; use microserver\ProcessSanitizer;
@@ -34,6 +35,13 @@ class PlanTask
case 'PULL_630_ZW_NOVEL_LATEST': case 'PULL_630_ZW_NOVEL_LATEST':
self::pull630ZwNovelLatest(); self::pull630ZwNovelLatest();
break; break;
case 'PULL_74_ZW_NOVEL':
self::pull74ZwNovel();
break;
case 'PULL_74_ZW_NOVEL_LATEST':
self::pull74ZwNovelLatest();
break;
default: default:
break; break;
} }
@@ -71,4 +79,37 @@ class PlanTask
$QueueManage = new QueueManage(); $QueueManage = new QueueManage();
$QueueManage->set($arrTask); $QueueManage->set($arrTask);
} }
/**
* Undocumented function
*
* @return void
*/
public static function pull74ZwNovel()
{
$arrTask = [
'callback' => [Zw74Scheduler::class, 'crawlFull'],
'data' => []
];
$QueueManage = new QueueManage();
$QueueManage->set($arrTask);
}
/**
* Undocumented function
*
* @return void
*/
public static function pull74ZwNovelLatest()
{
$arrTask = [
'callback' => [Zw74Scheduler::class, 'crawLatest'],
'data' => []
];
$QueueManage = new QueueManage();
$QueueManage->set($arrTask);
}
} }

View File

@@ -34,13 +34,13 @@
"aws/aws-sdk-php": "^3.337", "aws/aws-sdk-php": "^3.337",
"league/flysystem": "^1.1", "league/flysystem": "^1.1",
"league/flysystem-aws-s3-v3": "^1.0", "league/flysystem-aws-s3-v3": "^1.0",
"mongodb/mongodb": "^1.21",
"topthink/think-throttle": "^2.0", "topthink/think-throttle": "^2.0",
"phpoffice/phpspreadsheet": "^4.1" "phpoffice/phpspreadsheet": "^4.1"
}, },
"require-dev": { "require-dev": {
"topthink/think-dumper": "^1.0", "topthink/think-dumper": "^1.0",
"topthink/think-trace": "^1.0" "topthink/think-trace": "^1.0",
"mongodb/mongodb": "^1.21"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {

154
code/composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "feae02549eadbd38bfb677ca95107ab0", "content-hash": "b478b1d55a2646f40e59782fcccfd100",
"packages": [ "packages": [
{ {
"name": "aws/aws-crt-php", "name": "aws/aws-crt-php",
@@ -1231,82 +1231,6 @@
}, },
"time": "2022-12-02T22:17:43+00:00" "time": "2022-12-02T22:17:43+00:00"
}, },
{
"name": "mongodb/mongodb",
"version": "1.21.1",
"source": {
"type": "git",
"url": "https://github.com/mongodb/mongo-php-library.git",
"reference": "37bc8df3a67ddf8380704a5ba5dbd00e92ec1f6a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/37bc8df3a67ddf8380704a5ba5dbd00e92ec1f6a",
"reference": "37bc8df3a67ddf8380704a5ba5dbd00e92ec1f6a",
"shasum": ""
},
"require": {
"composer-runtime-api": "^2.0",
"ext-mongodb": "^1.21.0",
"php": "^8.1",
"psr/log": "^1.1.4|^2|^3"
},
"replace": {
"mongodb/builder": "*"
},
"require-dev": {
"doctrine/coding-standard": "^12.0",
"phpunit/phpunit": "^10.5.35",
"rector/rector": "^1.2",
"squizlabs/php_codesniffer": "^3.7",
"vimeo/psalm": "6.5.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"files": [
"src/functions.php"
],
"psr-4": {
"MongoDB\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Andreas Braun",
"email": "andreas.braun@mongodb.com"
},
{
"name": "Jeremy Mikola",
"email": "jmikola@gmail.com"
},
{
"name": "Jérôme Tamarelle",
"email": "jerome.tamarelle@mongodb.com"
}
],
"description": "MongoDB driver library",
"homepage": "https://jira.mongodb.org/browse/PHPLIB",
"keywords": [
"database",
"driver",
"mongodb",
"persistence"
],
"support": {
"issues": "https://github.com/mongodb/mongo-php-library/issues",
"source": "https://github.com/mongodb/mongo-php-library/tree/1.21.1"
},
"time": "2025-02-28T17:24:20+00:00"
},
{ {
"name": "mtdowling/jmespath.php", "name": "mtdowling/jmespath.php",
"version": "2.8.0", "version": "2.8.0",
@@ -3000,6 +2924,82 @@
} }
], ],
"packages-dev": [ "packages-dev": [
{
"name": "mongodb/mongodb",
"version": "1.21.1",
"source": {
"type": "git",
"url": "https://github.com/mongodb/mongo-php-library.git",
"reference": "37bc8df3a67ddf8380704a5ba5dbd00e92ec1f6a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mongodb/mongo-php-library/zipball/37bc8df3a67ddf8380704a5ba5dbd00e92ec1f6a",
"reference": "37bc8df3a67ddf8380704a5ba5dbd00e92ec1f6a",
"shasum": ""
},
"require": {
"composer-runtime-api": "^2.0",
"ext-mongodb": "^1.21.0",
"php": "^8.1",
"psr/log": "^1.1.4|^2|^3"
},
"replace": {
"mongodb/builder": "*"
},
"require-dev": {
"doctrine/coding-standard": "^12.0",
"phpunit/phpunit": "^10.5.35",
"rector/rector": "^1.2",
"squizlabs/php_codesniffer": "^3.7",
"vimeo/psalm": "6.5.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"files": [
"src/functions.php"
],
"psr-4": {
"MongoDB\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Andreas Braun",
"email": "andreas.braun@mongodb.com"
},
{
"name": "Jeremy Mikola",
"email": "jmikola@gmail.com"
},
{
"name": "Jérôme Tamarelle",
"email": "jerome.tamarelle@mongodb.com"
}
],
"description": "MongoDB driver library",
"homepage": "https://jira.mongodb.org/browse/PHPLIB",
"keywords": [
"database",
"driver",
"mongodb",
"persistence"
],
"support": {
"issues": "https://github.com/mongodb/mongo-php-library/issues",
"source": "https://github.com/mongodb/mongo-php-library/tree/1.21.1"
},
"time": "2025-02-28T17:24:20+00:00"
},
{ {
"name": "topthink/think-dumper", "name": "topthink/think-dumper",
"version": "v1.0.4", "version": "v1.0.4",

View File

@@ -6,6 +6,7 @@
return [ return [
'proxy_status' => env('PROXY_STATUS', false), 'proxy_status' => env('PROXY_STATUS', false),
'proxy_code' => env('PROXY_CODE', ''), 'proxy_code' => env('PROXY_CODE', ''),
'proxy_order' => env('PROXY_ORDER', ''), 'proxy_host' => env('PROXY_HOST', ''),
'proxy_key' => env('PROXY_KEY', ''),
'proxy_secret' => env('PROXY_SECRET', ''), 'proxy_secret' => env('PROXY_SECRET', ''),
]; ];

View File

@@ -3,7 +3,7 @@ return [
'collection' => 'chapter', 'collection' => 'chapter',
'indexes' => [ 'indexes' => [
[ [
'key' => ['c_site_uuid' => 1], 'key' => ['c_source_uuid' => 1],
'options' => ['unique' => true] 'options' => ['unique' => true]
], ],

View File

@@ -4,18 +4,22 @@ return [
'indexes' => [ 'indexes' => [
[ [
'key' => ['n_id' => 1], 'key' => ['n_id' => 1],
'options' => ['unique' => true]
],
[
'key' => ['n_name' => 1],
'options' => ['unique' => false] 'options' => ['unique' => false]
], ],
[ [
'key' => ['og_novel_book_name' => 1], 'key' => ['n_category' => 1],
'options' => ['unique' => false] 'options' => ['unique' => false]
], ],
[ [
'key' => ['og_novel_status' => 1], 'key' => ['n_status' => 1],
'options' => ['unique' => false] 'options' => ['unique' => false]
], ],
[ [
'key' => ['n_site_uuid' => 1], 'key' => ['n_source_uuid' => 1],
'options' => ['unique' => true] 'options' => ['unique' => true]
], ],
[ [

View File

@@ -20,13 +20,28 @@ class PlanTaskSeeder
[ [
'pt_name' => '630小说全量扫描', 'pt_name' => '630小说全量扫描',
'pt_code' => 'PULL_630_ZW_NOVEL', 'pt_code' => 'PULL_630_ZW_NOVEL',
'pt_enable' => 1, 'pt_enable' => 0,
'pt_limit' => 10 * 24 * 3600 * 3, 'pt_limit' => 10 * 24 * 3600 * 3,
], ],
[ [
'pt_name' => '630小说每日增量', 'pt_name' => '630小说每日增量',
'pt_code' => 'PULL_630_ZW_NOVEL_LATEST', 'pt_code' => 'PULL_630_ZW_NOVEL_LATEST',
'pt_enable' => 1, 'pt_enable' => 0,
'pt_limit' => 1 * 24 * 3600,
],
[
'pt_name' => '74小说全量扫描',
'pt_code' => 'PULL_74_ZW_NOVEL',
'pt_enable' => 0,
'pt_limit' => 10 * 24 * 3600 * 3,
],
[
'pt_name' => '74小说每日增量',
'pt_code' => 'PULL_74_ZW_NOVEL_LATEST',
'pt_enable' => 0,
'pt_limit' => 1 * 24 * 3600, 'pt_limit' => 1 * 24 * 3600,
], ],
]; ];

View File

@@ -76,17 +76,17 @@ class NovelManage extends Command
foreach ($arrDocs as $arrDoc) { foreach ($arrDocs as $arrDoc) {
$arrUpdateData = []; $arrUpdateData = [];
if (!empty($arrDoc['og_novel_category'])) { if (!empty($arrDoc['n_category'])) {
$arrUpdateData['category_pinyin'] = CategoryModel::getPinYinByZh($arrDoc['og_novel_category']); $arrUpdateData['n_category_pinyin'] = CategoryModel::getPinYin($arrDoc['n_category']);
$arrUpdateData['category_sex'] = CategoryModel::checkSex($arrDoc['og_novel_category']); $arrUpdateData['n_category_sex_en'] = CategoryModel::getSexEn($arrDoc['n_category']);
$arrUpdateData['category_sex_zh'] = CategoryModel::checkSexZh($arrDoc['og_novel_category']); $arrUpdateData['n_category_sex_zh'] = CategoryModel::getSexZh($arrDoc['n_category']);
} }
$arrLasteChapter = $ChapterModel->getLatestChapterByNId($arrDoc['n_id'], false); $arrLasteChapter = $ChapterModel->getLatestChapterByNId($arrDoc['n_id'], false);
if (!empty($arrLasteChapter)) { if (!empty($arrLasteChapter)) {
$arrUpdateData['n_have_chapter'] = 1; $arrUpdateData['n_have_chapter'] = 1;
$arrUpdateData['og_novel_latest_chapter_name'] = $arrLasteChapter['name']; $arrUpdateData['n_latest_chapter_name'] = $arrLasteChapter['name'];
} }
if (!empty($arrUpdateData)) { if (!empty($arrUpdateData)) {

View File

@@ -61,6 +61,12 @@ class StorageCore
$this->Filesystem->writeStream($strPath, $Resource); $this->Filesystem->writeStream($strPath, $Resource);
} }
public function put($strKey, $strContent, array $arrConfig = [])
{
$strContent = zstd_compress($strContent);
return $this->Filesystem->put($strKey, $strContent, $arrConfig);
}
public function write($strKey, $strContent, array $arrConfig = []) public function write($strKey, $strContent, array $arrConfig = [])
{ {
$strContent = zstd_compress($strContent); $strContent = zstd_compress($strContent);
@@ -75,10 +81,14 @@ class StorageCore
public function read($strKey) public function read($strKey)
{ {
$Stream = $this->Filesystem->readStream($strKey); try {
$strContent = stream_get_contents($Stream); $Stream = $this->Filesystem->readStream($strKey);
$strContent = zstd_uncompress($strContent); $strContent = stream_get_contents($Stream);
return $strContent; $strContent = zstd_uncompress($strContent);
return $strContent;
} catch (\Exception $e) {
return '';
}
} }
public function has($strKey) public function has($strKey)

View File

@@ -3,15 +3,15 @@
```javascript ```javascript
use novel use novel
db.dropDatabase("novel") db.dropDatabase("novel")
use novel use novel
db.novel.createIndex({ "n_id": 1 }) db.novel.createIndex({ "n_id": 1 })
db.novel.createIndex({ "og_title": 1 }) db.novel.createIndex({ "og_title": 1 })
db.novel.createIndex({ "og_novel_status": 1 }) db.novel.createIndex({ "og_novel_status": 1 })
db.novel.createIndex({ "n_site_uuid": 1 }, { unique: true }) db.novel.createIndex({ "n_site_uuid": 1 }, { unique: true })
db.novel.createIndex({"n_related_novel.n_id": 1}) db.novel.createIndex({"n_related_novel.n_id": 1})
db.novel.createIndex({"n_forge_novel.n_forge_id": 1}) db.novel.createIndex({"n_forge_novel.n_forge_id": 1})
// db.novel.createIndex({ "og_novel_update_time": 1 }) // db.novel.createIndex({ "og_novel_update_time": 1 })
// { // {