manager.php 18 KB

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