123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916 |
- <?php
- namespace app\common\model;
- use app\common\library\Redis;
- use app\common\service\GussNovelService;
- use app\main\service\BookService;
- use app\common\service\BookRelationService;
- use BookCategory;
- use think\Config as ConfigAs;
- use think\Db;
- use think\Log;
- use think\Model;
- class Book extends BaseRwModel
- {
- // 表名
- protected $table = 'book';
- // 自动写入时间戳字段
- protected $autoWriteTimestamp = 'int';
- // 定义时间戳字段名
- protected $createTime = 'createtime';
- protected $updateTime = 'updatetime';
- // 追加属性
- protected $append = [
- 'state_text',
- 'free_stime_text',
- 'free_etime_text',
- 'last_chapter_utime_text',
- 'sex_text',
- 'category_text',
- 'billing_type_text',
- 'is_finish_text',
- 'corner_mark_text',
- 'cansee_text',
- 'rank_text',
- 'check_rank_text',
- 'is_expire',
- 'expire_time_text',
- ];
- public function getStateList()
- {
- return ['1' => '上架', '0' => '下架', '-1' => '入库'];
- }
- public function getCanseeList()
- {
- return ['1' => '可见', '0' => '不可见'];
- }
- public function getSexList()
- {
- return ['1' => '男频', '2' => '女频'];
- }
- public function getBillingTypeList()
- {
- return ['1' => '章', '2' => '本'];
- }
- public function getIsFinishList()
- {
- return ['0' => '连载', '1' => '完本'];
- }
- public function getCornerMarkList()
- {
- return ['hot' => '火热在推', 'exclusive' => '独家', 'new' => '新书'];
- }
- public function getIsExpireAttr($value,$data)
- {
- if(empty($data['expire_time'])){
- return 0;
- }
- if ($data['expire_time'] - time() < 3600*24*30){
- return 1;
- }
- return 2;
- }
- public function getExpireTimeTextAttr($value,$data)
- {
- return date('Y-m-d H:i:s',$data['expire_time']);
- }
- public function getRankTextAttr($value, $data)
- {
- $status = ['1'=>'不通过','2'=>'一级敏感','3'=>'二级敏感','4'=>'通过','5'=>'不收录','6'=>'二级可上架','0'=>'没有评级'];
- return $status[$data['rank']];
- }
- public function getCheckRankTextAttr($value, $data)
- {
- $status = ['1'=>'不合格','2'=>'合格','0'=>'未质检'];
- return $status[$data['check_rank']];
- }
- public function getCategoryName($book_category_id)
- {
- $category = model('BookCategory')->info($book_category_id);
- return $category['name'];
- }
- public function getCategoryTextAttr($value, $data)
- {
- $value = $value ? $value : $data['book_category_id'];
- $category = model('BookCategory')->info($value);
- return $category['name'];
- }
- public function getStateTextAttr($value, $data)
- {
- $value = $value ? $value : $data['state'];
- $list = $this->getStateList();
- return isset($list[$value]) ? $list[$value] : '';
- }
- public function getCornerMarkTextAttr($value, $data)
- {
- $value = $value ? $value : $data['corner_mark'];
- $list = $this->getCornerMarkList();
- return isset($list[$value]) ? $list[$value] : '';
- }
- public function getFreeStimeTextAttr($value, $data)
- {
- $value = $value ? $value : $data['free_stime'];
- return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
- }
- public function getFreeEtimeTextAttr($value, $data)
- {
- $value = $value ? $value : $data['free_etime'];
- return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
- }
- public function getLastChapterUtimeTextAttr($value, $data)
- {
- $value = $value ? $value : $data['last_chapter_utime'];
- return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
- }
- public function getSexTextAttr($value, $data)
- {
- $value = $value ? $value : $data['sex'];
- $list = $this->getSexList();
- return isset($list[$value]) ? $list[$value] : '';
- }
- public function getCanSeeTextAttr($value, $data)
- {
- $value = $value ? $value : $data['cansee'];
- $list = $this->getCanseeList();
- return isset($list[$value]) ? $list[$value] : '';
- }
- public function getBillingTypeTextAttr($value, $data)
- {
- $value = $value ? $value : $data['billing_type'];
- $list = $this->getBillingTypeList();
- return isset($list[$value]) ? $list[$value] : '';
- }
- public function getIsFinishTextAttr($value, $data)
- {
- $value = $value ? $value : $data['is_finish'];
- $list = $this->getIsFinishList();
- return isset($list[$value]) ? $list[$value] : '';
- }
- protected function setFreeStimeAttr($value)
- {
- return $value && !is_numeric($value) ? strtotime($value) : $value;
- }
- protected function setFreeEtimeAttr($value)
- {
- return $value && !is_numeric($value) ? strtotime($value) : $value;
- }
- protected function setLastChapterUtimeAttr($value)
- {
- return $value && !is_numeric($value) ? strtotime($value) : $value;
- }
- public function BookCategory()
- {
- return $this->belongsTo('BookCategory', 'book_category_id', 'id')->setEagerlyType(0);
- }
- /*
- * 检查书籍信息
- */
- public static function checkBookInfo($book)
- {
- $msg = '';
- //如果是按本收费,必须有价格。
- if ($book['billing_type'] == '2') {
- if (empty($book['price']) || $book['price'] <= 0) {
- return $msg = '书籍' . $book['id'] . '按本收费书籍必须填写价格';
- }
- }
- //名称、作者、封面、字数、描述、完结状态、首末章节信息
- if (empty($book['name'])) {
- return $msg = '书籍' . $book['id'] . '接口获取不到书籍名称';
- }
- if (empty($book['author'])) {
- return $msg = '书籍' . $book['id'] . '接口获取不到作者信息';
- }
- if (empty($book['image'])) {
- return $msg = '书籍' . $book['id'] . '接口获取不到封面';
- }
- if (empty($book['description'])) {
- return $msg = '书籍' . $book['id'] . '接口获取不到书籍描述';
- }
- if (empty($book['chapter_num'])) {
- return $msg = '书籍' . $book['id'] . '接口获取不到章节数';
- }
- if (empty($book['first_chapter_id']) || $book['first_chapter_id'] <= 0) {
- return $msg = '书籍' . $book['id'] . '接口获取不到章节数';
- }
- return $msg;
- }
- /**
- * 书籍信息 Redis缓存永久
- */
- public function BookInfo($id)
- {
- $redis = Redis::instance();
- $key = 'B:' . $id;
- if ($redis->exists($key)) {
- $info = $redis->hgetall($key);
- if (!is_array($info) || count($info) < 5 ) {
- $redis->del($key);
- $info = $this->get($id);
- if ($info) {
- $info = $info->toArray();
- //维护书籍互斥关系 wudd 《前台不做维护-20200115》 || !isset($info['relation_id'])
- //$info['relation_id']= BookRelationService::instance()->getBookRelationById( $id );
- $redis->hmset($key, $info);
- } else {
- return '';
- }
- }
- } else {
- $info = $this->get($id);
- if ($info) {
- $info = $info->toArray();
- //维护书籍互斥关系 wudd 《前台不做维护-20200115》
- //$info['relation_id']= BookRelationService::instance()->getBookRelationById( $id );
- $redis->hmset($key, $info);
- } else {
- return '';
- }
- }
- return $info;
- }
- /**************************通过API获取书籍信息***********************/
- /**
- * 根据书籍id获取存储路径
- *
- * @param $book_id
- * return string
- */
- protected static function getPath($book_id)
- {
- $path = '/' . substr($book_id, 0, 1) . 'x' . substr($book_id, 1, 1)
- . '/' . substr($book_id, 0, 2) . 'x' . substr($book_id, 2, 1)
- . '/' . substr($book_id, 0, 3) . 'x' . substr($book_id, 3, 1)
- . '/' . $book_id . '/';
- return $path;
- }
- /**
- * 获取单本书籍信息
- *
- * @param int $book_id 书籍ID
- * @return array
- */
- public static function getBookInfo($book_id)
- {
- $lastChapter = self::getChapterLimit($book_id, -1, -1);
- if (empty($lastChapter)) {
- Log::notice('获取末章信息失败!书籍ID:' . $book_id);
- return ['code' => 100];
- }
- $lastChapter = current($lastChapter);
- $firstChapter = self::getChapterLimit($book_id, 0, 0);
- if (empty($firstChapter)) {
- Log::notice('获取首章信息失败!书籍ID:' . $book_id);
- return ['code' => 100];
- }
- $firstChapter = current($firstChapter);
- $chapterCount = self::getChapterCount($book_id);
- if(ConfigAs::get('redis.change') == 1){
- $code = self::getCode('A03'.$book_id);
- $redis = Redis::instanceBookChange($code);
- $book = $redis->get("A03{$book_id}");
- $book = json_decode($book, true);
- }else {
- $redis = Redis::instanceBook();
- $book = $redis->get("basedata_book_{$book_id}");
- $book = json_decode(gzdecode($book), true);
- }
- if (strpos($book['coverWap'], 'cppartner') === false) {
- $cover = ConfigAs::get('api.cdn') . "/cppartner" . self::getPath($book['bookId']) . $book['coverWap'];
- } else {
- $cover = ConfigAs::get('api.cdn') . $book['coverWap'];
- }
- $extend = [];
- if (isset($book['extend'])){
- $extend = !is_array($book['extend'])?json_decode($book['extend'],true):$book['extend'];
- }
- $data = [
- "author" => $book['author'],
- "word_num" => $book['totalWordSize'] ?: 0,
- "first_chapter_id" => $firstChapter['id'],
- "first_chapter_name" => $firstChapter['name'],
- "last_chapter_id" => $book['lastChapterId'] ?? $lastChapter['id'],
- "last_chapter_name" => $book['lastChapterName'] ?? $lastChapter['name'],
- "last_chapter_utime" => empty($book['lastChapterUtime']) ? time() : strtotime($book['lastChapterUtime']),
- "description" => $book['introduction'],
- "chapter_num" => $chapterCount,
- "cover"=>$cover,
- "read_num" => $book['clickNum'],
- "name" => $book['bookName'],
- "is_finish" => strstr($book['status'], '连') === false ? 1 : 0,
- "id" => $book['bookId'],
- //wud 书籍互斥关系
- "childBookId"=>$book['childBookId'] ?? [],
- "parentBookId"=>$book['parentBookId'] ?? '',
- //同步书籍评级和质检状态 及质检备注
- "rank"=> $extend['grade'] ?? 0,
- "check_rank"=> !isset($extend['qaStatus'])? 0 : ($extend['qaStatus'] == 1 ? 2 : 1),
- 'check_remark'=>isset($extend['remark'])?substr($extend['remark'],0,140):'',
- 'cp_name'=>$book['cpPartnerName']??'',
- 'cp_id'=>$book['cpPartnerId']??0,
- 'tags' => $book['tag'] ?? '',
- ];
- return [
- 'data' => $data,
- 'code' => 0,
- 'msg' => 'success'
- ];
- // return self::getApi('bookinfo.do', ['book_id' => $book_id]);
- }
- /**
- * 获取多本书籍信息
- *
- * @param string $book_ids 书籍ID,书籍ID,书籍ID
- * @return array
- */
- public static function getBookInfos($book_ids)
- {
- $data = [];
- $ids = explode(',', $book_ids);
- foreach ($ids as $id) {
- if ($id) {
- $book = self::getBookInfo($id);
- if ($book['code'] != 0) {
- Log::notice('获取书籍信息失败!书籍ID:' . $id);
- return ['code' => 100];
- }
- $data[] = $book['data'];
- }
- }
- return [
- 'data' => $data,
- 'code' => 0,
- 'msg' => 'success'
- ];
- // return self::getApi('bookinfos.do', ['book_ids' => $book_ids]);
- }
- public static function getCode($val){
- $bKey = md5($val,true);
- $rv = (ord($bKey[3]) & 0xFF) << 24
- | (ord($bKey[2]) & 0xFF) << 16
- | (ord($bKey[1]) & 0xFF) << 8
- | ord($bKey[0]) & 0xFF;
- return $rv & 0xffffffff;
- }
- /**
- * 获取书籍章节信息
- * @deprecated use searchChapterByName getChapterList getChapterLimit
- * @param int $book_id 书籍ID
- * @param int $page_no 第几页
- * @param int $limit 单页条数
- * @return array
- */
- public static function getChapterListOld($book_id, $page_no = 1, $limit = 20, $search = '')
- {
- if(ConfigAs::get('redis.change') == 1){
- //Log::write('redis.change = 1','cctest');
- $code = self::getCode('A04'.$book_id);
- //Log::write('测试code = '.$code,'cctest');
- $redis = Redis::instanceBookChange($code);
- $list = $redis->zRange('A04' . $book_id, 0, -1);
- //dump($list);die;
- }else{
- $redis = Redis::instanceBook();
- $list = $redis->lRange("basedata_chapter_owchcp_{$book_id}", 0, -1);
- }
- $all = []; //全部章节
- $data = [
- 'data' => [],
- 'pageNo' => $page_no,
- 'limit' => $limit,
- 'totalNum' => 0,
- 'totalPage' => 0
- ];
- foreach ($list as $key => $value) {
- if(ConfigAs::get('redis.change') == 1){
- $json = json_decode($value, true);
- }else{
- $json = json_decode(gzdecode($value), true);
- }
- $chapter = [
- 'id' => $json[4] ?? $json['chapterId'],
- 'idx' => count($all) + 1,
- 'name' => $json[5] ?? $json['chapterName']
- ];
- if ($search) {
- if (!strstr($chapter['name'], $search)) {
- continue;
- }
- }
- $all[] = $chapter;
- }
- if ($limit > 0) {
- $data['data'] = array_slice($all, ($page_no - 1) * $limit, $limit);
- } else { //获取全部
- $data['data'] = $all;
- $data['limit'] = count($all);
- }
- if (!count($data['data'])) {
- Log::notice('获取章节列表失败!书籍ID:' . $book_id . ' 分页:' . $page_no . ' 条数:' . $limit);
- return $data;
- }
- $data['totalNum'] = count($all);
- $data['totalPage'] = ceil(count($all) / $limit);
- return [
- 'data' => $data,
- 'code' => 0,
- 'msg' => 'success'
- ];
- // return self::getApi('chapterlist.do', ['book_id' => $book_id, 'page_no' => $page_no, 'limit' => $limit]);
- }
- /**
- * 书籍章节列表redis的key
- * @param string $bookId 书籍id
- * @return string
- */
- private static function getChapterKey($bookId)
- {
- return 'A04' . $bookId;
- }
- /**
- * 通过章节名称搜索章节,此方法需要获取书籍所有章节列表,请不要在前台使用
- * @param $bookId
- * @param int $pageNo
- * @param int $limit
- * @param $name
- * @return array
- */
- public static function searchChapterByName($bookId, $pageNo = 1, $limit = 20, $name)
- {
- if (empty($name)) {
- return self::getChapterList($bookId, $pageNo, $limit);
- }
- $chapterKey = self::getChapterKey($bookId);
- $code = self::getCode($chapterKey);
- $redis = Redis::instanceBookChange($code);
- $list = $redis->zRange($chapterKey, 0, -1);
- $all = [];
- $data = [
- 'data' => [],
- 'pageNo' => $pageNo,
- 'limit' => $limit,
- 'totalNum' => 0,
- 'totalPage' => 0
- ];
- foreach ($list as $key => $value) {
- $json = json_decode($value, true);
- $chapter = [
- 'id' => $json[4] ?? $json['chapterId'],
- 'idx' => $key + 1,
- 'name' => $json[5] ?? $json['chapterName']
- ];
- if (!strstr($chapter['name'], $name)) {
- continue;
- }
- $all[] = $chapter;
- }
- if ($limit > 0) {
- $data['data'] = array_slice($all, ($pageNo - 1) * $limit, $limit);
- } else { //获取全部
- $data['data'] = $all;
- $data['limit'] = count($all);
- }
- if (!count($data['data'])) {
- Log::notice('获取章节列表失败!书籍ID:' . $bookId . ' 分页:' . $pageNo . ' 条数:' . $limit);
- return ['code' => 100];
- }
- $data['totalNum'] = count($all);
- $data['totalPage'] = ceil(count($all) / $limit);
- return [
- 'data' => $data,
- 'code' => 0,
- 'msg' => 'success'
- ];
- }
- /**
- * 获取书籍章节列表
- * @param $bookId
- * @param int $pageNo 当前页码
- * @param int $limit 每页显示条数
- * @return array
- */
- public static function getChapterList($bookId, $pageNo = 1, $limit = 20)
- {
- $chapterKey = self::getChapterKey($bookId);
- $code = self::getCode($chapterKey);
- $redis = Redis::instanceBookChange($code);
- $start = ($pageNo - 1) * $limit;
- $stop = $start + $limit - 1;
- $list = $redis->zRange($chapterKey, $start, $stop);
- $all = [];
- $data = [
- 'data' => [],
- 'pageNo' => $pageNo,
- 'limit' => $limit,
- 'totalNum' => 0,
- 'totalPage' => 0
- ];
- foreach ($list as $key => $value) {
- $json = json_decode($value, true);
- $chapter = [
- 'id' => $json[4] ?? $json['chapterId'],
- 'idx' => $start + $key + 1,
- 'name' => $json[5] ?? $json['chapterName']
- ];
- $all[] = $chapter;
- }
- $data['data'] = $all;
- $data['limit'] = count($all);
- if (!count($data['data'])) {
- Log::notice("获取章节列表失败!书籍ID:$bookId 分页:$pageNo 条数:$limit");
- return ['code' => 100];
- }
- $totalNum = self::getChapterCount($bookId);
- $data['totalNum'] = $totalNum;
- $data['totalPage'] = ceil($totalNum / $limit);
- return [
- 'data' => $data,
- 'code' => 0,
- 'msg' => 'success'
- ];
- }
- /**
- * 获取书籍章节数量
- * @param $bookId
- * @return int
- */
- public static function getChapterCount($bookId)
- {
- $chapterKey = self::getChapterKey($bookId);
- $code = self::getCode($chapterKey);
- $redis = Redis::instanceBookChange($code);
- $count = $redis->zCard($chapterKey);
- return $count;
- }
- /**
- * 按章节索引获取书籍章节列表
- * @param $bookId
- * @param $startIdx 起始索引,第一章的索引为0
- * @param $stopIdx 结束索引,最后一章的索引为-1,倒数第二章为-2
- * @return array
- */
- public static function getChapterLimit($bookId, $startIdx, $stopIdx)
- {
- $chapterKey = self::getChapterKey($bookId);
- $code = self::getCode($chapterKey);
- $redis = Redis::instanceBookChange($code);
- $list = $redis->zRange($chapterKey, $startIdx, $stopIdx);
- if (empty($list)) {
- Log::notice("获取章节列表失败!书籍ID:$bookId startIdx:$startIdx stopIdx:$stopIdx");
- return [];
- }
- foreach ($list as $key => $value) {
- $json = json_decode($value, true);
- $chapter = [
- 'id' => $json[4] ?? $json['chapterId'],
- 'idx' => $startIdx + $key + 1,
- 'name' => $json[5] ?? $json['chapterName']
- ];
- $all[] = $chapter;
- }
- return $all;
- }
- /**
- * 获取章节详情
- *
- * @param int $book_id 书籍ID
- * @param int $chapter_id 章节ID
- * @param int $type 分割格式 默认1<p> 2数组
- * @return array
- */
- public static function getChapterInfo($book_id, $chapter_id, $type = 1)
- {
- $chapterKey = self::getChapterKey($book_id);
- $code = self::getCode($chapterKey);
- $redis = Redis::instanceBookChange($code);
- $chapterList = $redis->zRangeByScore($chapterKey, $chapter_id, $chapter_id, array('limit' => array(0, 1)));
- if (empty($chapterList)) {
- Log::notice('获取章节列表失败!书籍ID:' . $book_id);
- return ['code' => 100];
- }
- $chapterInfoStr = current($chapterList);
- $chapterInfo = json_decode($chapterInfoStr, true);
- $data = [
- 'name' => $chapterInfo[5],
- 'idx' => $chapterInfo['k'] + 1,
- 'id' => $chapterInfo[4],
- ];
- $data['pre_id'] = $chapterInfo['l'] ?? '';
- $data['next_id'] = $chapterInfo['n'] ?? '';
- $redis = Redis::instance();
- $keyChapter = 'BCCT:' . $chapter_id;
- if ($type == 1 && $redis->exists($keyChapter)) {
- if (BookService::instance()->getChapterEditedModel()->getChapterFromDb($chapter_id)) {
- $data['from'] = 'db';
- } else {
- $data['from'] = 'cache';
- }
- $data['content'] = $redis->get($keyChapter);
- } else {
- $chapter_result = BookService::instance()->getChapter($book_id, $chapter_id)->data;
- $data['from'] = $chapter_result['from'];
- if (array_key_exists('name', $chapter_result)) {
- $data['name'] = $chapter_result['name'];
- }
- if ($content = $chapter_result['content']) {
- // if (false) {
- $content = str_replace("\r", '', $content);
- $arr = explode("\n", $content);
- $str = '';
- $newArr = [];
- foreach ($arr as &$value) {
- $value = ltrim($value);
- $value = mb_ereg_replace('^( | )+','', $value);
- $value = mb_convert_encoding($value, "UTF-8", "UTF-8"); //强制转换一次UTF-8编码
- if ($value) {
- if ($type == 1) {
- $str .= "<p>{$value}</p>";
- } else {
- $newArr[] = $value;
- }
- }
- }
- unset($value);
- if ($type == 1) {
- $data['content'] = $str;
- if (!empty($data['content'])) {
- $keyNum = 'BCN:' . $chapter_id . ':' . date('i');
- if ($redis->incr($keyNum) > 10) {
- $redis->setex($keyChapter, 86400, $data['content']);
- }
- $redis->expire($keyNum, 60);
- }
- } else {
- $data['content'] = $arr;
- }
- } else {
- Log::error('获取章节内容失败!书籍ID:' . $book_id . ' 章节ID:' . $chapter_id);
- if ($type == 1) {
- $data['content'] = '';
- } else {
- $data['content'] = [];
- }
- }
- }
- $json = json_decode($data['content'], true);
- if ($json) {
- $content = array_map(function ($item) {
- return '<p>' . $item . '</p>';
- }, $json);
- $data['content'] = implode('', $content);
- }
- return [
- 'data' => $data,
- 'code' => 0,
- 'msg' => 'success'
- ];
- // return self::getApi('chapterinfo.do', ['book_id' => $book_id, 'chapter_id' => $chapter_id]);
- }
- /**
- * 获取书籍头几章
- *
- * @param int $book_id 书籍ID
- * @param int $head 章节序号
- * @return array
- */
- public static function getHeadChapters($book_id, $head)
- {
- if ($head > 10) { //最多读取10章
- $head = 10;
- }
- $chapterList = self::getChapterLimit($book_id, 0, $head - 1);
- $data = [];
- foreach ($chapterList as $chapter) {
- $info = \app\main\service\BookService::instance()->getChapterInfo($book_id, $chapter['id']);
- if ($info->code != 0) {
- Log::error('获取章节内容失败!书籍ID:' . $book_id . ' 章节ID:' . $chapter['id']);
- return ['code' => 100];
- }
- if(is_string($info->data['content'])){
- preg_match_all('/<p>(.*?)<\/p>/', $info->data['content'], $match);
- if($match){
- $info->data['content'] = $match[1];
- $data[] = $info->data;
- }else{
- $data[] = $info->data;
- }
- }else{
- $data[] = $info->data;
- }
- }
- return [
- 'data' => $data,
- 'code' => 0,
- 'msg' => 'success'
- ];
- // return self::getApi('chapterinfos.do', ['book_id' => $book_id, 'head' => $head]);
- }
- /**
- * 批量获取书籍信息
- * @param array $ids 书籍id列表
- * @return array
- */
- public function getBooksInfo(array $ids)
- {
- if (empty($ids)) {
- return [];
- }
- $result = [];
- #region 从redis中获取书籍信息
- $keys = [];
- $dbIds = [];
- foreach ($ids as $id) {
- $keys[] = 'B:' . $id;
- }
- $getBooksInfoRedisIndex = Redis::splitKeysByRule($keys);
- $rdsBooksInfo = [];
- foreach ($getBooksInfoRedisIndex as $k => $v) {
- $redis = Redis::getRedisConnect($k);
- $pipe = $redis->multi(\Redis::PIPELINE);
- foreach ($v as $redisKey) {
- $pipe->hGetAll($redisKey);
- }
- $_rdsBooksInfo = $pipe->exec();
- $_rdsBooksInfo = array_filter($_rdsBooksInfo);
- $rdsBooksInfo = array_merge($rdsBooksInfo, $_rdsBooksInfo);
- }
- $rdsBookIds = [];
- foreach ($rdsBooksInfo as $item) {
- if (!is_array($item) || count($item) < 5) {
- continue;
- }
- $result[$item['id']] = $item;
- $rdsBookIds[] = $item['id'];
- }
- $dbIds = array_diff($ids, $rdsBookIds);
- #endregion
- #region 没有在redis中找到的书籍,从数据库中获取,并插入redis
- if (count($dbIds) > 0) {
- $dbBooksInfo = $this->whereIn('id', $dbIds)->select();
- if (count($dbBooksInfo) > 0) {
- $originBookInfo = [];
- $booksIdKey = [];
- foreach ($dbBooksInfo as $dbBookInfo) {
- $bookInfo = $dbBookInfo->toArray();
- //获取书籍的互斥关系 wdd 《前台不做维护-20200115》
- //$bookInfo['relation_id'] = BookRelationService::instance()->getBookRelationById( $bookInfo['id'] );
- $originBookInfo[$bookInfo['id']] = $bookInfo;
- $booksIdKey[] = 'B:' . $bookInfo['id'];
- }
- $writeBooksInfoRedisIndex = Redis::splitKeysByRule($booksIdKey);
- foreach ($writeBooksInfoRedisIndex as $k => $v) {
- $redis = Redis::getRedisConnect($k);
- $pipe = $redis->multi(\Redis::PIPELINE);
- foreach ($v as $redisKey) {
- $bookId = str_replace('B:', '', $redisKey);
- $result[$bookId] = $originBookInfo[$bookId];
- $pipe->hmset($redisKey, $originBookInfo[$bookId]);
- }
- $pipe->exec();
- }
- }
- }
- return $result;
- }
- /**
- * 获取作者其他书籍(随机选择一本书)
- * @param $expectBookid 书籍ID,排重
- * @param $author 作者名称
- * @param null $expectBookid
- */
- public function getBookIdByAuthor($author, $expectBookid = null, $sex = '1',$isWater=false)
- {
- $gussNovels = GussNovelService::instance()->getLikedNovels($sex,$isWater);
- // 跟猜你喜欢中的书籍进行滤重
- $gussBookIds = array_column($gussNovels, 'id');
- $waterWhere = $isWater ? ['classify_white_list'=>1] : [];
- $books = $this->where('author', 'eq', $author)
- ->where('state', 'eq', '1')
- ->where($waterWhere)
- ->select();
- if (!empty($expectBookid)) {
- foreach ($books as $k => $item) {
- if ($item['id'] == $expectBookid || in_array($item['id'],$gussBookIds)) {
- unset($books[$k]);
- }
- }
- }
- $books = array_values($books);
- if(empty($books)){
- return ;
- }else{
- $rand = rand(0, (count($books)-1));
- return $books[$rand]['id'];
- }
- }
- //获取当前渠道不能查看的书籍id
- public function getExclusiveBookIds($channel_id){
- $sql = 'select aeb.bid
- from exclusive_book aeb
- inner join exclusive ae on aeb.eid = ae.id and ae.endtime > '.time().' and ae.status = 1
- where aeb.bid not in(
- select distinct eb.bid
- from `exclusive_channel` as ec
- inner join `exclusive` as e on ec.eid = e.id and e.endtime > '.time().' AND e.status = 1
- inner join `exclusive_book` as eb on eb.eid = e.id
- where ec.cid = '.$channel_id.'
- ) and aeb.bid not in(
- select eb.bid from exclusive_book eb
- left join exclusive_channel ec on ec.eid=eb.eid
- where ec.id is null
- )';
- $rs = Db::query($sql);
- if(empty($rs)){
- return [];
- }
- return array_column($rs,'bid');
- }
- public function getVipExclusiveBookIds($channel_ids){
- $sql = 'select aeb.bid from exclusive_book aeb
- inner join exclusive ae on aeb.eid=ae.id and endtime>'.time().' and status=1 and
- aeb.bid not in(
- select eb.bid from exclusive_book eb
- inner join exclusive e on e.id=eb.eid and endtime>'.time().' and status=1
- inner join exclusive_channel ec on ec.eid=eb.eid
- where ec.cid in('.implode(',',$channel_ids).')
- )
- inner join exclusive_channel ec on ec.eid = ae.id';
- $rs = Db::query($sql);
- if(empty($rs)){
- return [];
- }
- return array_column($rs,'bid');
- }
- }
|