date.php 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942
  1. <?php
  2. /**
  3. * 任务计划 - 天执行的任务
  4. *
  5. *
  6. *
  7. *
  8. */
  9. defined('InShopNC') or exit('Access Invalid!');
  10. require_once(BASE_ROOT_PATH.'/helper/notify_helper.php');
  11. class dateControl extends BaseCronControl {
  12. /**
  13. * 该文件中所有任务执行频率,默认1天,单位:秒
  14. * @var int
  15. */
  16. const EXE_TIMES = 86400;
  17. /**
  18. * 优惠券即将到期提醒时间,单位:天
  19. * @var int
  20. */
  21. const VOUCHER_INTERVAL = 5;
  22. /**
  23. * 兑换码即将到期提醒时间,单位:天
  24. * @var int
  25. */
  26. const VR_CODE_INTERVAL = 5;
  27. /**
  28. * 订单结束后可评论时间,15天,60*60*24*15
  29. * @var int
  30. */
  31. const ORDER_EVALUATE_TIME = 1296000;
  32. /**
  33. * 每次到货通知消息数量
  34. * @var int
  35. */
  36. const ARRIVAL_NOTICE_NUM = 100;
  37. /**
  38. * 默认方法
  39. */
  40. public function indexOp() {
  41. //更新订单商品佣金值
  42. $this->_order_commis_rate_update();
  43. //订单超期后不允许评价
  44. $this->_order_eval_expire_update();
  45. //未付款订单超期自动关闭
  46. $this->_order_timeout_cancel();
  47. //增加会员积分和经验值
  48. // $this->_add_points();
  49. //订单自动完成
  50. $this->_order_auto_complete();
  51. //自提点中,已经关闭的订单删除
  52. $this->_order_delivery_cancel_del();
  53. //更新订单扩展表收货人所在省份ID
  54. $this->_order_reciver_provinceid_update();
  55. //更新退款申请超时处理
  56. Model('trade')->editRefundConfirm();
  57. //代金券即将过期提醒
  58. $this->_voucher_will_expire();
  59. //虚拟兑换码即将过期提醒
  60. $this->_vr_code_will_expire();
  61. //更新商品访问量
  62. $this->_goods_click_update();
  63. //更新商品促销到期状态
  64. $this->_goods_promotion_state_update();
  65. //商品到货通知提醒
  66. $this->_arrival_notice();
  67. //更新浏览量
  68. $this->_goods_browse_update();
  69. //缓存订单及订单商品相关数据
  70. $this->_order_goods_cache();
  71. //会员相关数据统计
  72. $this->_member_stat();
  73. //已领取但未使用的红包过期通知
  74. $this->bonus_expire_notify();
  75. }
  76. /**
  77. * 未付款订单超期自动关闭
  78. */
  79. private function _order_timeout_cancel() {
  80. //实物订单超期未支付系统自动关闭
  81. $_break = false;
  82. $model_order = Model('order');
  83. $logic_order = Logic('order');
  84. $condition = array();
  85. $condition['order_state'] = ORDER_STATE_NEW;
  86. $condition['add_time'] = array('lt',TIMESTAMP - ORDER_AUTO_CANCEL_DAY * self::EXE_TIMES);
  87. //分批,每批处理100个订单,最多处理5W个订单
  88. for ($i = 0; $i < 500; $i++){
  89. if ($_break) {
  90. break;
  91. }
  92. $order_list = $model_order->getOrderList($condition, '', '*', '', 100);
  93. if (empty($order_list)) break;
  94. foreach ($order_list as $order_info) {
  95. $result = $logic_order->changeOrderStateCancel($order_info,'system','系统','超期未支付系统自动关闭订单',true,false);
  96. if (!$result['state']) {
  97. $this->log('实物订单超期未支付关闭失败SN:'.$order_info['order_sn']); $_break = true; break;
  98. }
  99. }
  100. }
  101. //虚拟订单超期未支付系统自动关闭
  102. $_break = false;
  103. $model_vr_order = Model('vr_order');
  104. $logic_vr_order = Logic('vr_order');
  105. $condition = array();
  106. $condition['order_state'] = ORDER_STATE_NEW;
  107. $condition['add_time'] = array('lt',TIMESTAMP - ORDER_AUTO_CANCEL_DAY * self::EXE_TIMES);
  108. //分批,每批处理100个订单,最多处理5W个订单
  109. for ($i = 0; $i < 500; $i++){
  110. if ($_break) {
  111. break;
  112. }
  113. $order_list = $model_vr_order->getOrderList($condition, '', '*', '',100);
  114. if (empty($order_list)) break;
  115. foreach ($order_list as $order_info) {
  116. $result = $logic_vr_order->changeOrderStateCancel($order_info,'system','超期未支付系统自动关闭订单',false);
  117. }
  118. if (!$result['state']) {
  119. $this->log('虚拟订单超期未支付关闭失败SN:'.$order_info['order_sn']); $_break = true; break;
  120. }
  121. }
  122. }
  123. /**
  124. * 订单自动完成
  125. */
  126. private function _order_auto_complete() {
  127. //虚拟订单过使用期自动完成
  128. $_break = false;
  129. $model_order = Model('vr_order');
  130. $logic_order = Logic('vr_order');
  131. $condition = array();
  132. $condition['order_state'] = ORDER_STATE_PAY;
  133. $condition['vr_indate'] = array('lt',TIMESTAMP);
  134. //分批,每批处理100个订单,最多处理5W个订单
  135. for ($i = 0; $i < 500; $i++){
  136. if ($_break) {
  137. break;
  138. }
  139. $order_list = $model_order->getOrderList($condition, '', 'order_id,order_sn', 'vr_indate asc', 100);
  140. if (empty($order_list)) break;
  141. foreach ($order_list as $order_info) {
  142. $result = $logic_order->changeOrderStateSuccess($order_info['order_id']);
  143. if (!$result['state']) {
  144. $this->log('虚拟订单过使用期自动完成失败SN:'.$order_info['order_sn']); $_break = true; break;
  145. }
  146. }
  147. }
  148. //实物订单发货后,超期自动收货完成
  149. $_break = false;
  150. $model_order = Model('order');
  151. $logic_order = Logic('order');
  152. // $condition = array();
  153. // $condition['order_state'] = ORDER_STATE_SEND;
  154. // $condition['lock_state'] = 0;
  155. // $condition['delay_time'] = array('lt',TIMESTAMP - ORDER_AUTO_RECEIVE_DAY * 86400);
  156. $condition = "order_state=".ORDER_STATE_SEND." and lock_state=0 and "."delay_time<=".(TIMESTAMP - ORDER_AUTO_RECEIVE_DAY * 86400)." and delay_time>0";
  157. //分批,每批处理100个订单,最多处理5W个订单
  158. for ($i = 0; $i < 500; $i++){
  159. if ($_break) {
  160. break;
  161. }
  162. $order_list = $model_order->getOrderList($condition, '', '*', 'delay_time asc', 100);
  163. if (empty($order_list)) break;
  164. foreach ($order_list as $order_info) {
  165. $result = $logic_order->changeOrderStateReceive($order_info,'system','系统','超期未收货系统自动完成订单');
  166. if (!$result['state']) {
  167. $this->log('实物订单超期未收货自动完成订单失败SN:'.$order_info['order_sn']); $_break = true; break;
  168. }
  169. }
  170. }
  171. }
  172. /**
  173. * 自提订单中,已经关闭订单的,删除
  174. */
  175. private function _order_delivery_cancel_del() {
  176. $model_delivery = Model('delivery_order');
  177. $model_order = Model('order');
  178. for($i = 0; $i < 10; $i++) {
  179. $delivery_list = $model_delivery->getDeliveryOrderDefaultList(array(), '*', 0, 'order_id asc', 100);
  180. if (!empty($delivery_list)) {
  181. $order_ids = array();
  182. foreach ($delivery_list as $k => $v) {
  183. $order_ids[] = $v['order_id'];
  184. }
  185. $condition = array();
  186. $condition['order_state'] = ORDER_STATE_CANCEL;
  187. $condition['order_id'] = array('in',$order_ids);
  188. $order_list = $model_order->getOrderList($condition,'','order_id');
  189. if (!empty($order_list)) {
  190. $order_ids = array();
  191. foreach ($order_list as $k => $v) {
  192. $order_ids[] = $v['order_id'];
  193. }
  194. $del = $model_delivery->delDeliveryOrder(array('order_id'=>array('in',$order_ids)));
  195. if (!del) {
  196. $this->log('删除自提点订单失败');
  197. }
  198. } else {
  199. break;
  200. }
  201. } else {
  202. break;
  203. }
  204. }
  205. }
  206. /**
  207. * 更新订单扩展表中收货人所在省份ID
  208. */
  209. private function _order_reciver_provinceid_update() {
  210. $model_order = Model('order');
  211. $model_area = Model('area');
  212. //每次最多处理5W个订单
  213. $condition = array();
  214. $condition['reciver_province_id'] = 0;
  215. $condition['reciver_city_id'] = array('neq',0);
  216. for($i = 0; $i < 500; $i++) {
  217. $order_list = $model_order->getOrderCommonList($condition, 'reciver_city_id','order_id desc', 100);
  218. if (!empty($order_list)) {
  219. $city_ids = array();
  220. foreach ($order_list as $v) {
  221. if (!in_array($v['reciver_city_id'],$city_ids)) {
  222. $city_ids[] = $v['reciver_city_id'];
  223. }
  224. }
  225. $area_list = $model_area->getAreaList(array('area_id'=>array('in',$city_ids)),'area_parent_id,area_id');
  226. if (!empty($area_list)) {
  227. foreach ($area_list as $v) {
  228. $update = $model_order->editOrderCommon(array('reciver_province_id'=>$v['area_parent_id']),array('reciver_city_id'=>$v['area_id']));
  229. if (!$update) {
  230. $this->log('更新订单扩展表中收货人所在省份ID失败');break;
  231. }
  232. }
  233. }
  234. } else {
  235. break;
  236. }
  237. }
  238. }
  239. /**
  240. * 增加会员积分和经验值
  241. */
  242. private function _add_points() {
  243. return;
  244. $model_points = Model('points');
  245. $model_exppoints = Model('exppoints');
  246. //24小时之内登录的会员送积分和经验值,每次最多处理5W个会员
  247. $model_member = Model('member');
  248. $condition = array();
  249. $condition['member_login_time'] = array('gt',TIMESTAMP - self::EXE_TIMES);
  250. for($i = 0; $i < 50000; $i=$i+100) {
  251. $member_list = $model_member->getMemberList($condition, 'member_name,member_id',0,'', "{$i},100");
  252. if (!empty($member_list)) {
  253. foreach ($member_list as $member_info) {
  254. if (C('points_isuse')) {
  255. $model_points->savePointsLog('login',array('pl_memberid'=>$member_info['member_id'],'pl_membername'=>$member_info['member_name']),true);
  256. }
  257. $model_exppoints->saveExppointsLog('login',array('exp_memberid'=>$member_info['member_id'],'exp_membername'=>$member_info['member_name']),true);
  258. }
  259. } else {
  260. break;
  261. }
  262. }
  263. //24小时之内注册的会员送积分,每次最多处理5W个会员
  264. if (C('points_isuse')) {
  265. $condition = array();
  266. $condition['member_time'] = array('gt',TIMESTAMP - self::EXE_TIMES);
  267. for($i = 0; $i < 50000; $i=$i+100) {
  268. $member_list = $model_member->getMemberList($condition, 'member_name,member_id',0,'member_id desc', "{$i},100");
  269. if (!empty($member_list)) {
  270. foreach ($member_list as $member_info) {
  271. $model_points->savePointsLog('regist',array('pl_memberid'=>$member_info['member_id'],'pl_membername'=>$member_info['member_name']),true);
  272. }
  273. } else {
  274. break;
  275. }
  276. }
  277. }
  278. //24小时之内完成了实物订单送积分和经验值,每次最多处理5W个订单
  279. $model_order = Model('order');
  280. $condition = array();
  281. $condition['finnshed_time'] = array('gt',TIMESTAMP - self::EXE_TIMES);
  282. for($i = 0; $i < 50000; $i=$i+100) {
  283. $order_list = $model_order->getOrderList($condition,'','buyer_name,buyer_id,order_amount,order_sn,order_id','', "{$i},100");
  284. if (!empty($order_list)) {
  285. foreach ($order_list as $order_info) {
  286. if (C('points_isuse')) {
  287. $model_points->savePointsLog('order',array('pl_memberid'=>$order_info['buyer_id'],'pl_membername'=>$order_info['buyer_name'],'orderprice'=>$order_info['order_amount'],'order_sn'=>$order_info['order_sn'],'order_id'=>$order_info['order_id']),true);
  288. }
  289. $model_exppoints->saveExppointsLog('order',array('exp_memberid'=>$order_info['buyer_id'],'exp_membername'=>$order_info['buyer_name'],'orderprice'=>$order_info['order_amount'],'order_sn'=>$order_info['order_sn'],'order_id'=>$order_info['order_id']),true);
  290. }
  291. } else {
  292. break;
  293. }
  294. }
  295. //24小时之内完成了实物订单送积分和经验值,每次最多处理5W个订单
  296. $model_order = Model('vr_order');
  297. $condition = array();
  298. $condition['finnshed_time'] = array('gt',TIMESTAMP - self::EXE_TIMES);
  299. for($i = 0; $i < 50000; $i=$i+100) {
  300. $order_list = $model_order->getOrderList($condition,'','buyer_name,buyer_id,order_amount,order_sn,order_id','', "{$i},100");
  301. if (!empty($order_list)) {
  302. foreach ($order_list as $order_info) {
  303. if (C('points_isuse')) {
  304. $model_points->savePointsLog('order',array('pl_memberid'=>$order_info['buyer_id'],'pl_membername'=>$order_info['buyer_name'],'orderprice'=>$order_info['order_amount'],'order_sn'=>$order_info['order_sn'],'order_id'=>$order_info['order_id']),true);
  305. }
  306. $model_exppoints->saveExppointsLog('order',array('exp_memberid'=>$order_info['buyer_id'],'exp_membername'=>$order_info['buyer_name'],'orderprice'=>$order_info['order_amount'],'order_sn'=>$order_info['order_sn'],'order_id'=>$order_info['order_id']),true);
  307. }
  308. } else {
  309. break;
  310. }
  311. }
  312. }
  313. /**
  314. * 代金券即将过期提醒
  315. */
  316. private function _voucher_will_expire() {
  317. $time_start = mktime(0, 0, 0, date("m") , date("d")+self::VOUCHER_INTERVAL, date("Y"));
  318. $time_stop = $time_start + self::EXE_TIMES - 1;
  319. $where = array();
  320. $where['voucher_end_date'] = array(array('egt', $time_start), array('elt', $time_stop), 'and');
  321. $list = Model('voucher')->getVoucherUnusedList($where);
  322. if (!empty($list)) {
  323. foreach ($list as $val) {
  324. $param = array();
  325. $param['code'] = 'voucher_will_expire';
  326. $param['member_id'] = $val['voucher_owner_id'];
  327. $param['param'] = array(
  328. 'indate' => date('Y-m-d H:i:s', $val['voucher_end_date']),
  329. 'voucher_url' => urlShop('member_voucher', 'index')
  330. );
  331. QueueClient::push('sendMemberMsg', $param);
  332. }
  333. }
  334. }
  335. /**
  336. * 虚拟兑换码即将过期提醒
  337. */
  338. private function _vr_code_will_expire() {
  339. $time_start = mktime(0, 0, 0, date("m") , date("d")+self::VR_CODE_INTERVAL, date("Y"));
  340. $time_stop = $time_start + self::EXE_TIMES - 1;
  341. $where = array();
  342. $where['vr_indate'] = array(array('egt', $time_start), array('elt', $time_stop), 'and');
  343. $list = Model('vr_order')->getCodeUnusedList($where);
  344. if (!empty($list)) {
  345. foreach ($list as $val) {
  346. $param = array();
  347. $param['code'] = 'vr_code_will_expire';
  348. $param['member_id'] = $val['buyer_id'];
  349. $param['param'] = array(
  350. 'indate' => date('Y-m-d H:i:s', $val['vr_indate']),
  351. 'vr_order_url' => urlShop('member_vr_order', 'index')
  352. );
  353. QueueClient::push('sendMemberMsg', $param);
  354. }
  355. }
  356. }
  357. /**
  358. * 订单超期后不允许评价
  359. */
  360. private function _order_eval_expire_update() {
  361. //实物订单超期未评价自动更新状态,每次最多更新1000个订单
  362. $model_order = Model('order');
  363. $condition = array();
  364. $condition['order_state'] = ORDER_STATE_SUCCESS;
  365. $condition['evaluation_state'] = 0;
  366. $condition['finnshed_time'] = array('lt',TIMESTAMP - self::ORDER_EVALUATE_TIME);
  367. $update = array();
  368. $update['evaluation_state'] = 2;
  369. $update = $model_order->editOrder($update,$condition,1000);
  370. if (!$update) {
  371. $this->log('更新实物订单超期不能评价失败'); return;
  372. }
  373. //虚拟订单超期未评价自动更新状态,每次最多更新1000个订单
  374. $model_order = Model('vr_order');
  375. $condition = array();
  376. $condition['order_state'] = ORDER_STATE_SUCCESS;
  377. $condition['evaluation_state'] = 0;
  378. $condition['use_state'] = 1;
  379. $condition['finnshed_time'] = array('lt',TIMESTAMP - self::ORDER_EVALUATE_TIME);
  380. $update = array();
  381. $update['evaluation_state'] = 2;
  382. $update = $model_order->editOrder($update,$condition,1000);
  383. if (!$update) {
  384. $this->log('更新虚拟订单超期不能评价失败'); return;
  385. }
  386. }
  387. /**
  388. * 更新商品访问量(redis)
  389. */
  390. private function _goods_click_update() {
  391. $data = rcache('updateRedisDate', 'goodsClick');
  392. foreach ($data as $key => $val) {
  393. Model('goods')->editGoodsById(array('goods_click' => array('exp', 'goods_click +'.$val)), $key);
  394. }
  395. dcache('updateRedisDate', 'goodsClick');
  396. }
  397. /**
  398. * 更新商品促销到期状态(目前只有满即送)
  399. */
  400. private function _goods_promotion_state_update() {
  401. //满即送过期
  402. Model('p_mansong')->editExpireMansong();
  403. }
  404. /**
  405. * 商品到货通知提醒
  406. */
  407. private function _arrival_notice() {
  408. $strat_time = strtotime("-30 day"); // 只通知最近30天的记录
  409. $model_arrtivalnotice = Model('arrival_notice');
  410. // 删除30天之前的记录
  411. $model_arrtivalnotice->delArrivalNotice(array('an_addtime' => array('lt', $strat_time), 'an_type' => 1));
  412. $count = $model_arrtivalnotice->getArrivalNoticeCount(array());
  413. $times = ceil($count/self::ARRIVAL_NOTICE_NUM);
  414. if ($times == 0) return false;
  415. for ($i = 0; $i <= $times; $i++) {
  416. $notice_list = $model_arrtivalnotice->getArrivalNoticeList(array(), '*', $i.','.self::ARRIVAL_NOTICE_NUM);
  417. if (empty($notice_list)) continue;
  418. // 查询商品是否已经上架
  419. $goodsid_array = array();
  420. foreach ($notice_list as $val) {
  421. $goodsid_array[] = $val['goods_id'];
  422. }
  423. $goodsid_array = array_unique($goodsid_array);
  424. $goods_list = Model('goods')->getGoodsOnlineList(array('goods_id' => array('in', $goodsid_array), 'goods_storage' => array('gt', 0)), 'goods_id');
  425. if (empty($goods_list)) continue;
  426. // 需要通知到货的商品
  427. $goodsid_array = array();
  428. foreach ($goods_list as $val) {
  429. $goodsid_array[] = $val['goods_id'];
  430. }
  431. // 根据商品id重新查询需要通知的列表
  432. $notice_list = $model_arrtivalnotice->getArrivalNoticeList(array('goods_id' => array('in', $goodsid_array)), '*');
  433. if (empty($notice_list)) continue;
  434. foreach ($notice_list as $val) {
  435. $param = array();
  436. $param['code'] = 'arrival_notice';
  437. $param['member_id'] = $val['member_id'];
  438. $param['param'] = array(
  439. 'goods_name' => $val['goods_name'],
  440. 'goods_url' => urlShop('goods', 'index', array('goods_id' => $val['goods_id']))
  441. );
  442. $param['number'] = array('mobile' => $val['an_mobile'], 'email' => $val['an_email']);
  443. QueueClient::push('sendMemberMsg', $param);
  444. }
  445. // 清楚发送成功的数据
  446. $model_arrtivalnotice->delArrivalNotice(array('goods_id' => array('in', $goodsid_array)));
  447. }
  448. }
  449. /**
  450. * 将缓存中的浏览记录存入数据库中,并删除30天前的浏览历史
  451. */
  452. private function _goods_browse_update(){
  453. $model = Model('goods_browse');
  454. //将cache中的记录存入数据库
  455. if (C('cache_open')){//如果浏览记录已经存入了缓存中,则将其整理到数据库中
  456. //上次更新缓存的时间
  457. $latest_record = $model->getGoodsbrowseOne(array(),'','browsetime desc');
  458. $starttime = ($t = intval($latest_record['browsetime']))?$t:0;
  459. $monthago = strtotime(date('Y-m-d',time())) - 86400*30;
  460. $model_member = Model('member');
  461. //查询会员信息总条数
  462. $countnum = $model_member->getMemberCount(array());
  463. $eachnum = 100;
  464. for ($i=0; $i<$countnum; $i+=$eachnum){//每次查询100条
  465. $member_list = $model_member->getMemberList(array(), '*', 0, 'member_id asc', "$i,$eachnum");
  466. foreach ((array)$member_list as $k=>$v){
  467. $insert_arr = array();
  468. $goodsid_arr = array();
  469. //生成缓存的键值
  470. $hash_key = $v['member_id'];
  471. $browse_goodsid = rcache($hash_key,'goodsbrowse','goodsid');
  472. if ($browse_goodsid) {
  473. //删除缓存中多余的浏览历史记录,仅保留最近的30条浏览历史,先取出最近30条浏览历史的商品ID
  474. $cachegoodsid_arr = $browse_goodsid['goodsid']?unserialize($browse_goodsid['goodsid']):array();
  475. unset($browse_goodsid['goodsid']);
  476. if ($cachegoodsid_arr){
  477. $cachegoodsid_arr = array_slice($cachegoodsid_arr,-30,30,true);
  478. }
  479. //处理存入数据库的浏览历史缓存信息
  480. $_cache = rcache($hash_key, 'goodsbrowse');
  481. foreach((array)$_cache as $c_k=>$c_v){
  482. $c_v = unserialize($c_v);
  483. if ($c_v['browsetime'] >= $starttime){//如果 缓存中的数据未更新到数据库中(即添加时间大于上次更新到数据库中的数据时间)则将数据更新到数据库中
  484. $tmp_arr = array();
  485. $tmp_arr['goods_id'] = $c_v['goods_id'];
  486. $tmp_arr['member_id'] = $v['member_id'];
  487. $tmp_arr['browsetime'] = $c_v['browsetime'];
  488. $tmp_arr['gc_id'] = $c_v['gc_id'];
  489. $tmp_arr['gc_id_1'] = $c_v['gc_id_1'];
  490. $tmp_arr['gc_id_2'] = $c_v['gc_id_2'];
  491. $tmp_arr['gc_id_3'] = $c_v['gc_id_3'];
  492. $insert_arr[] = $tmp_arr;
  493. $goodsid_arr[] = $c_v['goods_id'];
  494. }
  495. //除了最近的30条浏览历史之外多余的浏览历史记录或者30天之前的浏览历史从缓存中删除
  496. if (!in_array($c_v['goods_id'], $cachegoodsid_arr) || $c_v['browsetime'] < $monthago){
  497. unset($_cache[$c_k]);
  498. }
  499. }
  500. //删除已经存在的该商品浏览记录
  501. if ($goodsid_arr){
  502. $model->delGoodsbrowse(array('member_id'=>$v['member_id'],'goods_id'=>array('in',$goodsid_arr)));
  503. }
  504. //将缓存中的浏览历史存入数据库
  505. if ($insert_arr){
  506. $model->addGoodsbrowseAll($insert_arr);
  507. }
  508. //重新赋值浏览历史缓存
  509. dcache($hash_key, 'goodsbrowse');
  510. $_cache['goodsid'] = serialize($cachegoodsid_arr);
  511. wcache($hash_key,$_cache,'goodsbrowse');
  512. }
  513. }
  514. }
  515. }
  516. //删除30天前的浏览历史
  517. $model->delGoodsbrowse(array('browsetime'=>array('lt',$monthago)));
  518. }
  519. /**
  520. * 缓存订单及订单商品相关数据
  521. */
  522. private function _order_goods_cache(){
  523. $model = Model('stat');
  524. //查询最后统计的记录
  525. $latest_record = $model->table('stat_ordergoods')->order('stat_updatetime desc,rec_id desc')->find();
  526. $stime = 0;
  527. if ($latest_record){
  528. $start_time = strtotime(date('Y-m-d',$latest_record['stat_updatetime']));
  529. } else {
  530. $start_time = strtotime(date('Y-m-d',strtotime(C('setup_date'))));//从系统的安装时间开始统计
  531. }
  532. for ($stime = $start_time; $stime < time(); $stime = $stime+86400){
  533. $etime = $stime + 86400 - 1;
  534. //避免重复统计,开始时间必须大于最后一条记录的记录时间
  535. $search_stime = $latest_record['stat_updatetime'] > $stime?$latest_record['stat_updatetime']:$stime;
  536. //统计一天的数据,如果结束时间大于当前时间,则结束时间为当前时间,避免因为查询时间的延迟造成数据遗落
  537. $search_etime = ($t = ($stime + 86400 - 1)) > time() ? time() : ($stime + 86400 - 1);
  538. //查询时间段内新订单或者更新过的订单,在缓存表中需要将新订单和更新过的订单进行重新缓存
  539. $where = array();
  540. $where['log_time'] = array('between',array($search_stime,$search_etime));
  541. //查询记录总条数
  542. $countnum_arr = $model->table('order_log')->field('COUNT(DISTINCT order_id) as countnum')->where($where)->find();
  543. $countnum = intval($countnum_arr['countnum']);
  544. for ($i=0; $i<$countnum; $i+=100){//每次查询100条
  545. $orderlog_list = array();
  546. $orderlog_list = $model->table('order_log')->field('DISTINCT order_id')->where($where)->limit($i.',100')->select();
  547. if ($orderlog_list){
  548. //店铺ID数组
  549. $storeid_arr = array();
  550. //商品ID数组
  551. $goodsid_arr = array();
  552. //商品公共表ID数组
  553. $goods_commonid_arr = array();
  554. //订单ID数组
  555. $orderid_arr = array();
  556. //整理需要缓存的订单ID
  557. foreach ((array)$orderlog_list as $k=>$v){
  558. $orderid_arr[] = $v['order_id'];
  559. }
  560. unset($orderlog_list);
  561. //查询订单数据
  562. $field = 'order_id,order_sn,store_id,buyer_id,buyer_name,add_time,payment_code,order_amount,shipping_fee,evaluation_state,order_state,refund_state,refund_amount,order_from';
  563. $order_list_tmp = $model->table('order')->field($field)->where(array('order_id'=>array('in',$orderid_arr)))->select();
  564. $order_list = array();
  565. foreach ((array)$order_list_tmp as $k=>$v){
  566. //判读订单是否计入统计(在线支付订单已支付或者经过退款的取消订单或者货到付款订单订单已成功)
  567. $v['order_isvalid'] = 0;
  568. if ($v['payment_code'] != 'offline' && $v['order_state'] != ORDER_STATE_NEW && $v['order_state'] != ORDER_STATE_CANCEL){//在线支付并且已支付并且未取消
  569. $v['order_isvalid'] = 1;
  570. } elseif ($v['order_state'] == ORDER_STATE_CANCEL && $v['refund_state'] != 0) {//经过退款的取消订单
  571. $v['order_isvalid'] = 1;
  572. } elseif ($v['payment_code'] == 'offline' && $v['order_state'] == ORDER_STATE_SUCCESS) {//货到付款订单,订单成功之后才计入统计
  573. $v['order_isvalid'] = 1;
  574. }
  575. $order_list[$v['order_id']] = $v;
  576. $storeid_arr[] = $v['store_id'];
  577. }
  578. unset($order_list_tmp);
  579. //查询订单扩展数据
  580. $field = 'order_id,reciver_province_id';
  581. $order_common_list_tmp = $model->table('order_common')->field($field)->where(array('order_id'=>array('in',$orderid_arr)))->select();
  582. $order_common_list = array();
  583. foreach ((array)$order_common_list_tmp as $k=>$v){
  584. $order_common_list[$v['order_id']] = $v;
  585. }
  586. unset($order_common_list_tmp);
  587. //查询店铺信息
  588. $field = 'store_id,store_name,grade_id,sc_id';
  589. $store_list_tmp = $model->table('store')->field($field)->where(array('store_id'=>array('in',$storeid_arr)))->select();
  590. $store_list = array();
  591. foreach ((array)$store_list_tmp as $k=>$v){
  592. $store_list[$v['store_id']] = $v;
  593. }
  594. unset($store_list_tmp);
  595. //查询订单商品
  596. $field = 'rec_id,order_id,goods_id,goods_name,goods_price,goods_num,goods_image,goods_pay_price,store_id,buyer_id,goods_type,promotions_id,commis_rate,gc_id';
  597. $ordergoods_list = $model->table('order_goods')->field($field)->where(array('order_id'=>array('in',$orderid_arr)))->select();
  598. foreach ((array)$ordergoods_list as $k=>$v){
  599. $goodsid_arr[] = $v['goods_id'];
  600. }
  601. //查询商品信息
  602. $field = 'goods_id,goods_commonid,goods_price,goods_serial,gc_id,gc_id_1,gc_id_2,gc_id_3,goods_image';
  603. $goods_list_tmp = $model->table('goods')->field($field)->where(array('goods_id'=>array('in',$goodsid_arr)))->select();
  604. foreach ((array)$goods_list_tmp as $k=>$v){
  605. $goods_commonid_arr[] = $v['goods_commonid'];
  606. }
  607. //查询商品公共信息
  608. $field = 'goods_commonid,goods_name,brand_id,brand_name';
  609. $goods_common_list_tmp = $model->table('goods_common')->field($field)->where(array('goods_commonid'=>array('in',$goods_commonid_arr)))->select();
  610. $goods_common_list = array();
  611. foreach ((array)$goods_common_list_tmp as $k=>$v){
  612. $goods_common_list[$v['goods_commonid']] = $v;
  613. }
  614. unset($goods_common_list_tmp);
  615. //处理商品数组
  616. $goods_list = array();
  617. foreach ((array)$goods_list_tmp as $k=>$v){
  618. $v['goods_commonname'] = $goods_common_list[$v['goods_commonid']]['goods_name'];
  619. $v['brand_id'] = $goods_common_list[$v['goods_commonid']]['brand_id'];
  620. $v['brand_name'] = $goods_common_list[$v['goods_commonid']]['brand_name'];
  621. $goods_list[$v['goods_id']] = $v;
  622. }
  623. unset($goods_list_tmp);
  624. //查询订单缓存是否存在,存在则删除
  625. $model->table('stat_ordergoods')->where(array('order_id'=>array('in',$orderid_arr)))->delete();
  626. //查询订单缓存是否存在,存在则删除
  627. $model->table('stat_order')->where(array('order_id'=>array('in',$orderid_arr)))->delete();
  628. //整理新增数据
  629. $ordergoods_insert_arr = array();
  630. foreach ((array)$ordergoods_list as $k=>$v){
  631. $tmp = array();
  632. $tmp['rec_id'] = $v['rec_id'];
  633. $tmp['stat_updatetime'] = $search_etime;
  634. $tmp['order_id'] = $v['order_id'];
  635. $tmp['order_sn'] = $order_list[$v['order_id']]['order_sn'];
  636. $tmp['order_add_time'] = $order_list[$v['order_id']]['add_time'];
  637. $tmp['payment_code'] = $order_list[$v['order_id']]['payment_code'];
  638. $tmp['order_amount'] = $order_list[$v['order_id']]['order_amount'];
  639. $tmp['shipping_fee'] = $order_list[$v['order_id']]['shipping_fee'];
  640. $tmp['evaluation_state'] = $order_list[$v['order_id']]['evaluation_state'];
  641. $tmp['order_state'] = $order_list[$v['order_id']]['order_state'];
  642. $tmp['refund_state'] = $order_list[$v['order_id']]['refund_state'];
  643. $tmp['refund_amount'] = $order_list[$v['order_id']]['refund_amount'];
  644. $tmp['order_from'] = $order_list[$v['order_id']]['order_from'];
  645. $tmp['order_isvalid'] = $order_list[$v['order_id']]['order_isvalid'];
  646. $tmp['reciver_province_id'] = $order_common_list[$v['order_id']]['reciver_province_id'];
  647. $tmp['store_id'] = $v['store_id'];
  648. $tmp['store_name'] = $store_list[$v['store_id']]['store_name'];
  649. $tmp['grade_id'] = $store_list[$v['store_id']]['grade_id'];
  650. $tmp['sc_id'] = $store_list[$v['store_id']]['sc_id'];
  651. $tmp['buyer_id'] = $order_list[$v['order_id']]['buyer_id'];
  652. $tmp['buyer_name'] = $order_list[$v['order_id']]['buyer_name'];
  653. $tmp['goods_id'] = $v['goods_id'];
  654. $tmp['goods_name'] = $v['goods_name'];
  655. $tmp['goods_commonid'] = intval($goods_list[$v['goods_id']]['goods_commonid']);
  656. $tmp['goods_commonname'] = ($t = $goods_list[$v['goods_id']]['goods_commonname'])?$t:'';
  657. $tmp['gc_id'] = intval($goods_list[$v['goods_id']]['gc_id']);
  658. $tmp['gc_parentid_1'] = intval($goods_list[$v['goods_id']]['gc_id_1']);
  659. $tmp['gc_parentid_2'] = intval($goods_list[$v['goods_id']]['gc_id_2']);
  660. $tmp['gc_parentid_3'] = intval($goods_list[$v['goods_id']]['gc_id_3']);
  661. $tmp['brand_id'] = intval($goods_list[$v['goods_id']]['brand_id']);
  662. $tmp['brand_name'] = ($t = $goods_list[$v['goods_id']]['brand_name'])?$t:'';
  663. $tmp['goods_serial'] = ($t = $goods_list[$v['goods_id']]['goods_serial'])?$t:'';
  664. $tmp['goods_price'] = $v['goods_price'];
  665. $tmp['goods_num'] = $v['goods_num'];
  666. $tmp['goods_image'] = $goods_list[$v['goods_id']]['goods_image'];
  667. $tmp['goods_pay_price'] = $v['goods_pay_price'];
  668. $tmp['goods_type'] = $v['goods_type'];
  669. $tmp['promotions_id'] = $v['promotions_id'];
  670. $tmp['commis_rate'] = $v['commis_rate'];
  671. $ordergoods_insert_arr[] = $tmp;
  672. }
  673. $model->table('stat_ordergoods')->insertAll($ordergoods_insert_arr);
  674. $order_insert_arr = array();
  675. foreach ((array)$order_list as $k=>$v){
  676. $tmp = array();
  677. $tmp['order_id'] = $v['order_id'];
  678. $tmp['order_sn'] = $v['order_sn'];
  679. $tmp['order_add_time'] = $v['add_time'];
  680. $tmp['payment_code'] = $v['payment_code'];
  681. $tmp['order_amount'] = $v['order_amount'];
  682. $tmp['shipping_fee'] = $v['shipping_fee'];
  683. $tmp['evaluation_state'] = $v['evaluation_state'];
  684. $tmp['order_state'] = $v['order_state'];
  685. $tmp['refund_state'] = $v['refund_state'];
  686. $tmp['refund_amount'] = $v['refund_amount'];
  687. $tmp['order_from'] = $v['order_from'];
  688. $tmp['order_isvalid'] = $v['order_isvalid'];
  689. $tmp['reciver_province_id'] = $order_common_list[$v['order_id']]['reciver_province_id'];
  690. $tmp['store_id'] = $v['store_id'];
  691. $tmp['store_name'] = $store_list[$v['store_id']]['store_name'];
  692. $tmp['grade_id'] = $store_list[$v['store_id']]['grade_id'];
  693. $tmp['sc_id'] = $store_list[$v['store_id']]['sc_id'];
  694. $tmp['buyer_id'] = $v['buyer_id'];
  695. $tmp['buyer_name'] = $v['buyer_name'];
  696. $order_insert_arr[] = $tmp;
  697. }
  698. $model->table('stat_order')->insertAll($order_insert_arr);
  699. }
  700. }
  701. }
  702. }
  703. /**
  704. * 会员相关数据统计
  705. */
  706. private function _member_stat(){
  707. $model = Model('stat');
  708. //查询最后统计的记录
  709. $latest_record = $model->getOneStatmember(array(), '', 'statm_id desc');
  710. $stime = 0;
  711. if ($latest_record){
  712. $start_time = strtotime(date('Y-m-d',$latest_record['statm_updatetime']));
  713. } else {
  714. $start_time = strtotime(date('Y-m-d',strtotime(C('setup_date'))));//从系统的安装时间开始统计
  715. }
  716. $j = 1;
  717. for ($stime = $start_time; $stime < time(); $stime = $stime+86400){
  718. //数据库更新数据数组
  719. $insert_arr = array();
  720. $update_arr = array();
  721. $etime = $stime + 86400 - 1;
  722. //避免重复统计,开始时间必须大于最后一条记录的记录时间
  723. $search_stime = $latest_record['statm_updatetime'] > $stime?$latest_record['statm_updatetime']:$stime;
  724. //统计一天的数据,如果结束时间大于当前时间,则结束时间为当前时间,避免因为查询时间的延迟造成数据遗落
  725. $search_etime = ($t = ($stime + 86400 - 1)) > time() ? time() : ($stime + 86400 - 1);
  726. //统计订单下单量和下单金额
  727. $field = ' order.order_id,add_time,buyer_id,buyer_name,order_amount';
  728. $where = array();
  729. $where['order.order_state'] = array('neq',ORDER_STATE_NEW);//去除未支付订单
  730. $where['order.refund_state'] = array('exp',"!(order.order_state = '".ORDER_STATE_CANCEL."' and order.refund_state = 0)");//没有参与退款的取消订单,不记录到统计中
  731. $where['order_log.log_time'] = array('between',array($search_stime,$search_etime));//按照订单付款的操作时间统计
  732. //货到付款当交易成功进入统计,非货到付款当付款后进入统计
  733. $where['payment_code'] = array('exp',"(order.payment_code='offline' and order_log.log_orderstate = '".ORDER_STATE_SUCCESS."') or (order.payment_code<>'offline' and order_log.log_orderstate = '".ORDER_STATE_PAY."' )");
  734. $orderlist_tmp = $model->statByOrderLog($where, $field, 0, 0, 'order_id');//此处由于底层的限制,仅能查询1000条,如果日下单量大于1000,则需要limit的支持
  735. $order_list = array();
  736. $orderid_list = array();
  737. foreach ((array)$orderlist_tmp as $k=>$v){
  738. $addtime = strtotime(date('Y-m-d',$v['add_time']));
  739. if ($addtime != $stime){//订单如果隔天支付的话,需要进行统计数据更新
  740. $update_arr[$addtime][$v['buyer_id']]['statm_membername'] = $v['buyer_name'];
  741. $update_arr[$addtime][$v['buyer_id']]['statm_ordernum'] = intval($update_arr[$addtime][$v['buyer_id']]['statm_ordernum'])+1;
  742. $update_arr[$addtime][$v['buyer_id']]['statm_orderamount'] = floatval($update_arr[$addtime][$v['buyer_id']]['statm_orderamount']) + (($t = floatval($v['order_amount'])) > 0?$t:0);
  743. } else {
  744. $order_list[$v['buyer_id']]['buyer_name'] = $v['buyer_name'];
  745. $order_list[$v['buyer_id']]['ordernum'] = intval($order_list[$v['buyer_id']]['ordernum']) + 1;
  746. $order_list[$v['buyer_id']]['orderamount'] = floatval($order_list[$v['buyer_id']]['orderamount']) + (($t = floatval($v['order_amount'])) > 0?$t:0);
  747. }
  748. //记录订单ID数组
  749. $orderid_list[] = $v['order_id'];
  750. }
  751. //统计下单商品件数
  752. if ($orderid_list){
  753. $field = ' add_time,order.buyer_id,order.buyer_name,goods_num ';
  754. $where = array();
  755. $where['order.order_id'] = array('in',$orderid_list);
  756. $ordergoods_tmp = $model->statByOrderGoods($where, $field, 0, 0, 'order.order_id');
  757. $ordergoods_list = array();
  758. foreach ((array)$ordergoods_tmp as $k=>$v){
  759. $addtime = strtotime(date('Y-m-d',$v['add_time']));
  760. if ($addtime != $stime){//订单如果隔天支付的话,需要进行统计数据更新
  761. $update_arr[$addtime][$v['buyer_id']]['statm_goodsnum'] = intval($update_arr[$addtime][$v['buyer_id']]['statm_goodsnum']) + (($t = floatval($v['goods_num'])) > 0?$t:0);
  762. } else {
  763. $ordergoods_list[$v['buyer_id']]['goodsnum'] = $ordergoods_list[$v['buyer_id']]['goodsnum'] + (($t = floatval($v['goods_num'])) > 0?$t:0);
  764. }
  765. }
  766. }
  767. //统计的预存款记录
  768. $field = ' lg_member_id,lg_member_name,SUM(IF(lg_av_amount>=0,lg_av_amount,0)) as predincrease, SUM(IF(lg_av_amount<=0,lg_av_amount,0)) as predreduce ';
  769. $where = array();
  770. $where['lg_add_time'] = array('between',array($stime,$etime));
  771. $predeposit_tmp = $model->getPredepositInfo($where, $field, 0, 'lg_member_id', 0, 'lg_member_id');
  772. $predeposit_list = array();
  773. foreach ((array)$predeposit_tmp as $k=>$v){
  774. $predeposit_list[$v['lg_member_id']] = $v;
  775. }
  776. //统计的积分记录
  777. $field = ' pl_memberid,pl_membername,SUM(IF(pl_points>=0,pl_points,0)) as pointsincrease, SUM(IF(pl_points<=0,pl_points,0)) as pointsreduce ';
  778. $where = array();
  779. $where['pl_addtime'] = array('between',array($stime,$etime));
  780. $points_tmp = $model->statByPointslog($where, $field, 0, 0, '', 'pl_memberid');
  781. $points_list = array();
  782. foreach ((array)$points_tmp as $k=>$v){
  783. $points_list[$v['pl_memberid']] = $v;
  784. }
  785. //处理需要更新的数据
  786. foreach ((array)$update_arr as $k=>$v){
  787. foreach ($v as $m_k=>$m_v){
  788. //查询记录是否存在
  789. $statmember_info = $model->getOneStatmember(array('statm_time'=>$k,'statm_memberid'=>$m_k));
  790. if ($statmember_info){
  791. $m_v['statm_ordernum'] = intval($statmember_info['statm_ordernum']) + $m_v['statm_ordernum'];
  792. $m_v['statm_orderamount'] = floatval($statmember_info['statm_ordernum']) + $m_v['statm_orderamount'];
  793. $m_v['statm_updatetime'] = $search_etime;
  794. $model->updateStatmember(array('statm_time'=>$k,'statm_memberid'=>$m_k),$m_v);
  795. } else {
  796. $tmp = array();
  797. $tmp['statm_memberid'] = $m_k;
  798. $tmp['statm_membername'] = $m_v['statm_membername'];
  799. $tmp['statm_time'] = $k;
  800. $tmp['statm_updatetime'] = $search_etime;
  801. $tmp['statm_ordernum'] = ($t = intval($m_v['statm_ordernum'])) > 0?$t:0;
  802. $tmp['statm_orderamount'] = ($t = floatval($m_v['statm_orderamount']))>0?$t:0;
  803. $tmp['statm_goodsnum'] = ($t = intval($m_v['statm_goodsnum']))?$t:0;
  804. $tmp['statm_predincrease'] = 0;
  805. $tmp['statm_predreduce'] = 0;
  806. $tmp['statm_pointsincrease'] = 0;
  807. $tmp['statm_pointsreduce'] = 0;
  808. $insert_arr[] = $tmp;
  809. }
  810. unset($statmember_info);
  811. }
  812. }
  813. //处理获得所有会员ID数组
  814. $memberidarr_order = $order_list?array_keys($order_list):array();
  815. $memberidarr_ordergoods = $ordergoods_list?array_keys($ordergoods_list):array();
  816. $memberidarr_predeposit = $predeposit_list?array_keys($predeposit_list):array();
  817. $memberidarr_points = $points_list?array_keys($points_list):array();
  818. $memberid_arr = array_merge($memberidarr_order,$memberidarr_ordergoods,$memberidarr_predeposit,$memberidarr_points);
  819. //查询会员信息
  820. $memberid_list = Model('member')->getMemberList(array('member_id'=>array('in',$memberid_arr)), '', 0);
  821. //查询记录是否存在
  822. $statmemberlist_tmp = $model->statByStatmember(array('statm_time'=>$stime));
  823. $statmemberlist = array();
  824. foreach ((array)$statmemberlist_tmp as $k=>$v){
  825. $statmemberlist[$v['statm_memberid']] = $v;
  826. }
  827. foreach ((array)$memberid_list as $k=>$v){
  828. $tmp = array();
  829. $tmp['statm_memberid'] = $v['member_id'];
  830. $tmp['statm_membername'] = $v['member_name'];
  831. $tmp['statm_time'] = $stime;
  832. $tmp['statm_updatetime'] = $search_etime;
  833. //因为记录可能已经存在,所以加上之前的统计记录
  834. $tmp['statm_ordernum'] = intval($statmemberlist[$tmp['statm_memberid']]['statm_ordernum']) + (($t = intval($order_list[$tmp['statm_memberid']]['ordernum'])) > 0?$t:0);
  835. $tmp['statm_orderamount'] = floatval($statmemberlist[$tmp['statm_memberid']]['statm_orderamount']) + (($t = floatval($order_list[$tmp['statm_memberid']]['orderamount']))>0?$t:0);
  836. $tmp['statm_goodsnum'] = intval($statmemberlist[$tmp['statm_memberid']]['statm_goodsnum']) + (($t = intval($ordergoods_list[$tmp['statm_memberid']]['goodsnum']))?$t:0);
  837. $tmp['statm_predincrease'] = (($t = floatval($predeposit_list[$tmp['statm_memberid']]['predincrease']))?$t:0);
  838. $tmp['statm_predreduce'] = (($t = floatval($predeposit_list[$tmp['statm_memberid']]['predreduce']))?$t:0);
  839. $tmp['statm_pointsincrease'] = (($t = intval($points_list[$tmp['statm_memberid']]['pointsincrease']))?$t:0);
  840. $tmp['statm_pointsreduce'] = (($t = intval($points_list[$tmp['statm_memberid']]['pointsreduce']))?$t:0);
  841. $insert_arr[] = $tmp;
  842. }
  843. //删除旧的统计数据
  844. $model->delByStatmember(array('statm_time'=>$stime));
  845. $model->table('stat_member')->insertAll($insert_arr);
  846. }
  847. }
  848. private function bonus_expire_notify()
  849. {
  850. notify_helper::onBonusExpire(10,5);
  851. }
  852. }