BookConfigService.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  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 App\Modules\Trade\Models\Order;
  19. use Illuminate\Support\Facades\DB;
  20. use phpDocumentor\Reflection\Types\This;
  21. use Redis;
  22. use Vinkla\Hashids\Facades\Hashids;
  23. class BookConfigService
  24. {
  25. /**
  26. * 根据id获取图书
  27. * @param $bid
  28. * @return mixed
  29. */
  30. public static function getBookById($bid)
  31. {
  32. return BookConfig::getBookById($bid);
  33. }
  34. /**
  35. * 获取图书组合信息
  36. * @param $bid
  37. * @return array
  38. */
  39. public static function getCombinationInfo($bid)
  40. {
  41. $info = BookCombinationConfig::where('bid', $bid)->where('is_enable', 1)->select('bid_group')->first();
  42. if ($info) return explode(',', $info->bid_group);
  43. return [];
  44. }
  45. /**
  46. * 根据bid数组获取多本图书
  47. * @param $where
  48. * @param null $order
  49. * @return mixed
  50. */
  51. public static function getBooksByIds(array $where, $order = [], $is_external_shelf = true)
  52. {
  53. if (empty($where)) {
  54. return (object)array();
  55. }
  56. if ($order)
  57. $res = BookConfig::getBooksByIds($where, $order, $is_external_shelf);
  58. else
  59. $res = BookConfig::getBooksByIds($where, [], $is_external_shelf);
  60. return $res;
  61. }
  62. public static function getBookLists(array $where, $order = [], $is_external_shelf = true)
  63. {
  64. if (empty($where)) {
  65. return (object)array();
  66. }
  67. if ($order) {
  68. $res = BookConfig::getBookLists($where, $order, $is_external_shelf);
  69. } else {
  70. $res = BookConfig::getBookLists($where, [], $is_external_shelf);
  71. }
  72. return $res;
  73. }
  74. /**
  75. *
  76. * 根据条件获取图书
  77. * @param array $where ['key'=>'根据关键词查询','category_id'=>'根据分类id查询','is_on_shelf'=>上下架查询,'channel_name'=>'频道查询(男频女频)']
  78. * @param array $order 排序 默认是bid排序
  79. * @param int $page_size
  80. * @return mixed
  81. */
  82. public static function getBooks(array $where, array $order = [], $page_size = 15)
  83. {
  84. return BookConfig::getBooks($where, $order, $page_size);
  85. }
  86. /**
  87. * 获取阅读完的推荐
  88. * @param $category_id
  89. * @param int $num
  90. * @return mixed
  91. */
  92. public static function getRecommendBooks($bid, $category_id, $num = 4)
  93. {
  94. return BookConfig::getRecommendBooks($bid, $category_id, $num);
  95. }
  96. /**
  97. * 获取阅读完的推荐(快应用)
  98. * @param $category_id
  99. * @param int $num
  100. * @return mixed
  101. */
  102. public static function getQuickAppRecommendBooks($bid, $category_id, $num = 4)
  103. {
  104. return BookConfig::getQuickAppRecommendBooks($bid, $category_id, $num);
  105. }
  106. public static function getSimpleBooksByIds(array $ids)
  107. {
  108. $str = implode(',', $ids);
  109. $field = 'bid,' . $str;
  110. return BookConfig::whereIn('bid', $ids)->select('bid', 'book_name')->orderBy(DB::raw('field(' . $field . ')'))->get();
  111. }
  112. public static function findBookKeywords(bool $is_all = false)
  113. {
  114. $sql = BookKeyword::where('status', 1)->orderBy('sequence');
  115. if ($is_all) {
  116. return $sql->get();
  117. } else {
  118. return $sql->paginate(10);
  119. }
  120. }
  121. public static function saveUserSearchLog(string $words, int $uid)
  122. {
  123. QappUserSearchBookLog::create([
  124. 'uid' => $uid,
  125. 'words' => $words,
  126. ]);
  127. }
  128. /**
  129. * @return FreeBookConfig
  130. */
  131. public static function findFreeBookConfig(int $sex)
  132. {
  133. return FreeBookConfig::where(['sex' => $sex, 'is_enabled' => 1])
  134. ->where('end_time', '>=', now())
  135. ->orderBy('end_time')
  136. ->first();
  137. }
  138. /**
  139. * 查找限免书籍
  140. * @return array
  141. */
  142. public static function findFreeBooks(int $sex)
  143. {
  144. $config = self::findFreeBookConfig($sex);
  145. \Log::info('return_empty_free_books:' . $sex);
  146. \Log::info($config);
  147. if ($config) {
  148. $free_books = FreeBook::where('config_id', $config->id)
  149. ->where('is_enabled', 1)
  150. ->get();
  151. $bids = $free_books->pluck('bid')->all();
  152. $book_configs = BookConfig::whereIn('bid', $bids)
  153. ->where('is_on_shelf', 2)
  154. ->select('bid', 'book_name', 'cover')
  155. ->get();
  156. $books = Book::whereIn('id', $bids)->select('id', 'intro')->get();
  157. \Log::info('return_empty_data:');
  158. \Log::info($books);
  159. $book_list = $book_configs->transform(function ($item) use ($books) {
  160. $book = $books->where('id', $item->bid)->first();
  161. return [
  162. 'book_id' => Hashids::encode($item->bid),
  163. 'cover_url' => $item->cover,
  164. 'book_name' => $item->book_name,
  165. 'intro' => $book->intro,
  166. ];
  167. })->all();
  168. return [
  169. 'title' => $config->name,
  170. 'end_time' => $config->end_time,
  171. 'list' => $book_list,
  172. ];
  173. }
  174. return [];
  175. }
  176. /**
  177. * 判断书籍是否限免
  178. * @return bool
  179. */
  180. public static function judgeBookIsFree(int $bid)
  181. {
  182. $ids = [];
  183. foreach ([1, 2] as $sex) {
  184. $config = self::findFreeBookConfig($sex);
  185. if ($config) {
  186. $ids[] = $config->id;
  187. }
  188. }
  189. return FreeBook::where('bid', $bid)
  190. ->whereIn('config_id', $ids)
  191. ->where('is_enabled', 1)->select('id')->first();
  192. }
  193. public static function getByBidNoFilter($bid)
  194. {
  195. return FreeBook::join('free_book_config', 'free_book_config.id', '=', 'free_books.config_id')
  196. ->where('bid', $bid)
  197. ->select('free_books.id', 'end_time')
  198. ->where('end_time', '<', date('Y-m-d H:i:s'))
  199. ->orderBy('free_book_config.end_time', 'desc')
  200. ->first();
  201. }
  202. public static function chargeStats($id, $amount, $uid)
  203. {
  204. if (!Redis::Sismember('qapp:free:virtual:uids' . $id, $uid)) {
  205. return;
  206. }
  207. $now = date('Y-m-d');
  208. $amount = $amount * 100;
  209. Redis::hincrby('qapp:book:free:charge:' . $id, $now, $amount);
  210. #Redis::sadd('qapp:free:charge'.$now,$id);
  211. Redis::sadd('qapp:free:actuality' . $now, $id);
  212. Redis::sadd('qapp:free:charge:uids' . $now . $id, $uid);
  213. }
  214. public static function getBookByField($bids, $field)
  215. {
  216. if (!$bids || !$field) return null;
  217. return BookConfig::join('books', 'books.id', '=', 'book_configs.bid')->
  218. whereIn('bid', $bids)->select($field)->get();
  219. }
  220. /**
  221. * 根据书籍bid去除无用bid
  222. * name: getAvailableBIdsbyBids
  223. * @param $bids
  224. * @param mixed $channel_id
  225. * @param mixed $is_external_shelf
  226. * @return array
  227. * date 2022/09/20 10:39
  228. */
  229. public static function getAvailableBIdsbyBids($bids, $channel_id = 0, $is_external_shelf = true)
  230. {
  231. if (empty($bids)) {
  232. return [];
  233. }
  234. $res = BookConfig::whereIn('bid', $bids);
  235. // if($channel_id == config('qapp_public_package_channel')){
  236. // $res->whereNotIn('cp_source',getHiddenCp());
  237. // }else{
  238. // $res->whereNotIn('cp_source',array_merge(getHiddenCp(),['lianshang']));
  239. // }
  240. $res->whereNotIn('cp_source', getHiddenCp($channel_id, 2));
  241. if ($is_external_shelf) {
  242. $res->where('is_on_shelf', 2);
  243. } else {
  244. $res->whereIn('is_on_shelf', [1, 2]);
  245. }
  246. return $res->pluck("bid")->toArray();
  247. }
  248. /***
  249. * 推荐位书籍检测和补齐
  250. * name: getCheckBooks
  251. * @param $bid_list
  252. * @param $channel
  253. * @param $package
  254. * @param $is_author
  255. * @return mixed
  256. * date 2022/10/26 10:11
  257. */
  258. public static function getCheckBooks($bid_list, $channel, $package, $is_author)
  259. {
  260. $hidden_cp = getHiddenCp($package);
  261. // if(!is_public_package($package)){
  262. // $hidden_cp = array_merge($hidden_cp,['lianshang']);
  263. // }
  264. //获取书本数量
  265. $count = count($bid_list);
  266. if (!$is_author) {
  267. $where = [
  268. ['book_configs.charge_type', '!=', 'BOOK'],
  269. ['book_configs.cp_source', '=', 'ycsd'],
  270. ];
  271. } else {
  272. $where = [
  273. ['book_configs.charge_type', '!=', 'BOOK'],
  274. ];
  275. }
  276. //获取书籍交集bid,过滤掉不符合要求的书
  277. $bid_list = BookConfig::join('books', 'book_configs.bid', '=', 'books.id')
  278. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  279. ->whereIn('book_configs.bid', $bid_list)
  280. ->where('book_configs.is_on_shelf', 2)
  281. ->where($where)
  282. ->whereNotIn('book_configs.cp_source', $hidden_cp)
  283. ->where('book_categories.pid', $channel)
  284. ->pluck('book_configs.bid')->all();
  285. $book_count = count($bid_list);
  286. if ($book_count === $count) {
  287. return $bid_list;
  288. }
  289. $supplement_count = $count - $book_count;
  290. //获取随机的有效的书籍bid
  291. $rand_bid = BookConfig::join('books', 'book_configs.bid', '=', 'books.id')
  292. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  293. ->where('book_configs.is_on_shelf', 2)
  294. ->where($where)
  295. ->whereNotIn('book_configs.cp_source', $hidden_cp)
  296. // ->where('book_configs.is_high_quality',1)
  297. ->where('book_categories.pid', $channel)
  298. ->orderBy('book_configs.is_high_quality', 'desc')
  299. // ->inRandomOrder()
  300. ->orderBy('book_configs.recommend_index', 'desc')
  301. ->limit($supplement_count)
  302. ->pluck('book_configs.bid')->all();
  303. return array_filter(array_merge($bid_list, $rand_bid));
  304. }
  305. public static function getRecommendBids($package = '', $channel = 1, $no_in_bid = [], $limit = 36, $is_on_shelf = true)
  306. {
  307. DB::enableQueryLog();
  308. $where = [
  309. ['book_configs.charge_type', '!=', 'BOOK'],
  310. ];
  311. //获取书籍交集bid,过滤掉不符合要求的书
  312. $bid_list = BookConfig::join('books', 'book_configs.bid', '=', 'books.id')
  313. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  314. ->distinct("books.name")
  315. ->where($where)
  316. ->whereNotIn('book_configs.cp_source', getHiddenCp($package))
  317. ->where('book_categories.pid', $channel);
  318. if ($is_on_shelf) {
  319. $bid_list->where('book_configs.is_on_shelf', 2);
  320. } else {
  321. $bid_list->whereIn('book_configs.is_on_shelf', [1, 2]);
  322. }
  323. if (!empty($no_in_bid)) {
  324. $bid_list->whereNotIn('book_configs.bid', $no_in_bid);
  325. }
  326. 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();
  327. }
  328. /***
  329. * 书籍授权情况 2黑名单 1白名单 其他 无特殊添加
  330. * name: bookCopyright
  331. * @param mixed $bid
  332. * @param mixed $distribution_channel_id
  333. * date 2022/11/14 17:16
  334. */
  335. public static function bookCopyright($bid, $distribution_channel_id = 0)
  336. {
  337. if ($distribution_channel_id < 1) {
  338. return 0;
  339. }
  340. return BookCopyright::where('distribution_channel_id', $distribution_channel_id)
  341. ->where('bid', $bid)
  342. ->where('is_enabled', 1)
  343. ->where('platform', "qapp")
  344. ->value('type');
  345. }
  346. public static function getNewRecommendBids($package, $channel, $bids = [], $limit = 12, $is_on_shelf = true)
  347. {
  348. $begin_time = date('Y-m-d', strtotime('-2 month'));
  349. $end_time = date('Y-m-d');
  350. $where = " and book_configs.charge_type = 'CHAPTER' and book_categories.pid= {$channel}";
  351. $hide = getHiddenCp($package);
  352. if ($hide) {
  353. $where .= " and book_configs.cp_source not in ( '" . implode("','", $hide) . "')";
  354. }
  355. if ($is_on_shelf) {
  356. $where .= " and book_configs.is_on_shelf = 2";
  357. } else {
  358. $where .= " and book_configs.is_on_shelf in (1,2)";
  359. }
  360. if (!empty($bids)) {
  361. $where .= " and books.id not in (" . implode(",", $bids) . ")";
  362. }
  363. $sql = "select book_configs.bid from book_promotion_day_stats
  364. INNER JOIN books on books.id=book_promotion_day_stats.bid
  365. INNER JOIN book_configs on book_configs.bid = books.id
  366. INNER JOIN book_categories ON book_categories.id=books.category_id
  367. where date >='{$begin_time}' and date <= '{$end_time}' {$where} group by bid order by sum(rechareg_amount) desc limit {$limit}";
  368. // $bids = DB::select($sql);
  369. // echo "<pre><hr>";
  370. // var_export($bids);
  371. // echo "<hr>";
  372. // var_export($sql);
  373. // die();
  374. }
  375. /***
  376. * 获取排行榜数据
  377. * name: getRankList
  378. * @param $package
  379. * @param mixed $sex 1:男频 2:女频
  380. * @param int $limit 条数默认30
  381. * date 2022/11/15 14:36
  382. */
  383. public static function getRankList($package, $sex = 1, $limit = 30)
  384. {
  385. $hide = getHiddenCp($package);
  386. $bids = BookConfig::join('books', 'book_configs.bid', '=', 'books.id')
  387. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  388. ->where('book_configs.is_on_shelf', 2)
  389. ->where('book_configs.charge_type', "CHAPTER")
  390. ->whereNotIn('book_configs.cp_source', $hide)
  391. ->where('book_categories.pid', $sex)
  392. ->pluck('book_configs.bid')->all();
  393. if (empty($bids)) {
  394. return [];
  395. }
  396. $begin_time = date('Y-m-d H:i:s', strtotime('-3 month'));
  397. $end_time = date('Y-m-d H:i:s');
  398. return Order::where("from_bid", ">", 0)->whereIn("from_bid", $bids)
  399. ->where('created_at', ">=", $begin_time)->where('created_at', "<=", $end_time)
  400. ->where('status','PAID')
  401. ->groupBy('from_bid')
  402. ->orderByRaw("SUM(price) desc")
  403. ->limit($limit)
  404. ->pluck('from_bid')
  405. ->all();
  406. }
  407. }