debug
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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([
|
||||||
|
|||||||
@@ -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']],
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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>
|
<a href="/">{$vo.n_name}</a>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
<a href="/sitemap_index.xml">XML地图</a>
|
<a href="/sitemap_index.xml">XML地图</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -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>
|
<a href='{$strPcPath}{site:nurl n_id="$Novel->n_id" n_py="$Novel->n_name_pinyin"/}'>{$Novel.n_name}</a>
|
||||||
{/foreach}
|
{/foreach}
|
||||||
<a href="/sitemap_index.xml">XML地图</a>
|
<a href="/sitemap_index.xml">XML地图</a>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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' : `第一章`,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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}",
|
||||||
|
|||||||
@@ -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' : `第一章`,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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': `第一章`,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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}",
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
27
code/app/home/view/kuangYu/pc/public/shukuNovelList.html
Normal file
27
code/app/home/view/kuangYu/pc/public/shukuNovelList.html
Normal 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>
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -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) ? '男生' : '女生';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 = [
|
||||||
|
|||||||
319
code/app/task/crawler/zw/Scheduler.php
Normal file
319
code/app/task/crawler/zw/Scheduler.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
|
||||||
226
code/app/task/crawler/zw/page/ChapterPage.php
Normal file
226
code/app/task/crawler/zw/page/ChapterPage.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
64
code/app/task/crawler/zw/page/LatestListPage.php
Normal file
64
code/app/task/crawler/zw/page/LatestListPage.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
418
code/app/task/crawler/zw/page/NovelPage.php
Normal file
418
code/app/task/crawler/zw/page/NovelPage.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
347
code/app/task/crawler/zw/page/Site.php
Normal file
347
code/app/task/crawler/zw/page/Site.php
Normal 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 . '×tamp=' . $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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 . '×tamp=' . $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 . '×tamp=' . $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());;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
37
code/app/task/crawler/zw74/Scheduler.php
Normal file
37
code/app/task/crawler/zw74/Scheduler.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
9
code/app/task/crawler/zw74/page/ChapterPage.php
Normal file
9
code/app/task/crawler/zw74/page/ChapterPage.php
Normal 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 {}
|
||||||
10
code/app/task/crawler/zw74/page/LatestListPage.php
Normal file
10
code/app/task/crawler/zw74/page/LatestListPage.php
Normal 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 {}
|
||||||
48
code/app/task/crawler/zw74/page/NovelPage.php
Normal file
48
code/app/task/crawler/zw74/page/NovelPage.php
Normal 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"],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
152
code/app/task/crawler/zw74/page/Site.php
Normal file
152
code/app/task/crawler/zw74/page/Site.php
Normal 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 . '×tamp=' . $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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
154
code/composer.lock
generated
@@ -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",
|
||||||
|
|||||||
@@ -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', ''),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -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]
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|||||||
@@ -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]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -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,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -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)) {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 })
|
||||||
|
|
||||||
// {
|
// {
|
||||||
|
|||||||
Reference in New Issue
Block a user