This commit is contained in:
make
2025-04-21 17:49:17 +08:00
parent 7ef217c1b9
commit 2337ab4f7d
942 changed files with 209166 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
<?php
declare (strict_types = 1);
namespace app\model;
use think\Model;
/**
* @mixin think\Model
*/
class AdminNodeModel extends BaseModel
{
protected $name = 'admin_node';
protected $pk = 'an_id';
}

View File

@@ -0,0 +1,47 @@
<?php
declare (strict_types = 1);
namespace app\model;
use think\Model;
use think\facade\Cache;
/**
* @mixin think\Model
*/
class AdminRoleModel extends BaseModel
{
protected $name = 'admin_role';
protected $pk = 'ar_id';
public function getRoleNodeByCache($intArId)
{
$strCacheKey = 'Admin:Role:Node:'.$intArId;
$arrRoleNode = Cache::get($strCacheKey);
if($arrRoleNode === NULL)
{
$AdminRoleNodeModel = new AdminRoleNodeModel();
$AdminRoleNodeModel = $AdminRoleNodeModel->alias('arn')
->field('an.an_url')
->leftjoin('admin_node an','an.an_id=arn.an_id');
if($intArId>0)
{
$AdminRoleNodeModel = $AdminRoleNodeModel->where('arn.ar_id',$intArId);
}
$arrRoleNode = $AdminRoleNodeModel
->select()
->toArray();
$arrRoleNode = array_column($arrRoleNode, 'an_url');
// Cache::set($strCacheKey,$arrRoleNode);
}
return $arrRoleNode;
}
}

View File

@@ -0,0 +1,15 @@
<?php
declare (strict_types = 1);
namespace app\model;
use think\Model;
/**
* @mixin think\Model
*/
class AdminRoleNodeModel extends BaseModel
{
protected $name = 'admin_role_node';
protected $pk = 'arn_id';
}

View File

@@ -0,0 +1,92 @@
<?php
declare(strict_types=1);
namespace app\model;
use think\facade\Cache;
use think\Model;
use think\helper\Str;
/**
* @mixin think\Model
*/
class AdminUserModel extends BaseModel
{
protected $name = 'admin_user';
protected $pk = 'au_id';
protected $token = "";
// protected $hidden = ['au_pwd'];
/**
* Undocumented function
*
* @param string $strToken
* @return AdminUserModel|NULL
*/
static public function getUserByToken($strToken = "")
{
if ($strToken == "") {
return NULL;
}
$strKey = "AdminToken:" . $strToken;
$intAuId = Cache::get($strKey);
if (empty($intAuId)) {
return NULL;
}
$AdminUserModel = self::getAdminUserModelByCache($intAuId);
$AdminUserModel->token = $strToken;
$AdminUserModel->refreshToken();
return $AdminUserModel;
}
public function checkRole()
{
return true;
}
public function createToken()
{
$this->token = Str::random(32);
$this->refreshToken();
return $this->token;
}
public function refreshToken()
{
Cache::set("AdminToken:" . $this->token, $this->au_id, 3600);
}
static public function getAdminUserModelByCache($intAuId, $boolForceUpdate = false)
{
$strKey = "AdminUser:Id:" . $intAuId;
$AdminUserModel = Cache::get($strKey);
if (empty($AdminUserModel) || $boolForceUpdate == true) {
$AdminUserModel = self::where('au_id', $intAuId)->find();
if (empty($AdminUserModel)) {
throw new \Exception("用户不存在", 9999);
}
$AdminUserModel->au_pwd = "";
Cache::set($strKey, $AdminUserModel);
}
return $AdminUserModel;
}
}

View File

@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace app\model;
use think\facade\Cache;
use think\Model;
/**
* @mixin think\Model
*/
class BaseModel extends Model
{
public function fill($arrData)
{
foreach ($arrData as $strKey => $strVal) {
$this->$strKey = $strVal;
}
}
}

View File

@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace app\model;
use think\facade\Cache;
use think\Model;
/**
* @mixin think\Model
*/
class CaiJiPeiZhiModel extends BaseModel
{
protected $name = 'cai_ji_pei_zhi';
protected $pk = 'cjpz_id';
static $arrCaiJiPeiZhi = [];
static public function getValByCode($strCode)
{
if (self::$arrCaiJiPeiZhi == []) {
self::$arrCaiJiPeiZhi = Cache::get('CaiJiPeiZhi');
if (empty(self::$arrCaiJiPeiZhi)) {
self::flushCache();
self::$arrCaiJiPeiZhi = Cache::get('CaiJiPeiZhi');
}
}
return self::$arrCaiJiPeiZhi[$strCode] ?? NULL;
}
static public function flushCache()
{
$arrCaiJiPeiZhi = self::column('cjpz_val', 'cjpz_code');
Cache::tag('CaiJiPeiZhi')->set('CaiJiPeiZhi', $arrCaiJiPeiZhi);
}
}

View File

@@ -0,0 +1,202 @@
<?php
declare(strict_types=1);
namespace app\model;
use DateTime;
use think\facade\Cache;
use think\Model;
/**
* @mixin think\Model
*/
class CategoryModel extends MongoModel
{
protected $strCollection = 'category';
/**
* Undocumented variable
*
* @var CategoryModel
*/
static public $CategoryModel;
static public function getInstance(): self
{
if (self::$CategoryModel == NULL) {
self::$CategoryModel = new self;
}
return self::$CategoryModel;
}
static $arrCategory = [
1 => '玄幻修真',
2 => '军史小说',
3 => '网游小说',
4 => '科幻小说',
5 => '重生穿越',
6 => '都市小说',
7 => '灵异小说',
8 => '言情小说',
9 => '其他小说',
];
static $arrCategoryAll = [
'man' => [
'xuanhuan-xiuzhen' => '玄幻修真',
'junshi-xiaoshuo' => '军史小说',
'wangyou-xiaoshuo' => '网游小说',
'kehuan-xiaoshuo' => '科幻小说',
],
'women' => [
'zhongsheng-chuanyue' => '重生穿越',
'dushi-xiaoshuo' => '都市小说',
'lingyi-xiaoshuo' => '灵异小说',
'yanqing-xiaoshuo' => '言情小说',
'qita-xiaoshuo' => '其他小说',
]
];
static $arrCategoryPinYin = [
1 => 'xuanhuan-xiuzhen', // 玄幻-修真
2 => 'junshi-xiaoshuo', // 军史-小说
3 => 'wangyou-xiaoshuo', // 网游-小说
4 => 'kehuan-xiaoshuo', // 科幻-小说
5 => 'zhongsheng-chuanyue', // 重生-穿越
6 => 'dushi-xiaoshuo', // 都市-小说
7 => 'lingyi-xiaoshuo', // 灵异-小说
8 => 'yanqing-xiaoshuo', // 言情-小说
9 => 'qita-xiaoshuo', // 其他-小说
];
static $arrMan = [
1 => '玄幻修真',
2 => '军史小说',
3 => '网游小说',
4 => '科幻小说',
];
static $arrWomen = [
5 => '重生穿越',
6 => '都市小说',
7 => '灵异小说',
8 => '言情小说',
9 => '其他小说',
];
/**
* get category of the novels
*
* @return array
*/
static public function getCategory(): array
{
return self::$arrCategory;
}
/**
* Undocumented function
*
* @param integer $intType
* @param boolean $boolOnlyValue
* @return array
*/
static public function getCategoryByType(int $intType, bool $boolOnlyValue = true): array
{
$arrCategory = [];
switch ($intType) {
case 1:
if ($boolOnlyValue) {
$arrCategory = array_values(CategoryModel::getManCategory());
} else {
$arrCategory = CategoryModel::getManCategory();
}
break;
case 2:
if ($boolOnlyValue) {
$arrCategory = array_values(CategoryModel::getWomenCategory());
} else {
$arrCategory = CategoryModel::getWomenCategory();
}
break;
}
return $arrCategory;
}
/**
* get a category of man's novels
*
* @return array
*/
static public function getManCategory(): array
{
return self::$arrMan;
}
/**
* get a category of the woman novels
*
* @return array
*/
static public function getWomenCategory(): array
{
return self::$arrWomen;
}
/**
* get pinyin based on chinese characters
*
* @param string $strZh
* @return string
*/
static public function getPinYin(string $strZh)
{
$intKey = array_search($strZh, self::$arrCategory);
return self::$arrCategoryPinYin[$intKey];
}
/**
* get chinese characters based on pinyin
*
* @param string $strPinYin
* @return string|null
*/
static public function getZhByPinYin(string $strPinYin): string|null
{
$strZh = NULL;
$intKey = array_search($strPinYin, self::$arrCategoryPinYin);
if (is_numeric($intKey)) {
$strZh = self::$arrCategory[$intKey];
}
return $strZh;
}
/**
* determine the gender of the novel category
*
* @param string $strName
* @return string
*/
static public function getSexEn(string $strName): string
{
return in_array($strName, self::$arrMan) ? 'man' : 'women';
}
/**
* determine the gender of the novel category
*
* @param string $strName
* @return string
*/
static public function getSexZh(string $strName): string
{
return in_array($strName, self::$arrMan) ? '男生' : '女生';
}
}

View File

@@ -0,0 +1,319 @@
<?php
declare(strict_types=1);
namespace app\model;
use storage\StorageCore;
class ChapterModel extends MongoModel
{
/**
* Undocumented variable
*
* @var self
*/
static public $obj;
static public function getInstance(): self
{
if (self::$obj == NULL) {
self::$obj = new self;
}
return self::$obj;
}
protected $strCollection = 'chapter';
static public $arrChapterOptions = [
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array',
],
'projection' => [
'_id' => 0,
'c_source_id' => 0,
'c_site_code' => 0,
'c_source_uuid' => 0,
],
];
/**
* Undocumented function
*
* @param array $arrFilter
* @param integer $intPage
* @param integer $intLimit
* @param array $arrSort
* @param string $strKey
* @param integer $intLifeTime
* @return array
*/
public function findPaginatedWithCache(
array $arrFilter,
int $intPage = 1,
int $intLimit = 20,
array $arrSort = ['c_sort_num' => 1],
string $strKey = '',
int $intLifeTime = 24 * 3600,
): array {
try {
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
return $arrResult;
}
$arrOptions = self::$arrChapterOptions;
$arrOptions = array_merge($arrOptions, [
'sort' => $arrSort,
'skip' => ($intPage - 1) * $intLimit,
'limit' => $intLimit,
]);
$Cursor = $this->getCol()->find($arrFilter, $arrOptions);
$intTotal = $this->getCol()->countDocuments($arrFilter);
$arrResult = iterator_to_array($Cursor);
if (!empty($arrResult)) {
foreach ($arrResult as &$arrChapter) {
applyToKeys($arrChapter, ['created_at', 'updated_at'], 'formatMongoDate');
}
}
$arrResult = [
'data' => $arrResult,
'total' => $intTotal,
'page' => $intPage,
'limit' => $intLimit,
'pages' => ceil($intTotal / $intLimit)
];
$this->setCacheByKey($strKey, $arrResult, $intLifeTime);
return $arrResult;
} catch (\Exception $e) {
return [];
}
}
/**
* Undocumented function
*
* @param array $arrFilter
* @return null|array
*/
public function findOne(array $arrFilter, array $arrOptions = [], bool $boolReadContent = true): null|array
{
if (empty($arrOptions)) {
$arrOptions = self::$arrChapterOptions;
}
$arrChapter = $this->getOne($arrFilter, $arrOptions);
if (!empty($arrChapter)) {
try {
applyToKeys($arrChapter, ['created_at', 'updated_at'], 'formatMongoDate');
} catch (\Exception $e) {
var_dump($arrChapter);
throw $e;
}
if ($boolReadContent) {
$arrChapter['c_content'] = StorageCore::getInstance()->read($arrChapter['c_content_path']);
} else {
$arrChapter['c_content'] = '';
}
}
return $arrChapter;
}
/**
* Undocumented function
*
* @param integer $intNId
* @return null|array
*/
public function getLatestChapterByNId(int $intNId, bool $boolReadContent = true): null|array
{
$arrFilter = ['n_id' => $intNId, 'c_page' => 0];
$arrOptions = self::$arrChapterOptions;
$arrOptions['sort'] = ['c_sort_num' => -1];
return $this->findOne($arrFilter, $arrOptions, $boolReadContent);
}
/**
* Undocumented function
*
* @param integer $intNId
* @return null|array
*/
public function getFirstChapterByNId(int $intNId, bool $boolReadContent = true): null|array
{
$arrFilter = ['n_id' => $intNId, 'c_page' => 0];
$arrOptions = self::$arrChapterOptions;
$arrOptions['sort'] = ['c_sort_num' => 1];
return $this->findOne($arrFilter, $arrOptions, $boolReadContent);
}
/**
* Undocumented function
*
* @param array $arrFilter
* @param integer $intCount
* @param array $arrSort
* @param array $arrOptions
* @param boolean $boolReadContent
* @return null|array
*/
public function findMany(array $arrFilter, int $intCount = 0, array $arrSort = ['c_sort_num' => -1], array $arrOptions = [], bool $boolReadContent = false): null|array
{
if (empty($arrOptions)) {
$arrOptions = self::$arrChapterOptions;
}
$arrOptions['sort'] = $arrSort;
if ($intCount > 0) {
$arrOptions['limit'] = $intCount;
}
$Cursor = $this->getCol()->find($arrFilter, $arrOptions);
$arrResult = iterator_to_array($Cursor);
foreach ($arrResult as &$arrItem) {
applyToKeys($arrItem, ['created_at', 'updated_at'], 'formatMongoDate');
$arrItem['c_content'] = '';
if ($boolReadContent) {
$arrItem['c_content'] = StorageCore::getInstance()->read($arrItem['c_content_path']);
}
}
return $arrResult;
}
/**
* Undocumented function
*
* @param array $arrFilter
* @param integer $intCount
* @param array $arrSort
* @param array $arrOptions
* @param boolean $boolReadContent
* @return null|array
*/
public function findManyShuffledWithCache(
array $arrFilter,
int $intCount = 0,
array $arrSort = ['c_sort_num' => -1],
string $strKey = '',
int $intLifeTime = 24 * 3600,
bool $boolReadContent = false
): null|array {
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
return $arrResult;
}
if (empty($arrOptions)) {
$arrOptions = self::$arrChapterOptions;
}
$arrResult = $this->findMany($arrFilter, $intCount, $arrSort, [], $boolReadContent);
$this->setCacheByKey($strKey, $arrResult, $intLifeTime);
return $arrResult;
}
/**
* Undocumented function
*
* @param integer $intNId
* @param integer $intCSortNum
* @param integer $intCPage
* @return null|array
*/
public function getPreChapter(int $intNId, int $intCSortNum, int $intCPage): null|array
{
$arrFilter = [
'$and' => [
[
'$or' => [
['c_sort_num' => ['$lt' => $intCSortNum]],
[
'$and' => [
['c_sort_num' => ['$eq' => $intCSortNum]],
['c_page' => ['$lt' => $intCPage]]
]
]
]
],
['n_id' => $intNId]
]
];
$arrSort = [
'c_sort_num' => -1,
'c_page' => -1,
];
$arrChapterAll = $this->findMany($arrFilter, 1, $arrSort);
return $arrChapterAll[0] ?? [];
}
/**
* Undocumented function
*
* @param integer $intNId
* @param integer $intCSortNum
* @param integer $intCPage
* @return null|array
*/
public function getNextChapter(int $intNId, int $intCSortNum, int $intCPage): null|array
{
$arrFilter = [
'$and' => [
[
'$or' => [
['c_sort_num' => ['$gt' => $intCSortNum]],
[
'$and' => [
['c_sort_num' => ['$eq' => $intCSortNum]],
['c_page' => ['$gt' => $intCPage]]
]
]
]
],
['n_id' => $intNId]
]
];
$arrSort = [
'c_sort_num' => 1,
'c_page' => 1,
];
$arrChapterAll = $this->findMany($arrFilter, 1, $arrSort);
return $arrChapterAll[0] ?? [];
}
}

View File

@@ -0,0 +1,146 @@
<?php
declare(strict_types=1);
namespace app\model;
use Exception;
/**
* @mixin think\Model
*/
class ConfigSubjectFomartModel extends MongoModel
{
/**
* Undocumented variable
*
* @var self
*/
static public $obj;
static public function getInstance(): self
{
if (self::$obj == NULL) {
self::$obj = new self;
}
return self::$obj;
}
/**
* Undocumented variable
*
* @var string
*/
protected $strCollection = 'config_subject_fomart';
static public $arrOptions = [
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array',
],
'projection' => [
'_id' => 0,
],
];
/**
* 直接读库查询大量小说
*
* @param integer $intNId
* @return null|array
*/
public function findMany(array $arrFilter, int $intCount = 10, array $arrSort = [], array $arrOptions = []): null|array
{
if (empty($arrOptions)) {
$arrOptions = self::$arrOptions;
}
if ($intCount > 0) {
$arrOptions['limit'] = $intCount;
}
if (empty($arrSort)) {
$arrOptions['sort'] = $arrSort;
}
$Cursor = $this->getCol()->find($arrFilter, $arrOptions);
$arrResult = iterator_to_array($Cursor);
return $arrResult;
}
/**
* 查询多条数据并缓存
*
* @param array $arrFilter
* @param integer $intCount
* @param array $arrSort
* @param array $arrOptions
* @param string $strKey
* @param integer $intLifeTime
* @return null|array
*/
public function findManyWithCache(
array $arrFilter,
int $intCount = 0,
array $arrSort = [],
array $arrOptions = [],
string $strKey = '',
int $intLifeTime = 24 * 3600,
): null|array {
try {
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
return $arrResult;
}
$arrResult = $this->findMany($arrFilter, $intCount, $arrSort, $arrOptions);
$this->setCacheByKey($strKey, $arrResult, $intLifeTime);
return $arrResult;
} catch (\Exception $e) {
return [];
}
}
/**
* find one novel
*
* @param array $arrFilter
* @param array $arrOptions
* @return null|array
*/
public function findOne(array $arrFilter, array $arrOptions = []): null|array
{
if (empty($arrOptions)) {
$arrOptions = self::$arrOptions;
}
$arrNovel = $this->getOne($arrFilter, $arrOptions);
return $arrNovel;
}
/**
* 根据小说ID查询指定小说
*
* @param integer $intNId
* @return array
*/
public function getConfigSubjectFomartByCsfKey(string $intNId): null|array
{
$arrFilter = ['csf_key' => $intNId];
return $this->findOne($arrFilter);
}
}

View File

@@ -0,0 +1,108 @@
<?php
declare(strict_types=1);
namespace app\model;
use DateTime;
use think\facade\Cache;
use think\Model;
/**
* @mixin think\Model
*/
class ConverterMovel
{
static private $arrMap = [
'{strSiteName}' => '',
'{strSiteDomain}' => '',
'{strSiteKeywords}' => '',
'{strSiteDescription}' => '',
'{strIndexTitle}' => '',
'{strIndexKeywords}' => '',
'{strIndexDescription}' => '',
'{strNovelName}' => '',
'{strNovelChapterName}' => '',
'{strNovelChapterSort}' => '',
'{strChapterDescription}' => '',
'{strNovelCategoryName}' => '',
'{strNovelSex}' => '',
'{strNovelStatus}' => '',
'{intPage}' => '',
'{strNovelAuthor}' => '',
'{strNovelDescription}' => '',
'{strSearchKeywords}' => '',
];
static public $arrDescription = [
'{strSiteName}' => '这个是网站名',
'{strSiteDomain}' => '这个是站点域名',
'{strSiteKeywords}' => '这个是网站关键字',
'{strSiteDescription}' => '这个是网站描述',
'{strIndexTitle}' => '这个是首页Title',
'{strIndexKeywords}' => '这个是首页Keywords',
'{strIndexDescription}' => '这个是首页Description',
'{strNovelName}' => '这个是当前页面小说名字',
'{strNovelChapterName}' => '当前页面小说章节名字',
'{strNovelChapterSort}' => '当前页面小说章节排序号',
'{strChapterDescription}' => '当前页面小说章节描述',
'{strNovelCategoryName}' => '当前页面小说分类名字',
'{strNovelSex}' => '当前页面小说是男生还是女生 小说',
'{strNovelStatus}' => '当前页面小说状态 是连载还是完结',
'{intPage}' => '当前页面分页页码',
'{strNovelAuthor}' => '小说作者',
'{strNovelDescription}' => '小说简介',
'{strSearchKeywords}' => '搜索关键词',
];
static private function getKey($strKey): string
{
return '{' . $strKey . '}';
}
/**
* Undocumented function
*
* @param string|array $mixedKey 全局动态变量键或者数组
* @param string $strVal 全局动态变量值
* @return void
*/
static public function setVal(string | array $mixedKey, $strVal = NULL)
{
if (is_string($mixedKey)) {
self::$arrMap[self::getKey($mixedKey)] = $strVal;
} else if (is_array($mixedKey)) {
foreach ($mixedKey as $strKey => $strVal) {
if (key_exists(self::getKey($strKey), self::$arrMap)) {
self::$arrMap[self::getKey($strKey)] = $strVal;
}
}
}
}
/**
* Undocumented function
*
* @param string $strKey
* @return void
*/
static public function getVal(string $strKey)
{
return self::$arrMap[self::getKey($strKey)];
}
/**
* Undocumented function
*
* @param string $strSubject
* @return string
*/
static public function convert(string $strSubject): string
{
$strSubject = str_replace(array_keys(self::$arrMap), array_values(self::$arrMap), $strSubject);
return str_replace(array_keys(self::$arrMap), array_values(self::$arrMap), $strSubject);
}
}

View File

@@ -0,0 +1,63 @@
<?php
declare(strict_types=1);
namespace app\model;
/**
* @mixin think\Model
*/
class CountersModel extends MongoModel
{
/**
* Undocumented variable
*
* @var self
*/
static public $obj;
static public function getInstance(): self
{
if (self::$obj == NULL) {
self::$obj = new self;
}
return self::$obj;
}
/**
* Undocumented variable
*
* @var string
*/
protected $strCollection = 'counters';
static public $arrOptions = [
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array',
],
'projection' => [
'_id' => 0,
],
];
/**
* 获取下一个自增序列值
* @param string $strSequenceName 序列名称
* @return int 自增 ID
*/
public function getNextSequence(string $strSequenceName): int
{
$Result = $this->getCol()->findOneAndUpdate(
['_id' => $strSequenceName],
['$inc' => ['sequence_value' => 1]],
[
'upsert' => true,
'returnDocument' => \MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
]
);
return $Result->sequence_value ?? 1;
}
}

View File

@@ -0,0 +1,148 @@
<?php
declare(strict_types=1);
namespace app\model;
use think\facade\Cache;
use think\Model;
/**
* @mixin think\Model
*/
class DomainModel extends BaseModel
{
protected $name = 'domain';
protected $pk = 'd_id';
protected $json = ['t_cfg'];
static public $arrAllDomain = [];
/**
* Undocumented function
*
* @return array
*/
static public function getAllDomainOnCache(): array
{
if (empty(self::$arrAllDomain)) {
$strKey = 'Domain:All';
self::$arrAllDomain = Cache::get($strKey);
if (empty(self::$arrAllDomain)) {
self::flushAllDomianOnCache();
}
}
return self::$arrAllDomain;
}
/**
* Undocumented function
*
* @return void
*/
static public function flushAllDomianOnCache()
{
self::$arrAllDomain = [];
$strKey = 'Domain:All';
$DomainModelAll = DomainModel::select();
foreach ($DomainModelAll as $DomainModel) {
self::$arrAllDomain[$DomainModel->d_domain] = $DomainModel;
}
return Cache::set($strKey, self::$arrAllDomain);
}
/**
* Undocumented function
*
* @param string $strDomain
* @return DomainModel|NULL
*/
static public function getDomainOnCacheByDomain($strDomain): DomainModel|NULL
{
if (key_exists($strDomain, self::getAllDomainOnCache())) {
return self::getAllDomainOnCache()[$strDomain];
}
return NULL;
}
/**
* Undocumented function
*
* @param string $strWords
* @return string
*/
static public function wordsEncode($strWords): string
{
$Request = request();
$intEncode = $Request->DomainModel->d_content_encode;
if ($intEncode == 1) {
$strWords = customEntities($strWords);
}
return $strWords;
}
/**
* Undocumented function
*
* @param string $strKey
* @return string
*/
public function getFomartSubject($strKey, $strDiff = '', bool $boolJoin = true)
{
$intSfgId = $this->t_cfg->{$strKey}['sfg_id'];
$SubjectFomartModel = NULL;
$arrAllSubjectFomartModel = SubjectFomartModel::getAllSubjectFomartOnCacheBySfgId($intSfgId);
if (empty($arrAllSubjectFomartModel)) {
return '';
}
$strDomain = request()->DomainModel->d_domain;
$strController = request()->controller();
$strAction = request()->action();
if ($boolJoin) {
$strUUId = sprintf('%s-%s-%s-%s-%s', $strDomain, $strController, $strAction, $strKey, $strDiff);
} else {
$strUUId = sprintf('%s-%s-%s', $strDomain, $strKey, $strDiff);
}
$arrConfigSubjectFomart = ConfigSubjectFomartModel::getInstance()->getConfigSubjectFomartByCsfKey($strUUId);
if (empty($arrConfigSubjectFomart)) {
$intKey = array_rand($arrAllSubjectFomartModel);
$SubjectFomartModel = $arrAllSubjectFomartModel[$intKey];
ConfigSubjectFomartModel::getInstance()->insert([
'csf_key' => $strUUId,
'sf_id' => $SubjectFomartModel->sf_id,
]);
} else {
$intSfId = $arrConfigSubjectFomart['sf_id'];
foreach ($arrAllSubjectFomartModel as $objTemp) {
if ($objTemp->sf_id == $intSfId) {
$SubjectFomartModel = $objTemp;
break;
}
}
}
return $SubjectFomartModel->sf_val ?? '';
}
}

View File

@@ -0,0 +1,133 @@
<?php
declare(strict_types=1);
namespace app\model;
use think\facade\Cache;
use think\Model;
/**
* @mixin think\Model
*/
class FenLeiModel extends BaseModel
{
protected $name = 'fen_lei';
protected $pk = 'fl_id';
static $arrFenLei = [];
static public function addFenlei($intFlId, $intFlPId = 0, $strFlMingzi)
{
try {
if (empty($strFlMingzi)) {
return true;
}
$FenLeiModel = self::where('fl_pid',$intFlPId)->where('fl_mingzi',$strFlMingzi)->find();
if ($FenLeiModel) {
return $FenLeiModel;
}
$FenLeiModel = new self;
// $FenLeiModel->fl_id = $intFlId;
$FenLeiModel->fl_leixing = 0;
$FenLeiModel->fl_pid = $intFlPId;
$FenLeiModel->fl_mingzi = $strFlMingzi;
$FenLeiModel->save();
return $FenLeiModel;
} catch (\Throwable $T) {
}
if ($T->getCode() == 10501) {
return self::addFenlei($intFlId, $intFlPId, $strFlMingzi);
}
throw $T;
}
static public function getAllFenLei()
{
if (self::$arrFenLei == []) {
self::$arrFenLei = Cache::get('SHI_PIN_FEN_LEI');
if (empty(self::$arrFenLei)) {
self::flushCache();
self::$arrFenLei = Cache::get('SHI_PIN_FEN_LEI');
}
}
return self::$arrFenLei;
}
static public function getFenLeiByFlId($intFlId)
{
if (self::$arrFenLei == []) {
self::$arrFenLei = Cache::get('SHI_PIN_FEN_LEI');
if (empty(self::$arrFenLei)) {
self::flushCache();
self::$arrFenLei = Cache::get('SHI_PIN_FEN_LEI');
}
}
return self::$arrFenLei[$intFlId] ?? "";
}
static public function getFenLeiMingZiByFlId($intFlId, $intZiFlId)
{
if (empty(self::$arrFenLei)) {
self::$arrFenLei = Cache::get('SHI_PIN_FEN_LEI');
if (empty(self::$arrFenLei)) {
self::flushCache();
self::$arrFenLei = Cache::get('SHI_PIN_FEN_LEI');
}
}
if ($intZiFlId == 0) {
return self::$arrFenLei[$intFlId]['fl_mingzi'] ?? '';
} else {
$arrFenLeiChild = self::$arrFenLei[$intFlId]['child'] ?? [];
foreach ($arrFenLeiChild as $item) {
if ($item['fl_id'] == $intZiFlId) {
return $item['fl_mingzi'];
}
}
}
return '';
}
static public function flushCache()
{
// $arrFenLei = self::select()->toArray();
$arrFenLei = self::order('fl_sort', 'desc')->select()->toArray();
$arrFenLei = static::buildTree($arrFenLei);
Cache::tag('SHI_PIN_FEN_LEI')->set('SHI_PIN_FEN_LEI', $arrFenLei);
}
static public function buildTree(array $elements, $parentId = 0)
{
$branch = [];
foreach ($elements as $element) {
if ($element['fl_pid'] == $parentId) {
$children = static::buildTree($elements, $element['fl_id']);
if ($children) {
$element['child'] = $children;
}
$branch[$element['fl_id']] = $element;
}
}
return $branch;
}
}

View File

@@ -0,0 +1,260 @@
<?php
declare(strict_types=1);
namespace app\model;
use DateTime;
use Exception;
use storage\StorageCore;
use think\facade\Cache;
use think\Model;
/**
* @mixin think\Model
*/
class GanRaoMaModel extends MongoModel
{
/**
* Undocumented variable
*
* @var self
*/
static public $obj;
static public function getInstance(): self
{
if (self::$obj == NULL) {
self::$obj = new self;
}
return self::$obj;
}
/**
* Undocumented variable
*
* @var string
*/
protected $strCollection = 'gan_rao_ma';
static public $arrOptions = [
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array',
],
'projection' => [
'_id' => 0,
],
];
/**
* 可选属性
*/
const POSSIBLE_ATTRIBUTES = [
'draggable',
'date-time',
'lang',
'id',
'dir',
'class'
];
/**
* 配置常量
*/
const TAG_MAX_LENGTH = 8;
const ATTR_VALUE_MAX_LENGTH = 10;
const ATTR_MIN_COUNT = 1;
const ATTR_MAX_COUNT = 3;
/**
* Undocumented variable
*
* @var array
*/
static public $arrSelfClosing = [
'<meta name="%s" content="%s" id="%s" class="%s">',
'<input type="hidden" name="%s" value="%s" id="%s" class="%s">',
'<link rel="%s" href="%s" id="%s" class="%s">',
'<base href="%s" id="%s" class="%s">',
'<param name="%s" value="%s" id="%s" class="%s">',
'<col span="%s" id="%s" class="%s">',
'<area shape="rect" coords="%s" href="%s" id="%s" class="%s">',
'<span id="%s" class="%s" style="display:none;">%s</span>',
'<div id="%s" class="%s" style="display:none;">%s</div>',
'<p id="%s" class="%s" style="display:none;">%s</p>',
'<strong id="%s" class="%s" style="display:none;">%s</strong>',
'<em id="%s" class="%s" style="display:none;">%s</em>',
'<%s id="%s"> </%s>',
];
const LETTERS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
const CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
public static function generateRandomStrings(int $count): array
{
static $lettersLength = null;
static $charsLength = null;
if ($lettersLength === null) {
$lettersLength = strlen(self::LETTERS) - 1;
$charsLength = strlen(self::CHARS) - 1;
}
$result = array_fill(0, $count, '');
array_walk($result, function (&$value) use ($lettersLength, $charsLength) {
$length = random_int(5, 10);
$value = self::LETTERS[random_int(0, $lettersLength)];
$i = 1;
while ($i < $length) {
$value .= self::CHARS[random_int(0, $charsLength)];
$i++;
}
});
return $result;
}
/**
* Undocumented function
* 随机生成自定义标签-干扰码
*
* @param integer $intMinTags
* @param integer $intMaxTags
* @return string
*/
static public function generateRandomCustomizeHtml(int $intMinTags = 5, int $intMaxTags = 20): string
{
// 随机标签数量
$intNumTags = rand($intMinTags, $intMaxTags);
$strHtmlResult = '';
for ($i = 0; $i < $intNumTags; $i++) {
// 生成随机标签名
$strTagName = self::generateRandomString(rand(3, self::TAG_MAX_LENGTH), self::LETTERS);
// 随机属性数量
$intNumAttributes = rand(self::ATTR_MIN_COUNT, self::ATTR_MAX_COUNT);
$strAttributes = self::generateAttributes($intNumAttributes);
// 拼接标签
$strHtmlResult .= "<{$strTagName}{$strAttributes}></{$strTagName}>\n";
}
return $strHtmlResult;
}
/**
* Undocumented function
* 生成自定义属性
*
* @param integer $intTotal
* @return string
*/
static public function generateAttributes(int $intTotal): string
{
$strAttributes = '';
$arrUsedAttributes = array_rand(array_flip(self::POSSIBLE_ATTRIBUTES), $intTotal);
foreach ((array) $arrUsedAttributes as $strAttrName) {
$strAttrValue = self::generateRandomString(
rand(3, self::ATTR_VALUE_MAX_LENGTH),
self::CHARS
);
$strAttributes .= " {$strAttrName}=\"{$strAttrValue}\"";
}
return $strAttributes;
}
/**
* Undocumented function
* 生成随机字符串
*
* @param integer $length
* @param string $strCharset
* @return string
*/
static public function generateRandomString(int $length, string $strCharset): string
{
$intCharsetLength = strlen($strCharset);
$strRandomString = '';
for ($i = 0; $i < $length; $i++) {
$strRandomString .= $strCharset[rand(0, $intCharsetLength - 1)];
}
return $strRandomString;
}
/**
* Undocumented function
*
* @param string $strDomain 域名
* @param string $strPageCode 视图编码
* @param string $strDifference 差异
* @param int $intNum 生成数量
* @return array
*/
static public function getGrmCode($strDomain, $strPageCode, $strDifference, $intNum)
{
$arrFilter = [
'grm_domain' => (string) $strDomain,
'grm_page_code' => (string) $strPageCode,
'grm_page_diff' => (string) $strDifference,
];
$arrResult = self::getInstance()->getOne($arrFilter, self::$arrOptions);
if (empty($arrResult)) {
// $intNum = mt_rand($intStartNumber, $intEndNumber);
// $arrGrmCode = self::$arrSelfClosing;
// shuffle($arrGrmCode);
// $arrGrmCode = array_slice($arrGrmCode, 0, $intNum);
// $strGrmCode = implode('', $arrGrmCode);
// $intRandNum = substr_count($strGrmCode, '%s');
// $arrRandStr = self::generateRandomStrings($intRandNum);
// $strGrmCode = sprintf($strGrmCode, ...$arrRandStr);
$arrGrmCode = [];
while ($intNum-- > 0) {
// $arrGrmCode[] = self::generateRandomCustomizeHtml(mt_rand(1, 3), mt_rand(3, 6));
$arrGrmCode[] = self::generateRandomCustomizeHtml(1, 1);
}
$arrData = $arrFilter;
$arrData['grm_code'] = $arrGrmCode;
self::getInstance()->insert($arrData);
} else {
$arrGrmCode = $arrResult['grm_code'];
}
return $arrGrmCode;
}
static public function splitTagsToArray(string $htmlTags): array
{
// 按换行符分割,兼容不同系统
$tagsArray = preg_split('/\r\n|\n|\r/', $htmlTags);
// 去除空白行并清理首尾空格
$tagsArray = array_filter(array_map('trim', $tagsArray), function ($tag) {
return !empty($tag);
});
// 重置索引
return array_values($tagsArray);
}
}

View File

@@ -0,0 +1,147 @@
<?php
declare(strict_types=1);
namespace app\model;
use db\mongo\MongoBase;
use ddl\DDLManage;
use MongoDB\Collection;
use think\facade\Cache;
/**
* @mixin think\Model
*/
abstract class MongoModel
{
/**
* collection name
*
* @var string
*/
protected $strCollection;
/**
* Undocumented variable
*
* @var MongoBase
*/
private $MongoBase;
/**
* Undocumented function
*/
public function __construct()
{
DDLManage::load('MongoBase');
$this->MongoBase = MongoBase::getInstance();
}
/**
* Undocumented function
*
* @return MongoBase
*/
public function getMongoBase(): MongoBase
{
return $this->MongoBase;
}
/**
* Undocumented function
*
* @return Collection
*/
public function getCol(): Collection
{
return $this->getMongoBase()->getDb()->selectCollection($this->getCollectionName());
}
/**
* Undocumented function
*
* @return string
*/
public function getCollectionName(): string
{
return $this->strCollection;
}
/**
* Undocumented function
*
* @param array $arrFilter
* @return array|object|null
*/
public function getOne(array $arrFilter = [], array $arrOptions = []): array|object|null
{
return $this->getCol()->findOne($arrFilter, $arrOptions);
}
/**
* Undocumented function
*
* @param string $strKey
* @return array|object|NULL
*/
public function checkCacheByKey(string $strKey): array|object|NULL
{
if (config('view.view_data_cache') == false) {
return NULL;
}
if (!empty($strKey)) {
$arrResult = Cache::get($strKey);
if (!empty($arrResult)) {
return $arrResult;
}
}
return NULL;
}
/**
* Undocumented function
*
* @param string $strKey
* @param mixed $mixedData
* @param integer $intLifeTime
* @return void
*/
public function setCacheByKey(string $strKey, mixed $mixedData, int $intLifeTime)
{
if (!empty($strKey) && !empty($mixedData)) {
Cache::set($strKey, $mixedData, $intLifeTime);
}
}
/**
* Undocumented function
*
* @param array $arrData
* @return mixed
*/
public function insert(array $arrData, array $arrOptions = []): mixed
{
$Result = $this->getCol()->insertOne($arrData);
return $Result->getInsertedId();
}
/**
* 更新单条数据
* @param string $strColName 集合名称
* @param array $arrFilter 查询条件
* @param array $arrUpdate 更新内容
* @param array $arrOptions 更新选项
* @return int 受影响的文档数
*/
public function updateOne(array $arrFilter, array $arrUpdate, array $arrOptions = []): int
{
$Result = $this->getCol()->updateOne($arrFilter, $arrUpdate, $arrOptions);
return $Result->getModifiedCount();
}
}

View File

@@ -0,0 +1,118 @@
<?php
declare(strict_types=1);
namespace app\model;
use DateTime;
use think\facade\Cache;
use think\Model;
/**
* @mixin think\Model
*/
class NovelClicksModel extends MongoModel
{
/**
* Undocumented variable
*
* @var NovelClicksModel
*/
static public $NovelClicksModel;
static public function getInstance(): self
{
if (self::$NovelClicksModel == NULL) {
self::$NovelClicksModel = new self;
}
return self::$NovelClicksModel;
}
protected $strCollection = 'novel_clicks';
/**
* Undocumented function
*
* @param integer $intNId
* @return void
*/
public function addStatis(int $intNId)
{
$NovelModel = NovelModel::getInstance();
$Novel = $NovelModel->getCol()->findOne([
"n_id" => $intNId,
]);
if (empty($Novel)) {
return false;
}
$Now = new DateTime();
$strDailyDate = $Now->format('Y-m-d');
$strWeeklyDate = $Now->modify('monday this week')->format('Y-m-d');
$MonthlyDate = $Now->format('Y-m-01');
$arrClickTypes = [
'daily' => $strDailyDate,
'weekly' => $strWeeklyDate,
'monthly' => $MonthlyDate,
'total' => null,
];
foreach ($arrClickTypes as $strType => $strDate) {
$this->getCol()->updateOne(
[
'n_id' => $intNId,
'nc_date' => $strDate,
'nc_type' => $strType,
],
[
'$inc' => ['nc_clicks' => 1],
'$set' => ['n_category' => $Novel->n_category]
],
[
'upsert' => true
]
);
}
return true;
}
public function getStats(int $intNId): array
{
$Now = new DateTime();
$strDailyDate = $Now->format('Y-m-d');
$strWeeklyDate = $Now->modify('monday this week')->format('Y-m-d');
$strMonthlyDate = $Now->format('Y-m-01');
$query = [
'n_id' => $intNId,
'$or' => [
['nc_type' => 'daily', 'nc_date' => $strDailyDate],
['nc_type' => 'weekly', 'nc_date' => $strWeeklyDate],
['nc_type' => 'monthly', 'nc_date' => $strMonthlyDate],
['nc_type' => 'total', 'nc_date' => null]
]
];
$arrOptions = [
'projection' => ['nc_type' => 1, 'nc_clicks' => 1, '_id' => 0],
'typeMap' => ['root' => 'array', 'document' => 'array', 'array' => 'array']
];
$arrResults = $this->getCol()->find($query, $arrOptions)->toArray();
$arrStats = array_column($arrResults, 'nc_clicks', 'nc_type');
$defaultStats = [
'daily' => 0,
'weekly' => 0,
'monthly' => 0,
'total' => 0
];
$arrStats = array_merge($defaultStats, $arrStats);
return $arrStats;
}
}

View File

@@ -0,0 +1,486 @@
<?php
declare(strict_types=1);
namespace app\model;
use Exception;
/**
* @mixin think\Model
*/
class NovelModel extends MongoModel
{
/**
* Undocumented variable
*
* @var self
*/
static public $obj;
static public function getInstance(): self
{
if (self::$obj == NULL) {
self::$obj = new self;
}
return self::$obj;
}
/**
* Undocumented variable
*
* @var string
*/
protected $strCollection = 'novel';
static public $arrOptions = [
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array',
],
'projection' => [
'_id' => 0,
'n_site_code' => 0,
'n_source_uuid' => 0,
'n_source_id' => 0,
],
];
/**
* 根据关键词数组更新小说推荐等级
* @param array $arrKeywords 关键词数组,例如 ["斗罗", "遮天", "凡人"]
* @param int $intLevel 推荐等级1~9例如 3
* @return array 更新结果
*/
public function updateByKeywords(array $arrKeywords, int $intLevel)
{
if (empty($arrKeywords)) {
return false;
}
try {
$arrConditions = array_map(function ($strKeyword) {
return ['n_name' => ['$regex' => trim($strKeyword), '$options' => 'i']];
}, $arrKeywords);
$UpdateResult = $this->getCol()->updateMany(
['$or' => $arrConditions],
['$set' => ['n_level' => $intLevel]]
);
$UpdateResult->getModifiedCount();
} catch (Exception $e) {
return false;
}
return true;
}
/**
* 直接读库查询大量小说
*
* @param integer $intNId
* @return null|array
*/
public function findMany(array $arrFilter, int $intCount = 10, array $arrSort = [], array $arrOptions = []): null|array
{
if (empty($arrOptions)) {
$arrOptions = self::$arrOptions;
}
if ($intCount > 0) {
$arrOptions['limit'] = $intCount;
}
if (empty($arrSort)) {
$arrOptions['sort'] = $arrSort;
}
$arrFilter['n_have_chapter'] = 1;
$Cursor = $this->getCol()->find($arrFilter, $arrOptions);
$arrResult = iterator_to_array($Cursor);
foreach ($arrResult as &$arrItem) {
applyToKeys($arrItem, ['created_at', 'updated_at'], 'formatMongoDate');
}
return $arrResult;
}
/**
* 查询多条数据并缓存
*
* @param array $arrFilter
* @param integer $intCount
* @param array $arrSort
* @param array $arrOptions
* @param string $strKey
* @param integer $intLifeTime
* @return null|array
*/
public function findManyWithCache(
array $arrFilter,
int $intCount = 0,
array $arrSort = [],
array $arrOptions = [],
string $strKey = '',
int $intLifeTime = 24 * 3600,
): null|array {
try {
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
return $arrResult;
}
$arrResult = $this->findMany($arrFilter, $intCount, $arrSort, $arrOptions);
$this->setCacheByKey($strKey, $arrResult, $intLifeTime);
return $arrResult;
} catch (\Exception $e) {
return [];
}
}
/**
* find one novel
*
* @param array $arrFilter
* @param array $arrOptions
* @return null|array
*/
public function findOne(array $arrFilter, array $arrOptions = []): null|array
{
if (empty($arrOptions)) {
$arrOptions = self::$arrOptions;
}
$arrNovel = $this->getOne($arrFilter, $arrOptions);
if (!empty($arrNovel)) {
applyToKeys($arrNovel, ['created_at', 'updated_at'], 'formatMongoDate');
}
return $arrNovel;
}
/**
* 根据小说ID查询指定小说
*
* @param integer $intNId
* @return array
*/
public function getNovelByNId(int $intNId): null|array
{
$arrFilter = ['n_id' => $intNId, 'n_have_chapter' => 1];
return $this->findOne($arrFilter);
}
/**
* 查询符合条件的随机多条小说
*
* @param string $strKey
* @param array $arrFilter
* @param integer $intCount
* @param integer $intLifeTime
* @return array
*/
public function getRandNovelWithCache(array $arrFilter = [], int $intCount = 10, string $strKey = '', int $intLifeTime = 24 * 3600,): array
{
try {
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
return $arrResult;
}
$arrFilter['n_have_chapter'] = 1;
$arrPipeline = [
['$match' => $arrFilter],
['$sample' => ['size' => $intCount]]
];
$Novel = $this->getCol()->aggregate($arrPipeline);
$arrResult = iterator_to_array($Novel);
$this->setCacheByKey($strKey, $arrResult, $intLifeTime);
return $arrResult;
} catch (\Exception $e) {
return [];
}
}
/**
* 通用小说分页
*
* @param array $arrFilter
* @param integer $intPage
* @param integer $intLimit
* @param array $arrSort
* @param string $strKey
* @param int $intLifeTime
* @return array
*/
public function findPaginatedWithCache(
array $arrFilter,
int $intPage = 1,
int $intLimit = 20,
array $arrSort = ['n_level' => -1],
string $strKey = '',
int $intLifeTime = 24 * 3600,
): array {
try {
$arrFilter['n_have_chapter'] = 1;
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
return $arrResult;
}
$arrOptions = self::$arrOptions;
$arrOptions['sort'] = $arrSort;
$arrOptions['skip'] = ($intPage - 1) * $intLimit;
$arrOptions['limit'] = $intLimit;
unset($arrOptions['typeMap']);
$Cursor = $this->getCol()->find($arrFilter, $arrOptions);
$intTotal = $this->getCol()->countDocuments($arrFilter);
$arrResult = iterator_to_array($Cursor);
shuffle($arrResult);
$arrResult = [
'data' => $arrResult,
'total' => $intTotal,
'page' => $intPage,
'limit' => $intLimit,
'pages' => ceil($intTotal / $intLimit)
];
$this->setCacheByKey($strKey, $arrResult, $intLifeTime);
return $arrResult;
} catch (\Exception $e) {
return [];
}
}
/**
* 用于Home下的书库分页
*
* @param string $strKey
* @param integer $intPage
* @param integer $intLimit
* @param int $intLifeTime
* @param integer $intType
* @param string $strStatus
* @param array $arrSort
* @return array
*/
public function getCustomPage01(
string $strKey,
int $intPage = 1,
int $intLimit = 20,
int $intLifeTime = 24 * 3600,
int $intType = 0,
$strStatus = NULL,
array $arrSort = ['n_level' => -1]
): array {
$arrFilter = ['n_have_chapter' => 1,];
switch ($intType) {
case 1:
$arrCategory = array_values(CategoryModel::getManCategory());
$arrFilter['n_category'] = ['$in' => $arrCategory];
break;
case 2:
$arrCategory = array_values(CategoryModel::getWomenCategory());
$arrFilter['n_category'] = ['$in' => $arrCategory];
break;
}
if ($strStatus !== NULL) {
$arrFilter['n_status'] = $strStatus;
}
return $this->findPaginatedWithCache($arrFilter, $intPage, $intLimit, $arrSort, $strKey, $intLifeTime,);
}
/**
* Undocumented function
*
* @param array $arrFilter
* @param integer $intCount
* @param array $arrSort
* @param string $strKey
* @param integer $intLifeTime
* @return array
*/
public function findManyShuffledWithCache(
array $arrFilter,
int $intCount = 10,
array $arrSort = [],
string $strKey = '',
int $intLifeTime = 24 * 3600,
): array {
try {
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
return $arrResult;
}
$arrFilter['n_have_chapter'] = 1;
$arrOptions = self::$arrOptions;
if (!empty($arrSort)) {
$arrOptions['sort'] = $arrSort;
}
$arrOptions['limit'] = $intCount * 3;
unset($arrOptions['typeMap']);
$Cursor = $this->getCol()->find($arrFilter, $arrOptions);
$arrResult = iterator_to_array($Cursor);
shuffle($arrResult);
$arrResult = array_slice($arrResult, 0, $intCount);
$this->setCacheByKey($strKey, $arrResult, $intLifeTime);
return $arrResult;
} catch (\Exception $e) {
return [];
}
}
/**
* Undocumented function
*
* @param string $strKey
* @param int $intLifeTime
* @param integer $intCount
* @param integer $intType
* @param string $strStatus
* @param array $arrSort
* @return array
*/
public function getCommonNovelOnCache(
string $strKey,
int $intLifeTime = 24 * 3600,
int $intCount = 10,
int $intType = 0,
$strStatus = NULL,
array $arrSort = ['n_level' => -1]
): array {
try {
$arrFilter = [];
if (in_array($intType, [1, 2])) {
$arrFilter['n_category'] = ['$in' => CategoryModel::getCategoryByType($intType)];
}
if ($strStatus !== NULL) {
$arrFilter['n_status'] = $strStatus;
}
return $this->findManyShuffledWithCache($arrFilter, $intCount, $arrSort, $strKey, $intLifeTime);
} catch (\Exception $e) {
return [];
}
}
/**
* Undocumented function
*
* @param string $strSign
* @param integer $intCount
* @param integer $intType
* @param string strDateType
* * daily 天
* * weekly 周
* * monthly 月
* * total 总
* @return array
*/
public function getRankNovelOnCache(
string $strKey,
int $intCount = 10,
int $intType = 0,
$strDateType = 'daily',
$strStatus = NULL,
$intLifeTime = 24 * 3600,
): array {
try {
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
return $arrResult;
}
$arrFilter = [
'nc_type' => $strDateType,
];
if ($strStatus !== NULL) {
$arrFilter['n_status'] = $strStatus;
}
if (in_array($intType, [1, 2])) {
$arrFilter['n_category'] = ['$in' => CategoryModel::getCategoryByType($intType)];
}
$arrOptions = [
'sort' => ['nc_clicks' => -1],
'limit' => $intCount * 3,
'projection' => [
'n_id' => 1,
],
];
$NovelClicksModel = NovelClicksModel::getInstance();
$Cursor = $NovelClicksModel->getCol()->find($arrFilter, $arrOptions);
$arrNId = [];
foreach ($Cursor as $Doc) {
$arrNId[] = $Doc['n_id'];
}
$arrFilter = ['n_id' => ['$in' => $arrNId]];
$arrOptions = self::$arrOptions;
unset($arrOptions['typeMap']);
$Cursor = $this->getCol()->find(
$arrFilter,
$arrOptions
);
$arrResult = iterator_to_array($Cursor);
shuffle($arrResult);
$arrResult = array_slice($arrResult, 0, $intCount);
$this->setCacheByKey($strKey, $arrResult, $intLifeTime);
return $arrResult;
} catch (\Exception $e) {
return [];
}
}
}

View File

@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace app\model;
use think\facade\Cache;
use think\Model;
/**
* @mixin think\Model
*/
class PlanTaskModel extends BaseModel
{
protected $name = 'plan_task';
protected $pk = 'pt_id';
}

View File

@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace app\model;
use think\facade\Cache;
use think\Model;
/**
* @mixin think\Model
*/
class SubjectFomartGroupModel extends BaseModel
{
protected $name = 'subject_fomart_group';
protected $pk = 'sfg_id';
}

View File

@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
namespace app\model;
use think\facade\Cache;
use think\Model;
/**
* @mixin think\Model
*/
class SubjectFomartModel extends BaseModel
{
protected $name = 'subject_fomart';
protected $pk = 'sf_id';
static public $arrAllSubjectFomart = [];
/**
* Undocumented function
*
* @param integer $intSfgId
* @return SubjectFomartModel[]
*/
static public function getAllSubjectFomartOnCacheBySfgId(int $intSfgId): array
{
if (empty(self::$arrAllSubjectFomart)) {
$strKey = 'SubjectFomart:All';
self::$arrAllSubjectFomart = Cache::get($strKey);
if (empty(self::$arrAllSubjectFomart)) {
self::flushAllSubjectFomartOnCache();
}
}
return self::$arrAllSubjectFomart[$intSfgId] ?? [];
}
/**
* Undocumented function
*
* @return void
*/
static public function flushAllSubjectFomartOnCache()
{
self::$arrAllSubjectFomart = [];
$strKey = 'SubjectFomart:All';
$SubjectFomartModelAll = SubjectFomartModel::select();
foreach ($SubjectFomartModelAll as $SubjectFomartModel) {
self::$arrAllSubjectFomart[$SubjectFomartModel->sfg_id][] = $SubjectFomartModel;
}
return Cache::set($strKey, self::$arrAllSubjectFomart);
}
}

View File

@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace app\model;
use think\facade\Cache;
use think\Model;
/**
* @mixin think\Model
*/
class SystemConfigModel extends BaseModel
{
protected $name = 'system_config';
protected $pk = 'sc_id';
static $arrSystemConfig = [];
static public function getValByCode($strCode)
{
if (self::$arrSystemConfig == []) {
self::$arrSystemConfig = Cache::get('Config');
if (empty(self::$arrSystemConfig)) {
self::flushCache();
self::$arrSystemConfig = Cache::get('Config');
}
}
return self::$arrSystemConfig[$strCode] ?? NULL;
}
static public function flushCache()
{
$arrSystemConfig = self::column('sc_val', 'sc_code');
Cache::tag('Config')->set('Config', $arrSystemConfig);
}
}

View File

@@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
namespace app\model;
use think\facade\Cache;
use think\Model;
/**
* @mixin think\Model
*/
class TemplatesModel extends BaseModel
{
protected $name = 'templates';
protected $pk = 't_id';
protected $json = ['t_cfg_template'];
/**
* Undocumented function
*
* @param string $strVal
* @return void
*/
// public function getTCfgTemplatesAttr($strVal)
// {
// if (!empty($strVal)) {
// return json_decode($strVal);
// }
// }
static public $arrAllTemplate = [];
/**
* Undocumented function
*
* @return array
*/
static public function getAllTemplateOnCache(): array
{
if (empty(self::$arrAllTemplate)) {
$strKey = 'Template:All';
self::$arrAllTemplate = Cache::get($strKey);
if (empty(self::$arrAllTemplate)) {
self::flushAllTemplateOnCache();
}
}
return self::$arrAllTemplate;
}
/**
* Undocumented function
*
* @return void
*/
static public function flushAllTemplateOnCache()
{
self::$arrAllTemplate = [];
$strKey = 'Template:All';
$TemplateModelAll = self::select();
foreach ($TemplateModelAll as $TemplateModel) {
self::$arrAllTemplate[$TemplateModel->t_id] = $TemplateModel;
}
return Cache::set($strKey, self::$arrAllTemplate);
}
/**
* Undocumented function
*
* @param int $intTId
* @return TemplatesModel|NULL
*/
static public function getTemplateOnCacheByTId(int $intTId): TemplatesModel|NULL
{
if (key_exists($intTId, self::getAllTemplateOnCache())) {
return self::getAllTemplateOnCache()[$intTId];
}
return NULL;
}
}

View File

@@ -0,0 +1,124 @@
<?php
declare(strict_types=1);
namespace app\model;
use DateTime;
use think\facade\Cache;
use think\Model;
/**
* @mixin think\Model
*/
class VideoClicksModel extends MongoModel
{
/**
* VideoClicksModel
*
* @var VideoClicksModel
*/
static public $VideoClicksModel;
static public function getInstance(): self
{
if (self::$VideoClicksModel == NULL) {
self::$VideoClicksModel = new self;
}
return self::$VideoClicksModel;
}
protected $strCollection = 'video_clicks';
/**
* addStatis
*
* @param integer $intVId
* @return void
*/
public function addStatis(int $intVId)
{
$NovelModel = NovelModel::getInstance();
$Novel = $NovelModel->getCol()->findOne([
"v_id" => $intVId,
]);
if (empty($Novel)) {
return false;
}
$Now = new DateTime();
$strDailyDate = $Now->format('Y-m-d');
$strWeeklyDate = $Now->modify('monday this week')->format('Y-m-d');
$MonthlyDate = $Now->format('Y-m-01');
$arrClickTypes = [
'daily' => $strDailyDate,
'weekly' => $strWeeklyDate,
'monthly' => $MonthlyDate,
'total' => null,
];
foreach ($arrClickTypes as $strType => $strDate) {
$this->getCol()->updateOne(
[
'v_id' => $intVId,
'vc_date' => $strDate,
'vc_type' => $strType,
],
[
'$inc' => ['vc_clicks' => 1],
'$set' => ['v_category_id' => $Novel->v_category_id]
],
[
'upsert' => true
]
);
}
return true;
}
/**
* GetStats
*
* @param integer $intVId
* @return array
*/
public function getStats(int $intVId): array
{
$Now = new DateTime();
$strDailyDate = $Now->format('Y-m-d');
$strWeeklyDate = $Now->modify('monday this week')->format('Y-m-d');
$strMonthlyDate = $Now->format('Y-m-01');
$query = [
'v_id' => $intVId,
'$or' => [
['vc_type' => 'daily', 'vc_date' => $strDailyDate],
['vc_type' => 'weekly', 'vc_date' => $strWeeklyDate],
['vc_type' => 'monthly', 'vc_date' => $strMonthlyDate],
['vc_type' => 'total', 'vc_date' => null]
]
];
$arrOptions = [
'projection' => ['vc_type' => 1, 'vc_clicks' => 1, '_id' => 0],
'typeMap' => ['root' => 'array', 'document' => 'array', 'array' => 'array']
];
$arrResults = $this->getCol()->find($query, $arrOptions)->toArray();
$arrStats = array_column($arrResults, 'vc_clicks', 'vc_type');
$defaultStats = [
'daily' => 0,
'weekly' => 0,
'monthly' => 0,
'total' => 0
];
$arrStats = array_merge($defaultStats, $arrStats);
return $arrStats;
}
}

View File

@@ -0,0 +1,484 @@
<?php
declare(strict_types=1);
namespace app\model;
use Exception;
/**
* @mixin think\Model
*/
class VideoModel extends MongoModel
{
/**
* Undocumented variable
*
* @var self
*/
static public $obj;
static public function getInstance(): self
{
if (self::$obj == NULL) {
self::$obj = new self;
}
return self::$obj;
}
/**
* Undocumented variable
*
* @var string
*/
protected $strCollection = 'video';
static public $arrOptions = [
'typeMap' => [
'root' => 'array',
'document' => 'array',
'array' => 'array',
],
'projection' => [
'_id' => 0,
'n_site_code' => 0,
'n_source_uuid' => 0,
'n_source_id' => 0,
],
];
/**
* 根据关键词数组更新小说推荐等级
* @param array $arrKeywords 关键词数组,例如 ["斗罗", "遮天", "凡人"]
* @param int $intLevel 推荐等级1~9例如 3
* @return array 更新结果
*/
public function updateByKeywords(array $arrKeywords, int $intLevel)
{
if (empty($arrKeywords)) {
return false;
}
try {
$arrConditions = array_map(function ($strKeyword) {
return ['n_name' => ['$regex' => trim($strKeyword), '$options' => 'i']];
}, $arrKeywords);
$UpdateResult = $this->getCol()->updateMany(
['$or' => $arrConditions],
['$set' => ['n_level' => $intLevel]]
);
$UpdateResult->getModifiedCount();
} catch (Exception $e) {
return false;
}
return true;
}
/**
* 直接读库查询大量小说
*
* @param integer $intNId
* @return null|array
*/
public function findMany(array $arrFilter, int $intCount = 10, array $arrSort = [], array $arrOptions = []): null|array
{
if (empty($arrOptions)) {
$arrOptions = self::$arrOptions;
}
if ($intCount > 0) {
$arrOptions['limit'] = $intCount;
}
if (empty($arrSort)) {
$arrOptions['sort'] = $arrSort;
}
$arrFilter['n_have_chapter'] = 1;
$Cursor = $this->getCol()->find($arrFilter, $arrOptions);
$arrResult = iterator_to_array($Cursor);
foreach ($arrResult as &$arrItem) {
applyToKeys($arrItem, ['created_at', 'updated_at'], 'formatMongoDate');
}
return $arrResult;
}
/**
* 查询多条数据并缓存
*
* @param array $arrFilter
* @param integer $intCount
* @param array $arrSort
* @param array $arrOptions
* @param string $strKey
* @param integer $intLifeTime
* @return null|array
*/
public function findManyWithCache(
array $arrFilter,
int $intCount = 0,
array $arrSort = [],
array $arrOptions = [],
string $strKey = '',
int $intLifeTime = 24 * 3600,
): null|array {
try {
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
return $arrResult;
}
$arrResult = $this->findMany($arrFilter, $intCount, $arrSort, $arrOptions);
$this->setCacheByKey($strKey, $arrResult, $intLifeTime);
return $arrResult;
} catch (\Exception $e) {
return [];
}
}
/**
* find one Video
*
* @param array $arrFilter
* @param array $arrOptions
* @return null|array
*/
public function findOne(array $arrFilter, array $arrOptions = []): null|array
{
if (empty($arrOptions)) {
$arrOptions = self::$arrOptions;
}
$arrVideo = $this->getOne($arrFilter, $arrOptions);
if (!empty($arrVideo)) {
applyToKeys($arrVideo, ['created_at', 'updated_at'], 'formatMongoDate');
}
return $arrVideo;
}
/**
* 根据小说ID查询指定小说
*
* @param integer $intNId
* @return array
*/
public function getVideoByNId(int $intNId): null|array
{
$arrFilter = ['n_id' => $intNId, 'n_have_chapter' => 1];
return $this->findOne($arrFilter);
}
/**
* 查询符合条件的随机多条小说
*
* @param string $strKey
* @param array $arrFilter
* @param integer $intCount
* @param integer $intLifeTime
* @return array
*/
public function getRandVideoWithCache(array $arrFilter = [], int $intCount = 10, string $strKey = '', int $intLifeTime = 24 * 3600,): array
{
try {
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
return $arrResult;
}
$arrFilter['n_have_chapter'] = 1;
$arrPipeline = [
['$match' => $arrFilter],
['$sample' => ['size' => $intCount]]
];
$Video = $this->getCol()->aggregate($arrPipeline);
$arrResult = iterator_to_array($Video);
$this->setCacheByKey($strKey, $arrResult, $intLifeTime);
return $arrResult;
} catch (\Exception $e) {
return [];
}
}
/**
* 通用小说分页
*
* @param array $arrFilter
* @param integer $intPage
* @param integer $intLimit
* @param array $arrSort
* @param string $strKey
* @param int $intLifeTime
* @return array
*/
public function findPaginatedWithCache(
array $arrFilter,
int $intPage = 1,
int $intLimit = 20,
array $arrSort = ['n_level' => -1],
string $strKey = '',
int $intLifeTime = 24 * 3600,
): array {
try {
$arrFilter['n_have_chapter'] = 1;
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
return $arrResult;
}
$arrOptions = self::$arrOptions;
$arrOptions['sort'] = $arrSort;
$arrOptions['skip'] = ($intPage - 1) * $intLimit;
$arrOptions['limit'] = $intLimit;
unset($arrOptions['typeMap']);
$Cursor = $this->getCol()->find($arrFilter, $arrOptions);
$intTotal = $this->getCol()->countDocuments($arrFilter);
$arrResult = iterator_to_array($Cursor);
shuffle($arrResult);
$arrResult = [
'data' => $arrResult,
'total' => $intTotal,
'page' => $intPage,
'limit' => $intLimit,
'pages' => ceil($intTotal / $intLimit)
];
$this->setCacheByKey($strKey, $arrResult, $intLifeTime);
return $arrResult;
} catch (\Exception $e) {
return [];
}
}
/**
* 用于Home下的书库分页
*
* @param string $strKey
* @param integer $intPage
* @param integer $intLimit
* @param int $intLifeTime
* @param integer $intType
* @param string $strStatus
* @param array $arrSort
* @return array
*/
public function getCustomPage01(
string $strKey,
int $intPage = 1,
int $intLimit = 20,
int $intLifeTime = 24 * 3600,
int $intType = 0,
$strStatus = NULL,
array $arrSort = ['n_level' => -1]
): array {
$arrFilter = ['n_have_chapter' => 1,];
switch ($intType) {
case 1:
$arrCategory = array_values(CategoryModel::getManCategory());
$arrFilter['n_category'] = ['$in' => $arrCategory];
break;
case 2:
$arrCategory = array_values(CategoryModel::getWomenCategory());
$arrFilter['n_category'] = ['$in' => $arrCategory];
break;
}
if ($strStatus !== NULL) {
$arrFilter['n_status'] = $strStatus;
}
return $this->findPaginatedWithCache($arrFilter, $intPage, $intLimit, $arrSort, $strKey, $intLifeTime,);
}
/**
* Undocumented function
*
* @param array $arrFilter
* @param integer $intCount
* @param array $arrSort
* @param string $strKey
* @param integer $intLifeTime
* @return array
*/
public function findManyShuffledWithCache(
array $arrFilter,
int $intCount = 10,
array $arrSort = [],
string $strKey = '',
int $intLifeTime = 24 * 3600,
): array {
try {
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
return $arrResult;
}
$arrFilter['n_have_chapter'] = 1;
$arrOptions = self::$arrOptions;
if (!empty($arrSort)) {
$arrOptions['sort'] = $arrSort;
}
$arrOptions['limit'] = $intCount * 3;
unset($arrOptions['typeMap']);
$Cursor = $this->getCol()->find($arrFilter, $arrOptions);
$arrResult = iterator_to_array($Cursor);
shuffle($arrResult);
$arrResult = array_slice($arrResult, 0, $intCount);
$this->setCacheByKey($strKey, $arrResult, $intLifeTime);
return $arrResult;
} catch (\Exception $e) {
return [];
}
}
/**
* Undocumented function
*
* @param string $strKey
* @param int $intLifeTime
* @param integer $intCount
* @param integer $intType
* @param string $strStatus
* @param array $arrSort
* @return array
*/
public function getCommonVideoOnCache(
string $strKey,
int $intLifeTime = 24 * 3600,
int $intCount = 10,
int $intType = 0,
$strStatus = NULL,
array $arrSort = ['n_level' => -1]
): array {
try {
$arrFilter = [];
if (in_array($intType, [1, 2])) {
$arrFilter['n_category'] = ['$in' => CategoryModel::getCategoryByType($intType)];
}
if ($strStatus !== NULL) {
$arrFilter['n_status'] = $strStatus;
}
return $this->findManyShuffledWithCache($arrFilter, $intCount, $arrSort, $strKey, $intLifeTime);
} catch (\Exception $e) {
return [];
}
}
/**
* Undocumented function
*
* @param string $strSign
* @param integer $intCount
* @param integer $intType
* @param string strDateType
* * daily 天
* * weekly 周
* * monthly 月
* * total 总
* @return array
*/
public function getRankVideoOnCache(string $strKey, int $intCount = 10, int $intType = 0, $strDateType = 'daily', $strStatus = NULL): array
{
try {
$intLifeTime = 24 * 3600;
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
return $arrResult;
}
$arrFilter = [
'nc_type' => $strDateType,
];
if ($strStatus !== NULL) {
$arrFilter['n_status'] = $strStatus;
}
if (in_array($intType, [1, 2])) {
$arrFilter['n_category'] = ['$in' => CategoryModel::getCategoryByType($intType)];
}
$arrOptions = [
'sort' => ['nc_clicks' => -1],
'limit' => $intCount * 3,
'projection' => [
'n_id' => 1,
],
];
$VideoClicksModel = VideoClicksModel::getInstance();
$Cursor = $VideoClicksModel->getCol()->find($arrFilter, $arrOptions);
$arrNId = [];
foreach ($Cursor as $Doc) {
$arrNId[] = $Doc['n_id'];
}
$arrFilter = ['n_id' => ['$in' => $arrNId]];
$arrOptions = self::$arrOptions;
unset($arrOptions['typeMap']);
$Cursor = $this->getCol()->find(
$arrFilter,
$arrOptions
);
$arrResult = iterator_to_array($Cursor);
shuffle($arrResult);
$arrResult = array_slice($arrResult, 0, $intCount);
$this->setCacheByKey($strKey, $arrResult, $intLifeTime);
return $arrResult;
} catch (\Exception $e) {
return [];
}
}
}

View File

@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace app\model;
use think\facade\Cache;
use think\Model;
/**
* @mixin think\Model
*/
class ZiYuanDuanDianModel extends BaseModel
{
protected $name = 'zi_yuan_duan_dian';
protected $pk = 'zydd_id';
static $arrZiYuanDuanDian = [];
static public function getDomainByCode($strCode)
{
if (self::$arrZiYuanDuanDian == []) {
self::$arrZiYuanDuanDian = Cache::get('Zydd');
if (empty(self::$arrZiYuanDuanDian)) {
self::flushCache();
self::$arrZiYuanDuanDian = Cache::get('Zydd');
}
}
return self::$arrZiYuanDuanDian[$strCode] ?? "";
}
static public function flushCache()
{
$arrZiYuanDuanDian = self::column('zydd_domain', 'zydd_code');
Cache::tag('Zydd')->set('Zydd', $arrZiYuanDuanDian);
}
}