checkParamRequired(['bookId', 'type'], false); $bookId = $this->params['bookId']; $chapterId = empty($this->params['chapterId']) ? 0 : $this->params['chapterId']; $type = $this->params['type']; $bookInfo = BookService::instance()->getBookModel()->BookInfo($bookId); if (!$bookInfo) { $this->error("书籍不存在"); } //书籍已下架 if ($bookInfo['state'] == BookConstants::BOOK_STATE_OFF_SALE) { $result['state'] = ClientApiConstants::CHAPTER_STATE_BOOK_OFF_SALE; $this->info($result); } $needCostFee = true; $chapterInfoResult = BookService::instance()->getBookChapterInfoForClient($bookInfo, $chapterId, $type); if ($chapterInfoResult->code == ErrorCodeConstants::SUCCESS) { $chapterInfo = $chapterInfoResult->data; $result = [ 'chapter' => [ 'chapter_id' => $chapterInfo['id'], 'chapter_name' => $chapterInfo['name'], 'chapter_index' => $chapterInfo['idx'], 'book_id' => $bookId, 'next_chapter' => $chapterInfo['next_id'], 'pre_chapter' => $chapterInfo['pre_id'], 'content' => $chapterInfo['content'] ?: '', ] ]; if (isset($chapterInfo['status'])) { $result['chapter']['state'] = $chapterInfo['status']; } } elseif ($chapterInfoResult->code == ClientApiConstants::CHAPTER_NOT_EXIST && in_array($type, [ClientApiConstants::GET_CHAPTER_TYPE_PRE, ClientApiConstants::GET_CHAPTER_TYPE_NEXT])) { if ($bookInfo['is_finish'] == '1') {//完本 $result['state'] = ClientApiConstants::CHAPTER_STATE_NO_NEXT_FINISHED; } else { $result['state'] = ClientApiConstants::CHAPTER_STATE_NO_NEXT_SERIALIZING; } $needCostFee = false; } elseif ($chapterInfoResult->code == ClientApiConstants::CHAPTER_NOT_EXIST) { $needCostFee = false; $result['state'] = ClientApiConstants::CHAPTER_STATE_NO_CONTENT; } else { $this->error($chapterInfoResult->msg, $chapterInfoResult->code); } if ($needCostFee) { $feeResult = FinancialService::instance()->feeChapterForClient($this->userInfo, $bookInfo, $chapterInfo); if ($feeResult->code == ErrorCodeConstants::SUCCESS) { $feeInfo = $feeResult->data; if (!isset($result['chapter']['state'])) { $result['chapter']['state'] = $feeInfo['orderState']; } if (isset($feeInfo['cost'])) { $result['chapter']['cost'] = $feeInfo['cost']; } $result['state'] = $feeInfo['state']; if ($feeInfo['state'] == ClientApiConstants::CHAPTER_STATE_BALANCE_NOT_ENOUGH) { $result['billing_type'] = $bookInfo['billing_type']; $result['price'] = $feeInfo['cost']; } } else { $this->error($feeResult->msg, $feeResult->code); } } $this->info($result); } /** * 获取书籍目录接口 * @return mixed */ public function getchapters() { $this->checkParamRequired('bookId'); $bookId = $this->params['bookId']; $bookInfo = BookService::instance()->getBookModel()->BookInfo($bookId); if (!$bookInfo) { $this->error('书籍不存在'); } $chaptersResult = BookService::instance()->getChapterListForClient($bookId); if ($chaptersResult->code == ErrorCodeConstants::SUCCESS) { $chapters = $chaptersResult->data; $chapterList = []; foreach ($chapters as $chapter) { $chapterList[] = [ 'chapter_id' => $chapter['id'], 'chapter_name' => $chapter['name'], 'chapter_index' => $chapter['idx'], ]; } $lastChapter = end($chapterList); $result = ['chapter_list' => $chapterList]; if ($lastChapter) { $result['chapter_key'] = $lastChapter['chapter_id']; } $result['chapter_key'] = strval($bookInfo['last_chapter_id']); $this->success('', $result); } else { $this->error($chaptersResult->msg); } } /** * 获取书籍信息接口 */ public function getbookinfo() { $this->checkParamRequired('bookId'); $bookId = $this->params['bookId']; $recommendBookSize = $this->params['recommendBookSize'] ?? 9; $result = []; $bookInfoResult = ClientAppService::instance()->userReadBooksInfo([$bookId => ''], $this->userInfo); if ($bookInfoResult->code == ErrorCodeConstants::SUCCESS) { if (count($bookInfoResult->data['originalBookList']) > 0 && count($bookInfoResult->data['bookList']) > 0) { $originalBook = current($bookInfoResult->data['originalBookList']); $book = current($bookInfoResult->data['bookList']); $bookInfo = [ 'book_id' => $originalBook['id'], 'book_name' => $originalBook['name'], 'author' => $originalBook['author'], 'cover' => $originalBook['image'], 'state' => $book['state'], 'current_cid' => $book['current_cid'] ?? 0, 'action_time' => $book['action_time'] ?? 0, 'chapter_key' => $book['chapter_key'], 'is_finish' => $originalBook['is_finish'], 'word_count' => formatNumber($originalBook['word_count']) . '字', 'read_num' => formatNumber($originalBook['read_num']), 'category_text' => $originalBook['category_text'], 'description' => $originalBook['description'], 'last_chapter_id' => $originalBook['last_chapter_id'], 'last_chapter_name' => $originalBook['last_chapter_name'], 'last_chapter_utime' => $originalBook['last_chapter_utime'], 'chapter_num' => $originalBook['chapter_num'], ]; $result['book_info'] = $bookInfo; } else { throw new Exception('没有找到书籍信息,bookID:' . $bookId); } } else { throw new Exception($bookInfoResult->msg); } $sex = 0; if (!empty($this->userInfo)) { $sex = $this->userInfo['sex']; } $recommendBookIds = BookService::instance()->getRecommendBookIdsForClient($sex, $recommendBookSize); $needBookIds = array_diff($recommendBookIds, [$bookId]); $needBookIds = array_slice($needBookIds, 0, 8); $recommendBookIdsParams = []; foreach ($needBookIds as $recommendBookId) { $recommendBookIdsParams[$recommendBookId] = ''; } $recommendBooksInfoResult = ClientAppService::instance()->userReadBooksInfo($recommendBookIdsParams, $this->userInfo); if ($recommendBooksInfoResult->code != ErrorCodeConstants::SUCCESS) { throw new Exception($recommendBooksInfoResult->msg); } $result['recommend_book_list'] = $recommendBooksInfoResult->data['bookList']; $this->info($result); } /** * 书架接口 */ public function syncbookshelf() { $this->checkParamRequired('json'); $bookParamsStr = $this->params['json']; $bookParamsList = json_decode($bookParamsStr, true); $userId = $this->userInfo['id'] ?? null; $bookParams = []; $recentUpBookIds = []; $recentDelBookIds = []; foreach ($bookParamsList as $bookParam) { $bookId = $bookParam['bookId']; $bookParams[$bookId] = $bookParam['chapterKey']; } if (!empty($this->userInfo)) {//登录后的用户处理更新与删除 foreach ($bookParamsList as $bookParam) { $bookId = $bookParam['bookId']; switch ($bookParam['operate']) { case ClientApiConstants::RECENT_OPERATE_UPDATE: $recentUpBookIds[] = $bookId; break; case ClientApiConstants::RECENT_OPERATE_DELETE: $recentDelBookIds[] = $bookId; break; default: break; } } } //获取书籍信息和最近阅读信息 $booksInfoResult = ClientAppService::instance()->userReadBooksInfo($bookParams, $this->userInfo, true); if ($booksInfoResult->code != ErrorCodeConstants::SUCCESS) { throw new Exception($booksInfoResult->msg); } $bookList = $booksInfoResult->data['bookList']; $originalBookList = $booksInfoResult->data['originalBookList']; $recentList = isset($booksInfoResult->data['recentList']) ? $booksInfoResult->data['recentList'] : []; //更新最近阅读 foreach ($recentUpBookIds as $recentUpBookId) { //待更新书籍的章节列表 $chaptersResult = BookService::instance()->getChapterListForClient($recentUpBookId); if ($chaptersResult->code != ErrorCodeConstants::SUCCESS) { LogService::error(sprintf('更新最近阅读失败,userId:%s,bookId:%s,msg:%s', $userId, $recentUpBookId, $chaptersResult->msg)); continue; } $chapterList = $chaptersResult->data; //从输入参数中获取待更新书籍对象 $bookUpParamsItem = ArrayHelper::array_column_search($bookParamsList, 'bookId', $recentUpBookId); //从章节列表获取用户阅读最新章节的"阅读记录对象" $chapterItem = ArrayHelper::array_column_search($chapterList, 'id', $bookUpParamsItem['currentCid']); if (empty($chapterItem)) { LogService::error(sprintf('没有找到书籍指定章节,bookId:%s,currentCid:%s', $recentUpBookId, $bookUpParamsItem['currentCid'])); continue; } //从数据库获取待更新书籍原始对象 // $bookItem = ArrayHelper::array_column_search($originalBookList, 'id', $recentUpBookId); $upRecentResult = BookService::instance()->setRecentlyRead($chapterItem['name'], $chapterItem['id'], $recentUpBookId, $userId, $chapterItem['idx']); if ($upRecentResult->code != ErrorCodeConstants::SUCCESS) { $this->error($upRecentResult->msg, $upRecentResult->code); } #region 更新阅读记录后,将最新的阅读章节信息返回 foreach ($bookList as &$orgBookItem) { if ($recentUpBookId == $orgBookItem['book_id']) { $orgBookItem['current_cid'] = $chapterItem['id']; $orgBookItem['current_c_name'] = $chapterItem['name']; $orgBookItem['action_time'] = strval(time()); } } #endregion } $delRecentIds = []; $delRecentBookIds = []; //删除最近阅读记录 foreach ($recentDelBookIds as $recentDelBookId) { $recentItem = ArrayHelper::array_column_search($recentList, 'book_id', $recentDelBookId); #region 在返回的书籍列表中删除需要在阅读记录删除的书籍信息 foreach ($bookList as $key => $item) { if ($item['book_id'] == $recentDelBookId) { unset($bookList[$key]); break; } } #endregion if (empty($recentItem)) { LogService::error(sprintf('删除最近阅读失败,用户没有阅读过这本书,userId:%s,bookIds:%s', $userId, $recentDelBookId)); continue; } $delRecentIds[] = $recentItem['id']; $delRecentBookIds[] = $recentItem['book_id']; } if (count($delRecentIds) > 0 && count($delRecentBookIds) > 0) { $delRecentResult = BookService::instance()->removeRecentlyRead($delRecentIds, $delRecentBookIds, $userId); if ($delRecentResult->code != ErrorCodeConstants::SUCCESS) { LogService::error(sprintf('删除最近阅读失败,userId:%s,msg:%s', $userId, $delRecentResult->msg)); } } foreach ($bookList as &$bookItem) { if (empty($bookItem['action_time'])) { $paramItem = ArrayHelper::array_column_search($bookParamsList, 'bookId', $bookItem['book_id'], true); $bookItem['action_time'] = strval($paramItem['actionTime']); } } $bookList = array_values($bookList); $result['book_list'] = $bookList; $this->info($result); } /** * 书籍详情页推荐书籍接口 * @throws Exception */ public function recommendbooks() { $this->checkParamRequired(['bookIds', 'size']); $strExcludeBookIds = $this->params['bookIds']; $excludeBookIds = explode(',', $strExcludeBookIds);//需要排除的书籍id列表 $size = $this->params['size']; $sex = 0; if (!empty($this->userInfo)) { $sex = $this->userInfo['sex']; } //推荐书籍id列表,获取的数量是客户端展示数量的3倍,用于随机处理。 $recommendBookIds = BookService::instance()->getRecommendBookIdsForClient($sex, $size * 3); //过滤需要排除的书籍id列表 $needBookIds = array_diff($recommendBookIds, $excludeBookIds); //随机获取书籍id的key $needBookKeys = array_rand($needBookIds, $size); $needBookResIds = []; foreach ($needBookKeys as $needBookKey) { //获取需要输出的书籍id列表 $needBookResIds[$needBookIds[$needBookKey]] = ''; } $booksInfoResult = ClientAppService::instance()->userReadBooksInfo($needBookResIds, $this->userInfo); if ($booksInfoResult->code != ErrorCodeConstants::SUCCESS) { throw new Exception($booksInfoResult->msg); } $result['recommend_book_list'] = $booksInfoResult->data['bookList']; $this->info($result); } }