BooksController.php 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907
  1. <?php
  2. namespace App\Http\Controllers\Channel\Book;
  3. use App\Http\Controllers\Channel\BaseController;
  4. use App\Http\Controllers\Channel\Book\Transformers\BookTransformer;
  5. use App\Http\Controllers\Channel\Book\Transformers\BookV2Transformer;
  6. use App\Http\Controllers\Channel\Book\Transformers\ChapterListTransformer;
  7. use App\Modules\Book\Services\BookCategoryService;
  8. use App\Modules\Book\Services\BookConfigService;
  9. use App\Modules\Book\Services\BookSpecialChannelService;
  10. use App\Modules\Book\Services\BookSubscribleChapterService;
  11. use App\Modules\Book\Services\ChapterService;
  12. use App\Modules\Book\Services\SuperiorHistoryBookService;
  13. use App\Modules\Book\Services\SuperiorNewBookService;
  14. use App\Modules\Channel\Services\ChannelService;
  15. use App\Modules\SendOrder\Services\SendOrderService;
  16. use App\Modules\Channel\Services\CompanySpecialBookService;
  17. use App\Modules\Channel\Services\ChannelUserService;
  18. use App\Modules\Channel\Services\CompanyService;
  19. use App\Modules\Book\Models\BookOrderStatistical;
  20. use Hashids;
  21. use Illuminate\Http\Request;
  22. use Log;
  23. use Storage;
  24. use Illuminate\Support\Facades\Cache;
  25. use Redis;
  26. use DB;
  27. class BooksController extends BaseController
  28. {
  29. /**
  30. * @apiDefine Book 图书模块
  31. */
  32. /**
  33. * @apiVersion 1.0.0
  34. * @apiDescription 按bid获取图书详情
  35. * @api {get} book/getBookInfo 获取图书详情
  36. * @apiGroup Book
  37. * @apiParam {Number} bid 图书id
  38. * @apiName getBookInfo
  39. * @apiSuccess {int} code 状态码
  40. * @apiSuccess {String} msg 信息
  41. * @apiSuccess {object} data 结果集
  42. * @apiSuccess {Int} data.book_id bid
  43. * @apiSuccess {String} data.book_name 书名
  44. * @apiSuccess {String} data.book_summary 简介
  45. * @apiSuccess {String} data.book_author 作者
  46. * @apiSuccess {String} data.cover_url 封面
  47. * @apiSuccess {Int} data.book_word_count 字数
  48. * @apiSuccess {Int} data.book_chapter_total 章节数
  49. * @apiSuccess {Int} data.book_category_id 分类
  50. * @apiSuccess {String} data.book_category 分类名
  51. * @apiSuccess {Int} data.book_end_status 是否完结
  52. * @apiSuccess {String} data.book_published_time 发布时间
  53. * @apiSuccess {String} data.copyright 版权信息
  54. * @apiSuccess {Int} data.force_subscribe_chapter_seq 强制关注的章节序号
  55. * @apiSuccess {String} data.update_time 更新时间
  56. * @apiSuccess {Int} data.is_on_shelf 是否上架
  57. * @apiSuccess {Int} data.book_price 是否上架
  58. * @apiSuccess {String} data.charge_type 收费类型
  59. * @apiSuccess {String} data.keyword 关键词
  60. * @apiSuccess {String} data.recommend_index 推荐指数
  61. * @apiSuccess {String} data.is_show_index_content 是否显示推荐指数文本
  62. * @apiSuccess {Int} data.click_count 点击数
  63. * @apiSuccessExample {json} Success-Response:
  64. * {
  65. * "code": 0,
  66. * "msg": "",
  67. * "data": {
  68. * "book_id": 5,
  69. * "book_name": "肌缘巧合",
  70. * "book_summary": "&nbsp;&nbsp;&nbsp;&nbsp;他是权势倾天,纵横商界的王者,却偏偏钟情于她,一宠成瘾。“女人,我要你......只要你能满足我,别墅、游轮、支票,你随便挑。”她羞涩的半低着头:“我只想要你。”他挑眉,“你野心不小啊!”她妩媚一笑,解开他的领带,“难道你不愿意!”他宠她爱她,给她所有想要的。只是有一天她终于忍不住暴走,“靠,你有没有节制呀?我要离婚。”",
  71. * "book_author": "妖火",
  72. * "cover_url": "http://www.leyuee.com/cover/0/8.jpg",
  73. * "book_word_count": 0,
  74. * "book_chapter_total": 0,
  75. * "book_category_id": null,
  76. * "book_category": "爆笑,宠文,潜规则",
  77. * "book_end_status": 8,
  78. * "book_published_time": null,
  79. * "copyright": null,
  80. * "charge_type": null,
  81. * "force_subscribe_chapter_seq": 0,
  82. * "update_time": null,
  83. * "is_on_shelf": 0,
  84. * "book_price": null,
  85. * "keyword": "关键词",
  86. * "recommend_index":2,
  87. * "is_show_index_content":0,
  88. * "click_count":0
  89. * }
  90. * }
  91. */
  92. function getBookInfo(Request $request)
  93. {
  94. $bid = $request->has('bid') ? $request->input('bid') : '';
  95. if (empty($bid)) return response()->error("PARAM_EMPTY");
  96. $bid = Hashids::decode($bid)[0];
  97. $hidden_book = env('HIDE_BOOKS');
  98. if ($hidden_book) {
  99. $hidden_book_array = explode(',', $hidden_book);
  100. if (in_array($bid, $hidden_book_array)) {
  101. //return response()->error("PARAM_ERROR");
  102. }
  103. }
  104. $data = BookConfigService::getBookById($bid);
  105. $subscribe_chapter_seq = BookSubscribleChapterService::getSubcribleChapter($bid, $this->getChannelId());
  106. if ($subscribe_chapter_seq && $subscribe_chapter_seq->subscribe_chapter_id > 0) {
  107. $data->force_subscribe_chapter_seq = $subscribe_chapter_seq->subscribe_chapter_id;
  108. }
  109. $chapter = ChapterService::getChapterInfoByBidAndSeq($bid, $data->force_subscribe_chapter_seq);
  110. if ($chapter) {
  111. $data->force_subscribe_cid = $chapter->id;
  112. $data->force_subscribe_chapter_name = $chapter->name;
  113. }
  114. return response()->item(new BookTransformer(), $data);
  115. }
  116. /**
  117. * @apiVersion 1.0.0
  118. * @apiDescription 获取图书目录
  119. * @api {get} book/getBookDirectory 获取图书目录
  120. * @apiGroup Book
  121. * @apiName getBookDirectory
  122. * @apiParam {Int} bid 书本id
  123. * @apiParam {Int} page 页数
  124. * @apiParam {Int} pageSize 分页大小(默认15)
  125. * @apiSuccess {int} code 状态码
  126. * @apiSuccess {String} msg 信息
  127. * @apiSuccess {object} data 结果集
  128. * @apiSuccess {Array} data.list 分页结果集
  129. * @apiSuccess {Int} data.list.bid bid
  130. * @apiSuccess {Int} data.list.chapter_id 章节id
  131. * @apiSuccess {String} data.list.chapter_name 章节名称
  132. * @apiSuccess {Int} data.list.chapter_sequence 序号
  133. * @apiSuccess {Int} data.list.chapter_is_vip 是否vip
  134. * @apiSuccess {Int} data.list.chapter_size 章节大小
  135. * @apiSuccess {Int} data.list.prev_cid 上一章节id
  136. * @apiSuccess {Int} data.list.next_cid 下一章节
  137. * @apiSuccess {Int} data.list.dafault_subscribe 是否默认强关章节
  138. * @apiSuccess {Int} data.list.channel_subscribe 是否用户自定义强关章节
  139. * @apiSuccess {String} data.list.recent_update_at 更新时间
  140. * @apiSuccess {Int} data.list.is_recommend 是否是推荐章节
  141. * @apiSuccess {String} data.list.recommend_text 推荐内容
  142. * @apiSuccess {String} data.list.is_need_subscirbe 是否强制关注
  143. * @apiSuccess {object} data.meta 分页信息
  144. * @apiSuccess {Int} data.meta.total 总条数
  145. * @apiSuccess {Int} data.meta.per_page 每页条数
  146. * @apiSuccess {Int} data.meta.current_page 当前页
  147. * @apiSuccess {Int} data.meta.last_page 最后页
  148. * @apiSuccess {String} data.meta.next_page_url 下一页
  149. * @apiSuccess {String} data.meta.prev_page_url 上一页
  150. * @apiSuccessExample {json} Success-Response:
  151. * {
  152. * "code": 0,
  153. * "msg": "",
  154. * "data":
  155. * "pagination":[
  156. * {
  157. * "bid": 5,
  158. * "chapter_id": 5,
  159. * "chapter_name": "第1240章 不是我",
  160. * "chapter_sequence": 1239,
  161. * "chapter_is_vip": 1,
  162. * "chapter_size": 2422,
  163. * "prev_cid": 0,
  164. * "is_recommend": 1,
  165. * "recommend_text": "",
  166. * "next_cid": 0,
  167. * "recent_update_at": 2017-11-20 15:01:56,
  168. * "is_need_subscirbe": 1,
  169. * },
  170. * {
  171. * "bid": 5,
  172. * "chapter_id": 5,
  173. * "chapter_name": "第1240章 不是我",
  174. * "chapter_sequence": 1239,
  175. * "chapter_is_vip": 1,
  176. * "chapter_size": 2422,
  177. * "is_recommend": 1,
  178. * "recommend_text": "",
  179. * "prev_cid": 0,
  180. * "next_cid": 0,
  181. * "recent_update_at": 2017-11-20 15:01:56,
  182. * "is_need_subscirbe": 1,
  183. * },
  184. * ]
  185. * "meta":{
  186. * "total": 1253,
  187. * "per_page": 15,
  188. * "current_page": 1,
  189. * "last_page": 84,
  190. * "next_page_url": "http://myapi.cn/api/books/1/chapter?page=2",
  191. * "prev_page_url": ""
  192. * }
  193. * }
  194. */
  195. function getBookDirectory(Request $request)
  196. {
  197. $bid = $request->has('bid') ? $request->input('bid') : '';
  198. if (empty($bid)) return response()->error("PARAM_EMPTY");
  199. $bid = Hashids::decode($bid)[0];
  200. $pageSize = $request->has('pageSize') ? (int)$request->input('pageSize') : 15;
  201. $data = ChapterService::getChapterListsPage($bid, $pageSize);
  202. $book = BookConfigService::getBookById($bid);//force_subscribe_chapter_seq
  203. $subscribe_chapter_seq = BookSubscribleChapterService::getSubcribleChapter($bid, $this->getChannelId());
  204. $default_subscribe = $book->force_subscribe_chapter_seq;
  205. $channel_subscribe = 0;
  206. if ($subscribe_chapter_seq && $subscribe_chapter_seq->subscribe_chapter_id > 0) {
  207. $channel_subscribe = $subscribe_chapter_seq->subscribe_chapter_id;
  208. $book->force_subscribe_chapter_seq = $subscribe_chapter_seq->subscribe_chapter_id;
  209. }
  210. foreach ($data as &$item) {
  211. $item->dafault_subscribe = 0;
  212. $item->channel_subscribe = 0;
  213. if ($item->sequence == $default_subscribe) {
  214. $item->dafault_subscribe = 1;
  215. }
  216. if ($channel_subscribe && $item->sequence == $channel_subscribe) {
  217. $item->channel_subscribe = 1;
  218. }
  219. if ($item->sequence >= ($book->force_subscribe_chapter_seq)) {
  220. $item->is_need_subscirbe = 1;
  221. } else {
  222. $item->is_need_subscirbe = 0;
  223. }
  224. if ($item->id == $book->recommend_cid) {
  225. $item->is_recommend = 1;
  226. if (Storage::exists('RecommendChapterPositionWord.txt')) {
  227. $item->recommend_text = Storage::get('RecommendChapterPositionWord.txt');
  228. } else {
  229. $item->recommend_text = '建议此章节生成推广文案(原文转化率好)';
  230. }
  231. }
  232. }
  233. return response()->pagination(new ChapterListTransformer(), $data);
  234. }
  235. /**
  236. * @apiVersion 1.0.0
  237. * @apiDescription 获取分类
  238. * @api {get} book/getBookCategories 获取分类
  239. * @apiGroup Book
  240. * @apiName getBookCategories
  241. * @apiSuccess {int} code 状态码
  242. * @apiSuccess {String} msg 信息
  243. * @apiSuccess {object} data 结果集
  244. * @apiSuccessExample {json} Success-Response:
  245. * {
  246. * "code": 0,
  247. * "msg": "",
  248. * "data": [
  249. * {
  250. * "id": 1,
  251. * "name": "男频",
  252. * "children": [
  253. * {
  254. * "id": 7,
  255. * "name": "灵异鬼怪"
  256. * },
  257. * {
  258. * "id": 8,
  259. * "name": "历史穿越"
  260. * },
  261. * {
  262. * "id": 30,
  263. * "name": "青春爱情"
  264. * }
  265. * ]
  266. * },
  267. * {
  268. * "id": 2,
  269. * "name": "女频",
  270. * "children": [
  271. * {
  272. * "id": 26,
  273. * "name": "豪门总裁"
  274. * },
  275. * {
  276. * "id": 35,
  277. * "name": "民国爱情"
  278. * }
  279. * ]
  280. * }
  281. * ]
  282. * }
  283. */
  284. function getBookCategories(Request $request)
  285. {
  286. $res = BookCategoryService::getSecondCategories();
  287. $male = [];
  288. $female = [];
  289. foreach ($res as $v) {
  290. if ($v->channel_name == '男频') {
  291. $male[] = ['id' => $v->id, 'name' => $v->category_name];
  292. }
  293. if ($v->channel_name == '女频') {
  294. $female[] = ['id' => $v->id, 'name' => $v->category_name];
  295. }
  296. }
  297. $data = [
  298. ['id' => 1, 'name' => '男频', 'children' => $male],
  299. ['id' => 2, 'name' => '女频', 'children' => $female],
  300. ];
  301. //$data = BookCategoryService::getSecondCategories();
  302. return response()->success($data);
  303. }
  304. function getBookCategoriesV2(Request $request)
  305. {
  306. //$res = BookCategoryService::getSecondCategories();
  307. $female = [['id'=>13,'name'=>'豪门虐情'], ['id'=> 14,'name'=>'婚恋生活'] ,['id'=>18,'name'=>'穿越重生'], ['id'=>22,'name'=>'女生灵异']];
  308. $male = [
  309. ['id'=>4,'name'=>'都市艳遇'],
  310. ['id'=>5,'name'=>'兵王保镖'],
  311. ['id'=>8,'name'=>'风云职场'],
  312. ['id'=>12,'name'=>'悬疑灵异']
  313. ];
  314. $data = [
  315. ['id' => 1, 'name' => '男频', 'children' => $male],
  316. ['id' => 2, 'name' => '女频', 'children' => $female],
  317. ];
  318. //$data = BookCategoryService::getSecondCategories();
  319. return response()->success($data);
  320. }
  321. /**
  322. * @apiVersion 1.0.0
  323. * @apiDescription 根据分类id和关键词获取并按照推荐指数排序
  324. * @api {get} book/getPromotionBookList 获取图书列表
  325. * @apiParam {String} key
  326. * @apiParam {Int} category_id 分类id
  327. * @apiParam {String} order_field 排序字段(推荐指数:recommend_index|点击数:click_count)
  328. * @apiParam {String} order_seq 排序顺序(顺序:asc|逆序:desc)
  329. * @apiParam {Int} is_on_shelf 上架与否(0|1)
  330. * @apiParam {Int }pageSize 分页大小
  331. * @apiGroup Book
  332. * @apiName getPromotionBookList
  333. * @apiSuccess {int} code 状态码
  334. * @apiSuccess {String} msg 信息
  335. * @apiSuccess {object} data 结果集
  336. * @apiSuccess {Array} data.list 结果数据集
  337. * @apiSuccess {Int} data.list.book_id bid
  338. * @apiSuccess {String} data.list.book_name 书名
  339. * @apiSuccess {String} data.list.book_summary 简介
  340. * @apiSuccess {String} data.list.book_author 作者
  341. * @apiSuccess {String} data.list.cover_url 封面
  342. * @apiSuccess {Int} data.list.book_word_count 字数
  343. * @apiSuccess {Int} data.list.book_chapter_total 章节数
  344. * @apiSuccess {Int} data.list.book_category_id 分类
  345. * @apiSuccess {String} data.list.book_category 分类名
  346. * @apiSuccess {String} data.list.book_end_status 是否完结
  347. * @apiSuccess {String} data.list.promotion_count 推广次数
  348. * @apiSuccess {String} data.list.book_published_time 发布时间
  349. * @apiSuccess {String} data.list.copyright 版权信息
  350. * @apiSuccess {Int} data.list.force_subscribe_chapter_seq 强制关注的章节序号
  351. * @apiSuccess {String} data.list.update_time 更新时间
  352. * @apiSuccess {Int} data.list.is_on_shelf 是否上架
  353. * @apiSuccess {String} data.list.book_price 价格
  354. * @apiSuccess {String} data.list.recommend_index 推荐指数
  355. * @apiSuccess {Int} data.list.charge_type 收费类型(BOOK: 按本收费,CHAPTER: 按章收费)
  356. * @apiSuccess {Int} data.list.keyword 关键词
  357. * @apiSuccess {Int} data.list.is_show_index_content 是否显示推荐指数文本
  358. * @apiSuccess {Int} data.list.click_count 点击数
  359. * @apiSuccess {object} data.meta 分页信息
  360. * @apiSuccess {Int} data.meta.total 总条数
  361. * @apiSuccess {Int} data.meta.per_page 每页条数
  362. * @apiSuccess {Int} data.meta.current_page 当前页
  363. * @apiSuccess {Int} data.meta.sex_preference 性别偏好
  364. * @apiSuccess {Int} data.meta.last_page 最后页
  365. * @apiSuccess {String} data.meta.next_page_url 下一页
  366. * @apiSuccess {String} data.meta.prev_page_url 上一页
  367. * @apiSuccessExample {json} Success-Response:
  368. * {
  369. * "code": 0,
  370. * "msg": "",
  371. * "data": {
  372. * "list": [
  373. * {
  374. * "book_id": 5,
  375. * "book_name": "肌缘巧合",
  376. * "book_summary": "&nbsp;&nbsp;&nbsp;&nbsp;他是权势倾天,纵横商界的王者,却偏偏钟情于她,一宠成瘾。“女人,我要你......只要你能满足我,别墅、游轮、支票,你随便挑。”她羞涩的半低着头:“我只想要你。”他挑眉,“你野心不小啊!”她妩媚一笑,解开他的领带,“难道你不愿意!”他宠她爱她,给她所有想要的。只是有一天她终于忍不住暴走,“靠,你有没有节制呀?我要离婚。”",
  377. * "book_author": "妖火",
  378. * "cover_url": "http://www.leyuee.com/cover/0/8.jpg",
  379. * "book_word_count": 0,
  380. * "book_chapter_total": 0,
  381. * "book_category_id": null,
  382. * "book_category": "爆笑,宠文,潜规则",
  383. * "book_end_status": 8,
  384. * "promotion_count": 12,
  385. * "sex_preference":"女频",
  386. * "book_published_time": null,
  387. * "copyright": null,
  388. * "charge_type": null,
  389. * "force_subscribe_chapter_seq": 0,
  390. * "update_time": null,
  391. * "is_on_shelf": 1,
  392. * "book_price": null,
  393. * "keyword": "温馨,虐心,清水",
  394. * "recommend_index":2,
  395. * "is_show_index_content":0,
  396. * "click_count":0
  397. * },
  398. * ],
  399. * "meta": {
  400. * "total": 18,
  401. * "per_page": 15,
  402. * "current_page": 1,
  403. * "last_page": 2,
  404. * "next_page_url": "http://myapi.cn/api/hotrank/books?page=2",
  405. * "prev_page_url": ""
  406. * }
  407. * }
  408. * }
  409. */
  410. public function getPromotionBookList(Request $request)
  411. {
  412. $channel_id = $this->getChannelId();
  413. $channel_user = ChannelService::getUserIdById($channel_id);
  414. $channel_user_id = $channel_user->channel_user_id;
  415. $channel_user_info = ChannelUserService::getById($channel_user_id);
  416. // $is_important_channel = ChannelUserService::getImpotantById($channel_user_id)->is_important;
  417. // if (1 == $is_important_channel) {
  418. // $where['is_on_shelf'] = [2, 1];
  419. // } else {
  420. // $where['is_on_shelf'] = [2];
  421. // }
  422. $bids = [];
  423. if ($channel_user_info && !empty($channel_user_info->company_id)) {
  424. $bids = CompanySpecialBookService::getBidByCompany($channel_user_info->company_id);
  425. }
  426. $hidden_book = env('HIDE_BOOKS');
  427. if ($hidden_book) {
  428. $hidden_book_array = explode(',', $hidden_book);
  429. $where['hidden_books'] = $hidden_book_array;
  430. if ($bids) {
  431. $bids = array_diff($bids, $hidden_book_array);
  432. }
  433. }
  434. //$bids = BookSpecialChannelService::getBids($channel_user_id);
  435. $where['is_on_shelf'] = [2];
  436. $category_id = $request->input('category_id');
  437. if ($request->has('key') && trim($request->input('key'))) $where['key'] = trim($request->input('key'));
  438. if ($category_id) {
  439. if ($category_id == 1) {
  440. $where['channel_name'] = '男频';
  441. } elseif ($category_id == 2) {
  442. $where['channel_name'] = '女频';
  443. } else {
  444. $where['category_id'] = $category_id;
  445. }
  446. }
  447. $order_field = $request->input('order_field');
  448. $order_seq = $request->input('order_seq', 'desc');
  449. if ($order_field) {
  450. $order = ['book_configs.recommend_index', $order_seq];
  451. } else {
  452. $order = ['book_configs.id', $order_seq];
  453. }
  454. $data = BookConfigService::getPromotionBooks($where, $bids, $order);
  455. if (!empty($data)) {
  456. foreach ($data as $item) {
  457. $item->promotion_count = SendOrderService::getPromotionCountByBid($item->bid, $channel_id);
  458. }
  459. }
  460. return response()->pagination(new BookTransformer(), $data);
  461. }
  462. /**
  463. * @apiVersion 1.0.0
  464. * @apiDescription 小说推广
  465. * @api {get} book/getPromotionBookListV2 小说推广
  466. * @apiParam {String} [key] 关键词
  467. * @apiParam {Int} [category_id] 类型
  468. * @apiParam {String} [order_field] 排序字段 (全站指数,)
  469. * @apiParam {String} [order_type] 顺序(asc)or倒叙(desc) 默认倒叙
  470. * @apiParam {Int} [sex] 1:女频,2:男频
  471. * @apiParam {Int} [status] 0:连载,1:完结
  472. * @apiParam {String} [recommend_index] 编辑评分 (A,B,C...)
  473. * @apiParam {Int} [onshelf] 上架时间 (一周:7,一月:30,..:90)
  474. * @apiParam {Int} [size] 字数 (200万以上:1,100-200:2,3,4,5:长篇,6,短篇)
  475. * @apiParam {Int} [own_score] 自主评级 (A,B,)
  476. * @apiGroup Book
  477. * @apiName getPromotionBookListV2
  478. * @apiSuccess {int} code 状态码
  479. * @apiSuccess {String} msg 信息
  480. * @apiSuccess {object} data 结果集C
  481. * @apiSuccess {Array} data.list 结果数据集
  482. * @apiSuccess {Int} data.list.book_id bid
  483. * @apiSuccess {String} data.list.book_name 书名
  484. * @apiSuccess {String} data.list.cover_url 封面
  485. * @apiSuccess {String} data.list.book_category 类型
  486. * @apiSuccess {String} data.list.book_end_status 完结状态
  487. * @apiSuccess {String} data.list.recommend_index 编辑评级
  488. * @apiSuccess {String} data.list.sex_preference 性别
  489. * @apiSuccess {String} data.list.total_send_order_sum 全站派单指数
  490. * @apiSuccess {String} data.list.week_send_order_sum 7天派单指数
  491. * @apiSuccess {String} data.list.read_deep 深度阅读
  492. * @apiSuccess {String} data.list.channel_send_order_sum 我的派单
  493. * @apiSuccess {String} data.list.own_score 自主评级
  494. * @apiSuccess {String} data.list.word_size 字数
  495. * @apiSuccess {String} data.list.chapter_type 长篇or短片
  496. * @apiSuccess {String} data.list.on_shelf_time 上架时间
  497. * @apiSuccess {object} data.meta 分页信息
  498. * @apiSuccess {Int} data.meta.total 总条数
  499. * @apiSuccess {Int} data.meta.per_page 每页条数
  500. * @apiSuccess {Int} data.meta.current_page 当前页
  501. * @apiSuccess {Int} data.meta.sex_preference 性别偏好
  502. * @apiSuccess {Int} data.meta.last_page 最后页
  503. * @apiSuccess {String} data.meta.next_page_url 下一页
  504. * @apiSuccess {String} data.meta.prev_page_url 上一页
  505. * @apiSuccessExample {json} Success-Response:
  506. * {
  507. * "code": 0,
  508. * "msg": "",
  509. * "data": {
  510. * "list": [
  511. * {
  512. * "book_id": 5,
  513. * "book_name": "肌缘巧合",
  514. * },
  515. * ],
  516. * "meta": {
  517. * "total": 18,
  518. * "per_page": 15,
  519. * "current_page": 1,
  520. * "last_page": 2,
  521. * "next_page_url": "http://myapi.cn/api/hotrank/books?page=2",
  522. * "prev_page_url": ""
  523. * }
  524. * }
  525. * }
  526. */
  527. public function getPromotionBookListV2(Request $request)
  528. {
  529. $data = [];
  530. $where = [];
  531. $orwhere = [];
  532. $channel_id = $this->getChannelId();
  533. $data['distribution_channel_id'] = $channel_id;
  534. $channel_user = ChannelService::getUserIdById($channel_id);
  535. $channel_user_id = $channel_user->channel_user_id;
  536. $channel_user_info = ChannelUserService::getById($channel_user_id);
  537. //获取重点渠道的额外书单
  538. $bids = [];
  539. if ($channel_user_info && !empty($channel_user_info->company_id)) {
  540. $bids = CompanySpecialBookService::getBidByCompany($channel_user_info->company_id);
  541. }
  542. //隐藏的图书,搜不到,但不影响阅读
  543. $hidden_book = env('HIDE_BOOKS');
  544. $whereIn = [];
  545. if ($hidden_book) {
  546. $hidden_book_array = explode(',', $hidden_book);
  547. $whereIn = $hidden_book_array;
  548. if ($bids) {
  549. $bids = array_diff($bids, $hidden_book_array);
  550. }
  551. }
  552. //性别
  553. $sex = $request->get('sex', 0);
  554. if ($sex && in_array($sex, [1, 2])) {
  555. $sex_str = ['', '男频', '女频'];
  556. $where[] = ['book_categories.channel_name', '=', $sex_str[$sex]];
  557. //$orwhere[] = ['book_categories.channel_name', '=', $sex_str[$sex]];
  558. }
  559. //自主评级
  560. $own_score = $request->get('own_score');
  561. if ($own_score && in_array($own_score, range('A', 'Z'))) {
  562. $where[] = ['book_channel_scores.score', '=', $own_score];
  563. //$orwhere[] = ['book_channel_scores.score', '=', $own_score];
  564. }
  565. //编辑评分
  566. $score = $request->get('recommend_index');
  567. if ($score && in_array($score, ['A', 'B', 'C', 'S', 'D', 'SS', 'A+']) && !$own_score) {
  568. $score_number = ['SS' => [100, 110], 'S' => [95, 99], 'A+' => [90, 94], 'A' => [85, 89], 'B' => [80, 84], 'C' => [70, 79], 'D' => [0, 69]];
  569. $where[] = ['book_configs.recommend_index', '>=', $score_number[$score][0]];
  570. //$orwhere[] = ['book_configs.recommend_index', '>=', $score_number[$score][0]];
  571. $where[] = ['book_configs.recommend_index', '<=', $score_number[$score][1]];
  572. //$orwhere[] = ['book_configs.recommend_index', '<=', $score_number[$score][1]];
  573. }
  574. //上架时间
  575. $onshelf = $request->get('onshelf');
  576. if ($onshelf && in_array($onshelf, [7, 30, 90])) {
  577. $where[] = ['book_configs.created_at', '>=', date('Y-m-d H:i:s', time() - $onshelf * 86400)];
  578. //$orwhere[] = ['book_configs.created_at', '>=', date('Y-m-d H:i:s', time() - $onshelf * 86400)];
  579. }
  580. //分类
  581. $category_id = $request->get('category_id');
  582. if ($category_id) {
  583. $where[] = ['books.category_id', '=', $category_id];
  584. //$orwhere[] = ['books.category_id', '=', $category_id];
  585. }
  586. //字数
  587. $size = $request->get('size');
  588. if ($size && in_array($size, [1, 2, 3, 4, 5, 6])) {
  589. $size_arr = [[], [200, -1], [100, 200], [20, 100], [0, 20], [20, -1], [0, 20]];
  590. $where[] = ['books.size', '>=', $size_arr[$size][0] * 10000];
  591. //$orwhere[] = ['books.size', '>=', $size_arr[$size][0] * 10000];
  592. if ($size_arr[$size][1] != -1) {
  593. $where[] = ['books.size', '<=', $size_arr[$size][1] * 10000];
  594. // $orwhere[] = ['books.size', '<=', $size_arr[$size][1] * 10000];
  595. }
  596. }
  597. //状态
  598. $status = $request->get('status', -1);
  599. if (in_array($status, [0, 1])) {
  600. $where[] = ['books.status', '=', $status];
  601. //$orwhere[] = ['books.status', '=', $status];
  602. }
  603. $key = $request->get('key','');
  604. if ($key) {
  605. $key = trim($key);
  606. //$where[] = ['book_configs.book_name', 'like', '%' . $key . '%'];
  607. //$orwhere[] = ['book_configs.book_name', 'like', '%' . $key . '%'];
  608. }
  609. //$superior_orwhere = [];
  610. /*$where[] = ['book_configs.is_on_shelf', '=', 2];
  611. //$is_on_shelf =2;
  612. if ($bids) {
  613. $orwhere[] = ['book_configs.is_on_shelf', '=', 1];
  614. //$superior_orwhere[] = ['book_configs.is_on_shelf', '=', 1];
  615. //$orwhere[] = ['book_configs.bid','in','('.implode(',',$bids).')'];
  616. } else {
  617. $orwhere = [];
  618. }*/
  619. //优质书库
  620. $Superior = $request->input('superior',0);
  621. //\Log::info('superior:'.$Superior);
  622. //$Superior = $request->input('superior',0);
  623. $whereDeedIn = [];
  624. $superior_lib = '';
  625. //排序
  626. $order_field = $request->get('order_field','');
  627. $order_type = $request->get('order_type', 'desc');
  628. //$data['order_field'] = 'book_configs.recommend_index';
  629. // $data['order_type'] = 'desc';
  630. if ($order_field && in_array($order_field, ['order_index','recommend_index', 'total_send_order_sum', 'week_send_order_sum', 'read_deep', 'channel_send_order_sum', 'own_score'])) {
  631. $data['order_field'] = $order_field;
  632. if (!in_array($order_type, ['asc', 'desc'])) {
  633. $order_type = 'desc';
  634. }
  635. $data['order_type'] = $order_type;
  636. }
  637. if($Superior==1){
  638. $history_lib = SuperiorHistoryBookService::getSupriorBidList();
  639. //array_merge($whereIn,$his);
  640. $whereDeedIn=count($history_lib)>0?$history_lib:[0];
  641. $superior_lib = 'superior_history_book';
  642. $data['order_field'] = 'order_index';
  643. //$superior_orwhere[] = ['book_configs.bid', 'in', $whereDeedIn];
  644. }
  645. if($Superior==2){
  646. $new_lib = SuperiorNewBookService::getSupriorBidList();
  647. //array_merge($whereIn,$his);
  648. $whereDeedIn=count($new_lib)>0?$new_lib:['-1'];
  649. $superior_lib = 'superior_new_book';
  650. $data['order_field'] = 'superior_new_book.order_index';
  651. $data['order_type'] = 'desc';
  652. //$superior_orwhere[] = ['book_configs.bid', 'in', $whereDeedIn];
  653. }
  654. if($Superior==3){
  655. $where[]=['book_configs.is_current_week_promotion','=',1];
  656. $data['order_field'] = 'recommend_index';
  657. $data['order_type'] = 'desc';
  658. }
  659. if($Superior ==1) $data['order_type'] = 'asc';
  660. $result = BookConfigService::getPromotionBooksV2($where, $whereIn, $data, $bids, $whereDeedIn,$superior_lib,$key);
  661. if ($result) {
  662. $total_send_order = (int)DB::table('send_orders')->max('id');
  663. $week_send_order = (int)DB::table('send_orders')->where('created_at', '>=', date('Y-m-d', strtotime('-7 day')))->count();
  664. foreach ($result as &$v) {
  665. if ($total_send_order > 0) {
  666. $rate = (round($v->total_send_order_sum / $total_send_order, 4)) * 10000;
  667. $v->total_send_order_sum = $this->sendOrderIndex($rate);
  668. }
  669. $v->week_send_order_bid = $v->week_send_order_sum;
  670. if ($week_send_order > 0) {
  671. $rate = (round($v->week_send_order_sum / $week_send_order, 4)) * 10000;
  672. $v->week_send_order_sum = $this->sendOrderIndex($rate);
  673. }
  674. $v->week_send_order = $week_send_order;
  675. }
  676. }
  677. return response()->pagination(new BookV2Transformer(), $result);
  678. }
  679. private function sendOrderIndex($rate)
  680. {
  681. if ($rate < 1) {
  682. return 60;
  683. }
  684. if ($rate >= 200) {
  685. return 100;
  686. } elseif ($rate >= 100) {
  687. return 98;
  688. } elseif ($rate >= 60) {
  689. return 96;
  690. } else {
  691. if ($rate >= 10) {
  692. return 96 - ceil((60 - $rate) / 10) * 2;
  693. } else {
  694. return 96 - 12 - ceil((10 - $rate)) * 2;
  695. }
  696. }
  697. }
  698. /**
  699. * @apiVersion 1.0.0
  700. * @apiDescription 排行榜
  701. * @api {get} book/getRanks 排行榜
  702. * @apiParam {String} type 类型{new:新书榜,sale_total:销售总榜,sale_half_month:半月榜,recommend:编辑推荐}
  703. * @apiGroup Book
  704. * @apiName getRanks
  705. * @apiSuccess {int} code 状态码
  706. * @apiSuccess {String} msg 信息
  707. * @apiSuccess {object} data 结果集
  708. * @apiSuccess {Int} data.book_id bid
  709. * @apiSuccess {String} data.book_name 书名
  710. * @apiSuccess {String} data.book_summary 简介
  711. * @apiSuccess {String} data.book_author 作者
  712. * @apiSuccess {String} data.cover_url 封面
  713. * @apiSuccess {Int} data.book_word_count 字数
  714. * @apiSuccess {Int} data.book_chapter_total 章节数
  715. * @apiSuccess {Int} data.book_category_id 分类
  716. * @apiSuccess {String} data.book_category 分类名
  717. * @apiSuccess {String} data.book_end_status 是否完结
  718. * @apiSuccess {String} data.promotion_count 推广次数
  719. * @apiSuccess {String} data.book_published_time 发布时间
  720. * @apiSuccess {String} data.copyright 版权信息
  721. * @apiSuccess {Int} data.force_subscribe_chapter_seq 强制关注的章节序号
  722. * @apiSuccess {String} data.update_time 更新时间
  723. * @apiSuccess {Int} data.is_on_shelf 是否上架
  724. * @apiSuccess {String} data.book_price 价格
  725. * @apiSuccess {String} data.recommend_index 推荐指数
  726. * @apiSuccess {Int} data.charge_type 收费类型(BOOK: 按本收费,CHAPTER: 按章收费)
  727. * @apiSuccess {Int} data.keyword 关键词
  728. * @apiSuccess {Int} data.is_show_index_content 是否显示推荐指数文本
  729. * @apiSuccess {Int} data.click_count 点击数
  730. * @apiSuccessExample {json} Success-Response:
  731. * {
  732. * "code": 0,
  733. * "msg": "",
  734. * "data": {
  735. * [
  736. * {
  737. * "book_id": 5,
  738. * "book_name": "肌缘巧合",
  739. * "book_summary": "&nbsp;&nbsp;&nbsp;&nbsp;他是权势倾天,纵横商界的王者,却偏偏钟情于她,一宠成瘾。“女人,我要你......只要你能满足我,别墅、游轮、支票,你随便挑。”她羞涩的半低着头:“我只想要你。”他挑眉,“你野心不小啊!”她妩媚一笑,解开他的领带,“难道你不愿意!”他宠她爱她,给她所有想要的。只是有一天她终于忍不住暴走,“靠,你有没有节制呀?我要离婚。”",
  740. * "book_author": "妖火",
  741. * "cover_url": "http://www.leyuee.com/cover/0/8.jpg",
  742. * "book_word_count": 0,
  743. * "book_chapter_total": 0,
  744. * "book_category_id": null,
  745. * "book_category": "爆笑,宠文,潜规则",
  746. * "book_end_status": 8,
  747. * "promotion_count": 12,
  748. * "sex_preference":"女频",
  749. * "book_published_time": null,
  750. * "copyright": null,
  751. * "charge_type": null,
  752. * "force_subscribe_chapter_seq": 0,
  753. * "update_time": null,
  754. * "is_on_shelf": 1,
  755. * "book_price": null,
  756. * "keyword": "温馨,虐心,清水",
  757. * "recommend_index":2,
  758. * "is_show_index_content":0,
  759. * "click_count":0
  760. * },
  761. * ]
  762. * }
  763. * }
  764. */
  765. function getRanks(Request $request)
  766. {
  767. $type = $request->input('type');
  768. if (!$type) {
  769. return response()->error("PARAM_EMPTY");
  770. }
  771. $flush = $request->input('flush');
  772. $book = [];
  773. $channel_user_id = $this->getChannelUserId();
  774. $channel_user_info = ChannelUserService::getById($channel_user_id);
  775. $company = CompanyService::getCompany($channel_user_info->company_id);
  776. $on_shelf = [2];
  777. $important = 'unimportant';
  778. $important_books = null;
  779. if ($company && $company->is_important == 1) {
  780. $bids = [];
  781. $bids = CompanySpecialBookService::getBidByCompany($channel_user_info->company_id);
  782. //隐藏的图书,搜不到,但不影响阅读
  783. $hidden_book = env('HIDE_BOOKS');
  784. if ($hidden_book) {
  785. $hidden_book_array = explode(',', $hidden_book);
  786. if ($bids) {
  787. $bids = array_diff($bids, $hidden_book_array);
  788. }
  789. }
  790. if ($bids) {
  791. $important_books = BookConfigService::getBooksByIds($bids, ['book_configs.created_at', 'desc']);
  792. }
  793. $important = 'important';
  794. }
  795. $key = 'channel_book_rank_' . $type . '_' . $important;
  796. if ($flush == 1) {
  797. Cache::forget($key);
  798. }
  799. $cache = Cache::get($key, []);
  800. if ($cache) {
  801. $cache = json_decode($cache);
  802. return response()->collection(new BookTransformer(), $cache);
  803. }
  804. switch ($type) {
  805. case 'new':
  806. $order = [['book_configs.created_at', 'desc'], ['book_configs.recommend_index', 'desc']];
  807. $book = BookConfigService::getBooksNoPage([], $order, $on_shelf, 20);
  808. $book = $this->sortBooks($important_books, $book);
  809. break;
  810. case 'sale_total';
  811. $start = date('Y-m') . '-01';
  812. $end = date('Y-m-d');
  813. $bids = BookOrderStatistical::getTopSaleBooks($start, $end, $on_shelf, 20);
  814. $id = [];
  815. foreach ($bids as $v) {
  816. $id[] = $v->bid;
  817. }
  818. if ($id) {
  819. $book = BookConfigService::getBooksByIds($id);
  820. }
  821. break;
  822. case 'sale_half_month':
  823. $start = date('Y-m-d', strtotime('-14 day'));
  824. $end = date('Y-m-d');
  825. $bids = BookOrderStatistical::getTopSaleBooks($start, $end, $on_shelf, 10);
  826. $id = [];
  827. foreach ($bids as $v) {
  828. $id[] = $v->bid;
  829. }
  830. if ($id) {
  831. $book = BookConfigService::getBooksByIds($id);
  832. }
  833. break;
  834. case 'recommend':
  835. $id_arr = env('CHANNEL_RECOMMEND_BIDS', '');
  836. $redis_field = 'unimportant';
  837. if ($important == 'important') {
  838. $redis_field = 'important';
  839. $id_arr = env('CHANNEL_RECOMMEND_IMPORTANT_BIDS', '');
  840. }
  841. $ids = Redis::hget('channel_recomm_books', $redis_field);
  842. if ($ids) $id_arr = $ids;
  843. if ($id_arr) {
  844. $book = BookConfigService::getBooksByIds(explode(',', $id_arr));
  845. }
  846. break;
  847. }
  848. if ($book) {
  849. Cache::put($key, json_encode($book), 60);
  850. }
  851. return response()->collection(new BookTransformer(), $book);
  852. }
  853. private function sortBooks($book1, $book2)
  854. {
  855. if (!$book1)
  856. return $book2;
  857. $book1 = $book1->filter(function ($value) {
  858. return $value->is_on_shelf = 1;
  859. });
  860. return $book2->concat($book1)->sortByDesc('created_at')->slice(0, 20);
  861. }
  862. }