util.php 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056
  1. <?php
  2. namespace refill;
  3. require_once(BASE_HELPER_PATH . '/mtopcard/mtopcard.php');
  4. require_once(BASE_HELPER_PATH . '/queue/rdispatcher.php');
  5. require_once(BASE_HELPER_PATH . '/queue/monitor.php');
  6. require_once(BASE_HELPER_PATH . '/refill/policy/rlock.php');
  7. require_once(BASE_HELPER_PATH . '/refill/EventManager.php');
  8. use queue;
  9. use mtopcard;
  10. use Log;
  11. use Exception;
  12. use Cache;
  13. use QueueClient;
  14. use refill;
  15. use trans_wapper;
  16. class util
  17. {
  18. const ThirdRefillAmount = 100;
  19. static function make_mobile()
  20. {
  21. static $prefix = ["139", "138", "137", "136", "135", "134", "159", "158", "157", "150", "151", "152",
  22. "188", "187", "182", "183", "184", "178", "130", "131", "132", "156", "155", "186", "185",
  23. "176", "133", "153", "189", "180", "181", "177"];
  24. $pos = mt_rand(0, count($prefix) - 1);
  25. $no = "{$prefix[$pos]}" . mt_rand(10000000, 99999999);
  26. return $no;
  27. }
  28. public static function can_refill($card_no, $card_type)
  29. {
  30. if ($card_type == mtopcard\SinopecCard || $card_type == mtopcard\PetroChinaCard) {
  31. $result = rcache('card_expired', '', "{$card_no}");
  32. if (empty($result)) {
  33. wcache("card_expired", [$card_no => time()], '');
  34. return [true, 0];
  35. } else {
  36. $latest = current($result);
  37. $cur = time();
  38. $success = ($cur - $latest) > 2;
  39. if ($success) {
  40. wcache("card_expired", [$card_no => time()], '');
  41. }
  42. return [$success, $latest + 2 - $cur];
  43. }
  44. } else {
  45. return [true, 0];
  46. }
  47. }
  48. public static function can_commit($card_no, $card_type)
  49. {
  50. if ($card_type == mtopcard\SinopecCard || $card_type == mtopcard\PetroChinaCard)
  51. {
  52. $result = rcache('card_expired', '', "{$card_no}");
  53. if (empty($result)) {
  54. wcache("card_expired", [$card_no => time()], '');
  55. return [true, 0];
  56. }
  57. else
  58. {
  59. $latest = current($result);
  60. $cur = time();
  61. $lowest = 30;
  62. if ($cur > $latest && ($cur - $latest) >= $lowest) {
  63. wcache("card_expired", [$card_no => time()], '');
  64. return [true, 0];
  65. } else {
  66. wcache("card_expired", [$card_no => $latest + $lowest], '');
  67. return [false, $latest + $lowest - $cur];
  68. }
  69. }
  70. }
  71. else {
  72. return [true, 0];
  73. }
  74. }
  75. static function write_card($card_no, $card_type,$bind_phone)
  76. {
  77. if(empty($bind_phone)) {
  78. return false;
  79. }
  80. if ($card_type !== mtopcard\SinopecCard && $card_type !== mtopcard\PetroChinaCard) {
  81. return false;
  82. }
  83. $mobile_types = [mtopcard\ChinaMobileCard,mtopcard\ChinaUnicomCard,mtopcard\ChinaTelecomCard];
  84. $ctype = mtopcard\simple_card_type($bind_phone);
  85. if (!in_array($ctype,$mobile_types)) {
  86. return false;
  87. }
  88. $mod_topcard = Model('topcard');
  89. $ret = $mod_topcard->get_card($card_no);
  90. if (empty($ret)) {
  91. $mod_topcard->add($card_no, $card_type, time(), $bind_phone);
  92. } else {
  93. $mod_topcard->edit($card_no,$bind_phone);
  94. }
  95. dcache($card_no, 'cardrefill-');
  96. return true;
  97. }
  98. static function read_card($card_no, $card_type = 0)
  99. {
  100. if (empty($card_no)) return false;
  101. $data = rcache($card_no, 'cardrefill-');
  102. if (empty($data)) {
  103. $mod_topcard = Model('topcard');
  104. $ret = $mod_topcard->get_card($card_no);
  105. if (empty($ret)) {
  106. if ($card_type === 0) {
  107. $card_type = mtopcard\card_type($card_no,$regin_no);
  108. }
  109. $bind_phone = util::make_mobile();
  110. $mod_topcard->add($card_no, $card_type, time(), $bind_phone);
  111. $data['bind_phone'] = $bind_phone;
  112. $data['refill_time'] = time();
  113. $data['times'] = 0;
  114. $data['black_card'] = 0;
  115. wcache($card_no, $data, 'cardrefill-');
  116. } else {
  117. $val = $ret[0];
  118. $data['bind_phone'] = $val['bind_phone'];
  119. $data['black_card'] = $val['black_card'];
  120. $data['refill_time'] = time();
  121. $data['times'] = 0;
  122. }
  123. }
  124. //之前没加black_card处理,这个字段不存在.
  125. if (!array_key_exists('black_card', $data)) {
  126. $data['black_card'] = 0;
  127. }
  128. return $data;
  129. }
  130. static function inc_card($card_no, $card_info)
  131. {
  132. $card_info['times'] += 1;
  133. $card_info['refill_time'] = time();
  134. wcache($card_no, $card_info, 'cardrefill-');
  135. }
  136. public static function del_card($card_no)
  137. {
  138. dcache($card_no, 'cardrefill-');
  139. }
  140. public static function set_black($card_no)
  141. {
  142. if (empty($card_no)) return false;
  143. $card_info = util::read_card($card_no);
  144. if (!empty($card_info)) {
  145. $card_info['black_card'] = 1;
  146. $mod_topcard = Model('topcard');
  147. $mod_topcard->table('topcard')->where(['card_no' => $card_no])->update(['black_card' => 1]);
  148. wcache($card_no, $card_info, 'cardrefill-');
  149. return true;
  150. } else {
  151. return false;
  152. }
  153. }
  154. private static function black_order($order_sn, $msg)
  155. {
  156. static $errMsgs = ["只能给主卡且卡状态正常的加油卡充值", "加油卡卡号错误或不支持"];
  157. if (empty($msg)) return false;
  158. if (in_array($msg, $errMsgs)) {
  159. $refill = Model('refill_order');
  160. $order = $refill->getOrderInfo(['order_sn' => $order_sn]);
  161. if (empty($order)) return false;
  162. $card_no = $order['card_no'];
  163. return util::set_black($card_no);
  164. }
  165. }
  166. public static function black_from_log($file_name)
  167. {
  168. $fn = fopen($file_name, "r");
  169. if (empty($fn)) {
  170. Log::record("Open File {$file_name} error.", Log::ERR);
  171. return false;
  172. } else {
  173. Log::record("{$file_name} start woring", Log::DEBUG);
  174. }
  175. $errs = [];
  176. while (!feof($fn)) {
  177. $line = trim(fgets($fn));
  178. $ret = preg_match('/[\w\W]+"channelOrderNumber":"(?P<order_sn>[^"]+)"[\w\W]+"message":"(?P<message>[\x{4e00}-\x{9fa5}]+)"[\w\W]+"status":109/u', $line, $matches);
  179. if ($ret) {
  180. $order_sn = $matches['order_sn'];
  181. $message = $matches['message'];
  182. self::black_order($order_sn, $message);
  183. $errs[$message] = empty($errs[$message]) ? 1 : $errs[$message] + 1;
  184. }
  185. }
  186. foreach ($errs as $msg => $count) {
  187. Log::record("msg:{$msg} count:{$count}", Log::DEBUG);
  188. }
  189. fclose($fn);
  190. return true;
  191. }
  192. public static function async_add($params, $period = 10)
  193. {
  194. try {
  195. QueueClient::async_push("AysncAddDispatcher", ['method' => 'add', 'params' => $params], $period);
  196. return true;
  197. } catch (Exception $ex) {
  198. return false;
  199. }
  200. }
  201. public static function async_notify($chname,$data, $period)
  202. {
  203. try {
  204. QueueClient::async_push("AysncAddDispatcher", ['method' => 'notify', 'params' => ['channel' => $chname, 'params' => $data]], $period);
  205. return true;
  206. } catch (Exception $ex) {
  207. return false;
  208. }
  209. }
  210. public static function push_add($params)
  211. {
  212. try
  213. {
  214. $ret = self::push_queue('add', $params);
  215. return $ret !== false;
  216. }
  217. catch (Exception $ex) {
  218. return false;
  219. }
  220. }
  221. public static function push_add_zero($params)
  222. {
  223. try
  224. {
  225. $ret = self::push_queue('add_zero', $params);
  226. return $ret !== false;
  227. }
  228. catch (Exception $ex) {
  229. return false;
  230. }
  231. }
  232. public static function push_addthird($params)
  233. {
  234. try
  235. {
  236. $ret = self::push_queue('addthird', $params);
  237. return $ret !== false;
  238. }
  239. catch (Exception $ex) {
  240. return false;
  241. }
  242. }
  243. public static function push_notify($chname, $params)
  244. {
  245. try
  246. {
  247. $ret = self::push_queue('notify', ['channel' => $chname, 'params' => $params]);
  248. return $ret !== false;
  249. }
  250. catch (Exception $ex) {
  251. return false;
  252. }
  253. }
  254. public static function push_notify_merchant($order_id, $manual)
  255. {
  256. try
  257. {
  258. $ret = self::push_queue('notify_mechant', ['order_id' => $order_id, 'manual' => $manual]);
  259. return $ret !== false;
  260. }
  261. catch (Exception $ex) {
  262. return false;
  263. }
  264. }
  265. public static function push_query($order_id)
  266. {
  267. try
  268. {
  269. $ret = self::push_queue('query', ['order_id' => $order_id]);
  270. return $ret !== false;
  271. }
  272. catch (Exception $ex) {
  273. return false;
  274. }
  275. }
  276. public static function push_auto_query($order_id,$query_times)
  277. {
  278. try
  279. {
  280. $ret = self::push_queue('query_auto', ['order_id' => $order_id,'query_times' => $query_times]);
  281. return $ret !== false;
  282. }
  283. catch (Exception $ex) {
  284. return false;
  285. }
  286. }
  287. public static function push_query_net($order_id)
  288. {
  289. try {
  290. $ret = self::push_queue('query_net', ['order_id' => $order_id]);
  291. return $ret !== false;
  292. }
  293. catch (Exception $ex) {
  294. return false;
  295. }
  296. }
  297. public static function manual_success($order_id)
  298. {
  299. try
  300. {
  301. $ret = self::push_queue('manual_success', ['order_id' => $order_id]);
  302. return $ret !== false;
  303. }
  304. catch (Exception $ex) {
  305. return false;
  306. }
  307. }
  308. public static function manual_cancel($order_id)
  309. {
  310. try
  311. {
  312. $ret = self::push_queue('manual_cancel', ['order_id' => $order_id]);
  313. return $ret !== false;
  314. }
  315. catch (Exception $ex) {
  316. return false;
  317. }
  318. }
  319. public static function push_queue($method, $value)
  320. {
  321. if (defined('USE_COROUTINE') && USE_COROUTINE && defined('COROUTINE_HOOK_TCP') && COROUTINE_HOOK_TCP) {
  322. $queue_name = 'QUEUE_DISPATCHER_CO';
  323. $ins = Cache::getInstance('cacheredis');
  324. return $ins->lpush($queue_name, serialize([$method => $value]));
  325. }
  326. else {
  327. return queue\DispatcherClient::instance()->push($method,$value);
  328. }
  329. }
  330. public static function dispatcher_queue_length()
  331. {
  332. $ins = Cache::getInstance('cacheredis');
  333. return $ins->lLen('QUEUE_DISPATCHER_CO');
  334. }
  335. public static function monitor_queue_length()
  336. {
  337. $ins = Cache::getInstance('cacheredis');
  338. return $ins->lLen('REFILL_MONITOR_QUEUE');
  339. }
  340. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  341. public static function monitor_submit($mchid, $spec, $card_type, $mch_amount, $time)
  342. {
  343. $time = intval($time);
  344. queue\MonitorClient::instance()->onSubmit($mchid,$time,$spec,$card_type,$mch_amount);
  345. }
  346. public static function monitor_callback($mchid,$spec,$card_type,$mch_amount,$channel_amount,$succ,$time)
  347. {
  348. queue\MonitorClient::instance()->onCallback($mchid,$time,$spec,$card_type,floatval($mch_amount),floatval($channel_amount),$succ);
  349. }
  350. public static function monitor_netchk($chname,$succ)
  351. {
  352. queue\MonitorClient::instance()->onNetCheck($chname, time(),$succ);
  353. }
  354. public static function monitor_commit($chname, $spec, $card_type, $channel_amount,$commit_time)
  355. {
  356. queue\MonitorClient::instance()->onCommit($chname, $commit_time, $spec, $card_type, $channel_amount);
  357. }
  358. public static function monitor_notify($chname, $spec, $card_type, $channel_amount, $period, $succ,$commit_time,$mch_amount)
  359. {
  360. if ($succ) {
  361. $mch_amount = floatval($mch_amount);
  362. } else {
  363. $mch_amount = 0;
  364. }
  365. queue\MonitorClient::instance()->onNotify($chname, $commit_time, $spec, $card_type, floatval($channel_amount), $period, $succ,$mch_amount);
  366. }
  367. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  368. public static function onEventBeforeSubmit(order $order) : bool
  369. {
  370. Log::record("onEvent before submit {$order->unique_id()}",Log::DEBUG);
  371. return EventManager::instance()->onBeforeSubmit($order);
  372. }
  373. public static function onEventSubmit(order $order)
  374. {
  375. Log::record("onEvent submit {$order->unique_id()}",Log::DEBUG);
  376. EventManager::instance()->onSubmit($order);
  377. }
  378. public static function onEventBeforeCommit(order $order, $ch_name): bool
  379. {
  380. Log::record("onEvent before commit uid={$order->unique_id()} channel=$ch_name", Log::DEBUG);
  381. return EventManager::instance()->onBeforeCommit($order,$ch_name);
  382. }
  383. public static function onEventCommit(order $order, $ch_name)
  384. {
  385. Log::record("onEvent commit uid={$order->unique_id()} channel=$ch_name", Log::DEBUG);
  386. EventManager::instance()->onCommit($order,$ch_name);
  387. }
  388. public static function onEventNeterror(order $order, $ch_name)
  389. {
  390. Log::record("onEvent neterror uid={$order->unique_id()} channel=$ch_name", Log::DEBUG);
  391. EventManager::instance()->onNeterror($order,$ch_name);
  392. }
  393. public static function onEventNotify($refill_info, $order_info, $success)
  394. {
  395. $uid = "{$refill_info['mchid']}-{$refill_info['mch_order']}";
  396. $ch_name = $refill_info['channel_name'];
  397. Log::record("onEvent notify uid=$uid channel=$ch_name success=$success", Log::DEBUG);
  398. EventManager::instance()->onNotify($refill_info, $order_info, $success);
  399. }
  400. public static function onEventComplete($refill_info, $order_info, $success)
  401. {
  402. $uid = "{$refill_info['mchid']}-{$refill_info['mch_order']}";
  403. $ch_name = $refill_info['channel_name'];
  404. Log::record("onEvent complete uid=$uid channel=$ch_name success=$success", Log::DEBUG);
  405. EventManager::instance()->onComplete($refill_info, $order_info, $success);
  406. }
  407. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  408. public static function set_order_channels($mchid,$mchorder,$datas)
  409. {
  410. $ins = Cache::getInstance('cacheredis');
  411. $name = 'order_channels';
  412. $key = "{$mchid}-{$mchorder}";
  413. $ins->hset($name, '', [$key => serialize($datas)]);
  414. }
  415. public static function get_order_channels($mchid, $mchorder)
  416. {
  417. //old-name oil_exclude_channels
  418. $ins = Cache::getInstance('cacheredis');
  419. $name = 'order_channels';
  420. $key = "{$mchid}-{$mchorder}";
  421. $chnames = $ins->hget($name, '', $key);
  422. $chnames = unserialize($chnames);
  423. if(is_array($chnames)) {
  424. return $chnames;
  425. } else {
  426. return [];
  427. }
  428. }
  429. public static function del_order_channels($mchid, $mchorder)
  430. {
  431. $ins = Cache::getInstance('cacheredis');
  432. $name = 'order_channels';
  433. $key = "{$mchid}-{$mchorder}";
  434. $ins->hdel($name, '', $key);
  435. }
  436. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  437. public static function set_cancel_order($mchid,$mch_order)
  438. {
  439. $ins = Cache::getInstance('cacheredis');
  440. $name = 'order_cancel_hash';
  441. $key = "{$mchid}-{$mch_order}";
  442. $ins->hset($name, '', [$key=> 1]);
  443. }
  444. public static function query_cancel_order($mchid,$mch_order)
  445. {
  446. $ins = Cache::getInstance('cacheredis');
  447. $name = 'order_cancel_hash';
  448. $key = "{$mchid}-{$mch_order}";
  449. $value = $ins->hget($name,'',$key);
  450. return $value;
  451. }
  452. public static function del_cancel_order($mchid,$mch_order)
  453. {
  454. $ins = Cache::getInstance('cacheredis');
  455. $name = 'order_cancel_hash';
  456. $key = "{$mchid}-{$mch_order}";
  457. $ins->hdel($name, $key);
  458. }
  459. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  460. public static function set_next_order($mchid,$mch_order)
  461. {
  462. $ins = Cache::getInstance('cacheredis');
  463. $name = 'order_next_hash';
  464. $key = "{$mchid}-{$mch_order}";
  465. $ins->hset($name, '', [$key=> 1]);
  466. }
  467. public static function query_next_order($mchid,$mch_order)
  468. {
  469. $ins = Cache::getInstance('cacheredis');
  470. $name = 'order_next_hash';
  471. $key = "{$mchid}-{$mch_order}";
  472. $value = $ins->hget($name,'',$key);
  473. return $value;
  474. }
  475. public static function del_next_order($mchid,$mch_order)
  476. {
  477. $ins = Cache::getInstance('cacheredis');
  478. $name = 'order_success_hash';
  479. $key = "{$mchid}-{$mch_order}";
  480. $ins->hdel($name, $key);
  481. }
  482. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  483. public static function merchant_debt_stoped($mchid)
  484. {
  485. if($mchid > 0)
  486. {
  487. $ret = rcache('merchant-debt-judge', 'refill-',"{$mchid}");
  488. if(empty($ret)) {
  489. return false;
  490. }
  491. $stoped = intval($ret[$mchid]);
  492. return ($stoped === 1);
  493. }
  494. else {
  495. return false;
  496. }
  497. }
  498. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  499. public static function loop_order_inc($card_no, $spec)
  500. {
  501. if(defined('COMPANY_NAME') && in_array(COMPANY_NAME,['ZY_COMPANY']))
  502. {
  503. $ins = Cache::getInstance('cacheredis');
  504. $name = 'loop_order_check_query';
  505. $key = "{$card_no}-{$spec}";
  506. $count = $ins->hget($name, '', $key);
  507. $count = intval($count);
  508. if($count < 0) {
  509. $ins->hset($name, '', [$key => 0]);
  510. return false;
  511. }
  512. elseif($count === 0) {
  513. $ins->hIncrBy($name, $key, 1);
  514. return false;
  515. }
  516. else {
  517. $ins->hIncrBy($name, $key, 1);
  518. return true;
  519. }
  520. }
  521. else {
  522. return false;
  523. }
  524. }
  525. public static function loop_order_dec($card_no, $spec)
  526. {
  527. if (defined('COMPANY_NAME') && in_array(COMPANY_NAME, ['ZY_COMPANY'])) {
  528. $ins = Cache::getInstance('cacheredis');
  529. $name = 'loop_order_check_query';
  530. $spec = intval($spec);
  531. $key = "{$card_no}-{$spec}";
  532. $ins->hIncrBy($name, $key, -1);
  533. }
  534. }
  535. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  536. public static function push_queue_order($mchid,$mch_order,$order_state)
  537. {
  538. if(empty($mch_order)) return;
  539. $ins = Cache::getInstance('cacheredis');
  540. $name = 'merchant_order_query';
  541. $key = "{$mchid}-{$mch_order}";
  542. $ins->hset($name, '', [$key => $order_state]);
  543. }
  544. public static function del_queue_order($mchid,$mch_order)
  545. {
  546. if(empty($mch_order)) return;
  547. $ins = Cache::getInstance('cacheredis');
  548. $name = 'merchant_order_query';
  549. $key = "{$mchid}-{$mch_order}";
  550. $ret = $ins->hdel($name, '', $key);
  551. }
  552. public static function pop_queue_order($mchid,$mch_order,$order_time = 0)
  553. {
  554. util::del_order_channels($mchid,$mch_order);
  555. Model('refill_order')->partition(util::part_refill($order_time))->edit_detail($mchid,$mch_order,['order_state' => ORDER_STATE_HANDLED]);
  556. $ins = Cache::getInstance('cacheredis');
  557. $name = 'merchant_order_query';
  558. $key = "{$mchid}-{$mch_order}";
  559. $ret = $ins->hdel($name, '', $key);
  560. }
  561. public static function query_queue_order($mchid,$mch_order)
  562. {
  563. $ins = Cache::getInstance('cacheredis');
  564. $name = 'merchant_order_query';
  565. $key = "{$mchid}-{$mch_order}";
  566. $value = $ins->hget($name,'',$key);
  567. return $value;
  568. }
  569. public static function need_check($net_errno)
  570. {
  571. if(empty($net_errno)) return false;
  572. [$type,$code] = explode('-',$net_errno);
  573. $code = intval($code);
  574. if($type == "CURL") {
  575. static $errors = [CURLE_GOT_NOTHING,CURLE_RECV_ERROR];
  576. return in_array($code,$errors);
  577. } elseif($type == "HTTP") {
  578. static $excludes = [404];
  579. return !in_array($code,$excludes);
  580. } else {
  581. return false;
  582. }
  583. }
  584. public static function order_errflag($net_errno) {
  585. return ($net_errno === 'ORDER_CREATE_FAIL');
  586. }
  587. public static function onOrderSuccess($refill_info,$order_info)
  588. {
  589. $data = store_member::instance()->get_member($order_info['store_id']);
  590. if(empty($data)) {
  591. Log::record("cannot find member when store_id={$order_info['store_id']}",Log::ERR);
  592. return false;
  593. }
  594. $data['order_sn'] = $refill_info['order_sn'];
  595. $data['amount'] = $refill_info['channel_amount'];
  596. $model_pd = Model('predeposit');
  597. $model_pd->changePd('order_pay',$data,true);
  598. return true;
  599. }
  600. public static function getProvider($name,$type = 'RefillPhone')
  601. {
  602. $file = BASE_HELPER_RAPI_PATH . "/$name/{$type}.php";
  603. if(!file_exists($file)){
  604. Log::record("provider api file={$file} not exist.",Log::DEBUG);
  605. return false;
  606. } else {
  607. require_once($file);
  608. Log::record("file={$file} load success.",Log::DEBUG);
  609. }
  610. $class_name = "refill\\{$name}\\{$type}";
  611. if (class_exists($class_name, false)) {
  612. $caller = new $class_name([]);
  613. return $caller;
  614. } else {
  615. $error = "Base Error: class {$class_name} isn't exists!";
  616. Log::record($error, Log::ERR);
  617. return false;
  618. }
  619. }
  620. public static function xmlToArray($xml)
  621. {
  622. $object = simplexml_load_string($xml);
  623. $val = json_decode(json_encode($object), true);
  624. $msg = json_encode($val);
  625. Log::record("xmlToArray result={$msg}", Log::DEBUG);
  626. return $val;
  627. }
  628. //for tester
  629. public static function send_normal($order_sn)
  630. {
  631. $status = mt_rand(1,100);
  632. if($status > 97) {
  633. $status = 1;
  634. } else {
  635. $status = 0;
  636. }
  637. $url = BASE_SITE_URL . "/mobile/callback/refill_baidu.php";
  638. go(function () use ($url, $status,$order_sn)
  639. {
  640. sleep(3);
  641. while (true)
  642. {
  643. $resp = http_request($url,['status' => $status,'order_sn' => $order_sn],'GET', false, [], $net_errno);
  644. if($resp == 'SUCCESS') {
  645. break;
  646. }
  647. }
  648. Log::record("resp = {$resp}",Log::DEBUG);
  649. });
  650. }
  651. public static function send_quick($order_sn)
  652. {
  653. $status = mt_rand(1,10);
  654. if($status > 3) {
  655. $status = 1;
  656. } else {
  657. $status = 0;
  658. }
  659. $url = BASE_SITE_URL . "/mobile/callback/refill_baidu.php";
  660. go(function () use ($url, $status,$order_sn)
  661. {
  662. sleep(3);
  663. while (true)
  664. {
  665. $resp = http_request($url,['status' => $status,'order_sn' => $order_sn],'GET', false, [], $net_errno);
  666. if($resp == 'SUCCESS') {
  667. break;
  668. }
  669. }
  670. Log::record("resp = {$resp}",Log::DEBUG);
  671. });
  672. }
  673. public static function retry_canceled_order($order_id, $skip)
  674. {
  675. $mod_order = Model('vr_order');
  676. $mod_refill = Model('refill_order');
  677. $order_info = $mod_order->getOrderInfo(['order_id' => $order_id]);
  678. $refill_info = $mod_refill->getOrderInfo(['order_id' => $order_id,'inner_status' => 0]);
  679. if(empty($refill_info) || empty($order_info)) {
  680. return [false,'无此订单或者订单已经重试中了...'];
  681. }
  682. $tran = new trans_wapper($mod_order,'notify change order state trans');
  683. try
  684. {
  685. $order_info = $mod_order->getOrderInfo(['order_id' => $order_id], '*', true, true);
  686. $refill_info = $mod_refill->getOrderInfo(['order_id' => $order_id, 'inner_status' => 0], '*', true, true);
  687. $order_state = intval($order_info['order_state']);
  688. if(empty($refill_info) || $refill_info['is_retrying'] == 1 || $order_state != ORDER_STATE_CANCEL) {
  689. $tran->commit();
  690. return [false,'订单已经在重试'];
  691. }
  692. $mod_refill->edit($order_id, ['is_retrying' => 1]);
  693. $tran->commit();
  694. $order = refill\order::from_db($refill_info,$order_info);
  695. $params = $order->queue_params();
  696. $params['order_time'] = time();
  697. if ($skip) {
  698. $mchid = $refill_info['mchid'];
  699. $mch_order = $refill_info['mch_order'];
  700. refill\util::set_next_order($mchid, $mch_order);
  701. }
  702. if(util::push_add($params)) {
  703. return [true,''];
  704. } else {
  705. return [false,'加入队列出错'];
  706. }
  707. }
  708. catch (Exception $ex) {
  709. $tran->rollback();
  710. Log::record($ex->getMessage(),Log::ERR);
  711. return [false,"{$ex->getMessage()}"];
  712. }
  713. }
  714. public static function transfer_success_order($order_id, $manual_recharge_amount)
  715. {
  716. $mod_order = Model('vr_order');
  717. $mod_refill = Model('refill_order');
  718. $order_info = $mod_order->getOrderInfo(['order_id' => $order_id]);
  719. $refill_info = $mod_refill->getOrderInfo(['order_id' => $order_id,'inner_status' => 0]);
  720. if(empty($refill_info) || empty($order_info)) {
  721. return [false,'无此订单'];
  722. }
  723. $tran = new trans_wapper($mod_order,'notify change order state trans');
  724. try
  725. {
  726. $order_info = $mod_order->getOrderInfo(['order_id' => $order_id], '*', true, true);
  727. $refill_info = $mod_refill->getOrderInfo(['order_id' => $order_id, 'inner_status' => 0], '*', true, true);
  728. $order_state = intval($order_info['order_state']);
  729. if(empty($refill_info) || $refill_info['is_retrying'] == 1 || $order_state != ORDER_STATE_CANCEL) {
  730. $tran->commit();
  731. return [false,'订单已经在重试'];
  732. }
  733. $mod_refill->edit($order_id, ['is_retrying' => 1]);
  734. $order = refill\order::from_db($refill_info,$order_info);
  735. $mchid = $order->mchid();
  736. [$success,$success_order_id,$errmsg] = refill\RefillFactory::instance()->success_order($order);
  737. if(!$success) {
  738. $tran->rollback();
  739. return [false, $errmsg];
  740. }
  741. $mod_refill->edit($success_order_id, ['mch_notify_state' => 1, 'mch_notify_times' => ['exp', 'mch_notify_times+1']]);
  742. $mod_refill->edit($order_id, ['is_retrying' => 0]);
  743. if($manual_recharge_amount > 0) {
  744. $mod_refill->edit($success_order_id, ['channel_amount' => $manual_recharge_amount]);
  745. }
  746. $tran->commit();
  747. return [true,''];
  748. }
  749. catch (Exception $ex) {
  750. $tran->rollback();
  751. Log::record($ex->getMessage(),Log::ERR);
  752. return [false,"{$ex->getMessage()}"];
  753. }
  754. }
  755. public static function vr_order_part()
  756. {
  757. $miner = function ($time) {
  758. return strtotime(date('Y-m-d',$time)) - 86400 * 15;
  759. };
  760. $maxer = function ($time) {
  761. return $time + 3600;
  762. };
  763. $now = time();
  764. return [['egt', $miner($now)], ['elt', $maxer($now)], 'and'];
  765. }
  766. public static function refill_order_part($order_time = 0)
  767. {
  768. $miner = function ($time) {
  769. return strtotime(date('Y-m-d',$time)) - 86400 * 15;
  770. };
  771. $maxer = function ($time) {
  772. return $time + 3600;
  773. };
  774. if($order_time == 0)
  775. {
  776. $now = time();
  777. return [['egt', $miner($now)], ['elt', $maxer($now)], 'and'];
  778. } else {
  779. return $order_time;
  780. }
  781. }
  782. private static function part_calc($time, $sub_period, $add_period)
  783. {
  784. //查询30天的订单
  785. $miner = function ($time) use($sub_period) {
  786. return strtotime(date('Y-m-d', $time)) - $sub_period;
  787. };
  788. $maxer = function ($time) use($add_period) {
  789. return $time + $add_period;
  790. };
  791. $namer = function ($time) {
  792. return 'p'.date('Ym', $time);
  793. };
  794. if (defined('DB_PARTIONED') && DB_PARTIONED)
  795. {
  796. if(is_string($time)) {
  797. $time = intval($time);
  798. }
  799. if($time == 0)
  800. {
  801. $now = time();
  802. $a = $namer($miner($now));
  803. $b = $namer($maxer($now));
  804. if($a != $b) {
  805. return [$a,$b];
  806. } else {
  807. return $a;
  808. }
  809. }
  810. else {
  811. return $namer($time);
  812. }
  813. }
  814. else {
  815. return '';
  816. }
  817. }
  818. public static function part_query($order_time = 0)
  819. {
  820. return self::part_calc($order_time, 86400 * 30, 3600);
  821. }
  822. public static function part_notify()
  823. {
  824. return self::part_calc(0, 86400 * 7, 3600);
  825. }
  826. public static function part_refill($order_time)
  827. {
  828. return self::part_calc($order_time, 86400 * 2, 3600);
  829. }
  830. public static function part_vr_order($add_time)
  831. {
  832. return self::part_calc($add_time, 86400 * 2, 3600);
  833. }
  834. public static function part_vr_order_time($order_time)
  835. {
  836. $namer = function ($time) {
  837. return 'p'.date('Ym', $time);
  838. };
  839. if (defined('DB_PARTIONED') && DB_PARTIONED)
  840. {
  841. if(is_string($order_time)) {
  842. $order_time = intval($order_time);
  843. }
  844. if ($order_time == 0) {
  845. return '';
  846. }
  847. else
  848. {
  849. $a = $namer($order_time);
  850. $b = $namer(time() + 3600); //当前时间加上一个小时误差
  851. if ($a == $b) {
  852. return $a;
  853. } else {
  854. return [$a, $b];
  855. }
  856. }
  857. }
  858. else {
  859. return '';
  860. }
  861. }
  862. public static function part_vr_create()
  863. {
  864. return self::part_calc(0, 3600, 3600);
  865. }
  866. public static function calc_part($time = 0)
  867. {
  868. return self::part_calc($time, 86400 * 15, 3600);
  869. }
  870. public static function write_ch_submit_times($chname, $fail_times, $enough_times)
  871. {
  872. $name = 'channel_submit_times_limit';
  873. $data = ["$chname" => json_encode([$fail_times, $enough_times])];
  874. wcache($name,$data,'refill-');
  875. }
  876. public static function read_ch_submit_times($chname)
  877. {
  878. $name = 'channel_submit_times_limit';
  879. $ret = rcache($name,'refill-',$chname);
  880. if(empty($ret)) {
  881. return [-1, -1];
  882. }
  883. $times = $ret[$chname];
  884. [$fail_times, $enough_times] = json_decode($times,true);
  885. return [$fail_times, $enough_times];
  886. }
  887. public static function read_ches_submit_times()
  888. {
  889. $name = 'channel_submit_times_limit';
  890. $datas = rcache($name,'refill-');
  891. if(empty($datas)) {
  892. return [-1, -1];
  893. }
  894. $ret = [];
  895. foreach ($datas as $ch_name => $times) {
  896. $ret[$ch_name] = json_decode($times, true);
  897. }
  898. return $ret;
  899. }
  900. }