BuyMoreService.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Bear
  5. * Date: 2019/10/11
  6. * Time: 下午7:38
  7. */
  8. namespace app\main\service;
  9. use app\common\library\Redis;
  10. use app\main\constants\BookConstants;
  11. use app\main\constants\CacheConstants;
  12. use app\main\constants\PayConstants;
  13. use app\main\constants\RechargeConstants;
  14. class BuyMoreService extends BaseService
  15. {
  16. protected static $self = null;
  17. public static function instance()
  18. {
  19. if (self::$self == null) {
  20. self::$self = new self();
  21. }
  22. return self::$self;
  23. }
  24. public function checkOrderBuyMore($user_id, $out_trade_no, $order_id)
  25. {
  26. $cacheOrder = CacheConstants::getBuyMoreOrderCache($out_trade_no);
  27. $cache = Redis::instance()->get($cacheOrder);
  28. if ($cache) {
  29. Redis::instance()->del($cacheOrder);
  30. LogService::info('PAYMORECACHE:' . $cache);
  31. switch ($cache) {
  32. case '1':
  33. $freeBook = Redis::instance()->get(CacheConstants::getBuyMoreFreeBookCache($user_id, 0));
  34. $this->addKandian($user_id, 500, $order_id);
  35. $this->addFreeKandian($user_id, 100, $order_id);
  36. $this->addFreeLimitBook($user_id, 5, 5);
  37. $this->addFreeBook($user_id, $freeBook);
  38. Redis::instance()->del(CacheConstants::getBuyMoreFreeBookCache($user_id, 0));
  39. break;
  40. case '2':
  41. $freeBook = Redis::instance()->get(CacheConstants::getBuyMoreFreeBookCache($user_id, 1));
  42. $this->addKandian($user_id, 1000, $order_id);
  43. $this->addFreeKandian($user_id, 500, $order_id);
  44. $this->addFreeLimitBook($user_id, 5, 5);
  45. $this->addFreeBook($user_id, $freeBook);
  46. $this->addPayDiscount($user_id, 0.8, 3);
  47. Redis::instance()->del(CacheConstants::getBuyMoreFreeBookCache($user_id, 1));
  48. break;
  49. case '3':
  50. $freeBook = Redis::instance()->get(CacheConstants::getBuyMoreFreeBookCache($user_id, 2));
  51. $this->addKandian($user_id, 3000, $order_id);
  52. $this->addFreeKandian($user_id, 1000, $order_id);
  53. $this->addFreeLimitBook($user_id, 10, 5);
  54. $this->addFreeBook($user_id, $freeBook);
  55. $this->addPayDiscount($user_id, 0.7, 3);
  56. Redis::instance()->del(CacheConstants::getBuyMoreFreeBookCache($user_id, 2));
  57. break;
  58. case '4':
  59. $freeBook = Redis::instance()->get(CacheConstants::getBuyMoreFreeBookCache($user_id, 3));
  60. $this->addKandian($user_id, 4900, $order_id);
  61. $this->addFreeKandian($user_id, 1500, $order_id);
  62. $this->addFreeLimitBook($user_id, 10, 5);
  63. $this->addFreeBook($user_id, $freeBook);
  64. $this->addPayDiscount($user_id, 0.7, 3);
  65. Redis::instance()->del(CacheConstants::getBuyMoreFreeBookCache($user_id, 3));
  66. break;
  67. }
  68. }
  69. }
  70. /**
  71. * 添加免费书币
  72. * @param $user_id
  73. * @param $kandian
  74. * @param $time
  75. * @return \app\main\model\object\ReturnObject
  76. */
  77. public function addFreeKandian($user_id, $kandian, $order_id, $time = 3, $type = RechargeConstants::RECHARGE_TYPE_KANDIAN)
  78. {
  79. $recharge = [
  80. 'user_id' => $user_id,
  81. 'type' => $type,
  82. 'kandian' => 0,
  83. 'remain_kandian' => 0,
  84. 'free_kandian' => $kandian,
  85. 'remain_free_kandian' => $kandian,
  86. 'free_endtime' => time() + $time * 86400,
  87. 'day' => 0,
  88. 'orders_id' => $order_id,
  89. 'book_id' => '',
  90. 'createtime' => time(),
  91. 'updatetime' => time(),
  92. 'business_line' => PayConstants::BUSINESS_WECHAT,
  93. ];
  94. $result = FinancialService::instance()->getRechargeModel()->setConnect($user_id)->insertGetId($recharge);
  95. Redis::instance()->del(CacheConstants::getFreeKandianUserRechargeListCacheKey($user_id));
  96. return $this->setData($result)->getReturn();
  97. }
  98. /**
  99. * 添加免费书币
  100. * @param $user_id
  101. * @param $kandian
  102. * @return \app\main\model\object\ReturnObject
  103. */
  104. public function addKandian($user_id, $kandian, $order_id)
  105. {
  106. $recharge = [
  107. 'user_id' => $user_id,
  108. 'type' => RechargeConstants::RECHARGE_TYPE_KANDIAN,
  109. 'kandian' => $kandian,
  110. 'remain_kandian' => $kandian,
  111. 'free_kandian' => 0,
  112. 'remain_free_kandian' => 0,
  113. 'day' => 0,
  114. 'orders_id' => $order_id,
  115. 'book_id' => '',
  116. 'createtime' => time(),
  117. 'updatetime' => time(),
  118. 'business_line' => PayConstants::BUSINESS_WECHAT,
  119. ];
  120. $result = FinancialService::instance()->getRechargeModel()->setConnect($user_id)->insertGetId($recharge);
  121. Redis::instance()->del(CacheConstants::getKandianUserRechargeListCacheKey($user_id));
  122. return $this->setData($result)->getReturn();
  123. }
  124. /**
  125. * 获取用户限免忽略书籍
  126. * @param $user_id
  127. * @return \app\main\model\object\ReturnObject
  128. */
  129. public function getIgnoreBooks($user_id)
  130. {
  131. //最近阅读
  132. $readBookIds = UserService::instance()->getUserRecentlyReadModel()
  133. ->setConnect($user_id)
  134. ->where('user_id', $user_id)
  135. ->group('book_id')
  136. ->column('book_id');
  137. $return = array_unique($readBookIds);
  138. return $this->setData($return)->getReturn();
  139. }
  140. /**
  141. * 添加限免书籍
  142. * @param $user_id
  143. * @param $count
  144. * @param $time
  145. * @return \app\main\model\object\ReturnObject
  146. */
  147. public function addFreeLimitBook($user_id, $count, $time)
  148. {
  149. $now = time();
  150. $ignore = $this->getIgnoreBooks($user_id)->data;
  151. //限免书
  152. $free = $this->getFreeLimitCacheBook($user_id)->data;
  153. $ignore = array_merge($ignore, array_keys($free));
  154. $bookIds = array_diff(PayConstants::FREE_LIMIT_BOOKS, $ignore);
  155. if (count($bookIds) < $count) {
  156. $diff = array_diff(PayConstants::FREE_LIMIT_BOOKS, $bookIds);
  157. $currentCount = count($bookIds);
  158. for ($i = 0; $i < $count - $currentCount; $i++) {
  159. if ($diff) {
  160. shuffle($diff);
  161. array_push($bookIds, array_pop($diff));
  162. }
  163. }
  164. } else {
  165. $bookIds = array_slice($bookIds, 0, $count);
  166. }
  167. foreach ($bookIds as $bookId) {
  168. if (array_key_exists($bookId, $free)) {
  169. $free[$bookId] += $time * 86400 + 0;
  170. } else {
  171. $free[$bookId] = $time * 86400 + $now;
  172. }
  173. BookService::instance()->setBookShelf($bookId, $user_id);
  174. }
  175. $cache = CacheConstants::getBuyMoreFreeLimitBookCache($user_id);
  176. Redis::instance()->hMset($cache, $free);
  177. Redis::instance()->expire($cache, max($free) - $now);
  178. return $this->setData(true)->getReturn();
  179. }
  180. /**
  181. * 获取缓存的限免书籍
  182. * @param $user_id
  183. * @return \app\main\model\object\ReturnObject
  184. */
  185. public function getFreeLimitCacheBook($user_id)
  186. {
  187. //限免书
  188. $cache = CacheConstants::getBuyMoreFreeLimitBookCache($user_id);
  189. $free = Redis::instance()->hGetAll($cache);
  190. $data = [];
  191. if ($free) {
  192. foreach ($free as $bookId => $time) {
  193. if ($time > time()) {
  194. $data[$bookId] = $time;
  195. } else {
  196. Redis::instance()->hDel($cache, $bookId);
  197. }
  198. }
  199. if (!$data) {
  200. Redis::instance()->del($cache);
  201. }
  202. }
  203. return $this->setData($data)->getReturn();
  204. }
  205. /**
  206. * 添加免费书籍
  207. * @param $user_id
  208. * @param $book_id
  209. * @return \app\main\model\object\ReturnObject
  210. */
  211. public function addFreeBook($user_id, $book_id)
  212. {
  213. $book = BookService::instance()->getBookModel()->getBooksInfo([$book_id]);
  214. $exists = FinancialService::instance()->getConsumeModel()->setConnect($user_id)
  215. ->where('user_id', $user_id)
  216. ->where('book_id', $book_id)
  217. ->where('type', BookConstants::BOOK_BILLING_MODEL_BOOK)
  218. ->find();
  219. if (!$book) {
  220. LogService::error('书籍不存在');
  221. return $this->setData(true)->getReturn();
  222. }
  223. if (!$exists) {
  224. $consume = [
  225. 'user_id' => $user_id,
  226. 'book_id' => $book_id,
  227. 'book_name' => $book[$book_id]['name'],
  228. 'type' => BookConstants::BOOK_BILLING_MODEL_BOOK,
  229. 'chapter_id' => '',
  230. 'chapter_name' => '',
  231. 'createtime' => time(),
  232. 'updatetime' => time(),
  233. 'extend1' => $book_id,
  234. 'extend2' => '',
  235. ];
  236. FinancialService::instance()->getConsumeModel()->setConnect($user_id)->insertGetId($consume);
  237. } else {
  238. LogService::info('书籍已经存在');
  239. }
  240. BookService::instance()->setBookShelf($book_id, $user_id);
  241. return $this->setData(true)->getReturn();
  242. }
  243. /**
  244. * 缓存永久免费书籍,回调使用
  245. * @param $user_id
  246. * @return \app\main\model\object\ReturnObject
  247. */
  248. public function setFreeBook($user_id)
  249. {
  250. $books = [];
  251. for ($i = 0; $i < 4; $i++) {
  252. $cache = CacheConstants::getBuyMoreFreeBookCache($user_id, $i);
  253. $id = Redis::instance()->get($cache);
  254. if (!$id) {
  255. $readBooks = $this->getIgnoreBooks($user_id)->data;
  256. $ids = array_diff(PayConstants::FREE_PERMANENT_BOOKS, $readBooks, $books);
  257. if (!$ids) {
  258. $ids = PayConstants::FREE_PERMANENT_BOOKS;
  259. }
  260. shuffle($ids);
  261. $id = array_pop($ids);
  262. Redis::instance()->set($cache, $id, 86400);
  263. }
  264. $books[] = $id;
  265. }
  266. return $this->setData($books)->getReturn();
  267. }
  268. /**
  269. * 用户阅读折扣
  270. * @param $user_id
  271. * @param $rate
  272. * @param $time
  273. * @return \app\main\model\object\ReturnObject
  274. */
  275. public function addPayDiscount($user_id, $rate, $time)
  276. {
  277. $cache = CacheConstants::getBuyMoreDiscountCache($user_id);
  278. $now = time();
  279. if ($cacheList = Redis::instance()->zRangeByScore($cache, time(), '+inf', ['withscores' => TRUE])) {
  280. $time = max($cacheList) + $time * 86400;
  281. } else {
  282. $time = $time * 86400 + $now;
  283. }
  284. Redis::instance()->zAdd($cache, $time, $time . ":" . $rate);
  285. Redis::instance()->expire($cache, $time - $now);
  286. // Redis::instance()->set($cache, $rate, $time * 86400);
  287. return $this->setData(true)->getReturn();
  288. }
  289. }