This commit is contained in:
Default
2025-04-21 11:56:50 +08:00
parent 3216cffb5e
commit 65b8710bff
17 changed files with 2432 additions and 55 deletions

View File

@@ -242,7 +242,7 @@ class NovelModel extends MongoModel
): array {
try {
$arrFilter['n_have_chapter'] = 1;
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
return $arrResult;
@@ -417,10 +417,16 @@ class NovelModel extends MongoModel
* * total 总
* @return array
*/
public function getRankNovelOnCache(string $strKey, int $intCount = 10, int $intType = 0, $strDateType = 'daily', $strStatus = NULL): array
{
public function getRankNovelOnCache(
string $strKey,
int $intCount = 10,
int $intType = 0,
$strDateType = 'daily',
$strStatus = NULL,
$intLifeTime = 24 * 3600,
): array {
try {
$intLifeTime = 24 * 3600;
$arrResult = $this->checkCacheByKey($strKey);
if ($arrResult !== NULL) {
@@ -477,8 +483,4 @@ class NovelModel extends MongoModel
return [];
}
}
}

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 [];
}
}
}