BookConfig.php 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123
  1. <?php
  2. namespace App\Modules\Book\Models;
  3. use App\Modules\Book\Services\BookRoleService;
  4. use App\Modules\Book\Services\BookTagsService;
  5. use App\Modules\User\Services\ReadRecordService;
  6. use App\Modules\Book\Services\BookConfigService;
  7. use App\Modules\Channel\Services\ChannelService;
  8. use App\Modules\OfficialAccount\Services\ForceSubscribeService;
  9. use DB;
  10. use Hashids;
  11. use Illuminate\Database\Eloquent\Model;
  12. use App\Modules\User\Models\User;
  13. use Log;
  14. use Redis;
  15. class BookConfig extends Model
  16. {
  17. protected $table = 'book_configs';
  18. protected $fillable = ['bid', 'force_subscribe_chapter_seq', 'price', 'cover', 'book_name',
  19. 'copyright', 'charge_type', 'hot', 'is_on_shelf', 'source_domain', 'recommend_index', 'roles', 'test_status', 'plan_push_user_num', 'test_update_time',
  20. 'is_show_index_content', 'click_count', 'promotion_domain', 'copyright_limit_data', 'recommend_cid', 'is_high_quality', 'vip_seq','editor_recommend','is_current_week_promotion'];
  21. /*
  22. public static function getBooks($where, $order, $page_size = 15, $category = [], $key = null)
  23. {
  24. $res = self::join('books', 'book_configs.bid', '=', 'books.id')
  25. ->join('book_categories', 'books.category_id', 'book_categories.id')
  26. ->select('book_configs.bid', 'book_configs.force_subscribe_chapter_seq', 'book_configs.price',
  27. 'book_configs.cover', 'book_configs.book_name', 'book_configs.copyright', 'book_configs.charge_type', 'book_configs.is_on_shelf',
  28. 'books.author', 'books.intro', 'books.category_name', 'books.category_id', 'status', 'chapter_count', 'book_configs.click_count',
  29. 'first_cid', 'last_cid', 'size', 'last_chapter', 'books.keyword', 'book_configs.recommend_index', 'book_configs.is_show_index_content', 'book_configs.product_id'
  30. , 'book_categories.channel_name', 'books.last_cid', 'books.last_chapter'
  31. )
  32. ->where($where)
  33. ->orderBy($order[0], $order[1]);
  34. if ($category) {
  35. $res = $res->whereIn('books.category_id', $category);
  36. }
  37. if ($key) {
  38. $res = $res->orwhere('book_configs.name', 'like', $key['name'])->orwhere('books.author', 'like', $key['author']);
  39. }
  40. return $res->paginate($page_size);
  41. }
  42. */
  43. /**
  44. * 根据条件获取图书
  45. * @param array $where
  46. * @param array $order
  47. * @param int $page_size
  48. * @return mixed
  49. */
  50. public static function getBooks(array $where = [], array $order = [], $page_size = 15)
  51. {
  52. if (!$order) {
  53. $order = ['recommend_index', 'desc'];
  54. }
  55. $res = self::join('books', 'book_configs.bid', '=', 'books.id')
  56. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  57. ->select('book_configs.bid', 'book_configs.roles', 'book_configs.force_subscribe_chapter_seq', 'book_configs.cp_source', 'book_configs.vip_seq', 'book_configs.price', 'book_configs.cover', 'book_configs.book_name',
  58. 'book_configs.copyright', 'book_configs.charge_type', 'book_configs.is_on_shelf', 'books.author', 'books.intro', 'book_categories.category_name',
  59. 'category_id', 'status', 'chapter_count', 'book_configs.click_count', 'first_cid', 'last_cid', 'books.size', 'last_chapter', 'books.keyword',
  60. 'book_configs.recommend_index', 'book_configs.is_show_index_content', 'book_configs.product_id', 'book_categories.channel_name',
  61. 'books.last_cid', 'books.last_chapter', 'book_configs.product_id', 'book_configs.copyright_limit_data', 'books.updated_at as last_update_time',
  62. 'book_configs.promotion_domain', 'books.name as old_name', 'book_configs.recommend_cid', 'book_configs.is_high_quality','is_current_week_promotion'
  63. );
  64. if ($where) {
  65. foreach ($where as $key => $v) {
  66. //关键词查询
  67. if ($key == 'key' && $v) {
  68. //$res = $res->where('book_configs.book_name', 'like', '%' . $v . '%');
  69. $res = $res->where(function ($query) use ($v) {
  70. $query->where('book_configs.book_name', 'like', '%' . $v . '%');
  71. if(mb_strlen($v)<=5) {
  72. $roles_bids = BookRoleService::getBidsByRole($v);
  73. if(count($roles_bids)>0) {
  74. $query->orWhereIn('book_configs.bid',$roles_bids);
  75. }
  76. }
  77. });
  78. //->orWhere('books.intro', 'like', '%' . $v . '%')
  79. //->orWhere('books.category_name', 'like', '%' . $v . '%')->orWhere('books.author', 'like', '%' . $v . '%')
  80. //->orWhere('books.keyword', 'like', '%' . $v . '%');
  81. }
  82. //分类id查询
  83. if ($key == 'category_id' && $v) {
  84. $res = $res->where('books.category_id', '=', $v);
  85. }
  86. //上架查询
  87. if ($key == 'is_on_shelf' && $v != '') {
  88. if (is_array($v)) {
  89. $res = $res->whereIn('is_on_shelf', $v);
  90. } else {
  91. $res = $res->where('is_on_shelf', '=', $v);
  92. }
  93. }
  94. //频道查询
  95. if ($key == 'channel_name' && $v) {
  96. $res = $res->where('book_categories.channel_name', '=', $v);
  97. }
  98. if ($key == 'status') {
  99. $res = $res->where('books.status', '=', $v);
  100. }
  101. if ($key == 'author') {
  102. $res = $res->where('books.author', 'like', '%' . $v . '%');
  103. }
  104. if ($key == 'roles') {
  105. $res = $res->where('book_configs.roles', 'like', '%' . $v . '%');
  106. }
  107. //旧书名查询
  108. if ($key == 'old_name') {
  109. $res = $res->where('books.name', 'like', '%' . $v . '%');
  110. }
  111. //版权日期查询
  112. if ($key == 'copy_right_date') {
  113. if (is_array($v)) {
  114. $res = $res->whereBetween('book_configs.copyright_limit_data', $v);
  115. } else {
  116. $res = $res->where('book_configs.copyright_limit_data', '<=', $v);
  117. }
  118. }
  119. if ($key == 'domain') {
  120. $res = $res->where('book_configs.promotion_domain', 'like', '%' . $v . '%');
  121. }
  122. if ($key == 'bid') {
  123. $res = $res->where('book_configs.bid', '=', $v);
  124. }
  125. if ($key == 'is_high_quality') {
  126. $res = $res->where('book_configs.is_high_quality', '=', $v);
  127. }
  128. if ($key == 'charge_type') {
  129. $res = $res->where('book_configs.charge_type', '=', $v);
  130. }
  131. if ($key == 'firstChapterContent') {
  132. $res = $res->join('chapters', function ($query) use ($v) {
  133. $query->on('book_configs.bid', '=', 'chapters.bid')
  134. ->where('chapters.sequence', 1);
  135. })->where('chapters.content', 'like', '%' . $v . '%');
  136. }
  137. if ($key == 'tags') {
  138. $tags_filter = BookTagsService::getSearchBooks($v);
  139. $res->whereIn('book_configs.bid', $tags_filter);
  140. }
  141. if ($key == 'is_current_week_promotion') {
  142. $res->where('book_configs.is_current_week_promotion', $v);
  143. }
  144. }
  145. }
  146. //$res->orderBy('book_configs.updated_at','desc');
  147. return $res->orderBy($order[0], $order[1])->orderBy('book_configs.updated_at', 'desc')->paginate($page_size);
  148. }
  149. /**
  150. * 根据条件获取图书
  151. * @param array $where
  152. * @param array $order
  153. * @param int $page_size
  154. * @return mixed
  155. */
  156. public static function getPromotionBooks(array $where = [], array $bids, array $order = [], $page_size = 15)
  157. {
  158. if (!$order) {
  159. $order = ['recommend_index', 'desc'];
  160. }
  161. $res1 = self::join('books', 'book_configs.bid', '=', 'books.id')
  162. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  163. ->select('book_configs.bid', 'book_configs.force_subscribe_chapter_seq', 'book_configs.cp_source', 'book_configs.vip_seq', 'book_configs.price', 'book_configs.cover', 'book_configs.book_name',
  164. 'book_configs.copyright', 'book_configs.charge_type', 'book_configs.is_on_shelf', 'books.author', 'books.intro', 'book_categories.category_name',
  165. 'category_id', 'status', 'chapter_count', 'book_configs.click_count', 'first_cid', 'last_cid', 'size', 'last_chapter', 'books.keyword',
  166. 'book_configs.recommend_index', 'book_configs.is_show_index_content', 'book_configs.product_id', 'book_categories.channel_name',
  167. 'books.last_cid', 'books.last_chapter', 'book_configs.product_id', 'book_configs.copyright_limit_data', 'books.updated_at as last_update_time',
  168. 'book_configs.promotion_domain', 'books.name as old_name', 'book_configs.recommend_cid', 'book_configs.is_high_quality'
  169. );
  170. if ($where) {
  171. foreach ($where as $key => $v) {
  172. //关键词查询
  173. if ($key == 'key' && $v) {
  174. $res1 = $res1->where('book_configs.book_name', 'like', '%' . $v . '%');
  175. }
  176. //分类id查询
  177. if ($key == 'category_id' && $v) {
  178. $res1 = $res1->where('books.category_id', '=', $v);
  179. }
  180. //上架查询
  181. if ($key == 'is_on_shelf' && $v != '') {
  182. if (is_array($v)) {
  183. $res1 = $res1->whereIn('is_on_shelf', $v);
  184. } else {
  185. $res1 = $res1->where('is_on_shelf', '=', $v);
  186. }
  187. }
  188. //频道查询
  189. if ($key == 'channel_name' && $v) {
  190. $res1 = $res1->where('book_categories.channel_name', '=', $v);
  191. }
  192. if ($key == 'status') {
  193. $res1 = $res1->where('books.status', '=', $v);
  194. }
  195. if ($key == 'author') {
  196. $res1 = $res1->where('books.author', 'like', '%' . $v . '%');
  197. }
  198. //旧书名查询
  199. if ($key == 'old_name') {
  200. $res1 = $res1->where('books.name', 'like', '%' . $v . '%');
  201. }
  202. //版权日期查询
  203. if ($key == 'copy_right_date') {
  204. if (is_array($v)) {
  205. $res1 = $res1->whereBetween('book_configs.copyright_limit_data', $v);
  206. } else {
  207. $res1 = $res1->where('book_configs.copyright_limit_data', '<=', $v);
  208. }
  209. }
  210. if ($key == 'domain') {
  211. $res1 = $res1->where('book_configs.promotion_domain', 'like', '%' . $v . '%');
  212. }
  213. if ($key == 'bid') {
  214. $res1 = $res1->where('book_configs.bid', '=', $v);
  215. }
  216. if ($key == 'is_high_quality') {
  217. $res1 = $res1->where('book_configs.is_high_quality', '=', $v);
  218. }
  219. if ($key == 'charge_type') {
  220. $res1 = $res1->where('book_configs.charge_type', '=', $v);
  221. }
  222. if ($key == 'hidden_books') {
  223. $res1 = $res1->whereNotIn('book_configs.bid', $v);
  224. }
  225. }
  226. if ($bids) {
  227. //$res1 = $res1->orwhereIn('book_configs.id', $bids);
  228. if ((isset($where['key']) && !empty($where['key'])) && (isset($where['channel_name']) && !empty($where['channel_name']))) {
  229. $res1 = $res1->orWhere(function ($query) use ($bids, $where) {
  230. $query->where('is_on_shelf', 1)
  231. ->whereIn('book_configs.bid', $bids)
  232. ->where('book_configs.book_name', 'like', '%' . $where['key'] . '%')
  233. ->where('book_categories.channel_name', '=', $where['channel_name']);;
  234. });
  235. } elseif (isset($where['key']) && !empty($where['key'])) {
  236. $res1 = $res1->orWhere(function ($query) use ($bids, $where) {
  237. $query->where('is_on_shelf', 1)
  238. ->whereIn('book_configs.bid', $bids)
  239. ->where('book_configs.book_name', 'like', '%' . $where['key'] . '%');
  240. });
  241. } elseif (isset($where['channel_name']) && !empty($where['channel_name'])) {
  242. $res1 = $res1->orWhere(function ($query) use ($bids, $where) {
  243. $query->where('is_on_shelf', 1)
  244. ->whereIn('book_configs.bid', $bids)
  245. ->where('book_categories.channel_name', '=', $where['channel_name']);
  246. });
  247. } else {
  248. $res1 = $res1->orwhereIn('book_configs.bid', $bids);
  249. }
  250. }
  251. }
  252. return $res1->orderBy($order[0], $order[1])->orderBy('book_configs.updated_at', 'desc')->paginate($page_size);
  253. }
  254. /**
  255. * 根据id数组获取图书信息
  256. * @param array $bid_arr
  257. * @param array $order
  258. * @return mixed
  259. */
  260. public static function getBooksByIds(array $bid_arr, array $order = [])
  261. {
  262. $res = self::join('books', 'book_configs.bid', '=', 'books.id')
  263. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  264. ->select('book_configs.bid', 'book_configs.force_subscribe_chapter_seq', 'book_configs.vip_seq', 'book_configs.price',
  265. 'book_configs.cover', 'book_configs.book_name', 'book_configs.copyright', 'book_configs.charge_type', 'book_configs.is_on_shelf',
  266. 'books.author', 'books.intro', 'book_categories.category_name', 'category_id', 'status', 'chapter_count', 'book_configs.click_count',
  267. 'first_cid', 'last_cid', 'size', 'last_chapter', 'books.keyword', 'book_configs.recommend_index', 'book_configs.is_show_index_content',
  268. 'book_configs.product_id', 'book_categories.channel_name', 'books.last_cid', 'books.last_chapter', 'book_configs.product_id', 'books.updated_at as last_update_time',
  269. 'book_configs.copyright_limit_data', 'book_configs.promotion_domain', 'books.name as old_name', 'book_configs.recommend_cid'
  270. )
  271. ->whereIn('book_configs.bid', $bid_arr);
  272. if ($order) {
  273. $res->orderBy($order[0], $order[1]);
  274. } else {
  275. $str = implode(',', $bid_arr);
  276. $field = 'bid,' . $str;
  277. $res->orderBy(DB::raw('field(' . $field . ')'));
  278. }
  279. return $res->limit(30)->get();
  280. }
  281. /**
  282. * 根据bid获取图书信息
  283. * @param $bid
  284. * @return mixed
  285. */
  286. public static function getBookById($bid)
  287. {
  288. if (empty($bid)) return null;
  289. return self::join('books', 'book_configs.bid', '=', 'books.id')
  290. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  291. ->select('book_configs.bid', 'book_configs.is_on_shelf', 'book_configs.force_subscribe_chapter_seq', 'book_configs.vip_seq', 'book_configs.cp_source', 'book_configs.price', 'book_configs.cover', 'book_configs.book_name',
  292. 'book_configs.copyright', 'book_configs.created_at', 'book_configs.charge_type', 'book_configs.is_on_shelf', 'books.author', 'books.intro', 'book_categories.category_name',
  293. 'category_id', 'status', 'chapter_count', 'first_cid', 'last_cid', 'size', 'last_chapter', 'books.keyword', 'book_configs.recommend_index','book_configs.test_status',
  294. 'book_configs.is_show_index_content', 'book_configs.click_count', 'book_configs.product_id', 'book_categories.channel_name', 'books.last_cid', 'books.updated_at as last_update_time',
  295. 'books.last_chapter', 'book_configs.product_id', 'book_configs.copyright_limit_data', 'book_configs.promotion_domain', 'books.name as old_name', 'book_configs.recommend_cid', 'book_configs.is_high_quality'
  296. )->where('book_configs.bid', $bid)->first();
  297. }
  298. /**
  299. * 根据关键词获取图书
  300. * @param $key
  301. * @param int $page_size
  302. * @param null $is_on_shelf
  303. * @return mixed
  304. */
  305. public static function getBooksByKey($key, $page_size = 15, $is_on_shelf = null)
  306. {
  307. $res = self::join('books', 'book_configs.bid', '=', 'books.id')
  308. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  309. ->select('book_configs.bid', 'book_configs.force_subscribe_chapter_seq', 'book_configs.vip_seq', 'book_configs.price',
  310. 'book_configs.cover', 'book_configs.book_name', 'book_configs.copyright', 'book_configs.charge_type', 'book_configs.is_on_shelf',
  311. 'books.author', 'books.intro', 'book_categories.category_name', 'category_id', 'status', 'chapter_count', 'book_configs.click_count',
  312. 'first_cid', 'last_cid', 'size', 'last_chapter', 'books.keyword', 'book_configs.recommend_index', 'book_configs.is_show_index_content',
  313. 'book_configs.product_id', 'book_categories.channel_name', 'books.last_cid', 'books.last_chapter', 'book_configs.product_id', 'books.updated_at as last_update_time',
  314. 'book_configs.copyright_limit_data', 'book_configs.promotion_domain', 'books.name as old_name', 'book_configs.recommend_cid', 'book_configs.is_high_quality'
  315. )
  316. ->where('book_configs.book_name', 'like', '%' . $key . '%');
  317. //->orWhere('books.intro', 'like', '%' . $key . '%')
  318. //->orWhere('books.keyword', 'like', '%' . $key . '%')
  319. //->orWhere('books.category_name', 'like', '%' . $key . '%')
  320. //->orWhere('books.author', 'like', '%' . $key . '%');
  321. /*
  322. if ($is_on_shelf) {
  323. if (is_array($is_on_shelf)) {
  324. $res->whereIn('book_configs.is_on_shelf', $is_on_shelf);
  325. } else {
  326. $res->where('book_configs.is_on_shelf', '=', $is_on_shelf);
  327. }
  328. }*/
  329. $res->whereIn('book_configs.is_on_shelf', [1, 2]);
  330. $res = $res->paginate($page_size);
  331. foreach ($res as $v) {
  332. $v->book_url = '/detail?id=' . Hashids::encode($v->bid);
  333. }
  334. return $res;
  335. }
  336. /**
  337. * 根据product_id获取图书
  338. * @param $product_id
  339. * @return mixed
  340. */
  341. public static function getBookByProduct($product_id)
  342. {
  343. return self::join('books', 'book_configs.bid', '=', 'books.id')
  344. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  345. ->select('book_configs.bid', 'book_configs.force_subscribe_chapter_seq', 'book_configs.vip_seq', 'book_configs.price',
  346. 'book_configs.cover', 'book_configs.book_name', 'book_configs.copyright', 'book_configs.charge_type', 'book_configs.is_on_shelf',
  347. 'books.author', 'books.intro', 'book_categories.category_name', 'category_id', 'status', 'chapter_count', 'first_cid', 'last_cid', 'size', 'last_chapter',
  348. 'books.keyword', 'book_configs.recommend_index', 'book_configs.is_show_index_content', 'book_configs.click_count', 'book_configs.product_id'
  349. , 'book_categories.channel_name', 'books.last_cid', 'books.last_chapter', 'book_configs.product_id', 'book_configs.recommend_cid', 'book_configs.is_high_quality'
  350. )->where('book_configs.product_id', $product_id)->first();
  351. }
  352. /**
  353. * 更新图书
  354. * @param $bid
  355. * @param array $param
  356. * @return bool
  357. */
  358. public static function updateBookInfo($bid, array $param)
  359. {
  360. $book_info = self::getBookById($bid);
  361. if (!$book_info) return false;
  362. $update_data = [];
  363. if (isset($param['force_subscribe_chapter_seq']) && !empty($param['force_subscribe_chapter_seq'])) $update_data['force_subscribe_chapter_seq'] = $param['force_subscribe_chapter_seq'];
  364. if (isset($param['product_id']) && !empty($param['product_id'])) $update_data['product_id'] = $param['product_id'];
  365. if (isset($param['book_name']) && !empty($param['book_name'])) $update_data['book_name'] = $param['book_name'];
  366. if (isset($param['price']) && !empty($param['price'])) $update_data['price'] = $param['price'];
  367. if (isset($param['cover']) && !empty($param['cover'])) $update_data['cover'] = $param['cover'];
  368. if (isset($param['charge_type']) && !empty($param['charge_type'])) {
  369. $update_data['charge_type'] = $param['charge_type'];
  370. if (is_numeric($update_data['charge_type'])) {
  371. $update_data['charge_type'] = 'CHAPTER';
  372. }
  373. }
  374. if (isset($param['hot']) && !empty($param['hot'])) $update_data['hot'] = $param['hot'];
  375. if (isset($param['roles']) && !empty($param['roles'])) $update_data['roles'] = $param['roles'];
  376. if (isset($param['is_on_shelf']) && $param['is_on_shelf'] != '') $update_data['is_on_shelf'] = $param['is_on_shelf'];
  377. if (isset($param['recommend_index']) && !empty($param['recommend_index'])) $update_data['recommend_index'] = $param['recommend_index'];
  378. if (isset($param['is_show_index_content'])) $update_data['is_show_index_content'] = $param['is_show_index_content'];
  379. if (isset($param['click_count']) && $param['click_count'] != '') $update_data['click_count'] = $param['click_count'];
  380. if (isset($param['copyright_limit_data']) && $param['copyright_limit_data'] != '') $update_data['copyright_limit_data'] = $param['copyright_limit_data'];
  381. if (isset($param['promotion_domain']) && $param['promotion_domain'] != '') $update_data['promotion_domain'] = $param['promotion_domain'];
  382. if (isset($param['copyright']) && $param['copyright'] != '') $update_data['copyright'] = $param['copyright'];
  383. $res1 = null;
  384. if (isset($param['status'])) {
  385. $res1 = Book::where('id', $bid)->update(['status' => $param['status']]);
  386. }
  387. if (isset($param['book_category_id'])) {
  388. $catagory = BookCategory::select('category_name')->where('id', $param['book_category_id'])->first();
  389. Book::where('id', $bid)->update(['category_id' => $param['book_category_id'], 'category_name' => $catagory->category_name]);
  390. }
  391. if (empty($update_data) && !$res1) return false;
  392. return self::where('bid', $bid)->update($update_data);
  393. }
  394. /*
  395. * 获取渠道,用户的全部书籍列表
  396. */
  397. public static function getLeftRecommendBook($channel_name, $is_high_quality,$force_update=false): array
  398. {
  399. if($force_update){
  400. \Log::info('force_set_full_book_channel_name:'.$channel_name);
  401. Redis::set('full_book_channel_name:'.$channel_name,null);
  402. }
  403. // 存redis里面
  404. $full_book_bids = Redis::get('full_book_channel_name:'.$channel_name);
  405. $full_book_bids = json_decode($full_book_bids);
  406. if(!empty($full_book_bids)){
  407. \Log::info('direct_get_full_book_bids_from_redis:'.$channel_name);
  408. }else{
  409. // 获取全集
  410. $full_book_bids = self::join('books', 'book_configs.bid', '=', 'books.id')
  411. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  412. ->select('book_configs.bid')
  413. ->where('book_categories.channel_name', $channel_name)
  414. ->where('book_configs.is_high_quality', $is_high_quality)
  415. ->where('book_configs.test_status', 0)// 不含测书
  416. ->whereIn('book_configs.is_on_shelf', [2])
  417. ->orderBy('book_configs.id', 'desc')
  418. ->get()->pluck('bid')->all();
  419. if(!empty($full_book_bids)){
  420. \Log::info('set_full_book_channel_name:'.$channel_name.' data:'.json_encode($full_book_bids));
  421. Redis::set('full_book_channel_name:'.$channel_name,json_encode($full_book_bids));
  422. }
  423. }
  424. // \Log::info('$full_book_bids:'.json_encode($full_book_bids));
  425. return $full_book_bids;
  426. }
  427. /*
  428. * 获取渠道,用户的全部需要测试的书籍列表
  429. */
  430. public static function getLeftRecommendTestBook($channel_name)
  431. {
  432. // 获取test全集
  433. $test_bids = self::getLeftRecommendTestBookConfigs($channel_name);
  434. // \Log::info('getLeftRecommendTestBook:'.json_encode($test_bids));
  435. $last_bids = [];
  436. if (!empty($test_bids)) {
  437. foreach ($test_bids as $test_bid) {
  438. $bid = $test_bid->bid;
  439. $redis_bid_push_num = Redis::hget('SmartPushBookUserNum', $bid);
  440. $plan_push_user_num = $test_bid->plan_push_user_num;
  441. \Log::info('left_test_book,bid:' . $bid . ' redis_bid_push_num:' . $redis_bid_push_num . ' plan_push_user_num:' . $plan_push_user_num);
  442. if ($redis_bid_push_num >= $plan_push_user_num) {
  443. \Log::info('full_update_test_book,bid:' . $bid . ' redis_bid_push_num:' . $redis_bid_push_num . ' plan_push_user_num:' . $plan_push_user_num);
  444. self::where('bid', $bid)->update(['test_status' => 2, 'test_update_time' => date('Y-m-d H:i:s')]);
  445. continue;
  446. }
  447. $last_bids[] = $bid;
  448. }
  449. }
  450. return $last_bids;
  451. }
  452. /*
  453. * 获取渠道,用户的全部需要测试的书籍列表
  454. */
  455. public static function getLeftRecommendTestBookConfigs($channel_name)
  456. {
  457. // 获取全集
  458. return self::join('books', 'book_configs.bid', '=', 'books.id')
  459. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  460. ->select('book_configs.bid', 'book_configs.plan_push_user_num')
  461. ->where('book_categories.channel_name', $channel_name)
  462. ->where('book_configs.test_status', 1)// 待测
  463. ->groupBy('book_configs.bid')
  464. ->orderBy('book_configs.test_update_time', 'asc')
  465. ->limit(1)// 每次1本
  466. ->get();
  467. }
  468. /*
  469. * 获取用户的曾经推荐过的书籍列表
  470. */
  471. public static function getUserRecommendRecords($uid)
  472. {
  473. $recommend_bids = Redis::smembers('userRecommendBids:' . $uid);
  474. return $recommend_bids;
  475. }
  476. /*
  477. * 添加用户的曾经推荐过的书籍列表
  478. */
  479. public static function addUserRecommendRecords($uid, $bids)
  480. {
  481. foreach ($bids as $bid) {
  482. Redis::sadd('userRecommendBids:' . $uid, $bid);
  483. }
  484. }
  485. /*
  486. * 清楚用户的曾经推荐过的书籍列表
  487. */
  488. public static function truncateUserRecommendRecords($uid)
  489. {
  490. \Log::info('truncateUserRecommendRecords:' . $uid);
  491. Redis::del('userRecommendBids:' . $uid);
  492. }
  493. /*
  494. * 书籍推送量+1
  495. */
  496. public static function incrBidPushNum($last_bids)
  497. {
  498. if (!empty($last_bids)) {
  499. foreach ($last_bids as $last_bid) {
  500. // \Log::info('incrBidPushNum:test_bid' . $last_bid);
  501. Redis::hincrby('SmartPushBookUserNum', $last_bid, 1);
  502. }
  503. }
  504. }
  505. /*
  506. * 获取相同频道的4本高推荐图书
  507. * 1、新书倒序 2、用户推荐过的,有阅读记录的不再推荐
  508. */
  509. public static function getLeftRecommendBids($uid = '', $channel_name, $num = 4, $loop = 1)
  510. {
  511. // \Log::info('getLeftRecommendBids_loop:'.$loop.' $uid:'.$uid.' $channel_name:'.$channel_name.' $num:'.$num.' $loop:'.$loop);
  512. if ($loop > 3) {
  513. \Log::info('getLeftRecommendBids_return_loop:' . $loop . ' $uid:' . $uid . ' $channel_name:' . $channel_name);
  514. return [];
  515. }
  516. // 测试书籍优先
  517. $test_bids = self::getLeftRecommendTestBook($channel_name);
  518. // 获取全集,不含测试书籍
  519. $full_bid_no_tests = self::getLeftRecommendBook($channel_name, 1,false);
  520. $full_bids = array_merge($test_bids, $full_bid_no_tests);
  521. // 获取用户推荐过的详情
  522. $recommend_bids = self::getUserRecommendRecords($uid);
  523. // 获取用户阅读记录详情
  524. $read_bids = ReadRecordService::getSimpleReadRecord($uid);
  525. // 得到差集
  526. $left_bids = array_diff($full_bids, $recommend_bids, $read_bids);
  527. // \Log::info('full_bids:'.json_encode($full_bids).' full_bid_no_tests:'.json_encode($full_bid_no_tests).' test_bids:'.json_encode($test_bids).' recommend_bids:'.json_encode($recommend_bids).' read_bids:'.json_encode($read_bids).' left_bids:'.json_encode($left_bids));
  528. $left_bid_num = count($left_bids);
  529. // 如果不够则清空推荐记录,重新追加剩下的
  530. $last_bids = $need_bids = array();
  531. if ($left_bid_num < $num) {
  532. self::truncateUserRecommendRecords($uid);
  533. $need_bids = self::getLeftRecommendBids($uid, $channel_name, $num - $left_bid_num, $loop + 1);
  534. // \Log::info('full_bids2:'.json_encode($full_bids));
  535. // \Log::info('merge_left_bids:'.json_encode($left_bids).' need_bids:'.json_encode($need_bids));
  536. $last_bids = array_merge($left_bids, $need_bids);
  537. } else {
  538. $last_bids = array_slice($left_bids, 0, $num, false);
  539. }
  540. // \Log::info('uid:'.$uid.' last_bids:'.json_encode($last_bids));
  541. // 加入已经推荐
  542. self::addUserRecommendRecords($uid, $last_bids);
  543. // 书籍推送量+1
  544. if ($loop == 1) {
  545. self::incrBidPushNum($last_bids);
  546. }
  547. return $last_bids;
  548. }
  549. /*
  550. * 获取相同频道的4本高推荐图书(循环获取)
  551. * 1、新书倒序 2、用户推荐过的,有阅读记录的不再推荐
  552. */
  553. public static function getSimpleChannelBookLoop($bid, $num = 4, $uid = '')
  554. {
  555. // \Log::info('getSimpleChannelBookLoop:bid:'.$bid.' num:'.$num.' uid:'.$uid);
  556. if (empty($uid)) {
  557. return self::getSimpleChannelBook($bid, $num);
  558. }
  559. $book_info = self::getBookById($bid);
  560. $channel_name = isset($book_info->channel_name) ? $book_info->channel_name : '女频';
  561. // 获取全集,减去阅读记录和推荐过的书籍id
  562. $bids = self::getLeftRecommendBids($uid, $channel_name, $num, 1);
  563. $res = self::join('books', 'book_configs.bid', '=', 'books.id')
  564. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  565. ->select('book_configs.bid', 'book_configs.force_subscribe_chapter_seq', 'book_configs.vip_seq', 'book_configs.price', 'books.updated_at as last_update_time',
  566. 'book_configs.cover', 'book_configs.book_name', 'book_configs.copyright', 'book_configs.charge_type', 'book_configs.is_on_shelf',
  567. 'books.author', 'books.intro', 'book_categories.category_name', 'category_id', 'status', 'chapter_count', 'first_cid', 'last_cid', 'size', 'last_chapter',
  568. 'books.keyword', 'book_configs.recommend_index', 'book_configs.is_show_index_content', 'book_configs.click_count', 'book_configs.product_id'
  569. , 'book_categories.channel_name', 'books.last_cid', 'books.last_chapter', 'book_configs.product_id', 'books.name as old_name'
  570. , 'book_configs.recommend_cid', 'book_configs.is_high_quality'
  571. )
  572. ->whereIn('book_configs.bid', $bids)
  573. ->orderBy('book_configs.id', 'desc')
  574. ->get();
  575. foreach ($res as $v) {
  576. $v->url = '/reader?bid=' . Hashids::encode($v->bid) . '&cid=' . $v->first_cid;
  577. }
  578. return $res;
  579. }
  580. public static function getHotRandomRecommendBooks($uid, $num=2){
  581. $sex = ForceSubscribeService::getSimpleSexByUid($uid);
  582. $channel_name = $sex==1?'男频':'女频';
  583. \Log::info('getHotRandomRecommendBooks,uid:'.$uid.' num:'.$num.' channel_name:'.$channel_name);
  584. $bids = [];
  585. $bids = self::getRandomRecommendBooks($channel_name, $num);
  586. return $bids;
  587. }
  588. public static function getHotRandomRecommendBookText($distribution_channel_id,$uid, $num){
  589. $bids = self::getHotRandomRecommendBooks($uid, $num);
  590. $recomm_books = BookConfigService::getBooksByIds($bids,['bid','asc']);
  591. $content = '';
  592. if ($recomm_books) {
  593. $content .= "\n\n" . '热门书籍推荐';
  594. foreach ($recomm_books as $book) {
  595. $url = env('PROTOCOL') . '://site' . encodeDistributionChannelId($distribution_channel_id) . '.' . env('CUSTOM_HOST') . '.com/reader?bid=' . Hashids::encode($book->bid) . '&cid=' . $book->first_cid;
  596. $content .= "\n\n" . '<a href="' . $url . '"> ☞ 《' . $book->book_name . '》</a>';
  597. }
  598. }
  599. return $content;
  600. }
  601. /**
  602. * 获取h5推荐的图书
  603. */
  604. public static function getH5RecommendBooks($uid, $pos, $num=4){
  605. // 先从缓存取,1天有效期
  606. $h5_book_cache = Redis::get('userH5RecommendBids:' . $uid.':'.$pos);
  607. if(!empty($h5_book_cache)){
  608. \Log::info('h5_book_cache_exist:'.$uid);
  609. return json_decode($h5_book_cache);
  610. }
  611. // 判断渠道男女频
  612. $user = User::getById($uid);
  613. $distribution_channel_id = isset($user->distribution_channel_id)?$user->distribution_channel_id:'';
  614. // 男频强制推广男频书
  615. $channel_sex = ChannelService::getChannelCompanySex($distribution_channel_id);
  616. $channel_name = '';
  617. if($channel_sex == 1){
  618. $channel_name = '男频';
  619. }else{
  620. $sex = ForceSubscribeService::getSimpleSexByUid($uid);
  621. $channel_name = $sex==1?'男频':'女频';
  622. }
  623. \Log::info('getH5RecommendBooks:pos:'.$pos.' uid:'.$uid.' num:'.$num.' channel_name:'.$channel_name.' channel_sex:'.$channel_sex.' distribution_channel_id:'.$distribution_channel_id);
  624. $bids = [];
  625. $random_recommend = true;
  626. if($random_recommend){
  627. $bids = self::getRandomRecommendBooks($channel_name, $num);
  628. }
  629. $forceSubscribeUser = ForceSubscribeService::forceSubscribeUsersByUid(['uid'=>$uid]);
  630. $distribution_channel_id = isset($forceSubscribeUser->distribution_channel_id)?$forceSubscribeUser->distribution_channel_id:'';
  631. if (in_array($distribution_channel_id, [4042, 4043, 4044]) && $sex==2) {
  632. $bids = [2323, 1347, 2168, 1550, 1295, 1574];
  633. }
  634. \Log::info('getH5RecommendBooks:uid:'.$uid.' distribution_channel_id:'.$distribution_channel_id.' bids:'.json_encode($bids));
  635. if(!empty($bids)){
  636. $books = BookConfigService::getBooksByIds($bids,['bid','asc']);
  637. $data = $books->toArray();
  638. // 有效期24小时
  639. $redis_key = 'userH5RecommendBids:' . $uid.':'.$pos;
  640. Redis::set($redis_key,json_encode(object_to_array($data)));
  641. Redis::expire($redis_key,3600*24);
  642. }
  643. return $books;
  644. }
  645. /**
  646. * 获取随机的推荐书籍bid
  647. */
  648. public static function getRandomRecommendBooks($channel_name, $num){
  649. if($channel_name == '男频'){
  650. $channel_name_replace = 'male';
  651. }else{
  652. $channel_name_replace = 'female';
  653. }
  654. $redis_key = sprintf('channel_name:%s:num:%s',$channel_name_replace,$num);
  655. $cache = Redis::get($redis_key);
  656. if($cache) return explode(',',$cache);
  657. $bids = self::join('books', 'book_configs.bid', '=', 'books.id')
  658. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  659. ->select('book_configs.bid')
  660. ->where('book_categories.channel_name', $channel_name)
  661. ->where('book_configs.is_high_quality', 1)
  662. ->where('book_configs.test_status', 0)// 不含测书
  663. ->whereIn('book_configs.is_on_shelf', [2])
  664. ->inRandomOrder()
  665. ->limit($num)
  666. ->get()->pluck('bid')->all();
  667. if($bids){
  668. Redis::setex($redis_key,7200,implode(',',$bids));
  669. }
  670. return $bids;
  671. }
  672. /*
  673. * 获取相同频道的4本高推荐图书
  674. */
  675. public static function getSimpleChannelBook($bid, $num = 4)
  676. {
  677. $book_info = self::getBookById($bid);
  678. if (!$book_info) return false;
  679. $channel_name = $book_info->channel_name;
  680. $res = self::join('books', 'book_configs.bid', '=', 'books.id')
  681. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  682. ->select('book_configs.bid', 'book_configs.force_subscribe_chapter_seq', 'book_configs.vip_seq', 'book_configs.price', 'books.updated_at as last_update_time',
  683. 'book_configs.cover', 'book_configs.book_name', 'book_configs.copyright', 'book_configs.charge_type', 'book_configs.is_on_shelf',
  684. 'books.author', 'books.intro', 'book_categories.category_name', 'category_id', 'status', 'chapter_count', 'first_cid', 'last_cid', 'size', 'last_chapter',
  685. 'books.keyword', 'book_configs.recommend_index', 'book_configs.is_show_index_content', 'book_configs.click_count', 'book_configs.product_id'
  686. , 'book_categories.channel_name', 'books.last_cid', 'books.last_chapter', 'book_configs.product_id', 'books.name as old_name'
  687. , 'book_configs.recommend_cid', 'book_configs.is_high_quality'
  688. )
  689. ->where('book_categories.channel_name', $channel_name)
  690. ->where('book_configs.is_high_quality', 1)
  691. ->whereIn('book_configs.is_on_shelf', [1, 2])
  692. ->orderBy('recommend_index', 'desc')
  693. ->get()
  694. ->random($num);
  695. foreach ($res as $v) {
  696. $v->url = '/reader?bid=' . Hashids::encode($v->bid) . '&cid=' . $v->first_cid;
  697. }
  698. return $res;
  699. }
  700. /*
  701. * 获取托管智能推送的书籍,头条要95分以上,其余4条优质书库随机,按分数倒叙排列
  702. * 新版1条
  703. */
  704. public static function getTrusteeShipChannelBook($distribution_channel_id, $channel_name, $num = 4)
  705. {
  706. // 找头条
  707. $first_res = self::join('books', 'book_configs.bid', '=', 'books.id')
  708. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  709. ->select('book_configs.bid', 'book_configs.recommend_index')
  710. ->where('book_categories.channel_name', $channel_name)
  711. ->where('book_configs.is_high_quality', 1)
  712. // ->where('book_configs.recommend_index', '>=',95)
  713. ->whereIn('book_configs.is_on_shelf', [2])
  714. ->orderBy('recommend_index', 'desc')
  715. ->limit(50)
  716. ->get()
  717. ->random(1);
  718. \Log::info('$first_res');
  719. \Log::info($first_res);
  720. $bids = [];
  721. $bids[] = $first_res[0]->bid;
  722. \Log::info('getTrusteeShipChannelBook_bids:' . json_encode($bids));
  723. $res = self::join('books', 'book_configs.bid', '=', 'books.id')
  724. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  725. ->select('book_configs.bid', 'book_configs.force_subscribe_chapter_seq', 'book_configs.vip_seq', 'book_configs.price', 'books.updated_at as last_update_time',
  726. 'book_configs.cover', 'book_configs.book_name', 'book_configs.copyright', 'book_configs.charge_type', 'book_configs.is_on_shelf',
  727. 'books.author', 'books.intro', 'book_categories.category_name', 'category_id', 'status', 'chapter_count', 'first_cid', 'last_cid', 'size', 'last_chapter',
  728. 'books.keyword', 'book_configs.recommend_index', 'book_configs.is_show_index_content', 'book_configs.click_count', 'book_configs.product_id'
  729. , 'book_categories.channel_name', 'books.last_cid', 'books.last_chapter', 'book_configs.product_id', 'books.name as old_name'
  730. , 'book_configs.recommend_cid', 'book_configs.is_high_quality'
  731. )
  732. ->where('book_categories.channel_name', $channel_name)
  733. ->where('book_configs.is_high_quality', 1)
  734. ->whereIn('book_configs.bid', $bids)
  735. ->orderBy('recommend_index', 'desc')
  736. ->get();
  737. foreach ($res as $v) {
  738. $v->url = '/reader?bid=' . Hashids::encode($v->bid) . '&cid=' . $v->first_cid;
  739. }
  740. \Log::info('last_res');
  741. \Log::info($res);
  742. return $res;
  743. }
  744. /*
  745. * 获取托管智能推送的书籍,头条要95分以上,其余4条优质书库随机,按分数倒叙排列
  746. * 老版多条
  747. */
  748. public static function getTrusteeShipChannelBookMulty($distribution_channel_id, $channel_name, $num = 4)
  749. {
  750. // TODO 内部渠道的书=内部+外部,外部渠道的书=外部
  751. // 内部上架判断有点复杂,先统一外部上架
  752. // 找头条
  753. $first_res = self::join('books', 'book_configs.bid', '=', 'books.id')
  754. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  755. ->select('book_configs.bid', 'book_configs.recommend_index')
  756. ->where('book_categories.channel_name', $channel_name)
  757. ->where('book_configs.is_high_quality', 1)
  758. // ->where('book_configs.recommend_index', '>=',95)
  759. ->whereIn('book_configs.is_on_shelf', [2])
  760. ->orderBy('recommend_index', 'desc')
  761. ->limit(10)
  762. ->get()
  763. ->random(1);
  764. \Log::info('$first_res');
  765. \Log::info($first_res);
  766. $bids = [];
  767. $bids[] = $first_res[0]->bid;
  768. // 找其余3条
  769. $left_res = self::join('books', 'book_configs.bid', '=', 'books.id')
  770. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  771. ->select('book_configs.bid')
  772. ->where('book_categories.channel_name', $channel_name)
  773. ->where('book_configs.is_high_quality', 1)
  774. ->whereNotIn('book_configs.bid', $bids)
  775. ->whereIn('book_configs.is_on_shelf', [2])
  776. ->orderBy('recommend_index', 'desc')
  777. ->get()
  778. ->random(3);
  779. \Log::info('left_res');
  780. \Log::info($left_res);
  781. foreach ($left_res as $left_r) {
  782. $bids[] = $left_r->bid;
  783. }
  784. \Log::info('getTrusteeShipChannelBook_bids:' . json_encode($bids));
  785. $res = self::join('books', 'book_configs.bid', '=', 'books.id')
  786. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  787. ->select('book_configs.bid', 'book_configs.force_subscribe_chapter_seq', 'book_configs.vip_seq', 'book_configs.price', 'books.updated_at as last_update_time',
  788. 'book_configs.cover', 'book_configs.book_name', 'book_configs.copyright', 'book_configs.charge_type', 'book_configs.is_on_shelf',
  789. 'books.author', 'books.intro', 'book_categories.category_name', 'category_id', 'status', 'chapter_count', 'first_cid', 'last_cid', 'size', 'last_chapter',
  790. 'books.keyword', 'book_configs.recommend_index', 'book_configs.is_show_index_content', 'book_configs.click_count', 'book_configs.product_id'
  791. , 'book_categories.channel_name', 'books.last_cid', 'books.last_chapter', 'book_configs.product_id', 'books.name as old_name'
  792. , 'book_configs.recommend_cid', 'book_configs.is_high_quality'
  793. )
  794. ->where('book_categories.channel_name', $channel_name)
  795. ->where('book_configs.is_high_quality', 1)
  796. ->whereIn('book_configs.bid', $bids)
  797. ->orderBy('recommend_index', 'desc')
  798. ->get();
  799. foreach ($res as $v) {
  800. $v->url = '/reader?bid=' . Hashids::encode($v->bid) . '&cid=' . $v->first_cid;
  801. }
  802. \Log::info('last_res');
  803. \Log::info($res);
  804. return $res;
  805. }
  806. /*
  807. * H5专用,用户阅读完推荐
  808. * 获取相同推荐
  809. */
  810. public static function getRecommendBooks($bid, $channel_name, $num = 4)
  811. {
  812. $res = self::join('books', 'book_configs.bid', '=', 'books.id')
  813. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  814. ->select('book_configs.bid', 'book_configs.force_subscribe_chapter_seq', 'book_configs.vip_seq', 'book_configs.price',
  815. 'book_configs.cover', 'book_configs.book_name', 'book_configs.copyright', 'book_configs.charge_type', 'book_configs.is_on_shelf',
  816. 'books.author', 'books.intro', 'book_categories.category_name', 'category_id', 'status', 'chapter_count', 'first_cid', 'last_cid', 'size', 'last_chapter',
  817. 'books.keyword', 'book_configs.recommend_index', 'book_configs.is_show_index_content', 'book_configs.click_count', 'book_configs.product_id'
  818. , 'book_categories.channel_name', 'books.last_cid', 'books.last_chapter', 'book_configs.product_id', 'books.name as old_name'
  819. , 'book_configs.recommend_cid', 'book_configs.is_high_quality', 'books.updated_at as last_update_time'
  820. )
  821. ->where('book_categories.channel_name', $channel_name)
  822. ->where('book_configs.bid', '!=', $bid)
  823. ->where('book_configs.is_high_quality', 1)
  824. ->orderBy('recommend_index', 'desc')->get();
  825. $count = $res->count() >= $num ? $num : $res->count();
  826. return $res->random($count);
  827. }
  828. /*
  829. * 签到专用
  830. * 获取相同推荐
  831. */
  832. public static function getSignRecommendBooks(array $bid, $channel_name, $num = 2)
  833. {
  834. $res = self::join('books', 'book_configs.bid', '=', 'books.id')
  835. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  836. ->select('book_configs.bid', 'book_configs.force_subscribe_chapter_seq', 'book_configs.vip_seq', 'book_configs.price',
  837. 'book_configs.cover', 'book_configs.book_name', 'book_configs.copyright', 'book_configs.charge_type', 'book_configs.is_on_shelf',
  838. 'books.author', 'books.intro', 'book_categories.category_name', 'category_id', 'status', 'chapter_count', 'first_cid', 'last_cid', 'size', 'last_chapter',
  839. 'books.keyword', 'book_configs.recommend_index', 'book_configs.is_show_index_content', 'book_configs.click_count', 'book_configs.product_id'
  840. , 'book_categories.channel_name', 'books.last_cid', 'books.last_chapter', 'book_configs.product_id', 'books.name as old_name'
  841. , 'book_configs.recommend_cid', 'book_configs.is_high_quality', 'books.updated_at as last_update_time'
  842. )
  843. ->where('book_categories.channel_name', $channel_name)
  844. ->where('book_configs.is_on_shelf', 2)
  845. ->whereNotIn('book_configs.bid', $bid)
  846. ->where('book_configs.is_high_quality', 1)
  847. ->get();
  848. $count = $res->count() >= $num ? $num : $res->count();
  849. return $res->random($count);
  850. }
  851. /*
  852. * 获取指定bid的书籍推荐
  853. */
  854. public static function getBidRecommendBooks(array $bids)
  855. {
  856. $res = self::join('books', 'book_configs.bid', '=', 'books.id')
  857. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  858. ->select('book_configs.bid', 'book_configs.force_subscribe_chapter_seq', 'book_configs.vip_seq', 'book_configs.price',
  859. 'book_configs.cover', 'book_configs.book_name', 'book_configs.copyright', 'book_configs.charge_type', 'book_configs.is_on_shelf',
  860. 'books.author', 'books.intro', 'book_categories.category_name', 'category_id', 'status', 'chapter_count', 'first_cid', 'last_cid', 'size', 'last_chapter',
  861. 'books.keyword', 'book_configs.recommend_index', 'book_configs.is_show_index_content', 'book_configs.click_count', 'book_configs.product_id'
  862. , 'book_categories.channel_name', 'books.last_cid', 'books.last_chapter', 'book_configs.product_id', 'books.name as old_name'
  863. , 'book_configs.recommend_cid', 'book_configs.is_high_quality', 'books.updated_at as last_update_time'
  864. )
  865. ->whereIn('book_configs.bid', $bids)
  866. ->get();
  867. return $res;
  868. }
  869. /**
  870. * 修改vip章节
  871. */
  872. public static function updateVipSeq($bid, $seq)
  873. {
  874. return self::where('bid', $bid)->update(['vip_seq' => $seq]);
  875. }
  876. public static function getAllBooks($on_shelf, $order)
  877. {
  878. if (!$order) {
  879. $order = ['id', 'asc'];
  880. }
  881. return self::whereIn('is_on_shelf', $on_shelf)->select('bid', 'book_name')->orderBy($order[0], $order[1])->get();
  882. }
  883. /**
  884. * 根据条件获取书籍,没有分页
  885. */
  886. public static function getBooksNoPage(array $where = [], array $order = [], array $on_shelf, $limit = 20)
  887. {
  888. if (!$order) {
  889. $order = [['recommend_index', 'desc']];
  890. }
  891. $res = self::join('books', 'book_configs.bid', '=', 'books.id')
  892. ->leftjoin('book_categories', 'books.category_id', 'book_categories.id')
  893. ->select('book_configs.bid', 'book_configs.force_subscribe_chapter_seq', 'book_configs.cp_source', 'book_configs.vip_seq', 'book_configs.price', 'book_configs.cover', 'book_configs.book_name',
  894. 'book_configs.copyright', 'book_configs.charge_type', 'book_configs.is_on_shelf', 'books.author', 'books.intro', 'book_categories.category_name',
  895. 'category_id', 'status', 'chapter_count', 'book_configs.click_count', 'first_cid', 'last_cid', 'size', 'last_chapter', 'books.keyword',
  896. 'book_configs.recommend_index', 'book_configs.is_show_index_content', 'book_configs.product_id', 'book_categories.channel_name',
  897. 'books.last_cid', 'books.last_chapter', 'book_configs.product_id', 'book_configs.copyright_limit_data', 'books.updated_at as last_update_time',
  898. 'book_configs.promotion_domain', 'books.name as old_name', 'book_configs.recommend_cid', 'book_configs.is_high_quality'
  899. );
  900. if ($where) {
  901. foreach ($where as $v) {
  902. $res->where($v[0], $v[1], $v[2]);
  903. }
  904. }
  905. $res->whereIn('is_on_shelf', $on_shelf);
  906. foreach ($order as $v) {
  907. $res->orderBy($v[0], $v[1]);
  908. }
  909. return $res->limit($limit)->get();
  910. }
  911. public static function getAllCps()
  912. {
  913. $cps = self::select('cp_source')->groupBy('cp_source')->get();
  914. $result = array();
  915. foreach ($cps as $cp) {
  916. if (!empty($cp['cp_source'])) {
  917. $result[] = $cp['cp_source'];
  918. }
  919. }
  920. return $result;
  921. }
  922. public static function getAllCpBooks()
  923. {
  924. $result = array();
  925. $cp_books = self::select('cp_source', 'bid')->groupBy('cp_source')->groupBy('bid')->get();
  926. foreach ($cp_books as $cp_book) {
  927. $result[$cp_book['cp_source']][] = $cp_book['bid'];
  928. }
  929. return $result;
  930. }
  931. /*
  932. * 得到cp某段时间某本书的消费
  933. */
  934. public static function getAllCpBookConsume($start_date, $end_date, $cps)
  935. {
  936. $result = self::leftjoin('book_order_statistical', 'book_order_statistical.bid', '=', 'book_configs.bid')
  937. ->select('book_order_statistical.bid',
  938. DB::raw('sum(book_order_statistical.charge_balance) as charge_balance'),
  939. 'book_configs.book_name', 'book_configs.is_on_shelf', 'book_configs.cp_source'
  940. )
  941. ->whereIn('book_configs.cp_source', $cps)
  942. ->where('book_order_statistical.day', '>=', $start_date)
  943. ->where('book_order_statistical.day', '<=', $end_date)
  944. ->groupBy('book_configs.cp_source')
  945. ->groupBy('book_order_statistical.bid')
  946. ->get();
  947. return $result;
  948. }
  949. public static function getBookByIdAndStatus($bid, $status)
  950. {
  951. return self::where('bid', $bid)->whereIn('is_on_shelf', $status)->first();
  952. }
  953. public static function get_all_test_books($is_all=false)
  954. {
  955. if($is_all){
  956. return self::where('test_status', '<>', 0)->orderBy('test_status', 'asc')->orderBy('test_update_time', 'desc')->get();
  957. }else{
  958. return self::where('test_status', '<>', 0)->orderBy('test_status', 'asc')->orderBy('test_update_time', 'desc')->paginate();
  959. }
  960. }
  961. public static function get_test_books($test_status)
  962. {
  963. return self::where('test_status', $test_status)->get();
  964. }
  965. public static function updateTestBook($bid, $test_status, $plan_push_user_num = 10000)
  966. {
  967. return self::where('bid', $bid)->update(['test_status' => $test_status, 'plan_push_user_num' => $plan_push_user_num, 'test_update_time' => date('Y-m-d H:i:s')]);
  968. }
  969. public static function get_all_smart_push_books($is_all = false)
  970. {
  971. if($is_all){
  972. return self::where('is_on_shelf', 2)->where('is_high_quality', 1)->orderBy('id', 'desc')->get();
  973. }else{
  974. return self::where('is_on_shelf', 2)->where('is_high_quality', 1)->orderBy('id', 'desc')->paginate();
  975. }
  976. }
  977. /**
  978. * 获取书本的id,名称,作者,封面 并带分页
  979. * @param bool $isAll 是否查询所有
  980. * @param int $pageSize 每页的条数
  981. * @param int $pageCount 页数
  982. * @return mixed
  983. */
  984. static function getBookCoverInfos($isAll = false, $pageSize = 200, $pageCount = 0)
  985. {
  986. $obj = self::join('books', 'book_configs.bid', '=', 'books.id')->select('book_configs.bid', 'book_configs.book_name', 'books.author', 'book_configs.cover');
  987. if ($isAll) {
  988. return $obj->get();
  989. } else {
  990. return $obj->limit($pageSize)->offset($pageCount * $pageSize)->get();
  991. }
  992. }
  993. /**
  994. * 获取书本的总数
  995. * @return mixed
  996. */
  997. static function getBooksCount()
  998. {
  999. return self::count();
  1000. }
  1001. /**
  1002. * 通过书名模糊搜索bid
  1003. * @param $book_name
  1004. * @return mixed
  1005. */
  1006. static function getIdByName($book_name)
  1007. {
  1008. return self::select('bid')->where('book_name', 'like', '%' . $book_name . '%')->get();
  1009. }
  1010. }