manager.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: stanley-king
  5. * Date: 16/4/17
  6. * Time: 下午11:34
  7. */
  8. namespace bonus;
  9. require_once(BASE_ROOT_PATH . '/helper/model_helper.php');
  10. require_once(BASE_ROOT_PATH . '/helper/algorithm.php');
  11. require_once(BASE_ROOT_PATH . '/helper/util_helper.php');
  12. use session_helper;
  13. use member_info;
  14. use algorithm;
  15. use Log;
  16. use Exception;
  17. use trans_wapper;
  18. use util;
  19. class manager
  20. {
  21. //红包抢到不绑定手机的过期时间
  22. const grab_period_timeout = 10 * 60;
  23. //红包的四种状态
  24. const bonus_state_ungrab = 0; //未抢
  25. const bonus_state_grabed = 1; //已抢到
  26. const bonus_state_binded = 2; //已绑定手机
  27. const bonus_state_topuped= 3; //已经充值
  28. const type_prefix = 'bonus_type';
  29. public function __construct() {
  30. }
  31. private function avatars($user_ids)
  32. {
  33. $result = [];
  34. $user_ids = array_unique($user_ids);
  35. $mod_member = Model('member');
  36. $items = $mod_member->getMemberList(['member_id' => ['in',$user_ids]]);
  37. foreach ($items as $item)
  38. {
  39. $member = new member_info($item);
  40. $uid = $member->member_id();
  41. $avatar = $member->avatar();
  42. $discount = $item['discount_self_amount'];
  43. $result[$uid]['avatar'] = $avatar;
  44. $result[$uid]['discount'] = $discount;
  45. }
  46. return $result;
  47. }
  48. public function get_typeinfo($type_sn)
  49. {
  50. $bonus_info = rcache($type_sn, self::type_prefix, '*');
  51. if (empty($bonus_info))
  52. {
  53. $type = type::create_by_sn($type_sn,true);
  54. $user_bonus = Model('user_bonus');
  55. $bonus_ex= $user_bonus->getTypeBinded(array('type_id' => $type->getType_id()));
  56. $type_info = $type->get_param();
  57. if($type->binded_over())
  58. {
  59. $lasted_time = Model('user_bonus')->lasted_binded_time(array('type_id' => $type->getType_id()));
  60. if($lasted_time > 0) {
  61. $period = $lasted_time - $type->get_start_time();
  62. $type_info['binded_period'] = $period == 0 ? 1 : $period;
  63. }
  64. $type_info['binded_over'] = 1;
  65. $type_info['grab_lastime'] = 0;
  66. }
  67. else
  68. {
  69. $type_info['binded_period'] = 0;
  70. $type_info['binded_over'] = 0;
  71. if($type->grabed_over()) {
  72. $lasted_time = Model('user_bonus')->lasted_grabed_time(array('type_id' => $type->getType_id(),'bonus_status' => 1));
  73. $type_info['grab_lastime'] = $lasted_time;
  74. } else {
  75. $type_info['grab_lastime'] = 0;
  76. }
  77. }
  78. $user_ids = [];
  79. $user_ids[] = $type->sender_id();
  80. $relay_id = $type->relayer_id();
  81. if($relay_id > 0) {
  82. $user_ids[] = $relay_id;
  83. }
  84. foreach ($bonus_ex as $bonus) {
  85. $user_ids[] = intval($bonus['user_id']);
  86. }
  87. $user_avatars = $this->avatars($user_ids);
  88. $type_sn = $type->getType_sn();
  89. $url = BASE_SITE_URL . "/mobile/index.php?act=bonusex&op=open&client_type=wap&type_sn={$type_sn}";
  90. $ret['url'] = $url;
  91. $bonus_info = ['type_info' => $type_info,'binded_info' => $bonus_ex,'avatars' => $user_avatars];
  92. wcache($type_sn,['infos' => serialize($bonus_info)],self::type_prefix);
  93. }
  94. else {
  95. $bonus_info = unserialize($bonus_info['infos']);
  96. }
  97. return $bonus_info;
  98. }
  99. public function get_mine_by_typesn($type_sn)
  100. {
  101. $bonus = $this->read_session($type_sn);
  102. if(empty($bonus))
  103. {
  104. $mod_bonus = Model('user_bonus');
  105. $session_id = session_helper::session_id();
  106. $mobile = session_helper::mobile();
  107. $user_id = session_helper::memberid();
  108. if(empty($session_id)) return false;
  109. if($user_id > 0 && !empty($mobile)) {
  110. $cond['session_id|user_mobile|user_id'] = ['_multi'=> true,$session_id,$mobile,$user_id];
  111. }
  112. elseif ($user_id > 0) {
  113. $cond['session_id|user_id'] = ['_multi'=> true,$session_id,$user_id];
  114. }
  115. elseif (!empty($mobile)) {
  116. $cond['session_id|user_mobile'] = ['_multi'=> true,$session_id,$mobile];
  117. }
  118. else {
  119. $cond['session_id'] = $session_id;
  120. }
  121. $cond['type_sn'] = $type_sn;
  122. $bonusex = $mod_bonus->get($cond);
  123. if(empty($bonusex)) {
  124. return false;
  125. }
  126. foreach($bonusex as $val)
  127. {
  128. if($val['user_mobile'] == session_helper::mobile()) {
  129. $this->write_session($val);
  130. return $val;
  131. }
  132. }
  133. }
  134. return $bonus;
  135. }
  136. public function get_mine_by_bonussn($bonus_sn)
  137. {
  138. $bonus = $this->read_session('',$bonus_sn);
  139. if(empty($bonus))
  140. {
  141. $mod_bonus = Model('user_bonus');
  142. $session_id = session_helper::session_id();
  143. $mobile = session_helper::mobile();
  144. $user_id = session_helper::memberid();
  145. if(empty($session_id)) return false;
  146. if($user_id > 0 && !empty($mobile)) {
  147. $cond['session_id|user_mobile|user_id'] = ['_multi'=> true,$session_id,$mobile,$user_id];
  148. }
  149. elseif ($user_id > 0) {
  150. $cond['session_id|user_id'] = ['_multi'=> true,$session_id,$user_id];
  151. }
  152. elseif (!empty($mobile)) {
  153. $cond['session_id|user_mobile'] = ['_multi'=> true,$session_id,$mobile];
  154. }
  155. else {
  156. $cond['session_id'] = $session_id;
  157. }
  158. $cond['bonus_sn'] = $bonus_sn;
  159. $bonusex = $mod_bonus->get($cond);
  160. if(empty($bonusex)) {
  161. return false;
  162. }
  163. foreach($bonusex as $val)
  164. {
  165. if($val['user_mobile'] == $_SESSION['member_mobile']) {
  166. $this->write_session($val);
  167. return $val;
  168. }
  169. }
  170. }
  171. return $bonus;
  172. }
  173. public function grab_bonus($type_sn)
  174. {
  175. $bonus = $this->read_session($type_sn);
  176. if($bonus === false)
  177. {
  178. $param = ['type_sn' => $type_sn,
  179. 'session_id' => session_helper::session_id(),
  180. 'time_out' => self::grab_period_timeout,
  181. 'user_mobile' => session_helper::mobile(),
  182. 'user_id' => session_helper::memberid()];
  183. $bonus_obj = factory::grab_bonus($param);
  184. if($bonus_obj == false) {
  185. return false;
  186. }
  187. else
  188. {
  189. $this->write_session($bonus_obj->get_param());
  190. dcache($bonus_obj->type_sn(),self::type_prefix);
  191. }
  192. $bonus = $bonus_obj->get_param();
  193. }
  194. return $bonus;
  195. }
  196. public function topup($type,$mod_user_bonus,&$bonus)
  197. {
  198. $usable_days = $type->usable_days();
  199. $expried_secs = $usable_days * 24 * 3600;
  200. $usable_time = time() + $expried_secs;
  201. $usable_time = util::last_day_secs($usable_time);
  202. $datas = array('bonus_status' => 3,
  203. 'user_id' => $_SESSION['member_id'],
  204. 'user_name' => session_helper::nickname(),
  205. 'usable_time' => $usable_time);
  206. $ret = $mod_user_bonus->where(array('bonus_id' => $bonus['bonus_id']))->update($datas);
  207. $affect_rows = $mod_user_bonus->affected_rows();
  208. if($ret == true && $affect_rows == 1) {
  209. array_merge($bonus,$datas);
  210. $this->write_session($bonus);
  211. return true;
  212. }
  213. else {
  214. return false;
  215. }
  216. }
  217. public function send($type_sn,$ids)
  218. {
  219. $member_ids = [];
  220. foreach ($ids as $id) {
  221. $member_ids[] = intval($id);
  222. }
  223. sort($member_ids);
  224. $mod_bonus = Model('user_bonus');
  225. $items = $mod_bonus->getBonusList(array('user_id' => array('in',$member_ids),'type_sn' => $type_sn),'*','',0,0,false,'',true);
  226. $ret = [];
  227. foreach ($items as $item)
  228. {
  229. $user_id = intval($item['user_id']);
  230. if(algorithm::binary_search($user_id,$member_ids) != false)
  231. {
  232. $pos = algorithm::lower_bonud($member_ids,$user_id);
  233. algorithm::array_erase($member_ids,$pos);
  234. $ret[] = $item;
  235. }
  236. }
  237. if(!empty($member_ids))
  238. {
  239. $count = count($member_ids);
  240. $items = $mod_bonus->getBonusList(array('bonus_status' => 0,'type_sn' => $type_sn),'*','',0,0,count($member_ids),'',true);
  241. if($count != count($items)) {
  242. return false;
  243. }
  244. $index = 0;
  245. $bonus_values = 0.00;
  246. foreach ($items as &$bonus)
  247. {
  248. try
  249. {
  250. $user_id = $member_ids[$index];
  251. $minfo = new member_info($user_id);
  252. $bonus['user_id'] = $user_id;
  253. $bonus['user_mobile'] = $minfo->mobile();
  254. $bonus['user_name'] = $minfo->nickname();
  255. $bonus['grab_time'] = time();
  256. $bonus['get_time'] = time();
  257. $bonus['bonus_status'] = 2;
  258. $ret[] = $bonus;
  259. $bonus_values += $bonus['bonus_value'];
  260. } catch (Exception $ex) {
  261. Log::record($ex->getMessage(),Log::ERR);
  262. }
  263. ++$index;
  264. }
  265. $mod_bonus->replaceAll($items);
  266. Model('bonus_type')->edit(array('type_sn' => $type_sn),
  267. array('binded_num' => array('exp', "binded_num+{$count}"),
  268. 'grabed_num' => array('exp', "grabed_num+{$count}"),
  269. 'remain_amount' => array('exp', "remain_amount-" . "{$bonus_values}")));
  270. dcache($type_sn,self::type_prefix);
  271. return $ret;
  272. } else {
  273. return false;
  274. }
  275. }
  276. public function send_mobile($type_sn, $mobiles,$status)
  277. {
  278. sort($mobiles);
  279. $mod_bonus = Model('user_bonus');
  280. $items = $mod_bonus->getBonusList(array('user_mobile' => array('in',$mobiles),'type_sn' => $type_sn),'*','',0,0,false,'',true);
  281. $ret = [];
  282. foreach ($items as $item)
  283. {
  284. $user_mobile = $item['user_mobile'];
  285. if(algorithm::binary_search($user_mobile,$mobiles) != false)
  286. {
  287. $pos = algorithm::lower_bonud($mobiles,$user_mobile);
  288. algorithm::array_erase($mobiles,$pos);
  289. $ret[] = $item;
  290. }
  291. }
  292. if(!empty($mobiles))
  293. {
  294. $count = count($mobiles);
  295. $items = $mod_bonus->getBonusList(array('bonus_status' => 0,'type_sn' => $type_sn),'*','',0,0,count($mobiles),'',true);
  296. if($count != count($items)) {
  297. return false;
  298. }
  299. $mod_member = Model('member');
  300. $index = 0;
  301. $bonus_values = 0.00;
  302. $bind_num = 0;
  303. foreach ($items as &$bonus)
  304. {
  305. $user_mobile = $mobiles[$index];
  306. $infos = $mod_member->getMemberInfo(['member_mobile' => $user_mobile,'member_mobile_bind' => 1]);
  307. if(!empty($infos)) {
  308. $minfo = new member_info($infos);
  309. $bonus['user_id'] = $minfo->member_id();
  310. $bonus['user_mobile'] = $minfo->mobile();
  311. $bonus['user_name'] = $minfo->nickname();
  312. $bonus['grab_time'] = time();
  313. $bonus['get_time'] = time();
  314. $bonus['bonus_status'] = $status;
  315. $bind_num++;
  316. $bonus_values += $bonus['bonus_value'];
  317. } else {
  318. $bonus['user_mobile'] = $user_mobile;
  319. $bonus['grab_time'] = time();
  320. $bonus['bonus_status'] = 1;
  321. }
  322. ++$index;
  323. $ret[] = $bonus;
  324. }
  325. $mod_bonus->replaceAll($items);
  326. Model('bonus_type')->edit(array('type_sn' => $type_sn),
  327. array('binded_num' => array('exp', "binded_num+{$bind_num}"),
  328. 'grabed_num' => array('exp', "grabed_num+{$count}"),
  329. 'remain_amount' => array('exp', "remain_amount-" . "{$bonus_values}")));
  330. dcache($type_sn,self::type_prefix);
  331. return $ret;
  332. } else {
  333. return false;
  334. }
  335. }
  336. public function bind_bonus($bonus_sn,$session_id,$mobile,$userid,&$new_bonus_sn)
  337. {
  338. $new_bonus_sn = $bonus_sn;
  339. $bonus_info = self::read_session('',$bonus_sn);
  340. if(!empty($bonus_info))
  341. {
  342. $user_bonus = user_bonus::create_by_param($bonus_info);
  343. if($user_bonus->isBinded()) {
  344. return true;
  345. } else {
  346. $bonus_id = $user_bonus->bonus_id();
  347. $type_id = $user_bonus->type_id();
  348. }
  349. }
  350. if(!isset($type_id))
  351. {
  352. $user_bonus = user_bonus::create_by_sn($bonus_sn);
  353. if($user_bonus->isBinded())
  354. {
  355. if($user_bonus->user_mobile() == $mobile || $user_bonus->user_id() == $userid) {
  356. return true;
  357. } else {
  358. return false;
  359. }
  360. }
  361. $bonus_id = $user_bonus->bonus_id();
  362. $type_id = $user_bonus->type_id();
  363. }
  364. $binded_bonus = array();
  365. $ret = Model('user_bonus')->bind($type_id,$bonus_id,$session_id,$mobile,$userid,$binded_bonus);
  366. Log::record("bind_bonus bind ret={$ret}",Log::DEBUG);
  367. if($ret == true)
  368. {
  369. try
  370. {
  371. //bind 一个新红包
  372. $bonus_val = $user_bonus->bonus_value();
  373. $trans = new trans_wapper(null,__METHOD__);
  374. Model('bonus_type')->edit(array('type_id' => $type_id),
  375. array('binded_num' => array('exp', 'binded_num+1'),
  376. 'remain_amount' => array('exp', "remain_amount-" . "{$bonus_val}")));
  377. $trans->commit();
  378. $this->clear_session($bonus_sn);
  379. dcache($user_bonus->type_sn(),self::type_prefix);
  380. } catch (Exception $ex) {
  381. $trans->rollback();
  382. return false;
  383. }
  384. }
  385. else
  386. {
  387. if(!empty($binded_bonus)) { //返回已经绑定的红包
  388. $this->clear_session($bonus_sn);
  389. $this->write_session($binded_bonus);
  390. $new_bonus_sn = $binded_bonus['bonus_sn'];
  391. } else {
  392. return false;
  393. }
  394. }
  395. return true;
  396. }
  397. public function shake($bonus_sn,$strength,$direction)
  398. {
  399. $bonus_info = self::read_session('',$bonus_sn);
  400. if(!empty($bonus_info))
  401. {
  402. $user_bonus = user_bonus::create_by_param($bonus_info);
  403. $bonus_id = $user_bonus->bonus_id();
  404. $type_id = $user_bonus->type_id();
  405. $bonus_val = $user_bonus->bonus_value();
  406. $bonus_status = $user_bonus->bonus_status();
  407. }
  408. if(!isset($type_id)) {
  409. $user_bonus = user_bonus::create_by_sn($bonus_sn);
  410. $bonus_id = $user_bonus->bonus_id();
  411. $type_id = $user_bonus->type_id();
  412. $bonus_val = $user_bonus->bonus_value();
  413. $bonus_status = $user_bonus->bonus_status();
  414. }
  415. if($user_bonus->can_shake() == false) {
  416. return false;
  417. }
  418. $shaker = new \bonus\shaker();
  419. $ret = $shaker->reassign($type_id,$bonus_id,$bonus_status,$bonus_val,$strength,$direction);
  420. if($ret == true)
  421. {
  422. $bonus = $this->read_session('',$bonus_sn);
  423. if(!empty($bonus)) {
  424. $this->clear_session($bonus_sn);
  425. $bonus['bonus_value'] = $bonus_val;
  426. $this->write_session($bonus);
  427. }
  428. dcache($user_bonus->type_sn(),self::type_prefix);
  429. return true;
  430. } else {
  431. return false;
  432. }
  433. }
  434. public function comment($bonus_sn,$content)
  435. {
  436. if(empty($bonus_sn)) return false;
  437. $condition = array('user_mobile' => $_SESSION['member_mobile'],
  438. 'bonus_sn' => $bonus_sn,
  439. 'bonus_status' => array('in',array(2,3)));
  440. $ret = Model('user_bonus')->edit($condition,array('user_comment' => $content));
  441. if($ret == true) {
  442. $user_bonus = user_bonus::create_by_sn($bonus_sn);
  443. dcache($user_bonus->type_sn(),self::type_prefix);
  444. return true;
  445. } else {
  446. return false;
  447. }
  448. }
  449. //个人抢到的红包,放到个人的Session 里面.
  450. private function read_session($type_sn,$b_sn = '')
  451. {
  452. if(!isset($_SESSION['bonus'])) return false;
  453. $bonusex = $_SESSION['bonus'];
  454. foreach($bonusex as $bonus_sn => $val)
  455. {
  456. if($bonus_sn == $b_sn) return $val;
  457. if($val['type_sn'] == $type_sn)
  458. {
  459. $status = $val['bonus_status'];
  460. if ($status == self::bonus_state_binded) {
  461. return $val;
  462. }
  463. else if ($status == self::bonus_state_grabed)
  464. {
  465. $grab_time = $val['grab_time'];
  466. if ($grab_time > time() - self::grab_period_timeout) {
  467. return $val;
  468. } else {
  469. unset ($_SESSION['bonus'][$bonus_sn]);
  470. return false; // 需要重新抢
  471. }
  472. }
  473. else {
  474. return $val;
  475. }
  476. }
  477. }
  478. return false;
  479. }
  480. private function write_session($bonus)
  481. {
  482. if(!isset($_SESSION['bonus'])) {
  483. $_SESSION['bonus'] = array();
  484. }
  485. $bonus_sn = $bonus['bonus_sn'];
  486. $_SESSION['bonus'][$bonus_sn] = $bonus;
  487. }
  488. private function clear_session($bonus_sn = '')
  489. {
  490. if(!empty($bonus_sn))
  491. {
  492. if(isset($_SESSION['bonus']) && isset($_SESSION['bonus'][$bonus_sn])) {
  493. unset($_SESSION['bonus'][$bonus_sn]);
  494. }
  495. }
  496. else
  497. {
  498. if(!isset($_SESSION['bonus'])) {
  499. unset($_SESSION['bonus']);
  500. }
  501. }
  502. }
  503. }