util.php 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057
  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. $card_type = $order->card_type();
  371. Log::record("onEvent before submit {$order->unique_id()} card_type=$card_type",Log::DEBUG);
  372. return EventManager::instance()->onBeforeSubmit($order);
  373. }
  374. public static function onEventSubmit(order $order)
  375. {
  376. Log::record("onEvent submit {$order->unique_id()}",Log::DEBUG);
  377. EventManager::instance()->onSubmit($order);
  378. }
  379. public static function onEventBeforeCommit(order $order, $ch_name): bool
  380. {
  381. Log::record("onEvent before commit uid={$order->unique_id()} channel=$ch_name", Log::DEBUG);
  382. return EventManager::instance()->onBeforeCommit($order,$ch_name);
  383. }
  384. public static function onEventCommit(order $order, $ch_name)
  385. {
  386. Log::record("onEvent commit uid={$order->unique_id()} channel=$ch_name", Log::DEBUG);
  387. EventManager::instance()->onCommit($order,$ch_name);
  388. }
  389. public static function onEventNeterror(order $order, $ch_name)
  390. {
  391. Log::record("onEvent neterror uid={$order->unique_id()} channel=$ch_name", Log::DEBUG);
  392. EventManager::instance()->onNeterror($order,$ch_name);
  393. }
  394. public static function onEventNotify($refill_info, $order_info, $success)
  395. {
  396. $uid = "{$refill_info['mchid']}-{$refill_info['mch_order']}";
  397. $ch_name = $refill_info['channel_name'];
  398. Log::record("onEvent notify uid=$uid channel=$ch_name success=$success", Log::DEBUG);
  399. EventManager::instance()->onNotify($refill_info, $order_info, $success);
  400. }
  401. public static function onEventComplete($refill_info, $order_info, $success)
  402. {
  403. $uid = "{$refill_info['mchid']}-{$refill_info['mch_order']}";
  404. $ch_name = $refill_info['channel_name'];
  405. Log::record("onEvent complete uid=$uid channel=$ch_name success=$success", Log::DEBUG);
  406. EventManager::instance()->onComplete($refill_info, $order_info, $success);
  407. }
  408. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  409. public static function set_order_channels($mchid,$mchorder,$datas)
  410. {
  411. $ins = Cache::getInstance('cacheredis');
  412. $name = 'order_channels';
  413. $key = "{$mchid}-{$mchorder}";
  414. $ins->hset($name, '', [$key => serialize($datas)]);
  415. }
  416. public static function get_order_channels($mchid, $mchorder)
  417. {
  418. //old-name oil_exclude_channels
  419. $ins = Cache::getInstance('cacheredis');
  420. $name = 'order_channels';
  421. $key = "{$mchid}-{$mchorder}";
  422. $chnames = $ins->hget($name, '', $key);
  423. $chnames = unserialize($chnames);
  424. if(is_array($chnames)) {
  425. return $chnames;
  426. } else {
  427. return [];
  428. }
  429. }
  430. public static function del_order_channels($mchid, $mchorder)
  431. {
  432. $ins = Cache::getInstance('cacheredis');
  433. $name = 'order_channels';
  434. $key = "{$mchid}-{$mchorder}";
  435. $ins->hdel($name, '', $key);
  436. }
  437. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  438. public static function set_cancel_order($mchid,$mch_order)
  439. {
  440. $ins = Cache::getInstance('cacheredis');
  441. $name = 'order_cancel_hash';
  442. $key = "{$mchid}-{$mch_order}";
  443. $ins->hset($name, '', [$key=> 1]);
  444. }
  445. public static function query_cancel_order($mchid,$mch_order)
  446. {
  447. $ins = Cache::getInstance('cacheredis');
  448. $name = 'order_cancel_hash';
  449. $key = "{$mchid}-{$mch_order}";
  450. $value = $ins->hget($name,'',$key);
  451. return $value;
  452. }
  453. public static function del_cancel_order($mchid,$mch_order)
  454. {
  455. $ins = Cache::getInstance('cacheredis');
  456. $name = 'order_cancel_hash';
  457. $key = "{$mchid}-{$mch_order}";
  458. $ins->hdel($name, $key);
  459. }
  460. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  461. public static function set_next_order($mchid,$mch_order)
  462. {
  463. $ins = Cache::getInstance('cacheredis');
  464. $name = 'order_next_hash';
  465. $key = "{$mchid}-{$mch_order}";
  466. $ins->hset($name, '', [$key=> 1]);
  467. }
  468. public static function query_next_order($mchid,$mch_order)
  469. {
  470. $ins = Cache::getInstance('cacheredis');
  471. $name = 'order_next_hash';
  472. $key = "{$mchid}-{$mch_order}";
  473. $value = $ins->hget($name,'',$key);
  474. return $value;
  475. }
  476. public static function del_next_order($mchid,$mch_order)
  477. {
  478. $ins = Cache::getInstance('cacheredis');
  479. $name = 'order_success_hash';
  480. $key = "{$mchid}-{$mch_order}";
  481. $ins->hdel($name, $key);
  482. }
  483. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  484. public static function merchant_debt_stoped($mchid)
  485. {
  486. if($mchid > 0)
  487. {
  488. $ret = rcache('merchant-debt-judge', 'refill-',"{$mchid}");
  489. if(empty($ret)) {
  490. return false;
  491. }
  492. $stoped = intval($ret[$mchid]);
  493. return ($stoped === 1);
  494. }
  495. else {
  496. return false;
  497. }
  498. }
  499. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  500. public static function loop_order_inc($card_no, $spec)
  501. {
  502. if(defined('COMPANY_NAME') && in_array(COMPANY_NAME,['ZY_COMPANY']))
  503. {
  504. $ins = Cache::getInstance('cacheredis');
  505. $name = 'loop_order_check_query';
  506. $key = "{$card_no}-{$spec}";
  507. $count = $ins->hget($name, '', $key);
  508. $count = intval($count);
  509. if($count < 0) {
  510. $ins->hset($name, '', [$key => 0]);
  511. return false;
  512. }
  513. elseif($count === 0) {
  514. $ins->hIncrBy($name, $key, 1);
  515. return false;
  516. }
  517. else {
  518. $ins->hIncrBy($name, $key, 1);
  519. return true;
  520. }
  521. }
  522. else {
  523. return false;
  524. }
  525. }
  526. public static function loop_order_dec($card_no, $spec)
  527. {
  528. if (defined('COMPANY_NAME') && in_array(COMPANY_NAME, ['ZY_COMPANY'])) {
  529. $ins = Cache::getInstance('cacheredis');
  530. $name = 'loop_order_check_query';
  531. $spec = intval($spec);
  532. $key = "{$card_no}-{$spec}";
  533. $ins->hIncrBy($name, $key, -1);
  534. }
  535. }
  536. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  537. public static function push_queue_order($mchid,$mch_order,$order_state)
  538. {
  539. if(empty($mch_order)) return;
  540. $ins = Cache::getInstance('cacheredis');
  541. $name = 'merchant_order_query';
  542. $key = "{$mchid}-{$mch_order}";
  543. $ins->hset($name, '', [$key => $order_state]);
  544. }
  545. public static function del_queue_order($mchid,$mch_order)
  546. {
  547. if(empty($mch_order)) return;
  548. $ins = Cache::getInstance('cacheredis');
  549. $name = 'merchant_order_query';
  550. $key = "{$mchid}-{$mch_order}";
  551. $ret = $ins->hdel($name, '', $key);
  552. }
  553. public static function pop_queue_order($mchid,$mch_order,$order_time = 0)
  554. {
  555. util::del_order_channels($mchid,$mch_order);
  556. Model('refill_order')->partition(util::part_refill($order_time))->edit_detail($mchid,$mch_order,['order_state' => ORDER_STATE_HANDLED]);
  557. $ins = Cache::getInstance('cacheredis');
  558. $name = 'merchant_order_query';
  559. $key = "{$mchid}-{$mch_order}";
  560. $ret = $ins->hdel($name, '', $key);
  561. }
  562. public static function query_queue_order($mchid,$mch_order)
  563. {
  564. $ins = Cache::getInstance('cacheredis');
  565. $name = 'merchant_order_query';
  566. $key = "{$mchid}-{$mch_order}";
  567. $value = $ins->hget($name,'',$key);
  568. return $value;
  569. }
  570. public static function need_check($net_errno)
  571. {
  572. if(empty($net_errno)) return false;
  573. [$type,$code] = explode('-',$net_errno);
  574. $code = intval($code);
  575. if($type == "CURL") {
  576. static $errors = [CURLE_GOT_NOTHING,CURLE_RECV_ERROR];
  577. return in_array($code,$errors);
  578. } elseif($type == "HTTP") {
  579. static $excludes = [404];
  580. return !in_array($code,$excludes);
  581. } else {
  582. return false;
  583. }
  584. }
  585. public static function order_errflag($net_errno) {
  586. return ($net_errno === 'ORDER_CREATE_FAIL');
  587. }
  588. public static function onOrderSuccess($refill_info,$order_info)
  589. {
  590. $data = store_member::instance()->get_member($order_info['store_id']);
  591. if(empty($data)) {
  592. Log::record("cannot find member when store_id={$order_info['store_id']}",Log::ERR);
  593. return false;
  594. }
  595. $data['order_sn'] = $refill_info['order_sn'];
  596. $data['amount'] = $refill_info['channel_amount'];
  597. $model_pd = Model('predeposit');
  598. $model_pd->changePd('order_pay',$data,true);
  599. return true;
  600. }
  601. public static function getProvider($name,$type = 'RefillPhone')
  602. {
  603. $file = BASE_HELPER_RAPI_PATH . "/$name/{$type}.php";
  604. if(!file_exists($file)){
  605. Log::record("provider api file={$file} not exist.",Log::DEBUG);
  606. return false;
  607. } else {
  608. require_once($file);
  609. Log::record("file={$file} load success.",Log::DEBUG);
  610. }
  611. $class_name = "refill\\{$name}\\{$type}";
  612. if (class_exists($class_name, false)) {
  613. $caller = new $class_name([]);
  614. return $caller;
  615. } else {
  616. $error = "Base Error: class {$class_name} isn't exists!";
  617. Log::record($error, Log::ERR);
  618. return false;
  619. }
  620. }
  621. public static function xmlToArray($xml)
  622. {
  623. $object = simplexml_load_string($xml);
  624. $val = json_decode(json_encode($object), true);
  625. $msg = json_encode($val);
  626. Log::record("xmlToArray result={$msg}", Log::DEBUG);
  627. return $val;
  628. }
  629. //for tester
  630. public static function send_normal($order_sn)
  631. {
  632. $status = mt_rand(1,100);
  633. if($status > 97) {
  634. $status = 1;
  635. } else {
  636. $status = 0;
  637. }
  638. $url = BASE_SITE_URL . "/mobile/callback/refill_baidu.php";
  639. go(function () use ($url, $status,$order_sn)
  640. {
  641. sleep(3);
  642. while (true)
  643. {
  644. $resp = http_request($url,['status' => $status,'order_sn' => $order_sn],'GET', false, [], $net_errno);
  645. if($resp == 'SUCCESS') {
  646. break;
  647. }
  648. }
  649. Log::record("resp = {$resp}",Log::DEBUG);
  650. });
  651. }
  652. public static function send_quick($order_sn)
  653. {
  654. $status = mt_rand(1,10);
  655. if($status > 3) {
  656. $status = 1;
  657. } else {
  658. $status = 0;
  659. }
  660. $url = BASE_SITE_URL . "/mobile/callback/refill_baidu.php";
  661. go(function () use ($url, $status,$order_sn)
  662. {
  663. sleep(3);
  664. while (true)
  665. {
  666. $resp = http_request($url,['status' => $status,'order_sn' => $order_sn],'GET', false, [], $net_errno);
  667. if($resp == 'SUCCESS') {
  668. break;
  669. }
  670. }
  671. Log::record("resp = {$resp}",Log::DEBUG);
  672. });
  673. }
  674. public static function retry_canceled_order($order_id, $skip)
  675. {
  676. $mod_order = Model('vr_order');
  677. $mod_refill = Model('refill_order');
  678. $order_info = $mod_order->getOrderInfo(['order_id' => $order_id]);
  679. $refill_info = $mod_refill->getOrderInfo(['order_id' => $order_id,'inner_status' => 0]);
  680. if(empty($refill_info) || empty($order_info)) {
  681. return [false,'无此订单或者订单已经重试中了...'];
  682. }
  683. $tran = new trans_wapper($mod_order,'notify change order state trans');
  684. try
  685. {
  686. $order_info = $mod_order->getOrderInfo(['order_id' => $order_id], '*', true, true);
  687. $refill_info = $mod_refill->getOrderInfo(['order_id' => $order_id, 'inner_status' => 0], '*', true, true);
  688. $order_state = intval($order_info['order_state']);
  689. if(empty($refill_info) || $refill_info['is_retrying'] == 1 || $order_state != ORDER_STATE_CANCEL) {
  690. $tran->commit();
  691. return [false,'订单已经在重试'];
  692. }
  693. $mod_refill->edit($order_id, ['is_retrying' => 1]);
  694. $tran->commit();
  695. $order = refill\order::from_db($refill_info,$order_info);
  696. $params = $order->queue_params();
  697. $params['order_time'] = time();
  698. if ($skip) {
  699. $mchid = $refill_info['mchid'];
  700. $mch_order = $refill_info['mch_order'];
  701. refill\util::set_next_order($mchid, $mch_order);
  702. }
  703. if(util::push_add($params)) {
  704. return [true,''];
  705. } else {
  706. return [false,'加入队列出错'];
  707. }
  708. }
  709. catch (Exception $ex) {
  710. $tran->rollback();
  711. Log::record($ex->getMessage(),Log::ERR);
  712. return [false,"{$ex->getMessage()}"];
  713. }
  714. }
  715. public static function transfer_success_order($order_id, $manual_recharge_amount)
  716. {
  717. $mod_order = Model('vr_order');
  718. $mod_refill = Model('refill_order');
  719. $order_info = $mod_order->getOrderInfo(['order_id' => $order_id]);
  720. $refill_info = $mod_refill->getOrderInfo(['order_id' => $order_id,'inner_status' => 0]);
  721. if(empty($refill_info) || empty($order_info)) {
  722. return [false,'无此订单'];
  723. }
  724. $tran = new trans_wapper($mod_order,'notify change order state trans');
  725. try
  726. {
  727. $order_info = $mod_order->getOrderInfo(['order_id' => $order_id], '*', true, true);
  728. $refill_info = $mod_refill->getOrderInfo(['order_id' => $order_id, 'inner_status' => 0], '*', true, true);
  729. $order_state = intval($order_info['order_state']);
  730. if(empty($refill_info) || $refill_info['is_retrying'] == 1 || $order_state != ORDER_STATE_CANCEL) {
  731. $tran->commit();
  732. return [false,'订单已经在重试'];
  733. }
  734. $mod_refill->edit($order_id, ['is_retrying' => 1]);
  735. $order = refill\order::from_db($refill_info,$order_info);
  736. $mchid = $order->mchid();
  737. [$success,$success_order_id,$errmsg] = refill\RefillFactory::instance()->success_order($order);
  738. if(!$success) {
  739. $tran->rollback();
  740. return [false, $errmsg];
  741. }
  742. $mod_refill->edit($success_order_id, ['mch_notify_state' => 1, 'mch_notify_times' => ['exp', 'mch_notify_times+1']]);
  743. $mod_refill->edit($order_id, ['is_retrying' => 0]);
  744. if($manual_recharge_amount > 0) {
  745. $mod_refill->edit($success_order_id, ['channel_amount' => $manual_recharge_amount]);
  746. }
  747. $tran->commit();
  748. return [true,''];
  749. }
  750. catch (Exception $ex) {
  751. $tran->rollback();
  752. Log::record($ex->getMessage(),Log::ERR);
  753. return [false,"{$ex->getMessage()}"];
  754. }
  755. }
  756. public static function vr_order_part()
  757. {
  758. $miner = function ($time) {
  759. return strtotime(date('Y-m-d',$time)) - 86400 * 15;
  760. };
  761. $maxer = function ($time) {
  762. return $time + 3600;
  763. };
  764. $now = time();
  765. return [['egt', $miner($now)], ['elt', $maxer($now)], 'and'];
  766. }
  767. public static function refill_order_part($order_time = 0)
  768. {
  769. $miner = function ($time) {
  770. return strtotime(date('Y-m-d',$time)) - 86400 * 15;
  771. };
  772. $maxer = function ($time) {
  773. return $time + 3600;
  774. };
  775. if($order_time == 0)
  776. {
  777. $now = time();
  778. return [['egt', $miner($now)], ['elt', $maxer($now)], 'and'];
  779. } else {
  780. return $order_time;
  781. }
  782. }
  783. private static function part_calc($time, $sub_period, $add_period)
  784. {
  785. //查询30天的订单
  786. $miner = function ($time) use($sub_period) {
  787. return strtotime(date('Y-m-d', $time)) - $sub_period;
  788. };
  789. $maxer = function ($time) use($add_period) {
  790. return $time + $add_period;
  791. };
  792. $namer = function ($time) {
  793. return 'p'.date('Ym', $time);
  794. };
  795. if (defined('DB_PARTIONED') && DB_PARTIONED)
  796. {
  797. if(is_string($time)) {
  798. $time = intval($time);
  799. }
  800. if($time == 0)
  801. {
  802. $now = time();
  803. $a = $namer($miner($now));
  804. $b = $namer($maxer($now));
  805. if($a != $b) {
  806. return [$a,$b];
  807. } else {
  808. return $a;
  809. }
  810. }
  811. else {
  812. return $namer($time);
  813. }
  814. }
  815. else {
  816. return '';
  817. }
  818. }
  819. public static function part_query($order_time = 0)
  820. {
  821. return self::part_calc($order_time, 86400 * 30, 3600);
  822. }
  823. public static function part_notify()
  824. {
  825. return self::part_calc(0, 86400 * 7, 3600);
  826. }
  827. public static function part_refill($order_time)
  828. {
  829. return self::part_calc($order_time, 86400 * 2, 3600);
  830. }
  831. public static function part_vr_order($add_time)
  832. {
  833. return self::part_calc($add_time, 86400 * 2, 3600);
  834. }
  835. public static function part_vr_order_time($order_time)
  836. {
  837. $namer = function ($time) {
  838. return 'p'.date('Ym', $time);
  839. };
  840. if (defined('DB_PARTIONED') && DB_PARTIONED)
  841. {
  842. if(is_string($order_time)) {
  843. $order_time = intval($order_time);
  844. }
  845. if ($order_time == 0) {
  846. return '';
  847. }
  848. else
  849. {
  850. $a = $namer($order_time);
  851. $b = $namer(time() + 3600); //当前时间加上一个小时误差
  852. if ($a == $b) {
  853. return $a;
  854. } else {
  855. return [$a, $b];
  856. }
  857. }
  858. }
  859. else {
  860. return '';
  861. }
  862. }
  863. public static function part_vr_create()
  864. {
  865. return self::part_calc(0, 3600, 3600);
  866. }
  867. public static function calc_part($time = 0)
  868. {
  869. return self::part_calc($time, 86400 * 15, 3600);
  870. }
  871. public static function write_ch_submit_times($chname, $fail_times, $enough_times)
  872. {
  873. $name = 'channel_submit_times_limit';
  874. $data = ["$chname" => json_encode([$fail_times, $enough_times])];
  875. wcache($name,$data,'refill-');
  876. }
  877. public static function read_ch_submit_times($chname)
  878. {
  879. $name = 'channel_submit_times_limit';
  880. $ret = rcache($name,'refill-',$chname);
  881. if(empty($ret)) {
  882. return [-1, -1];
  883. }
  884. $times = $ret[$chname];
  885. [$fail_times, $enough_times] = json_decode($times,true);
  886. return [$fail_times, $enough_times];
  887. }
  888. public static function read_ches_submit_times()
  889. {
  890. $name = 'channel_submit_times_limit';
  891. $datas = rcache($name,'refill-');
  892. if(empty($datas)) {
  893. return [-1, -1];
  894. }
  895. $ret = [];
  896. foreach ($datas as $ch_name => $times) {
  897. $ret[$ch_name] = json_decode($times, true);
  898. }
  899. return $ret;
  900. }
  901. }