Browse Source

引入redis锁插件:RedLock-PHP;预选车牌功能升级;

git 5 years ago
parent
commit
07eefb107e

+ 67 - 2
Home/Lib/Action/ApiAction.class.php

@@ -35,7 +35,7 @@ class ApiAction extends Action {
 	}
 	
  
-	public  function getPlateFromRedis(  ){
+	private  function getPlateFromRedis(  ){
 		$config = parse_url(C('REDIS_DSN'));
 		$redis = new Redis();
 		$redis->connect($config["host"],$config["port"]?:6379);  
@@ -121,7 +121,36 @@ class ApiAction extends Action {
 			json_fail('Openid不存在!');
 		}
 		
+		//车牌加锁(20分钟)
+		$servers = [
+		    parse_url(C('REDIS_DSN_LOCK'),
+		];
+		$expirein = C('EXPIREIN')?:10;
+		$redLock = new \RedLock\RedLock($servers);
+		$lock = $redLock->lock($licenseplate, $expirein*60*1000, $openid);
+		if(!$lock){
+			json_fail('车牌: '.$licenseplate .' 已被占用,请更换其它号牌!');
+		}
+		//预选车牌加入临时队列
+		$key = strtoupper($licenseplate);
+		$expire_time = time()+$expirein*60;
+		$info = array(
+			'ExpireTime' => $expire_time,
+			'LicensePlate' => $licenseplate
+		);
+		$preselect_plate_queue = Redis("wjw_preselect_plate_queue","queue");		
+		$preselect_plate_queue -> add($info);
+		//返回成功信息
+		$response = array(
+		  'LicensePlate' => $licenseplate,
+		  'ExpireIn' => C('EXPIREIN'),
+		  'Timestamp' => time()
+		);
+		//删除车牌库中的当前车牌
+		$this->deletePlateFromRedis($licenseplate);
+		json_success('上报预选车牌成功',$response);
 		
+		/*
 		//从redis获取车牌
 		$key = strtoupper($licenseplate);
 		$p = Redis("wjw_plate","hash");
@@ -194,6 +223,7 @@ class ApiAction extends Action {
 				}
 			}
 		}
+		*/
 	}
 	
  
@@ -304,6 +334,7 @@ class ApiAction extends Action {
 					json_success('操作成功',$place_message);
 				}else{
 					$licenseplate = $data['LicensePlate'];
+					/*
 					//从redis获取车牌
 					$key = strtoupper($licenseplate);
 					$p = Redis("wjw_plate","hash");
@@ -326,11 +357,22 @@ class ApiAction extends Action {
 							json_fail('该车牌已被占用,请重新选牌!');
 						}
 					}
-					//检测车牌
+					*/
+					
+					//检测车牌是否有效
 					$res = $this->plate_verify($licenseplate);
 					if(!res){
 						json_fail('无效车牌,请重新选择!');
 					}
+					//检测预选车牌是否超时
+					$result = $this->checkPreSelectPlateIsTimeout($licenseplate,$data['OpenId']);
+					if($result['success'] === true){
+						json_fail($result['message']);
+					}
+					if($result['success'] === -1){
+						json_fail($result['message']);
+					}
+					
 					$cond = array(
 						'LicensePlate'=>$data['LicensePlate'],
 						'OrderStatus'=>array('neq','2')
@@ -540,5 +582,28 @@ class ApiAction extends Action {
 		}
 	}
 	
+ 
+	private  function checkPreSelectPlateIsTimeout( $plate, $openid ){
+		if(!$openid){
+			array('success'=> -1,'message'=>'openid不能为空');
+		}
+		if(!$plate){
+			array('success'=> -1,'message'=>'车牌号不能为空');
+		}
+		$server = parse_url(C('REDIS_DSN_LOCK'));
+		$redis = new \Redis();
+		$redis->connect($server["host"],$server["port"]?:6379);  
+		$redis->auth($server["pass"]?: ""); 
+		$redis->select(trim($server['path'],'//') ? : 0);
+		$old_openid = $redis->get($plate);
+		if(!$old_openid){
+			return array('success'=>true,'message'=>'预选车牌超时,请重新选择车牌');
+		}
+		if($old_openid != $openid){
+			return array('success'=>true,'message'=>'您选择的车牌已超时释放,已被其他用户占用,请选择其它车牌');
+		}
+		return array('success'=>false,'message'=>'没有超时');
+	}
+	
 
 }

+ 24 - 5
Home/Lib/Action/CronAction.class.php

@@ -8,6 +8,29 @@ class CronAction extends Action {
 
  
 	public  function releaseRedisExpiredLicenseplate(  ){
+		$start = time();
+		$preselect_plate_queue = Redis("wjw_preselect_plate_queue","queue");	
+		$plate_preselect_pool = Redis("plate_preselect_pool","set");
+		do{	
+			$info = $preselect_plate_queue -> pop();
+			if(!$info){
+				echo "no more message".PHP_EOL;
+				sleep(1);
+				continue;
+			}
+			if(!$info['LicensePlate']){
+				echo "LicensePlate empty!".PHP_EOL;
+				continue;
+			}
+			//过期预约车牌,释放到公选池
+			if(time()>$info['ExpireTime']){
+				$plate_preselect_pool -> add($info['LicensePlate']);
+				echo 'LicensePlate: '.$info['LicensePlate'].' timeout, push to plate_preselect_pool'.PHP_EOL;
+			}
+		}while(time()-$start<60);
+		
+		
+		/*
 		$config = parse_url(C('REDIS_DSN'));
 		$redis = new Redis();
 		$redis->connect($config["host"],$config["port"]?:6379);  
@@ -21,11 +44,6 @@ class CronAction extends Action {
 			if($orderstatus == NULL){
 						$time = time() - (C('EXPIREIN')*60);
 						if($time > $data['Timestamp']){
-							/*$p = Redis("wjw_plate","hash");
-							$res = $p->where($key)->delete();
-							if(!$res){
-								json_fail('删除过期车牌失败');
-							}*/
 							$result = $redis->sAdd('plate_preselect_pool' , $key);
 							if(!$result){
 								json_fail('释放过期车牌失败');
@@ -52,6 +70,7 @@ class CronAction extends Action {
 					}
 		}
 		json_success('执行完毕');
+		*/
 	}
 	
 

+ 11 - 0
Home/Lib/Action/IndexAction.class.php

@@ -11,5 +11,16 @@ class IndexAction extends Action {
 		echo 'hello world';
 	}
 	
+ 
+	public  function test(  ){
+		$servers = [
+		    parse_url(C('REDIS_DSN'),
+		];
+		
+		$redLock = new RedLock($servers);
+		$lock = $redLock->lock('QS000001', 1000, $openid);
+		var_dump($lock);
+	}
+	
 
 }

+ 2 - 1
composer.json

@@ -13,7 +13,8 @@
 		"jrtk/jr-phpcls2": "dev-master",
 		"jrtk/aliyun-ots-sdk-php":"2.1.1",
 		"jrtk/jr-ucenter-tp31": "dev-develop",
-		"jrtk/aliyun-oss-sdk-php":"dev-master"
+		"jrtk/aliyun-oss-sdk-php":"dev-master",
+		"jrtkcoder/redlock-php":"dev-master"
     },
 	"config": {
 		"secure-http": false