load(); } private static $stInstance = null; public static function instance() { if (self::$stInstance == null) { self::$stInstance = new transfer_timeout(); } return self::$stInstance; } public function load() { $mch_checker = function ($mchid) { $item = Model()->table('merchant')->field('mchid,admin_id')->where(['mchid' => $mchid])->find(); return intval($item['admin_id']); }; $this->mMchid2Infos = []; $i = 0; while (true) { $start = $i * 1000; $items = Model()->table('merchant')->field('mchid,timeout_transfer_cfg')->order('mchid asc')->limit("{$start},1000")->select(); if(empty($items)) { return; } $i++; foreach ($items as $item) { $cfg = $item['timeout_transfer_cfg']; if(empty($cfg)) { continue; } $cfg = unserialize($cfg); if($cfg === false) { continue; } $mchid = intval($item['mchid']); $opened = intval($cfg['transfer_opened']); $tmchid = intval($cfg['transfer_mchid']); $maxtm = intval($cfg['transfer_maxtm']); if ($opened == 1 && $tmchid > 0 && $tmchid != $mchid && $maxtm > 0) { $admin_id = $mch_checker($tmchid); if ($admin_id > 0) { $this->mMchid2Infos[$mchid] = ['transfer_mchid' => $tmchid, 'admin_id' => $admin_id, 'transfer_maxtm' => $maxtm]; } } } } } private function time_out($mchid) { return $this->mMchid2Infos[$mchid]['transfer_maxtm']; } public function need_monitor($mchid) { if(array_key_exists($mchid,$this->mMchid2Infos)) { return true; } else { return false; } } public function has_tmout($mchid,$mch_order) { $need_monitor = $this->need_monitor($mchid); if(!$need_monitor) { return false; } $order_state = util::query_queue_order($mchid,$mch_order); if($order_state === false || $order_state == ORDER_STATE_TIMEOUT) { return false; } $mod_refill = Model('refill_order'); $detail = $mod_refill->get_detail($mchid, $mch_order); if(empty($detail)) { return false; } $order_state = intval($detail['order_state']); if($order_state == ORDER_STATE_HANDLED) { return false; } $order_time = intval($detail['order_time']); $tmout = $this->time_out($mchid); if (time() >= $order_time + $tmout) { return true; } else { $delta = $order_time + $tmout - time(); QueueClient::async_push("QueryMchOrderTimeout", ['mchid' => $mchid, 'mch_order' => $mch_order], $delta); return false; } } public function monitor(order $order) { $mchid = $order->mchid(); $mch_order = $order->mch_order(); $tmout = $this->time_out($mchid); QueueClient::async_push("QueryMchOrderTimeout", ['mchid' => $mchid, 'mch_order' => $mch_order], $tmout); } public function transfer_info($mchid) { if(array_key_exists($mchid,$this->mMchid2Infos)) { $transfer_cfg = $this->mMchid2Infos[$mchid]; $transfer_mchid = $transfer_cfg['transfer_mchid']; $admin_id = $transfer_cfg['admin_id']; return [$transfer_mchid,$admin_id]; } return [0,0]; } public function transfers() { return $this->mMchid2Infos; } }