header('x-package', ''); if (!$book_info) { return response()->error('QAPP_SYS_ERROR'); } $book_auth = BookConfigService::bookCopyright($bid, $this->distribution_channel_id); if ($book_auth == 2) { return response()->error('QAPP_OFF_SHELF'); } //yuyuedu、xinghe 快应用这两个cp的书屏蔽下 if (in_array($book_info->cp_source, getHiddenCp($package)) && $book_auth != 1) { return response()->error('QAPP_OFF_SHELF'); } if ($this->distribution_channel_id == 7477 && $bid == 13765) { $book_info->is_on_shelf = 2; } $special = get_special_bid(); if (in_array($this->distribution_channel_id, [9487, 9390]) && in_array($book_info->bid, $special)) { $book_info->is_on_shelf = 2; } if ($bid == 58886) { $book_info->is_on_shelf = 0; } if (!in_array($book_info->is_on_shelf, [1, 2])) { return response()->error('QAPP_OFF_SHELF'); } $is_on_shelf = UserShelfBooksService::getUserShelfBooksListByUidAndBid($this->uid, $bid); $book_info['is_on_user_shelf'] = 0; if ($is_on_shelf) { $book_info['is_on_user_shelf'] = 1; } $last_chapter = ChapterService::getChapterNameById($book_info['last_cid'], $bid); $book_info->last_chapter = $last_chapter['name']; list($is_split, $is_change_chapter_name) = BookService::splitContent($bid); if ($is_split && ($book_info->channel_name == '男频' || $is_change_chapter_name)) { $book_info->last_chapter = '第' . $book_info->chapter_count . '章'; } $book_info['last_chapter_is_vip'] = $last_chapter['is_vip']; $book_info['is_need_charge'] = $this->isNeedCharge($bid, $last_chapter, $book_info); $record = ReadRecordService::getBookReadRecordStatic($this->uid, $bid); if ($record) { $book_info['record_chapter_id'] = $record['record_chapter_id']; $book_info['record_chapter_name'] = $record['record_chapter_name']; } return response()->item(new BookTransformer(), $book_info); } /** * 获取订购记录 * @param $book_info * @param $chapter_id * @return bool */ protected function getOrderRecord($bid, $chapter_id) { //包年记录 $uid = $this->uid; $res = YearOrderService::getRecord($uid); if ($res) return true; $res = null; //单本订购记录 $res = BookOrderService::getRecordByuidBid($uid, $bid); if ($res) return true; $res = null; //章节订购记录 $chapterOrder = new ChapterOrderService(); if ($chapterOrder->checkIsOrdered($uid, $bid, $chapter_id)) return true; return false; } /** * 判断是否需要充值 */ private function isBookNeedCharge(int $bid, float $price) { $book_order = $this->getOrderRecord($bid, 0); if ($book_order) { return false; } else { $user_info = $this->user_info; return $user_info['balance'] < $price; } } /** * 判断章节是否需要充值 */ private function isChapterNeedCharge(int $bid, int $cid, float $price) { $book_order = $this->getOrderRecord($bid, $cid); if ($book_order) { return false; } else { $user_info = $this->user_info; return $user_info['balance'] < $price; } } /** * 判断是否需要充值 */ private function isNeedCharge(int $bid, $last_chapter, $book_info) { $is_free = BookConfigService::judgeBookIsFree($bid); if ($is_free) { return false; } switch ($book_info->charge_type) { case 'BOOK': $price = $this->getPrice($book_info); return $this->isBookNeedCharge($bid, $price); default: $price = isset($last_chapter->is_vip) ? $this->getPrice($book_info, $last_chapter->size) : 0; return isset($last_chapter->is_vip) ? $this->isChapterNeedCharge($bid, $last_chapter->id, $price) : false; } } /** * 计算价格 * @param $book_info * @param $chapter_size * @return float */ protected function getPrice($book_info, $chapter_size = 0) { if ($book_info->charge_type == 'BOOK') return $book_info->price * 100; return ceil($chapter_size / 100); } /** * 首页 */ public function getBookLists(Request $request, $sex) { // 获取基本数据 $package = $request->header('x-package', ''); $brand = $request->header('x-nbrand', ''); // $codeVersion = $request->header('x-codeversion', ''); $codeVersion = $request->header('x-version', ''); $user = (new QappUserService)->getGolableUser(); if ($package == "com.beidao.kuaiying.yueai" && $sex == "male" && isset($user->uid) && !empty($user->uid) && ($user->send_order_id > 0 || $user->user->send_order_id > 0)) { $orderRecord = ChapterOrderService::hasUserRecord($user->uid); if ($orderRecord) { $result = HomeCache::getHomePageInfo($package, $sex . "_dispatch"); if (is_empty($result)) { $result = $this->getHomeDataFromDb($request, $sex); HomeCache::setHomePageInfo($package, $sex . "_dispatch", $result, 86400 + rand(0, 100)); } return response()->success($result); } } if ($package == "com.beidao.kuaiying.hupoyuedu" && $sex == "male" && isset($user->uid) && !empty($user->uid) && ($user->send_order_id > 0 || $user->user->send_order_id > 0)) { $has_recharge = \App\Modules\Trade\Models\Order::where(['uid' => $user->uid, 'status' => "PAID"])->value('trade_no'); if ($has_recharge) { $result = HomeCache::getHomePageInfo($package, $sex . "_dispatch"); if (is_empty($result)) { $result = $this->getHomeDataFromDb($request, $sex); HomeCache::setHomePageInfo($package, $sex . "_dispatch", $result, 86400 + rand(0, 100)); } return response()->success($result); } } $result = HomeCache::getHomePageInfo($package, $sex); if (is_empty($result)) { $result = $this->getHomeDataFromDb($request, $sex); HomeCache::setHomePageInfo($package, $sex, $result, 86400 + rand(0, 100)); } return response()->success($result); } /**** * 从数据库获取首页数据 * name: getHomeDataFromDb * @param Request $request * @param $sex * @return array|array[] * date 2022/12/06 15:51 */ protected function getHomeDataFromDb(Request $request, $sex) { $package = $request->header('x-package', ''); $brand = $request->header('x-nbrand', ''); // $codeVersion = $request->header('x-codeversion', ''); $codeVersion = $request->header('x-version', ''); $isAuth = check_qapp_auth($package, 0); //新判断: 根据包名来获取对应所需的bid $qapp_package = QappPackage::getPackageByPackage($package); if ($qapp_package) { $package_id = $qapp_package->id; } else { $package_id = 0; } if (Utils::checkIsAudit($package, $brand, $codeVersion) || $isAuth == false) { return BookAuditService::getHomeBooksData($sex, $package, $isAuth,$package_id); } $user = (new QappUserService)->getGolableUser(); if ($package == "com.beidao.kuaiying.yueai" && $sex == "male" && isset($user->uid) && !empty($user->uid) && $user->send_order_id > 0) { $orderRecord = ChapterOrderService::hasUserRecord($user->uid); if ($orderRecord) { return BookAuditService::getYueaiHomeBooksData($sex, $package, $isAuth, 1,$package_id); } } if ($sex == 'male') { $channel = 1; $reco_banner_type = ['MALE', 'PUBLIC']; } else { $reco_banner_type = ['FEMALE', 'PUBLIC']; $channel = 2; } if ($isAuth) { $books = $this->getDefaultBanner($reco_banner_type); } else { $home = config('home.ycsd'); $banner = $home['reco_banner']; $books = $banner[$sex]; } if ($package == "com.beidao.kuaiying.hupoyuedu" && $sex == "male" && isset($user->uid) && !empty($user->uid) && ($user->send_order_id > 0 || $user->user->send_order_id > 0)) { $has_recharge = \App\Modules\Trade\Models\Order::where(['uid' => $user->uid, 'status' => "PAID"])->value('trade_no'); if ($has_recharge) { return BookAuditService::getHuPoHomeBooksData($channel, $books, $package_id, $package); } } \Log::info('un_send_order_book:package_id1:' . $package_id . ' $package:' . $package); if (isset($user->uid) && !empty($user->uid)) { if (!$this->send_order_id || $this->send_order_id == 0) { \Log::info('un_send_order_book:uid:' . $this->uid . ' $package:' . $package); $result = $this->getCheckBids($channel, $books, $package_id, $package); if (isset($result[1]['books']) && count((array)$result[1]['books']) > 1) { return $result; } return $this->getCheckBids($channel, $books, 0, $package); } else { $package_id = 0; } \Log::info('un_send_order_book:package_id2:' . $package_id . ' $package:' . $package); } else { $package_id = 0; } \Log::info('un_send_order_book:package_id3:' . $package_id . ' $package:' . $package); return $this->getCheckBids($channel, $books, $package_id, $package); } /** * 根据包名 * @param $channel * @param $books * @param $package_id * @return array */ private function getCheckBids($channel, $books, $package_id, $package) { $hotBids = QappRecommendService::getRecommendByPacketId($channel, 'hot', $package_id); $liveBids = QappRecommendService::getRecommendByPacketId($channel, 'live', $package_id); $recomBids = QappRecommendService::getRecommendByPacketId($channel, 'recom', $package_id); $newBids = QappRecommendService::getRecommendByPacketId($channel, 'new_recom', $package_id); [$hotBids, $liveBids, $recomBids, $newBids] = BookConfigService::HomePageRecomBookCheck($hotBids, $liveBids, $recomBids, $newBids,$package_id, $package,$channel); return array_filter([ ['type' => 'reco_banner', 'lable' => '首页banner', 'books' => $books], ['type' => 'hot', 'lable' => '热门书单', 'books' => collectionTransform(new BookTransformer, BookConfigService::getBooksByIds($hotBids))], ['type' => 'zhibo', 'lable' => '神书直播', 'books' => collectionTransform(new BookTransformer, BookConfigService::getBooksByIds($liveBids))], ['type' => 'recom', 'lable' => '小编精选', 'books' => collectionTransform(new BookTransformer, BookConfigService::getBooksByIds($recomBids))], ['type' => 'new_recom', 'lable' => '人气新书', 'books' => collectionTransform(new BookTransformer, BookConfigService::getBooksByIds($newBids))] ]); } /** * 根据包名 * @param $channel * @param $books * @param $package_id * @return array */ private function getCheckBidsOld($channel, $books, $package_id, $package) { $isAuthor = check_qapp_auth($package_id, 1); $hotBids = BookConfigService::getCheckBooks(QappRecommendService::getRecommendByPacketId($channel, 'hot', $package_id), $channel, $package, $isAuthor); $liveBids = BookConfigService::getCheckBooks(QappRecommendService::getRecommendByPacketId($channel, 'live', $package_id), $channel, $package, $isAuthor); $recomBids = BookConfigService::getCheckBooks(QappRecommendService::getRecommendByPacketId($channel, 'recom', $package_id), $channel, $package, $isAuthor); $newBids = BookConfigService::getCheckBooks(QappRecommendService::getRecommendByPacketId($channel, 'new_recom', $package_id), $channel, $package, $isAuthor); // myLog("Qapp_home_data")->info(['liveBids' =>$liveBids,'hotbids'=>$hotBids,'new' => $newBids,'recom'=> $recomBids]); return array_filter([ ['type' => 'reco_banner', 'lable' => '首页banner', 'books' => $books], ['type' => 'hot', 'lable' => '热门书单', 'books' => collectionTransform(new BookTransformer, BookConfigService::getBooksByIds($hotBids))], ['type' => 'zhibo', 'lable' => '神书直播', 'books' => collectionTransform(new BookTransformer, BookConfigService::getBooksByIds($liveBids))], ['type' => 'recom', 'lable' => '小编精选', 'books' => collectionTransform(new BookTransformer, BookConfigService::getBooksByIds($recomBids))], ['type' => 'new_recom', 'lable' => '人气新书', 'books' => collectionTransform(new BookTransformer, BookConfigService::getBooksByIds($newBids))] ]); } /** * 检测并补充不满足条件的书籍id * @param $bid_list * @param $channel : 频道 * @param $package : 包名 * @return array */ private function getCheckBooks($bid_list, $channel, $package, $is_author) { $hidden_cp = getHiddenCp($package); // if(!is_public_package($package)){ // $hidden_cp = array_merge($hidden_cp,['lianshang']); // } //获取书本数量 $count = count($bid_list); if (!$is_author) { $where = [ ['book_configs.charge_type', '!=', 'BOOK'], ['book_configs.cp_source', '=', 'ycsd'], ]; } else { $where = [ ['book_configs.charge_type', '!=', 'BOOK'], ]; } //获取当前有效书本数量 $book_count = BookConfig::join('books', 'book_configs.bid', '=', 'books.id') ->leftjoin('book_categories', 'books.category_id', 'book_categories.id') ->whereIn('book_configs.bid', $bid_list) ->where('book_configs.is_on_shelf', 2) ->where('book_configs.charge_type', '!=', 'BOOK') ->whereNotIn('book_configs.cp_source', $hidden_cp) ->where($where) ->where('book_categories.pid', $channel) ->count(); if ($count == $book_count) { return $bid_list; } //获取需要补充的书籍数量 $supplement_count = (($count - $book_count) > 0) ? $count - $book_count : 0; if ($supplement_count <= 0) { return $bid_list; } //获取书籍交集bid,过滤掉不符合要求的书 $bids = BookConfig::join('books', 'book_configs.bid', '=', 'books.id') ->leftjoin('book_categories', 'books.category_id', 'book_categories.id') ->whereIn('book_configs.bid', $bid_list) ->where('book_configs.is_on_shelf', 2) ->where($where) ->whereNotIn('book_configs.cp_source', $hidden_cp) ->where('book_categories.pid', $channel) ->pluck('book_configs.bid')->all(); $bid_list = array_intersect($bid_list, $bids); //获取随机的有效的书籍bid $rand_bid = BookConfig::join('books', 'book_configs.bid', '=', 'books.id') ->leftjoin('book_categories', 'books.category_id', 'book_categories.id') ->where('book_configs.is_on_shelf', 2) // ->where('book_configs.charge_type','!=','BOOK') ->where($where) ->whereNotIn('book_configs.cp_source', $hidden_cp) ->where('book_categories.pid', $channel) ->inRandomOrder() ->limit($supplement_count) ->get()->pluck('bid')->toArray(); return array_filter(array_merge($bid_list, $rand_bid)); } private function getBidCidFromUrl(string $url) { if (preg_match('/\?bid=(\w+)\S+cid=(\w+)/', $url, $matches) || preg_match('/\?id=(\w+)/', $url, $matches)) { return [ 'bid' => $matches[1], 'cid' => isset($matches[2]) ? $matches[2] : 0, ]; } else { return [ 'bid' => '', 'cid' => 0, ]; } } public function library(Request $request) { $package = $request->header('x-package', ''); if (in_array($package, ["com.app.kyy.dmzyd", "com.app.kyy.tths"])) { // return $this->getSpecialLibrary($request); } $where = []; $order = []; $where['is_on_shelf'] = [2]; $category_id = $request->input('category_id'); if ($category_id) { if ($category_id == 1) { $where['channel_name'] = '男频'; } elseif ($category_id == 2) { $where['channel_name'] = '女频'; } else { $where['category_id'] = $category_id; } } $key = $request->input('key'); $uid = $request->input('uid', 0); if ($key && $uid && is_numeric($uid)) { BookConfigService::saveUserSearchLog($key, $uid); } $where['key'] = $key; $order_field = $request->input('order_field'); $order_seq = $request->input('order_seq'); if ($order_field != '' && in_array($order_field, ['recommend_index', 'click_count', 'update', 'size', 'create'])) { if ($order_field == 'update') { $order = ['book_configs.updated_at', 'desc']; } elseif ($order_field == 'create') { $order = ['book_configs.created_at', 'desc']; } else { $order = [$order_field, 'desc']; } if ($order_seq == 'asc') { $order = [$order_field, 'asc']; } if ($order_seq == 'desc') { $order = [$order_field, 'desc']; } } // 审核状态默认值 $package = $request->header('x-package', ''); $brand = $request->header('x-nbrand', ''); // $codeVersion = $request->header('x-codeversion', ''); $codeVersion = $request->header('x-version', ''); if ($order_field === 'recommend_index' && Utils::checkIsAudit($package, $brand, $codeVersion)) { $order = ['book_configs.bid', 'desc']; } // 是否只使用原创书殿的书 $isAuth = check_qapp_auth($package, 0); if (!$isAuth) { $where['cp_source'] = "ycsd"; } $status = $request->input('status'); if ($status != '') { $where['status'] = $status; } // 搜索关键词的情况下,屏蔽书籍完本状态 if ($key && isset($where['status'])) { unset($where['status']); } $page_size = $request->input('page_size', 15); $where['channel_id'] = $request->input('distribution_channel_id', 0); $books = BookConfigService::getBooks($where, $order, $page_size); return response()->pagination(new BookTransformer, $books); } public function hotWords(Request $request) { $result = BookConfigService::findBookKeywords(); return response()->pagination(new KeywordTransformer, $result); } public function similarRecom(Request $request) { $package = $request->header('x-package', ''); $category_id = $request->input('category_id'); $bid = $request->input('bid'); $package = $request->header('x-package', ''); if (empty($bid) || (empty($category_id) && $category_id != 0)) { return response()->error('PARAM_ERROR'); } $isAuth = check_qapp_auth($package, 0); $bid = BookService::decodeBidStatic($bid); $where = ['category_id' => $category_id, 'is_on_shelf' => [2]]; if (!$isAuth) { $where['cp_source'] = "ycsd"; } $where['channel_id'] = $request->input('distribution_channel_id', 0); $books = BookConfigService::getBooks($where, [], 4); $data = []; foreach ($books as $v) { if ($v->bid != $bid && count($data) < 3) { $data[] = $v; } } return response()->collection(new BookTransformer(), $data); } public function readOverRecommend(Request $request) { $bid = $request->input('bid'); if (empty($bid)) { return response()->error('PARAM_ERROR'); } $bid = BookService::decodeBidStatic($bid); $book_info = BookConfigService::getBookById($bid); $res = BookConfigService::getRecommendBooks($bid, $book_info->channel_name); $urge_status = 0; if ($book_info->status == 0 && !BookUrgeUpdateService::isHadUrged($this->uid, $bid)) { $urge_status = 1; } $recommend_result = collectionTransform(new BookTransformer(), $res); $book_status = [ 'status' => $book_info->status, 'urge_status' => $urge_status ]; $data = [ 'recommend_result' => $recommend_result, 'book_status' => $book_status ]; return response()->success($data); } public function rank(Request $request) { // 1:男频,2:女频 $sex = (int)$request->input('sex'); $package = $request->header('x-package', ''); $channel_id = $request->input('distribution_channel_id', 0); if (!in_array($sex, [1, 2], true)) { return response()->error('PARAM_ERROR'); } $result = HomeCache::getRankPageInfo($package, $sex); // $result = null; if (is_empty($result)) { $result = $this->getRankData($package, $sex, $channel_id); if (!is_empty($result)) { HomeCache::setRankPageInfo($package, $sex, $result, 86400 + rand(0, 100)); } } return response()->success($result); } protected function getRankData($package, $sex, $channel_id) { $bids = BookConfigService::getAvailableBIdsbyBids(BookConfigService::getRankList($package, $sex), $channel_id, false); if (count($bids) > 30) { $bids = array_chunk($bids, 30)[0]; } else { $bids = [11529, 11941, 12720, 11990, 11988, 11976, 11977, 4183, 12717, 11833, 7287, 14297, 12716, 14312, 14000, 13577, 16712, 13002, 12717, 15103, 13928, 14793, 12708, 13286]; if ($sex === 2) { $bids = [8469, 11660, 9117, 7891, 12281, 12470, 8167, 11661, 11670, 8476, 8557, 11662, 11680, 11926, 12462, 7836, 11681, 11664, 11928, 8631]; } } return collectionTransform(new BookTransformer, BookConfigService::getBookLists(compact('bids', 'channel_id'))); } public function rankOld(Request $request) { // 1:男频,2:女频 $sex = (int)$request->input('sex'); if (!in_array($sex, [1, 2], true)) { return response()->error('PARAM_ERROR'); } // 默认 $bids = [11529, 11941, 12720, 11990, 11988, 11976, 11977, 4183, 12717, 11833, 7287, 14297, 12716, 14312, 14000, 13577, 16712, 13002, 12717, 15103, 13928, 14793, 12708, 13286]; if ($sex === 2) { $bids = [8469, 11660, 9117, 7891, 12281, 12470, 8167, 11661, 11670, 8476, 8557, 11662, 11680, 11926, 12462, 7836, 11681, 11664, 11928, 8631]; } /** * pid:1为男频 2为女频 * SELECT * CONCAT( books.id, ',' ) * FROM * books * LEFT JOIN book_configs ON books.id = book_configs.bid * WHERE * book_configs.is_on_shelf = 2 * AND books.category_id IN ( SELECT id FROM book_categories WHERE pid = 2 ) * ORDER BY * book_configs.recommend_index DESC * LIMIT 10; */ // 根据包名、平台、版本号判断是否审核 $package = $request->header('x-package', ''); $brand = $request->header('x-nbrand', ''); // $codeVersion = $request->header('x-codeversion', ''); $codeVersion = $request->header('x-version', ''); if (Utils::checkIsAudit($package, $brand, $codeVersion)) { $bids = [2266, 3838, 9700, 10175, 10301, 3422, 1166, 4546, 9163, 2509, 7287, 14297, 12716, 14312, 14000, 13577, 16712, 13002, 12717, 15103, 13928, 14793, 12708, 13286, 13336, 13275, 13073, 15121, 13929, 12693, 13254, 3526, 10313, 3483, 13278, 14004, 4098, 10378, 14072, 21376, 21139, 21757, 19449]; if ($sex === 2) { $bids = [159, 2439, 6276, 10074, 5409, 9379, 10323, 9078, 3603, 487]; } } $isAuth = check_qapp_auth($package, 0); if (!$isAuth) { $rank = config('home.rank'); $bids = $rank['male']; if ($sex === 2) { $bids = $rank['female'];; } } $channel_id = $request->input('distribution_channel_id', 0); $books = collectionTransform(new BookTransformer, BookConfigService::getBookLists(compact('bids', 'channel_id'))); return response()->success($books); } /** * 推荐书 */ public function recommen() { $books = $this->getDefaultBanner(); return response()->success($books); } /** * 阅爱小说任务轮播图 */ public function recommenYueAi() { $user = (new QappUserService)->getGolableUser(); if (isset($user->uid) && !empty($user->uid) && $user->send_order_id > 0) { $orderRecord = ChapterOrderService::hasUserRecord($user->uid); $data = config('home.yueai'); $books = $data['task_banner']; $bids = BookConfigService::getAvailableBIdsbyBids(array_column($books, 'bid'), $this->distribution_channel_id, false); if ($orderRecord && !empty($bids)) { foreach ($books as &$value) { $value['bid'] = Hashids::encode($value['bid']); $value['redirect_url '] = empty($value['cid']) ? "views/Detail" : "views/Reader"; } unset($value); return response()->success($books); } } $books = $this->getDefaultBanner(['FEMALE', 'PUBLIC']); return response()->success($books); } /** * 新获取各种广告列表 * @param Request $request * @return mixed */ public function getRecommendBanners(Request $request) { $release_type = $request->get('release_type', ''); $distribution_id = $this->distribution_channel_id; if (is_empty($release_type)) { //默认原banner // $recom_banner_type = ['FEMALE', 'PUBLIC'] : ['FEMALE', 'PUBLIC']; $banner = $this->getDefaultBanner(['FEMALE', 'PUBLIC']); return response()->success($banner); } if ($release_type == '4' || $release_type == '5') { //弹窗和充值页返回需要先判断频率跟权限 $advert = ChannelAdvert::select('id', 'photo as banner_url', 'activity_id', 'type', 'content', 'person', 'frequency') ->where('distribution_id', $distribution_id) ->where('release_type', $release_type) ->where('status', 1) ->first(); if (!$advert) { return response()->success([]); } $advert = $advert->toArray(); $advert['ids'] = Hashids::encode($advert['id']); if ($advert['type'] == 1) { $advert['redirect_url'] = 'views/Reader'; $content = explode(';', $advert['content']); $advert['bid'] = isset($content[2]) ? $content[2] : ''; $advert['cid'] = isset($content[3]) ? $content[3] : ''; } else { $advert['redirect_url'] = 'views/Detail'; } if ($release_type == '4') { //弹窗需要判断频率 if ($advert['frequency'] == 'always') { $advert = self::getBackFormat($advert); return response()->success($advert); } $day = strtotime(date('Y-m-d H:i:s')); $nextDay = strtotime(date('Y-m-d') . ' +1 day'); $nextWeek = strtotime(date('Y-m-d', strtotime('+1 week last monday'))); if ($advert['frequency'] == 'day') { if (!Redis::exists('banner:' . $distribution_id . ':' . $this->uid)) { Redis::setex('banner:' . $distribution_id . ':' . $this->uid, ($nextDay - $day), 1); $advert = self::getBackFormat($advert); return response()->success($advert); } } if ($advert['frequency'] == 'week') { if (!Redis::exists('banner:' . $distribution_id . ':' . $this->uid)) { Redis::setex('banner:' . $distribution_id . ':' . $this->uid, ($nextWeek - $day), 1); $advert = self::getBackFormat($advert); return response()->success($advert); } } return response()->success([]); } if ($release_type == '5') { //充值页返回需要判断用户权限 $check_user = $this->checkUsers($advert['person']); if (!$check_user) { return response()->success([]); } $activity = ActivityService::getById($advert['activity_id'] ?? 0); if ($activity) { if ($activity['permanent'] == 1 || ($activity['start_time'] < date("Y-m-d H:i:s") && $activity['end_time'] > date("Y-m-d H:i:s"))) { $advert['redirect_url'] = "/views/Activity"; $advert = self::getBackFormat($advert); $advert['param'] = ['token' => $activity['token']]; return response()->success($advert); } else { return response()->success([]); } } else { return response()->success([]); } } } //男女频,书架列表 $banner = ChannelAdvertService::getAdvertList($distribution_id, $release_type); if ($banner->isEmpty()) { $recom_banner_type = ["PUBLIC", $release_type == 1 ? "MALE" : "FEMALE"]; $banner = $this->getDefaultBanner($recom_banner_type); return response()->success($banner); } $banner->transform(function ($item) { $item->ids = Hashids::encode($item->id); if ($item->type == 1) { $content = explode(';', $item->content); $item->bid = isset($content[2]) ? $content[2] : ''; $item->cid = isset($content[3]) ? $content[3] : ''; if ($item->cid) { $item->redirect_url = "views/Reader"; } else { $item->redirect_url = "views/Detail"; } $item->redirect_type = "book"; } else { $activity = ActivityService::getById($item->activity_id); $item->redirect_url = "/views/Activity"; $item->redirect_type = "activity"; if ($activity && !empty($activity['token'])) { $item['param'] = ['token' => $activity['token']]; } else { $item->redirect_url = "#"; } } self::getBackFormat($item); return $item; }); return response()->success($banner); } static function getBackFormat($data) { if (isset($data['id']) || $data->id) unset($data['id'], $data->id); if (isset($data['type']) || $data->type) unset($data['type'], $data->type); if (isset($data['person']) || $data->person) unset($data['person'], $data->person); if (isset($data['frequency']) || $data->frequency) unset($data['frequency'], $data->frequency); return $data; } /** * 默认获取banner * @return mixed */ protected function getDefaultBanner($reco_banner_type = ['FEMALE', 'PUBLIC']) { $banner = (new RecoBannerService)->getByType($reco_banner_type, 2); $banner->transform(function ($item) { $result = $this->getBidCidFromUrl($item->redirect_url); $item->bid = $result['bid']; $item->cid = $result['cid']; $item->ids = Hashids::encode($item->id); $item->type = 'default'; if ($result['cid']) { $item->redirect_url = "views/Reader"; } else { $item->redirect_url = "views/Detail"; } $item->redirect_type = "book"; unset($item->id); return $item; }); return $banner; } /** * 限免 */ public function free(int $sex) { $result = BookConfigService::findFreeBooks($sex); return response()->success($result); } public function yueaiBackRecom(Request $request) { $package = $request->header('x-package', ''); if (empty($package) || $package != 'com.beidao.kuaiying.yueai') { return response()->success([]); } $user = (new QappUserService)->getGolableUser(); if (isset($user->uid) && !empty($user->uid) && $user->send_order_id > 0) { $bid = BookConfigService::getAvailableBIdsbyBids([58238, 60534, 63220, 14500, 13254, 63221, 63548, 14022, 59334, 58888, 63417, 61701], $this->distribution_channel_id, false); if (!empty($bid)) { $bid = array_random($bid, 4); } $orderRecord = ChapterOrderService::hasUserRecord($user->uid); if ($orderRecord && count($bid) >= 4) { $where = ['is_on_shelf' => [1, 2], 'bids' => $bid]; // $books = BookConfigService::getBooksByIds($bid,[],false); $books = BookConfigService::getBookLists($where, [], false); return response()->collection(new BookTransformer(), $books); } } return response()->success([]); $where = ['is_on_shelf' => [2]]; $where['channel_id'] = $request->input('distribution_channel_id', 0); $books = BookConfigService::getBooks($where, [], 4); return response()->collection(new BookTransformer(), $books); } public function shelfRecom(Request $request) { $package = $request->header('x-package', ''); $user = (new QappUserService)->getGolableUser(); if (!empty($package) && $package == 'com.beidao.kuaiying.yueai') { if (isset($user->uid) && !empty($user->uid) && $user->send_order_id > 0) { $bid = BookConfigService::getAvailableBIdsbyBids([58238, 60534, 63220, 14500, 13254, 63221, 63548, 14022, 59334, 58888, 63417, 61701], $this->distribution_channel_id, false); if (!empty($bid)) { $bid = array_random($bid, 4); } $orderRecord = ChapterOrderService::hasUserRecord($user->uid); if ($orderRecord && count($bid) > 1) { $where = ['is_on_shelf' => [1, 2], 'bids' => $bid]; // $books = BookConfigService::getBooksByIds($bid,[],false); $books = BookConfigService::getBookLists($where, [], false); return response()->collection(new BookTransformer(), $books); } } return response()->success([]); } else if (!empty($package) && $package == 'com.beidao.kuaiying.tiantiankanshu') { if (isset($user->uid) && !empty($user->uid) && $user->send_order_id > 0) { $bid = [61618, 14555, 60680, 58919, 58889, 58925]; $list = BookConfigService::getBooksByIds($bid, [], false); return response()->collection(new BookTransformer(), $list); } } $where = ['is_on_shelf' => [2], 'channel_id' => $this->distribution_channel_id, 'is_high_quality' => 1]; if (isset($user->uid) && $user->user->sex == 1) { $where['channel_name'] = "男频"; } else { $where['channel_name'] = "女频"; } $books = BookConfigService::getBooks($where, [], 3); return response()->collection(new BookTransformer(), $books); } /** * 新推荐书单 * @param Request $request * @return mixed */ public function recommendBooks(Request $request) { $distribution_id = $this->distribution_channel_id; $bid = $request->get('bid', 0); if (empty($distribution_id)) { \Log::info('recommendBooks:1'); return response()->success([]); } if (!empty($bid)) { \Log::info('recommendBooks:2'); $bid = str_decode($bid); } //判断包是否存在 $package_info = QappPackage::getPackage($distribution_id); if (empty($package_info) || !isset($package_info->channel_id)) { \Log::info('recommendBooks:3'); return response()->success([]); } //包对应有没有配置开启推荐书单 $config = ChannelRecommendBookConfigService::getRecommendConfigs($distribution_id); if (empty($config) || !isset($config->status) || $config->status == 0) { \Log::info('recommendBooks:4'); return response()->success([]); } //根据频率和用户属性决定是否需要返回 $res = $this->checkUsersAuth($config); if (!$res) { \Log::info('recommendBooks:5'); return response()->success([]); } $list = ChannelRecommendBooksService::getRecommendBooks($distribution_id, $bid); if (!is_empty($list)) { foreach ($list as $key => $item) { $this->incrRecommendNum($distribution_id, $item->bid); } \Log::info('recommendBooks:6'); return response()->collection(new BookTransformer(), $list); } \Log::info('recommendBooks:7' . json_encode($list)); return response()->success([]); } /** * 点击推荐书籍记录点击次数 * @param Request $request * @return mixed */ public function clickRecommendBooks(Request $request) { $distribution_id = $this->distribution_channel_id; $bid = $request->get('bid', ''); if (empty($bid)) { return response()->success(); } //判断包是否存在 $package_info = QappPackage::getPackage($distribution_id); if (empty($package_info) || !isset($package_info->channel_id)) { return response()->success([]); } $date = date('Ymd'); $bid = str_decode($bid); $cacheKey = 'recommend:click:' . $date . ':' . $distribution_id . $bid; $this->incrRedisKey($cacheKey); return response()->success(); } /** * 判断用户是否需要推荐 * @param $config * @return bool */ protected function checkUsersAuth($config) { \Log::info($config); \Log::info('$config->person:' . $config->person); \Log::info($this->uid); $res = $this->checkUsers($config->person); if ($res === false) { return false; } //频率判断 if ($config->frequency == 'back') { //返回即推送 return true; } $day = strtotime(date('Y-m-d H:i:s')); $nextDay = strtotime(date('Y-m-d') . ' +1 day'); $nextWeek = strtotime(date('Y-m-d', strtotime('+1 week last monday'))); if ($config->frequency == 'day') { //每日推送 if (!Redis::exists('recommend:' . $config->channel_id . ':' . $this->uid)) { Redis::setex('recommend:' . $config->channel_id . ':' . $this->uid, ($nextDay - $day), 1); return true; } \Log::info('当天已经推送过了'); return false; } if ($config->frequency == 'week') { //每周推送 if (!Redis::exists('recommend:' . $config->channel_id . ':' . $this->uid)) { Redis::setex('recommend:' . $config->channel_id . ':' . $this->uid, ($nextWeek - $day), 1); return true; } \Log::info('该周已经推送过了'); return false; } } /** * 判断用户是否有权限 * @param $type * @return bool */ protected function checkUsers($type) { $res = false; switch ($type) { case 'pay': //付费用户 $orders = OrderService::getUserLastestOrder($this->uid); if ($orders) { $res = true; } \Log::info('用户是否付费:'); \Log::info($orders); break; case 'send_order': //派单用户 if ($this->send_order_id != 0) { $res = true; } \Log::info('用户是否是派单用户:$this->send_order_id:' . $this->send_order_id); break; case 'pay_send_order': //付费派单用户 $orders = OrderService::getUserLastestOrder($this->uid); if ($orders && $this->send_order_id != 0) { $res = true; } \Log::info('用户是否是付费派单用户:$this->send_order_id:' . $this->send_order_id); \Log::info($orders); break; case 'unpaid': $orders = OrderService::getUserLastestOrder($this->uid); if (!$orders) { $res = true; } break; case 'all': $res = true; \Log::info('所有用户返回'); break; } return $res; } /** * 推广书籍推荐次数 * @param $channel_id * @param $bid */ protected function incrRecommendNum($channel_id, $bid) { $date = date('Ymd'); $cacheKey = 'recommend:sum:' . $date . ':' . $channel_id . $bid; $this->incrRedisKey($cacheKey); } /** * 点击广告统计 * @param Request $request * @return mixed */ public function getCheckAdvertisement(Request $request) { $type = $request->get('type', ''); $id = $request->get('ids', ''); $distribution_id = $this->distribution_channel_id; \Log::info('getCheckAdvertisement:type:' . $type . ' id:' . $id . ' $distribution_id:' . $distribution_id); if (empty($id) || empty($distribution_id)) { return response()->success(); } $id = str_decode($id); if (!$id) { return response()->success(); } if ($type == 'default') { //默认原表reco_banners广告,区分跟新表channel_advert的id $id = -$id; } else { $advert = ChannelAdvert::find($id); if (!$advert) { \Log::info('getCheckAdvertisement:error:不存在该广告'); \Log::info(json_encode($request->all())); return response()->success(); } } $where = ['channel_ad_id' => $id, 'uid' => $this->uid, 'distribution_id' => $distribution_id]; \Log::info('insert_where:'); \Log::info(json_encode($where)); ChannelAdUser::firstOrCreate($where); $date = date('Ymd'); $cacheKey = 'advertisement:pv:' . $date . ':' . $distribution_id . $id; $this->incrRedisKey($cacheKey); //设置当前用户的所属广告有效期一周 $key = 'advertisement:uid:' . $this->uid . ':id'; Redis::set($key, $id); Redis::expire($key, BaseConst::ONE_WEEK_SECONDS); return response()->success(); } /** * redis新增 * @param $cacheKey */ protected function incrRedisKey($cacheKey) { if (!Redis::exists($cacheKey)) { Redis::set($cacheKey, 1); } else { Redis::incrBy($cacheKey, 1); } } /** * 绑定广告和订单 * @param Request $request * @return mixed */ public function getAdvertOrders(Request $request) { $order_id = $request->get('trade_no', ''); $uid = $this->uid; $distribution_id = $this->distribution_channel_id; $cacheKey = 'advertisement:uid:' . $uid . ':id'; if (empty($order_id)) { return response()->success(); } $channel_ad_id = 0; \Log::info('getAdvertOrders:trade_no' . $order_id . ' uid:' . $uid); if (Redis::exists($cacheKey)) { try { //获取广告id $channel_ad_id = Redis::get($cacheKey); //判断订单跟广告是否有关系 $order = OrderService::getByTradeNo($order_id); if (!$order) { return response()->success(); } if ($channel_ad_id > 0) { //新版 $type = 1; $advert = ChannelAdvert::find($channel_ad_id); if (!$advert) { return response()->success(); } if ($advert->type == '2' && $advert->activity_id != 0) { //广告类型为活动 if ($order->activity_id != $advert->activity_id) { return response()->success(); } } else { //广告类型为书籍 $content = explode(';', $advert->content); if (!isset($content[2])) { return response()->success(); } if ($order->from_bid == 0 || $order->from_bid != str_decode($content[2])) { return response()->success(); } } } else { //旧版 $type = 0; $advert = RecoBanner::find(abs($channel_ad_id)); if (!$advert) { return response()->success(); } $result = $this->getBidCidFromUrl($advert->redirect_url); $bid = $result['bid']; $cid = $result['cid']; if ($cid) { if ($order->from_bid == 0 || $order->from_bid != str_decode($bid)) { return response()->success(); } } else { if ($order->activity_id == 0 || $order->from_bid != str_decode($bid)) { return response()->success(); } } } $created_at = $updated_at = date('Y-m-d H:i:s'); DB::table('channel_advert_orders')->insert(compact('order_id', 'uid', 'distribution_id', 'channel_ad_id', 'type', 'created_at', 'updated_at')); } catch (\Exception $e) { \Log::info('绑定广告和订单失败' . $e->getMessage()); \Log::info('order_id:' . $order_id . ' uid:' . $uid . ' distribution_id:' . $distribution_id . ' channel_ad_id:' . $channel_ad_id); } } return response()->success(); } private function getSpecialLibrary(Request $request) { $where = []; $order = []; $where['is_on_shelf'] = [2, 4]; $category_id = $request->input('category_id'); if ($category_id) { if ($category_id == 1) { $where['channel_name'] = '男频'; } elseif ($category_id == 2) { $where['channel_name'] = '女频'; } else { $where['category_id'] = $category_id; } } $key = $request->input('key'); $uid = $request->input('uid', 0); if ($key && $uid && is_numeric($uid)) { BookConfigService::saveUserSearchLog($key, $uid); } $where['key'] = $key; $order_field = $request->input('order_field'); $order_seq = $request->input('order_seq'); if ($order_field != '' && in_array($order_field, ['recommend_index', 'click_count', 'update', 'size', 'create'])) { if ($order_field == 'update') { $order = ['book_configs.updated_at', 'desc']; } elseif ($order_field == 'create') { $order = ['book_configs.created_at', 'desc']; } else { $order = [$order_field, 'desc']; } if ($order_seq == 'asc') { $order = [$order_field, 'asc']; } if ($order_seq == 'desc') { $order = [$order_field, 'desc']; } } // 审核状态默认值 $package = $request->header('x-package', ''); $brand = $request->header('x-nbrand', ''); // $codeVersion = $request->header('x-codeversion', ''); $codeVersion = $request->header('x-version', ''); if ($order_field === 'recommend_index' && Utils::checkIsAudit($package, $brand, $codeVersion)) { $order = ['book_configs.bid', 'desc']; } $status = $request->input('status'); if ($status != '') { $where['status'] = $status; } // 搜索关键词的情况下,屏蔽书籍完本状态 if ($key && isset($where['status'])) { unset($where['status']); } $page_size = $request->input('page_size', 15); $where['channel_id'] = ($package === 'com.beidao.kuaiying.zsy') ? 7477 : 0; $books = BookConfigService::getBooks($where, $order, $page_size); $special = get_special_bid(); $list = []; foreach ($books as $ke => $val) { if ($val->is_on_shelf != 2 && !in_array($val->bid, $special)) { unset($books[$ke]); } } return response()->pagination(new BookTransformer, $books); } /** * 首页 */ public function getBookListsNew(Request $request, $sex) { // 获取基本数据 $package = $request->header('x-package', ''); $brand = $request->header('x-brand', ''); $codeVersion = $request->header('x-Version', ''); $key = $sex . "_new"; if ( Utils::checkIsAudit($package, $brand, $codeVersion)){ $key .= "_audit"; } $result = HomeCache::getHomePageInfo($package,$key); // $result = null; if (is_empty($result)) { $isAuth = check_qapp_auth($package, 0); //新判断: 根据包名来获取对应所需的bid $qapp_package = QappPackage::getPackageByPackage($package); if ($qapp_package) { $package_id = $qapp_package->id; } else { $package_id = 0; } $channel = $sex == 'male' ? 1 : 2; // myLog("index-recom")->info(['$package' => $package,'brand' => $brand,'code' => $codeVersion]); $result = $this->getRecommendBooks($package_id, $package, $channel, $isAuth, Utils::checkIsAudit($package, $brand, $codeVersion)); HomeCache::setHomePageInfo($package, $key, $result, 86400 + rand(0, 100)); } return response()->success($result); } private function getRecommendBooks($package_id, $package, $channel, $is_auth,$is_audit = false) { // myLog("index-recom")->info(['pack' => $package,'is_audit' => $is_audit]); if($is_audit){ // return BookAuditService::getRecommendBooksNew($package_id, $package, $channel, $is_auth,$is_audit); } $data = BookConfigService::getRecommendBids($package, $channel, [], 48); $bids = array_chunk($data, 12); $guss_like = BookConfigService::getRecommendBids($package, $channel, $data, 20); // $new_recom = BookConfigService::getNewRecommendBids($package,$channel,$data); $default = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; return array_filter([ ["has_more" => false, 'type' => 'hot', 'lable' => '热门书单', 'books' => collectionTransform(new BookTransformer, BookConfigService::getBooksByIds($bids[0] ?? BookConfigService::getCheckBooks($default, $channel, $package, $is_auth)))], ["has_more" => false, 'type' => 'zhibo', 'lable' => '神书直播', 'books' => collectionTransform(new BookTransformer, BookConfigService::getBooksByIds($bids[2] ?? BookConfigService::getCheckBooks($default, $channel, $package, $is_auth)))], ["has_more" => false, 'type' => 'recom', 'lable' => '小编精选', 'books' => collectionTransform(new BookTransformer, BookConfigService::getBooksByIds($bids[3] ?? BookConfigService::getCheckBooks($default, $channel, $package, $is_auth)))], ["has_more" => false, 'type' => 'new_recom', 'lable' => '人气新书', 'books' => collectionTransform(new BookTransformer, BookConfigService::getBooksByIds($bids[4] ?? BookConfigService::getCheckBooks($default, $channel, $package, $is_auth)))], ["has_more" => false, 'type' => 'guss_like', 'lable' => '猜你喜欢', 'books' => collectionTransform(new BookTransformer, BookConfigService::getBooksByIds($guss_like))], ]); return []; } }