BookConfig.php 53 KB

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