BookConfigService.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: tandunzhao
  5. * Date: 2017/12/4
  6. * Time: 下午1:43
  7. */
  8. namespace App\Modules\Book\Services;
  9. use App\Modules\Book\Models\BookCombinationConfig;
  10. use App\Modules\Book\Models\BookConfig;
  11. use App\Modules\Book\Models\BookCopyright;
  12. use App\Modules\Product\Services\ProductService;
  13. use App\Modules\Book\Models\Book;
  14. use App\Modules\Book\Models\BookKeyword;
  15. use App\Modules\Book\Models\FreeBook;
  16. use App\Modules\Book\Models\FreeBookConfig;
  17. use App\Modules\Book\Models\QappUserSearchBookLog;
  18. use Illuminate\Support\Facades\DB;
  19. use phpDocumentor\Reflection\Types\This;
  20. use Redis;
  21. use Vinkla\Hashids\Facades\Hashids;
  22. class BookConfigService
  23. {
  24. /**
  25. * 根据id获取图书
  26. * @param $bid
  27. * @return mixed
  28. */
  29. public static function getBookById($bid)
  30. {
  31. return BookConfig::getBookById($bid);
  32. }
  33. /**
  34. * 获取图书组合信息
  35. * @param $bid
  36. * @return array
  37. */
  38. public static function getCombinationInfo($bid)
  39. {
  40. $info = BookCombinationConfig::where('bid', $bid)->where('is_enable', 1)->select('bid_group')->first();
  41. if ($info) return explode(',', $info->bid_group);
  42. return [];
  43. }
  44. /**
  45. * 根据bid数组获取多本图书
  46. * @param $where
  47. * @param null $order
  48. * @return mixed
  49. */
  50. public static function getBooksByIds(array $where, $order = [], $is_external_shelf = true)
  51. {
  52. if (empty($where)) {
  53. return (object)array();
  54. }
  55. if ($order)
  56. $res = BookConfig::getBooksByIds($where, $order, $is_external_shelf);
  57. else
  58. $res = BookConfig::getBooksByIds($where, [], $is_external_shelf);
  59. return $res;
  60. }
  61. public static function getBookLists(array $where, $order = [], $is_external_shelf = true)
  62. {
  63. if (empty($where)) {
  64. return (object)array();
  65. }
  66. if ($order) {
  67. $res = BookConfig::getBookLists($where, $order, $is_external_shelf);
  68. } else {
  69. $res = BookConfig::getBookLists($where, [], $is_external_shelf);
  70. }
  71. return $res;
  72. }
  73. /**
  74. *
  75. * 根据条件获取图书
  76. * @param array $where ['key'=>'根据关键词查询','category_id'=>'根据分类id查询','is_on_shelf'=>上下架查询,'channel_name'=>'频道查询(男频女频)']
  77. * @param array $order 排序 默认是bid排序
  78. * @param int $page_size
  79. * @return mixed
  80. */
  81. public static function getBooks(array $where, array $order = [], $page_size = 15)
  82. {
  83. return BookConfig::getBooks($where, $order, $page_size);
  84. }
  85. /**
  86. * 获取阅读完的推荐
  87. * @param $category_id
  88. * @param int $num
  89. * @return mixed
  90. */
  91. public static function getRecommendBooks($bid, $category_id, $num = 4)
  92. {
  93. return BookConfig::getRecommendBooks($bid, $category_id, $num);
  94. }
  95. /**
  96. * 获取阅读完的推荐(快应用)
  97. * @param $category_id
  98. * @param int $num
  99. * @return mixed
  100. */
  101. public static function getQuickAppRecommendBooks($bid, $category_id, $num = 4)
  102. {
  103. return BookConfig::getQuickAppRecommendBooks($bid, $category_id, $num);
  104. }
  105. public static function getSimpleBooksByIds(array $ids)
  106. {
  107. $str = implode(',', $ids);
  108. $field = 'bid,' . $str;
  109. return BookConfig::whereIn('bid', $ids)->select('bid', 'book_name')->orderBy(DB::raw('field(' . $field . ')'))->get();
  110. }
  111. public static function findBookKeywords(bool $is_all = false)
  112. {
  113. $sql = BookKeyword::where('status', 1)->orderBy('sequence');
  114. if ($is_all) {
  115. return $sql->get();
  116. } else {
  117. return $sql->paginate(10);
  118. }
  119. }
  120. public static function saveUserSearchLog(string $words, int $uid)
  121. {
  122. QappUserSearchBookLog::create([
  123. 'uid' => $uid,
  124. 'words' => $words,
  125. ]);
  126. }
  127. /**
  128. * @return FreeBookConfig
  129. */
  130. public static function findFreeBookConfig(int $sex)
  131. {
  132. return FreeBookConfig::where(['sex' => $sex, 'is_enabled' => 1])
  133. ->where('end_time', '>=', now())
  134. ->orderBy('end_time')
  135. ->first();
  136. }
  137. /**
  138. * 查找限免书籍
  139. * @return array
  140. */
  141. public static function findFreeBooks(int $sex)
  142. {
  143. $config = self::findFreeBookConfig($sex);
  144. \Log::info('return_empty_free_books:' . $sex);
  145. \Log::info($config);
  146. if ($config) {
  147. $free_books = FreeBook::where('config_id', $config->id)
  148. ->where('is_enabled', 1)
  149. ->get();
  150. $bids = $free_books->pluck('bid')->all();
  151. $book_configs = BookConfig::whereIn('bid', $bids)
  152. ->where('is_on_shelf', 2)
  153. ->select('bid', 'book_name', 'cover')
  154. ->get();
  155. $books = Book::whereIn('id', $bids)->select('id', 'intro')->get();
  156. \Log::info('return_empty_data:');
  157. \Log::info($books);
  158. $book_list = $book_configs->transform(function ($item) use ($books) {
  159. $book = $books->where('id', $item->bid)->first();
  160. return [
  161. 'book_id' => Hashids::encode($item->bid),
  162. 'cover_url' => $item->cover,
  163. 'book_name' => $item->book_name,
  164. 'intro' => $book->intro,
  165. ];
  166. })->all();
  167. return [
  168. 'title' => $config->name,
  169. 'end_time' => $config->end_time,
  170. 'list' => $book_list,
  171. ];
  172. }
  173. return [];
  174. }
  175. /**
  176. * 判断书籍是否限免
  177. * @return bool
  178. */
  179. public static function judgeBookIsFree(int $bid)
  180. {
  181. $ids = [];
  182. foreach ([1, 2] as $sex) {
  183. $config = self::findFreeBookConfig($sex);
  184. if ($config) {
  185. $ids[] = $config->id;
  186. }
  187. }
  188. return FreeBook::where('bid', $bid)
  189. ->whereIn('config_id', $ids)
  190. ->where('is_enabled', 1)->select('id')->first();
  191. }
  192. public static function getByBidNoFilter($bid)
  193. {
  194. return FreeBook::join('free_book_config', 'free_book_config.id', '=', 'free_books.config_id')
  195. ->where('bid', $bid)
  196. ->select('free_books.id', 'end_time')
  197. ->where('end_time', '<', date('Y-m-d H:i:s'))
  198. ->orderBy('free_book_config.end_time', 'desc')
  199. ->first();
  200. }
  201. public static function chargeStats($id, $amount, $uid)
  202. {
  203. if (!Redis::Sismember('qapp:free:virtual:uids' . $id, $uid)) {
  204. return;
  205. }
  206. $now = date('Y-m-d');
  207. $amount = $amount * 100;
  208. Redis::hincrby('qapp:book:free:charge:' . $id, $now, $amount);
  209. #Redis::sadd('qapp:free:charge'.$now,$id);
  210. Redis::sadd('qapp:free:actuality' . $now, $id);
  211. Redis::sadd('qapp:free:charge:uids' . $now . $id, $uid);
  212. }
  213. public static function getBookByField($bids, $field)
  214. {
  215. if (!$bids || !$field) return null;
  216. return BookConfig::join('books', 'books.id', '=', 'book_configs.bid')->
  217. whereIn('bid', $bids)->select($field)->get();
  218. }
  219. /**
  220. * 根据书籍bid去除无用bid
  221. * name: getAvailableBIdsbyBids
  222. * @param $bids
  223. * @param mixed $channel_id
  224. * @param mixed $is_external_shelf
  225. * @return array
  226. * date 2022/09/20 10:39
  227. */
  228. public static function getAvailableBIdsbyBids($bids, $channel_id = 0, $is_external_shelf = true)
  229. {
  230. if (empty($bids)) {
  231. return [];
  232. }
  233. $res = BookConfig::whereIn('bid',$bids);
  234. // if($channel_id == config('qapp_public_package_channel')){
  235. // $res->whereNotIn('cp_source',getHiddenCp());
  236. // }else{
  237. // $res->whereNotIn('cp_source',array_merge(getHiddenCp(),['lianshang']));
  238. // }
  239. $res->whereNotIn('cp_source',getHiddenCp($channel_id,2));
  240. if ($is_external_shelf){
  241. $res->where('is_on_shelf',2);
  242. }else{
  243. $res->whereIn('is_on_shelf',[1,2]);
  244. }
  245. return $res->pluck("bid")->toArray();
  246. }
  247. /***
  248. * 推荐位书籍检测和补齐
  249. * name: getCheckBooks
  250. * @param $bid_list
  251. * @param $channel
  252. * @param $package
  253. * @param $is_author
  254. * @return mixed
  255. * date 2022/10/26 10:11
  256. */
  257. public static function getCheckBooks($bid_list, $channel, $package, $is_author)
  258. {
  259. $hidden_cp = getHiddenCp($package);
  260. // if(!is_public_package($package)){
  261. // $hidden_cp = array_merge($hidden_cp,['lianshang']);
  262. // }
  263. //获取书本数量
  264. $count = count($bid_list);
  265. if (!$is_author) {
  266. $where = [
  267. ['book_configs.charge_type', '!=', 'BOOK'],
  268. ['book_configs.cp_source', '=', 'ycsd'],
  269. ];
  270. } else {
  271. $where = [
  272. ['book_configs.charge_type', '!=', 'BOOK'],
  273. ];
  274. }
  275. //获取书籍交集bid,过滤掉不符合要求的书
  276. $bid_list = BookConfig::join('books', 'book_configs.bid', '=', 'books.id')
  277. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  278. ->whereIn('book_configs.bid', $bid_list)
  279. ->where('book_configs.is_on_shelf', 2)
  280. ->where($where)
  281. ->whereNotIn('book_configs.cp_source', $hidden_cp)
  282. ->where('book_categories.pid', $channel)
  283. ->pluck('book_configs.bid')->all();
  284. $book_count = count($bid_list);
  285. if ($book_count === $count) {
  286. return $bid_list;
  287. }
  288. $supplement_count = $count - $book_count;
  289. //获取随机的有效的书籍bid
  290. $rand_bid = BookConfig::join('books', 'book_configs.bid', '=', 'books.id')
  291. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  292. ->where('book_configs.is_on_shelf', 2)
  293. ->where($where)
  294. ->whereNotIn('book_configs.cp_source', $hidden_cp)
  295. // ->where('book_configs.is_high_quality',1)
  296. ->where('book_categories.pid', $channel)
  297. ->orderBy('book_configs.is_high_quality', 'desc')
  298. // ->inRandomOrder()
  299. ->orderBy('book_configs.recommend_index', 'desc')
  300. ->limit($supplement_count)
  301. ->pluck('book_configs.bid')->all();
  302. return array_filter(array_merge($bid_list, $rand_bid));
  303. }
  304. public static function getRecommendBids($package = '', $channel = 1, $no_in_bid = [], $limit = 36,$is_on_shelf = true)
  305. {
  306. DB::enableQueryLog();
  307. $where = [
  308. ['book_configs.charge_type', '!=', 'BOOK'],
  309. ];
  310. //获取书籍交集bid,过滤掉不符合要求的书
  311. $bid_list = BookConfig::join('books', 'book_configs.bid', '=', 'books.id')
  312. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  313. ->distinct("books.name")
  314. ->where($where)
  315. ->whereNotIn('book_configs.cp_source', getHiddenCp($package))
  316. ->where('book_categories.pid', $channel);
  317. if ($is_on_shelf){
  318. $bid_list->where('book_configs.is_on_shelf', 2);
  319. }else{
  320. $bid_list->whereIn('book_configs.is_on_shelf', [1,2]);
  321. }
  322. if (!empty($no_in_bid)) {
  323. $bid_list->whereNotIn('book_configs.bid', $no_in_bid);
  324. }
  325. return $bid_list->orderBy('recommend_index' , 'desc')->orderBy("book_configs.is_high_quality",'desc')->orderBy('books.id' , 'asc')->limit($limit)->pluck('book_configs.bid')->toArray();
  326. }
  327. /***
  328. * 书籍授权情况 2黑名单 1白名单 其他 无特殊添加
  329. * name: bookCopyright
  330. * @param mixed $bid
  331. * @param mixed $distribution_channel_id
  332. * date 2022/11/14 17:16
  333. */
  334. public static function bookCopyright($bid, $distribution_channel_id = 0)
  335. {
  336. if ($distribution_channel_id < 1){
  337. return 0;
  338. }
  339. return BookCopyright::where('distribution_channel_id',$distribution_channel_id)
  340. ->where('bid',$bid)
  341. ->where('is_enabled',1)
  342. ->where('platform',"qapp")
  343. ->value('type');
  344. }
  345. public static function getNewRecommendBids($package, $channel, $bids = [], $limit=12,$is_on_shelf = true)
  346. {
  347. $begin_time = date('Y-m-d',strtotime('-2 month'));
  348. $end_time = date('Y-m-d');
  349. $where = " and book_configs.charge_type = 'CHAPTER' and book_categories.pid= {$channel}";
  350. $hide = getHiddenCp($package);
  351. if ($hide){
  352. $where .= " and book_configs.cp_source not in ( '" . implode("','",$hide) . "')";
  353. }
  354. if ($is_on_shelf){
  355. $where .= " and book_configs.is_on_shelf = 2";
  356. }else{
  357. $where .= " and book_configs.is_on_shelf in (1,2)";
  358. }
  359. if (!empty($bids)){
  360. $where .= " and books.id not in (" . implode(",",$bids) . ")";
  361. }
  362. $sql = "select book_configs.bid from book_promotion_day_stats
  363. INNER JOIN books on books.id=book_promotion_day_stats.bid
  364. INNER JOIN book_configs on book_configs.bid = books.id
  365. INNER JOIN book_categories ON book_categories.id=books.category_id
  366. where date >='{$begin_time}' and date <= '{$end_time}' {$where} group by bid order by sum(rechareg_amount) desc limit {$limit}";
  367. // $bids = DB::select($sql);
  368. // echo "<pre><hr>";
  369. // var_export($bids);
  370. // echo "<hr>";
  371. // var_export($sql);
  372. // die();
  373. }
  374. /***
  375. * 获取排行榜数据
  376. * name: getRankList
  377. * @param $package
  378. * @param mixed $sex 1:男频 2:女频
  379. * @param int $limit 条数默认30
  380. * date 2022/11/15 14:36
  381. */
  382. public static function getRankList($package, $sex = 1, $limit = 30)
  383. {
  384. if ($sex == 1){
  385. return [14928,14500,61020,14927,14016,14021,19409,14423,61596,62297,16451,15103,14022,14793,14351,17652,63721,63417,62781,63482,13300,14297,14072,13928,13879,16438,14312,16712,13929,14408,19993,14299,59580,60623,62666,19675,65187,15978,59784,58687,61944,13840,13286,16236,64284,58969,14811,14006,13254,13275,14000,9744,13266,15251,62875,6644,16434,13291,16431,59687,13994,16256,14272,19958,16435,13271,61564,13878,14302,61945,3483,13281,16453,59723,16443,13992,16455,9753,11408,62461,59389,13260,13257,17954,13280,11457,13284,13282,7680,16448,64225,21910,2939,22376,16442,13287,16440,16427,60827,21700,13361,59688,2079,20416,7956,16545,10418,13930,13867,64325,14300,16445,17242,14308,13288,19449,10537,12393,13250,13888,16454,14926,16484,13278,21139,61941,10417,21757,64239,13265,13272,13253,60175,8461,21376,2941,22056,13269,14806,14097,14303,59388,22148,16447,2053,13258,16433,16452,16476,2936,59677,20027,22157,16566,16441,17689,16251,13285,63989,2928,14925,2942,13931,13264,2945,20236,21999,46203,5618,16842,64340,59385,14295,64346,13884,61684,12480,59728,16798,94,20711,20072,20368,8253,2915,16822,20046,2993,12103,17268,12494,22153,32802,3542,61567,20837,16436,62355,64329,16542];
  386. }else{
  387. return [11316,11672,11679,11680,11681,11999,12331,12462,12464,12468,12949,13421,14220,14349,14620,15221,15537,15720,16301,17055,19382,58195,58593,59004,59579,61012,61425,61699,62175,62538,62865,64729,1389,2061,4938,6043,8141,8295,8476,9893,10682,10721,11063,11632,11648,11653,11658,11660,11661,11662,11928,12224,12281,12283,12470,12471,12689,12701,12739,13023,13038,13081,13088,13095,13113,13125,13154,13155,13157,13169,13173,13175,13176,13177,13183,13189,13190,13192,13193,13201,13207,13397,13439,13520,13593,13608,13853,14083,14318,14417,14684,14697,14709,14744,14892,14924,15255,15281,15368,15431,15779,15997,16005,16035,16112,16392,16395,16731,16951,17379,18817,19217,19249,19411,19430,58223,58236,58281,58344,58469,58481,58483,58731,58763,58776,58790,58869,58946,58950,59075,59214,59242,59296,59378,59512,60135,60610,60902,61079,61554,62202,62878,63333,63884,64027,1,11663,11664,11665,13182,3588,3697,6063,9525,10823,10961,11670,12474,13082,13092,13093,13104,13160,13166,13324,13374,13761,13842,14421,14561,14664,14890,15145,15282,15806,16053,16411,19381,24366,58216,58396,58864,58906,59549,60636,60672,60736,62473,62537,62864,62935,63413,64808,11671,12367,16289,19220,61958,61979,59546,11471];
  388. }
  389. $begin_time = date('Y-m-d H:i:s',strtotime('-3 month'));
  390. $end_time = date('Y-m-d H:i:s');
  391. $where = " and orders.from_bid > 0 and book_configs.charge_type = 'CHAPTER' and book_categories.pid= {$sex} and book_configs.is_on_shelf = 2";
  392. $hide = getHiddenCp($package);
  393. if ($hide){
  394. $where .= " and book_configs.cp_source not in ( '" . implode("','",$hide) . "')";
  395. }
  396. $sql = " select orders.from_bid from orders INNER JOIN books ON orders.from_bid = books.id INNER JOIN book_configs ON book_configs.bid = books.id INNER JOIN book_categories ON book_categories.id=books.category_id WHERE orders.created_at >= '{$begin_time}' and orders.created_at <= '{$end_time}' and orders.status = 'PAID' {$where} group by orders.from_bid order by sum(orders.price) desc ";
  397. return DB::select($sql);
  398. }
  399. }