mCommonID = $common_id; $this->mBatchCode = $batch_code; $this->mod_fcode = Model('goods_fcode'); $this->mMobile = $mobile; $this->mSessionID = $session_id; $this->mFUserMode = !empty($session_id); } public function grabed() { $cond = []; $cond['goods_commonid'] = $this->mCommonID; $cond['batch_code'] = $this->mBatchCode; if(empty($this->mMobile) && empty($this->mSessionID)) { return false; } elseif (empty($this->mMobile)) { $cond['session_id'] = $this->mSessionID; } elseif(empty($this->mSessionID)) { $cond['mobile'] = $this->mMobile; } else { $cond['mobile|session_id'] = ['_multi'=>true,$this->mMobile,$this->mSessionID]; } $fcode = $this->mod_fcode->getGoodsFCode($cond,true); if(empty($fcode)) { return false; } else { return $fcode; } } public function send() { $cond =['goods_commonid' => $this->mCommonID, 'batch_code' => $this->mBatchCode, 'fc_state' => 0, 'grab_state' => 0, 'session_id' => '', 'mobile' => '', 'grab_time' => 0]; $items = $this->mod_fcode->where($cond)->field('*')->order('fc_id asc')->select(); $user_mobile = $this->mMobile; foreach ($items as $item) { try { $fcid = intval($item['fc_id']); $datas = ['grab_state' => 2, 'grab_time' => time(), 'user_key' => mt_rand(1000, 9999), 'mobile' => $user_mobile, 'usable_time' => util::last_day_secs(time() + $item['usable_days'] * 86400)]; $trans = new trans_wapper($this->mod_fcode,"fcode send"); $ret = $this->mod_fcode->where(['fc_id' => $fcid,'session_id' => '','mobile' => '','grab_state' => 0])->update($datas); $rows = $this->mod_fcode->affected_rows(); $trans->commit(); if($ret && $rows > 0) { return $item['fc_code']; } } catch (Exception $ex) { $trans->rollback(); } } return false; } public function grab() { $fcode = $this->grabed(); if($fcode != false) return $fcode; while(true) { $cond = array('goods_commonid' => $this->mCommonID, 'batch_code' => $this->mBatchCode, 'fc_state' => '0', 'grab_state' => array('in', array(0,1)), 'grab_time' => array('lt',time() - self::time_out)); $fcodes = $this->mod_fcode->where($cond)->field('*')->order('fc_id asc')->limit(1)->select(array('master' => true)); if(empty($fcodes) || empty($fcodes[0])) return false; $fcode = $this->try_grab($fcodes[0]); if($fcode != false) { return $fcode; } } } public function bind($fcode) { $cond = []; $cond['goods_commonid'] = $this->mCommonID; $cond['batch_code'] = $this->mBatchCode; $cond['user_key'] = $fcode['user_key']; $cond['fc_id'] = $fcode['fc_id']; $cond['fc_state'] = $fcode['fc_state']; $cond['grab_state'] = $fcode['grab_state']; $cond['grab_time'] = $fcode['grab_time']; $cond['session_id'] = $fcode['session_id']; $cond['mobile'] = $fcode['mobile']; $datas = ['grab_state' => 2, 'user_key' => mt_rand(1000, 9999), 'usable_time' => util::last_day_secs(time() + $fcode['usable_days'] * 86400)]; if(!empty($this->mSessionID)) { $datas['session_id'] = $this->mSessionID; } if(!empty($this->mMobile)) { $datas['mobile'] = $this->mMobile; } $ret = $this->mod_fcode->where($cond)->update($datas); $affect_rows = $this->mod_fcode->affected_rows(); Log::record("fcode::grab try_grab ret={$ret} affected_rows={$affect_rows}",Log::DEBUG); if($ret != false && $affect_rows > 0) { $fcode = array_merge($fcode,$datas); return $fcode; } else { return false; } } public function change($fcode) { return $this->bind($fcode); } public function lock($pay_sn) { $fcode = $this->grabed(); if($fcode != false) return $fcode; while(true) { $cond = array('goods_commonid' => $this->mCommonID, 'batch_code' => $this->mBatchCode, 'fc_state' => '0', 'grab_state' => array('in', array(0,1)), 'grab_time' => array('lt',time() - self::time_out)); $fcodes = $this->mod_fcode->where($cond)->field('*')->order('fc_id asc')->limit(1)->select(array('master' => true)); if(empty($fcodes) || empty($fcodes[0])) return false; $fcode = $this->try_lock($fcodes[0],$pay_sn); if($fcode != false) { return $fcode; } } } public static function unlock($pay_sn) { $mod_fcode = Model('goods_fcode'); $cur_time = util::last_day_secs(time()); $ret = $mod_fcode->where(['pay_sn' => $pay_sn,'fc_state' => 3]) ->update(['fc_state' => 0,'usable_time' => array('exp', "usable_days * 86400 + {$cur_time}")]); $affect_rows = $mod_fcode->affected_rows(); if($ret != false && $affect_rows > 0) { return $affect_rows; } else { return 0; } } public static function reset($pay_sn) { $mod_fcode = Model('goods_fcode'); $ret = $mod_fcode->where(['pay_sn' => $pay_sn,'fc_state' => 3]) ->update(['fc_state' => 0, 'usable_time' => 0, 'mobile' => '', 'session_id' => '', 'grab_state' => 0, 'grab_time' => 0, 'pay_sn' => 0]); $affect_rows = $mod_fcode->affected_rows(); if($ret != false && $affect_rows > 0) { return $affect_rows; } else { return 0; } } private function try_lock($fcode,$pay_sn) { $cond = []; $cond['goods_commonid'] = $this->mCommonID; $cond['batch_code'] = $this->mBatchCode; $cond['user_key'] = $fcode['user_key']; $cond['fc_id'] = $fcode['fc_id']; $cond['fc_state'] = $fcode['fc_state']; $cond['grab_state'] = $fcode['grab_state']; $cond['grab_time'] = $fcode['grab_time']; $cond['session_id'] = $fcode['session_id']; $cond['mobile'] = $fcode['mobile']; $datas = ['grab_state' => 2, 'grab_time' => time(), 'fc_state' => 3, 'pay_sn' => $pay_sn, 'user_key' => mt_rand(1000, 9999)]; if(!empty($this->mSessionID)) { $datas['session_id'] = $this->mSessionID; } if(!empty($this->mMobile)) { $datas['mobile'] = $this->mMobile; } $ret = $this->mod_fcode->where($cond)->update($datas); $affect_rows = $this->mod_fcode->affected_rows(); Log::record("fcode::grab try_grab ret={$ret} affected_rows={$affect_rows}",Log::DEBUG); if($ret != false && $affect_rows > 0) { $fcode = array_merge($fcode,$datas); return $fcode; } else { return false; } } private function try_grab($fcode) { $cond = []; $cond['goods_commonid'] = $this->mCommonID; $cond['batch_code'] = $this->mBatchCode; $cond['user_key'] = $fcode['user_key']; $cond['fc_id'] = $fcode['fc_id']; $cond['fc_state'] = $fcode['fc_state']; $cond['grab_state'] = $fcode['grab_state']; $cond['grab_time'] = $fcode['grab_time']; $cond['session_id'] = $fcode['session_id']; $cond['mobile'] = $fcode['mobile']; if($this->mFUserMode && session_helper::logined()) { $datas = ['grab_state' => 2, 'grab_time' => time(), 'user_key' => mt_rand(1000, 9999), 'usable_time' => util::last_day_secs(time() + $fcode['usable_days'] * 86400)]; } else { $datas = ['grab_state' => 1, 'grab_time' => time()]; } if(!empty($this->mSessionID)) { $datas['session_id'] = $this->mSessionID; } if(!empty($this->mMobile)) { $datas['mobile'] = $this->mMobile; } $ret = $this->mod_fcode->where($cond)->update($datas); $affect_rows = $this->mod_fcode->affected_rows(); Log::record("fcode::grab try_grab ret={$ret} affected_rows={$affect_rows}",Log::DEBUG); if($ret != false && $affect_rows > 0) { $fcode = array_merge($fcode,$datas); return $fcode; } else { return false; } } }