<?php
use QL\QueryList;
use GuzzleHttp\Client;
use Nesk\Puphpeteer\Puppeteer;
use Nesk\Rialto\Data\JsFunction;
class vinAction  extends baseAction
{
	
	//?site=xxx&vin=xxx&engine6=xxx
	function test()
	{
		$btime = microtime(true);
		$YpwBase = new YpwBase();
		$OthPdfOcr = new OthPdfOcr();
		$YpwVin = new YpwVin();
		var_dump($_GET);
		echo 'a=>', ceil((microtime(true) - $btime)*1000), 'ms<hr>';
		if(0 && $_GET['site'] == 'engine6'){
			$res = $YpwVin->catchVinQingdan($_GET['vin'], $_GET['engine6'], 0, false);
			var_dump($res);exit;
		}else{
			$res = $YpwBase->get('stand_scqd_reg', ['*'], " and reg_code='{$_GET['site']}'", true);
			$reg = $res['data'];
			$OthPdfOcr->debug = true;
			if($_GET['vin']) $reg['reg_vin_demo'] = $_GET['vin'];
			$res = $OthPdfOcr->onlyCatchVin($reg['reg_vin_demo'], $reg, false, ['sce_error'=>'#error#车辆型号无法匹配', 'engine6'=>$_GET['engine6']]);
			var_dump($res);
			echo 'b=>', ceil((microtime(true) - $btime)*1000), 'ms<hr>';
			echo 'ok';
		}
	}


	//检测随车清单的生命状态 10分钟一次
	public function checkHbqdStatus()
	{
		if(!LibFc::hasFunLock(mvc::$URL_METHOD, 60)) return true;
		set_time_limit(0);
		$Params = mvc::$URL_PARAMS;
		$YpwBase = new YpwBase();
		$YpwVin = new YpwVin();
		//VIN10对应的年份
		$res = $YpwBase->get('yp_vin_year', ['*']);
		$yearArr = array_column($res['data'], 'vin_10', 'vin_year');
		$where = isset($Params['status']) ? sprintf(" and reg_status = %d", $Params['status']): " and reg_status > -1";
		if($Params['site']) $where .= sprintf(" and reg_code = '%s'", $Params['site']);
		$res = $YpwBase->get('stand_scqd_reg', ['*'], $where." order by reg_id");
		$regArr = array_column($res['data'], null, 'reg_code');
		$OthPdfOcr = new OthPdfOcr();
		$YpcBase = new YpcBase();
		//丰田特殊，同一个文件一天最多3次
		$YpwBase->exeAnySql(["UPDATE `stand_scqd_reg` SET reg_vin_demo = (
SELECT vf_vin FROM (
SELECT vf_vin FROM `stand_vin_file`
JOIN `stand_model_any` ON sma_vin = vf_vin AND sma_gxb_code_show !='' AND sma_from = 'catch'
 WHERE vf_id > 70398032 AND vf_vin LIKE 'LFM%' AND vf_url LIKE '%tftm%' ORDER BY vf_id DESC LIMIT 1000
) t ORDER BY RAND() LIMIT 1
) WHERE reg_code = 'tftm'"]);

		foreach($regArr as $site=>$reg)
		{
			//计算余量
			$set = [];
			$checkArr = ['time'=>date('Y-m-d H:i:s')];
			$reg['reg_wmi'] = empty($reg['reg_wmi'])? []: explode(',', $reg['reg_wmi']);
			$reg['reg_check_res'] = json_decode($reg['reg_check_res'], true);
			$reg['vin10'] = [];
			if($site == 'gacfca')
			{//广汽菲克-吉普
				$reg['vin10'] = ['H'];
			}
			else
			{
				foreach($yearArr as $y=>$vn)
				{
					if($y >= $reg['reg_min_year']) $reg['vin10'][] = $vn;
				}
			}
		
			//发动机编码识别错误的重新识别
			if(!empty($reg['reg_wmi']) && $reg['reg_ocr'])
			{
				$checkArr['ocreng6'] = empty($reg['reg_check_res']['ocreng6'])? '': $reg['reg_check_res']['ocreng6'];
				if(date('H') >= 6 && (empty($checkArr['ocreng6']) || $checkArr['ocreng6'] != date('Y-m-d')))
				{
					foreach($reg['reg_wmi'] as $rwmi)
					{
						$twhere = sprintf(" and sce_etime > %d and sce_vin like '%s%%' AND sce_reg_code = 'engine6' AND sce_engine6 != '' AND sce_error LIKE '%%不符%%'", strtotime('-7 day'), $rwmi);
						if($site == 'tftm') $twhere .= " and right(left(sce_vin, 11), 1) = '0'";
						if($site == 'sftm') $twhere .= " and right(left(sce_vin, 11), 1) = 'S'";
						$YpwBase->set('stand_catch_list', ['sce_reg_code'=>$site, 'sce_status'=>0, 'sce_error'=>'#again#发动机编号与信息公开不符！', 'sce_level'=>9999, 'sce_catch_count'=>0, 'sce_etime'=>0], $twhere);
					}
					$checkArr['ocreng6'] = date('Y-m-d');
				}
			}

			//发动机编码
			if($site == 'engine6')
			{
				//$YpwBase->exeAnySql(["UPDATE stand_catch_list SET sce_level = 9999 WHERE sce_reg_code = 'engine6' AND sce_status = 0 AND sce_level < 9999 AND sce_vin  IN (SELECT vs_vin FROM yp_vin_search)"]);

				//奇瑞 一天同步一次
				$checkArr['mychery'] = empty($reg['reg_check_res']['mychery'])? '': $reg['reg_check_res']['mychery'];
				if(LibFc::hasFunLock(mvc::$URL_METHOD.'mychery', 3600) && date('H') >= 6 && (empty($checkArr['mychery']) || $checkArr['mychery'] != date('Y-m-d')))
				{
					$addSql = "INSERT INTO ypdb_write.stand_catch_list (sce_reg_code, sce_vin, sce_level, sce_engine6) 
						SELECT 'engine6', tq_real_vin, vin_year, RIGHT(tq_engine, 6) FROM temp_qirui 
						JOIN ypdb_write.yp_vin_year ON tq_vin_10bit = vin_10
						WHERE vin_year >=2017 AND LENGTH(tq_engine) >= 6
						and lnk_id not in ( select lnk_id from temp_qirui join ypdb_write.stand_catch_list on tq_real_vin = sce_vin 
							where RIGHT(tq_engine, 6) = sce_engine6
						)
						AND lnk_id NOT IN ( SELECT lnk_id FROM temp_qirui JOIN ypdb_write.stand_model_any ON tq_real_vin = sma_vin 
							where sma_vyear >= 2017 AND (sma_from IN ('catch') or RIGHT(tq_engine, 6) = RIGHT(sma_engine6, 6))
						)";
					$YpcBase->query($addSql);
					$checkArr['mychery'] = date('Y-m-d');
					LibFc::delFunLock(mvc::$URL_METHOD.'mychery');
				}
				
				//宝沃
				$checkArr['borgward'] = empty($reg['reg_check_res']['borgward'])? '': $reg['reg_check_res']['borgward'];
				if(LibFc::hasFunLock(mvc::$URL_METHOD.'borgward', 3600) && date('H') >= 6 && (empty($checkArr['borgward']) || $checkArr['borgward'] != date('Y-m-d')))
				{
					$addSql = "INSERT INTO ypdb_write.stand_catch_list (sce_reg_code, sce_vin, sce_level, sce_engine6) 
						SELECT 'engine6', lnk_vin, vin_year, RIGHT(lnk_engineCode, 6) FROM temp_borgward 
						JOIN ypdb_write.yp_vin_year ON LEFT(lnk_vin_10_11, 1) = vin_10
						WHERE vin_year >=2017 AND LENGTH(lnk_engineCode) >= 6
						and lnk_id not in ( select lnk_id from temp_borgward join ypdb_write.stand_catch_list on lnk_vin = sce_vin 
							where RIGHT(lnk_engineCode, 6) = sce_engine6
						)
						AND lnk_id NOT IN ( SELECT lnk_id FROM temp_borgward  JOIN ypdb_write.stand_model_any ON lnk_vin = sma_vin 
							where sma_vyear >= 2017 AND (sma_from = 'catch' or RIGHT(lnk_engineCode, 6) = RIGHT(sma_engine6, 6))
						)";
					$YpcBase->query($addSql);
					$checkArr['borgward'] = date('Y-m-d');
					LibFc::delFunLock(mvc::$URL_METHOD.'borgward');
				}
				$checkArr['smatime'] = empty($reg['reg_check_res']['smatime'])? 0: $reg['reg_check_res']['smatime'];

				//总表
				$addSqlArr = [
					sprintf("INSERT INTO stand_catch_list (sce_reg_code, sce_vin, sce_level, sce_engine6) 
					SELECT 'engine6', sma_vin, sma_vyear, sma_engine6 FROM stand_model_any
					LEFT JOIN stand_catch_list ON sce_reg_code = 'engine6' AND sce_vin = sma_vin 
					WHERE (sce_id IS NULL or right(sma_engine6, 6) != sce_engine6) AND LENGTH(sma_engine6) > 5 AND sma_vin1_8 LIKE 'L%%' AND sma_vyear >= 2017 and sma_etime >= %d AND sma_gxb_code = ''", $checkArr['smatime']),

					sprintf("INSERT INTO stand_catch_list (sce_reg_code, sce_vin, sce_level, sce_engine6) 
					SELECT 'engine6', sma_vin, sma_vyear, sma_engine6 FROM stand_model_any
					LEFT JOIN stand_catch_list ON sce_reg_code = 'engine6' AND sce_vin = sma_vin
					WHERE (sce_id IS NULL or right(sma_engine6, 6) != sce_engine6) AND LENGTH(sma_engine6) > 5 AND sma_vin1_8 LIKE 'L%%' AND sma_vyear >= 2017 and sma_etime >= %d AND sma_year = ''", $checkArr['smatime']),

					sprintf("INSERT INTO stand_catch_list (sce_reg_code, sce_vin, sce_level, sce_engine6)
					SELECT 'engine6', sma_vin, -1, sma_engine6 FROM stand_model_any
					LEFT JOIN stand_catch_list ON sce_reg_code = 'engine6' AND sce_vin = sma_vin 
					WHERE (sce_id IS NULL OR  right(sma_engine6, 6) != sce_engine6) AND LENGTH(sma_engine6) > 5 AND sma_vin1_3 = 'LBV' AND sma_from = 'catch' AND sma_vyear >= 2017 AND LENGTH(sma_year) < 8  AND sma_engine != sma_engine6 AND sma_etime >= %d", $checkArr['smatime']),
					//LFV 发动机5位补0
					sprintf("INSERT INTO stand_catch_list (sce_reg_code, sce_vin, sce_level, sce_engine6)
					SELECT 'engine6', sma_vin, -1, CONCAT('0', sma_engine6) sma_engine6 FROM stand_model_any
					LEFT JOIN stand_catch_list ON sce_reg_code = 'engine6' AND sce_vin = sma_vin 
					WHERE (sce_id IS NULL OR  CONCAT('0', sma_engine6) != sce_engine6) AND LENGTH(sma_engine6) = 5 AND sma_vin1_3 = 'LFV' AND sma_from = 'catch' AND sma_gxb_code = '' AND sma_vyear >= 2017 AND sma_etime >= %d", $checkArr['smatime']),
					
					sprintf("INSERT INTO stand_catch_list (sce_reg_code, sce_vin, sce_level, sce_engine6) 
					SELECT 'engine6', sma_vin, sma_vyear, sma_engine6 FROM stand_model_any
					LEFT JOIN stand_catch_list ON sce_reg_code = 'engine6' AND sce_vin = sma_vin 
					WHERE (sce_id IS NULL or sma_engine6 != sce_engine6) AND LENGTH(sma_engine6) > 5 AND sma_vin1_8 LIKE 'L%%' AND sma_vyear >= 2017 and sma_etime >= %d AND sma_gxb_code != '' and sma_brand = ''", $checkArr['smatime']),
					"UPDATE stand_catch_list SET sce_status = 0 WHERE sce_reg_code='engine6' and sce_catch_count < 15 AND sce_level > 2050 AND sce_status IN (1,-1) AND sce_etime < (UNIX_TIMESTAMP(NOW()) - 600) AND sce_error NOT LIKE '%请提供%' AND sce_error NOT LIKE '%车架号前8%'",
					"UPDATE stand_catch_list SET sce_status = 0 WHERE sce_reg_code='engine6' and sce_catch_count < 10 AND sce_level > 0 AND sce_status IN (1,-1) AND sce_etime < (UNIX_TIMESTAMP(NOW()) - 3600*24) AND sce_error NOT LIKE '%请提供%' AND sce_error NOT LIKE '%车架号前8%'",
					"UPDATE `stand_catch_list` SET sce_status = -2 WHERE sce_reg_code = 'engine6' AND sce_status IN (1,0,-1) AND LENGTH(sce_engine6) < 6",
				];
				$YpwBase->exeAnySql($addSqlArr, false);
				
				$checkArr['smatime'] = time();
			}
			else if(!empty($reg['reg_wmi']) && !empty($reg['vin10']))
			{
				//将需要采集的入库
				$lastTime = empty($reg['reg_check_res']['time'])? 0: strtotime($reg['reg_check_res']['time'])-3600*24*3;
				$othwhere = '';
				$smawhere = '';
				if($site == 'wey'){
					$othwhere .= " and vs_vin like 'LGW_______H%'";
					$smawhere .= " and sma_vin like 'LGW_______H%'";
				}
				if($site == 'tftm'){
					$othwhere .= " and vs_vin like 'LFM_______0%'";
					$smawhere .= " and sma_vin like 'LFM_______0%'";
				}
				if($site == 'sftm'){
					$othwhere .= " and vs_vin like 'LFM_______S%'";
					$smawhere .= " and sma_vin like 'LFM_______S%'";
				}
				if($site == 'caky'){
					$othwhere .= " and vs_vin like 'LSC_______E%'";
					$smawhere .= " and sma_vin like 'LSC_______E%'";
				}

				$awhere = sprintf(" AND vs_vin1_3 IN ('%s') AND vs_vin10 IN ('%s') AND vs_last_time >= %d AND vs_vin9 = vs_checkcode 
					AND vs_vin NOT IN (
						SELECT sma_vin FROM stand_model_any WHERE sma_vin1_3 IN ('%s') AND sma_vin10 IN ('%s') and sma_from ='catch'
					)%s", implode("','", $reg['reg_wmi']), implode("','", $reg['vin10']), $lastTime, implode("','", $reg['reg_wmi']), implode("','", $reg['vin10']), $othwhere);
				$res = $YpwBase->get('yp_vin_search join yp_vin_year on vs_vin10 = vin_10', ['vs_vin sce_vin', 'vin_year sce_level'], $awhere);
				$YpwVin->addCatchList($site, $res['data']);
				
				//600万非采集 泽达的重新采集
				$awhere = sprintf(" and sma_vin1_3 IN ('%s') AND sma_vin10 IN ('%s') and sma_etime >=%d AND sma_from != 'catch' %s", implode("','", $reg['reg_wmi']), implode("','", $reg['vin10']), $lastTime, $smawhere);
				$res = $YpwBase->get('stand_model_any', ['sma_vin sce_vin', 'sma_vyear sce_level'], $awhere);
				$YpwVin->addCatchList($site, $res['data']);
			}

			$cwhereArr = [
				sprintf(" and sce_reg_code='%s' and sce_status = 0", $site),
				sprintf(" and sce_reg_code='%s' and sce_status = 1 and sce_catch_count < 5", $site)
			];
			$set['reg_waitcount'] = 0;
			foreach($cwhereArr as $cwhere)
			{
				$vinres = $YpwBase->get('stand_catch_list', ['count(*) as count'], $cwhere, true);
				$set['reg_waitcount'] += $vinres['data']['count'];
			}
			$regetCount = false;

			//追加任务
			$tper = 1000;
			$acount = 100000;
			if($site == 'ZDAPI' && $set['reg_waitcount'] < $acount)
			{
				/*$atable = "stand_catch_jsvin
						JOIN stand_vin_zdapireg ON scl_scode = vzr_code AND vzr_status = 1
						LEFT JOIN stand_catch_list ON sce_vin = scl_vin AND sce_reg_code = scl_reg_code
						LEFT JOIN stand_model_any ON  scl_vin = sma_vin AND (sma_from = 'catch' or (sma_from = 'epc' and sma_year != ''))";*/
				$atable = "stand_catch_jsvin
					JOIN stand_vin_zdapireg ON scl_scode = vzr_code AND vzr_status = 1";
				$awehre = sprintf(" and scl_reg_code = '%s' order by scl_year desc limit %d", $site, $tper);
				for($page = 1; $page <= ceil($acount/$tper); $page++)
				{
					$res = $YpwBase->get($atable, ["'{$site}' as sce_reg_code, scl_vin as sce_vin, scl_year-2000 as sce_level"], $awehre);
					if(empty($res['data'])) break;
					$addArr = $res['data'];
					$YpwBase->addAny('stand_catch_list', array_keys($addArr[0]), $addArr);
						
					$adel = sprintf(" and scl_reg_code='%s' and scl_vin in ('%s')", $site, implode("','", array_column($addArr, 'sce_vin')));
					$YpwBase->Del('stand_catch_jsvin', $adel);
				}
				$regetCount = true;
			}
			else if($reg['reg_jsvin'] && $set['reg_waitcount'] < $acount)
			{
				$awehre = sprintf(" and scl_reg_code = '%s' order by scl_year desc limit %d", $site, $tper);
				for($page = 1; $page <= ceil($acount/$tper); $page++)
				{
					$res = $YpwBase->get('stand_catch_jsvin', ["'{$site}' as sce_reg_code, scl_vin as sce_vin, scl_year-2000 as sce_level"], $awehre);
					if(empty($res['data'])) break;
					$addArr = $res['data'];
					$YpwBase->addAny('stand_catch_list', array_keys($addArr[0]), $addArr);
						
					$adel = sprintf(" and scl_reg_code='%s' and scl_vin in ('%s')", $site, implode("','", array_column($addArr, 'sce_vin')));
					$YpwBase->Del('stand_catch_jsvin', $adel);
				}
				$regetCount = true;
			}
			
			if($site == 'changan'){
				$adel = sprintf(" and sce_reg_code='%s' AND sce_status in (0,-1,1) AND sce_vin IN (SELECT sma_vin FROM stand_model_any WHERE sma_vin1_3 IN ('%s') AND sma_from IN ('catch', 'epc'))", $site, implode("','", $reg['reg_wmi']));
				$YpwBase->Del('stand_catch_list', $adel);
			}

			if($regetCount)
			{
				$set['reg_waitcount'] = 0;
				foreach($cwhereArr as $cwhere)
				{
					$vinres = $YpwBase->get('stand_catch_list', ['count(*) as count'], $cwhere, true);
					$set['reg_waitcount'] += $vinres['data']['count'];
				}
			}
			
			if($reg['reg_autochk']){//自动检测
				if($site == 'engine6'){
					$LibYpApi = new LibYpApi();
					$res = $LibYpApi->Get('vin/catchVinQingdan', ['vin'=>'LGWDB3172KB001643', 'engine6'=>'XX1238', 'usecache'=>-1], [], true);
					if($res['status'])
					{
						$checkArr['sma'] = $res['data'];
					}
					else
					{
						$checkArr['error'] = '出错了'.$res['data'];
					}
				}else if(!empty($reg['reg_url'])){
					$res = $OthPdfOcr->onlyCatchVin($reg['reg_vin_demo'], $reg, false);
					$checkArr = array_merge($checkArr, $res['data']);
				}
				
				if(!empty($checkArr['error'])) $checkArr['error'] = substr($checkArr['error'], 0, 2000);
				$set['reg_check_res'] = json_encode($checkArr, JSON_UNESCAPED_UNICODE);

				if((empty($reg['reg_url']) && empty($checkArr['error'])) || $checkArr['error'] == 'only_download' || (!empty($checkArr['sma']) && (!empty($checkArr['sma']['sma_gxb_code_show']) || !empty($checkArr['sma']['sma_engine6'])))){
					$set['reg_status'] = 1;
				}else{
					$set['reg_status'] = 0;
				}
			}
			$YpwBase->set('stand_scqd_reg', $set, sprintf(" and reg_id='%d'", $reg['reg_id']));
		}

		$YpwBase->exeAnySql(["UPDATE `yp_paojieling`.`pl_vin_error`, `ypdb_write`.`stand_model_any`  SET ve_status = 1, ve_check = '{\"uid\":8,\"remark\":\"谢谢您的建议，已处理\",\"time\":".time()."}' WHERE ve_status = 0 AND ve_vin = sma_vin AND (sma_from IN ('catch', 'manual', 'ZDAPI') OR (sma_from != 'buy02' AND sma_engine != ''))"]);

		LibFc::delFunLock(mvc::$URL_METHOD);
		echo 'ok';
	}



	//采集环保信息随车清单  site=x0,x1 vin=xxx  status=xxx   keepRun=1表示永久执行  php index.php vin catchHuanbaoScqdVin site=engine6 keepRun=1   
	public function catchHuanbaoScqdVin()
	{
		set_time_limit(0);
		$Params = mvc::$URL_PARAMS;
		$onlyVin = $Params['vin']?? '';
		$keepRun = $Params['keepRun'] == 1 ? 1: 0;
		if(empty($Params['site'])) exit('请指定site=x0,x1');
		$siteArr = explode(",", $Params['site']);
		//采集到的文件的存储路径
		$mainPdfRoot = mvc::$cfg['HuanbaoScqdPath'];
		$YpwBase = new YpwBase();
		
		//VIN10对应的年份
		$res = $YpwBase->get('yp_vin_year', ['*']);
		$yearArr = array_column($res['data'], 'vin_10', 'vin_year');

		$LibYpApi = new LibYpApi();
		$OthPdfOcr = new OthPdfOcr();
		$YpwVin = new YpwVin();
		while(1){
			shuffle($siteArr);
			$runSite = $maxTaskSite? $maxTaskSite: $siteArr;
			$maxTaskSite = [];
			foreach($runSite as $site){
				if($site == 'engine6'){
					//工信部数据8:00~20:00
					$engine6Work = date('H') < 7 || date('H') >= 20? false: true;
					if(!$engine6Work) continue;
				}
				$res = $YpwBase->get('stand_scqd_reg', ['*'], sprintf(" and reg_code = '%s'", LibFc::Escape($site)), true);
				$reg = $res['data'];
				if(empty($reg)){
					echo $site."=>站点不存在\n";
					continue;
				}
				$site = $reg['reg_code'];
				if($reg['reg_status'] != 1){
					echo $site."=>状态=>{$reg['reg_status']}\n";
					continue;
				}else if($reg['reg_waitcount'] < 1){
					echo $site."=>无任务\n";
					continue;
				}
				$reg['reg_wmi'] = explode(',', $reg['reg_wmi']);
				$reg['vin10'] = [];
				foreach($yearArr as $y=>$vn){
					if($y >= $reg['reg_min_year']) $reg['vin10'][] = $vn;
				}
				$per = $reg['reg_per'] < 100 ? $reg['reg_per']: 100;
				$limit = $per*100;
				$runCount = 0;
				while(1){
					$errorCount = 0;
					$maxError = 20;//连续出错多少次后中断
					$res = $YpwBase->get('stand_scqd_reg', ['reg_lastid', 'reg_lasttime', 'reg_lasterror'], sprintf(" and reg_code='%s'", $site), true);
					$cacheArr = $res['data'];
					$catchVinArr = [];
					$tableArr = [];
					if(['sce_status'])
					if($onlyVin){
						$tableArr[] = sprintf("(select sce_id as kid, sce_vin as vin, sce_engine6 as engine6, sce_error, sce_url, sce_status from stand_catch_list where sce_reg_code = '%s' and sce_vin = '%s') as a", $site, $onlyVin);
					}else{
						//发动机型号特殊
						if($site == 'engine6'){
							$tableArr[] = sprintf("(select sce_id as kid, sce_vin as vin, sce_engine6 as engine6, sce_error, sce_url, sce_status from stand_catch_list where sce_reg_code = '%s' and sce_catch_count < 10 and sce_status = 0 and sce_level >= 0 order by sce_level DESC, sce_id limit %d) as a", $site, $limit);

							$tableArr[] = sprintf("(select sce_id as kid, sce_vin as vin, sce_engine6 as engine6, sce_error, sce_url, sce_status from stand_catch_list where sce_reg_code = '%s' and sce_catch_count < 10 and sce_status = 1 and sce_level >= 0 and sce_etime < %d order by sce_level DESC, sce_id limit %d) as a", $site, time()-3600, $limit);

							$tableArr[] = sprintf("(select sce_id as kid, sce_vin as vin, sce_engine6 as engine6, sce_error, sce_url, sce_status from stand_catch_list where sce_reg_code = '%s' and sce_catch_count < 10 and sce_status = 0 and sce_level < 0 order by sce_level DESC, sce_id limit %d) as a", $site, $limit);

							$tableArr[] = sprintf("(select sce_id as kid, sce_vin as vin, sce_engine6 as engine6, sce_error, sce_url, sce_status from stand_catch_list where sce_reg_code = '%s' and sce_catch_count < 10 and sce_status = 1 and sce_level < 0 and sce_etime < %d order by sce_level DESC, sce_id limit %d) as a", $site, time()-3600, $limit);
						}else if($site == 'ZDAPI'){
							$tableArr[] = sprintf("(select sce_id as kid, sce_vin as vin, sce_engine6 as engine6, sce_error, sce_url, sce_status from stand_catch_list where sce_reg_code = '%s' and sce_catch_count < 10 and sce_status = 0 limit %d) as a", $site, $limit);
						}else{
							if(isset($Params['status'])){
								$tableArr[] = sprintf("(select sce_id as kid, sce_vin as vin, sce_engine6 as engine6, sce_error, sce_url, sce_status from stand_catch_list where sce_reg_code = '%s' and sce_catch_count < 10 and sce_status = %d order by sce_level DESC, sce_id limit %d) as a", $site, $Params['status'], $limit);
							}else{
								$tableArr[] = sprintf("(select sce_id as kid, sce_vin as vin, sce_engine6 as engine6, sce_error, sce_url, sce_status from stand_catch_list where sce_reg_code = '%s' and sce_catch_count < 10 and sce_status = 0 and sce_level >= 0 order by sce_level DESC, sce_id limit %d) as a", $site, $limit);
								
								$tableArr[] = sprintf("(select sce_id as kid, sce_vin as vin, sce_engine6 as engine6, sce_error, sce_url, sce_status from stand_catch_list where sce_reg_code = '%s' and sce_catch_count < 10 and sce_status = 1 and sce_level >= 0 and sce_etime < %d order by sce_level DESC,sce_id limit %d) as a", $site, time()-3600*4, $limit);

								$tableArr[] = sprintf("(select sce_id as kid, sce_vin as vin, sce_engine6 as engine6, sce_error, sce_url, sce_status from stand_catch_list where sce_reg_code = '%s' and sce_catch_count < 10 and sce_status = 0 and sce_level < 0 order by sce_level DESC, sce_id limit %d) as a", $site, $limit);
								
								$tableArr[] = sprintf("(select sce_id as kid, sce_vin as vin, sce_engine6 as engine6, sce_error, sce_url, sce_status from stand_catch_list where sce_reg_code = '%s' and sce_catch_count < 10 and sce_status = 1 and sce_level < 0 and sce_etime < %d order by sce_level DESC,sce_id limit %d) as a", $site, time()-3600*4, $limit);
							}
						}
					}
					$where = sprintf(" order by rand() limit %d", $per);
					foreach($tableArr as $tk=>$table){
						$vinres = $YpwBase->get($table, ['*'], $where);
						$catchVinArr = array_column($vinres['data'], null, 'vin');
						if(empty($catchVinArr)) continue;
						echo $site.'=>本轮任务=>'.count($catchVinArr)."\n";
						
						if($site == 'ZDAPI'){
							$res = $YpwVin->catchAnyVinfromZdApi(array_keys($catchVinArr));
							foreach($res['data'] as $ck=>$cv){
								$catchVinArr[$ck]['catch'] = $cv;
							}
						}

						foreach($catchVinArr as $vin=>$vsv){
							$btime = microtime(true);
							if($errorCount > $maxError) break;
							$addArr = []; $error = ''; 
							if($site == 'ZDAPI')
							{
								if(!isset($vsv['catch']))
									$error = '#error#';
								else if(!empty($vsv['catch'])){
									$addArr = $vsv['catch'];
								}else{
									$error = '#end#';
								}
							}
							else
							{
								$txtRes = $OthPdfOcr->onlyCatchVin($vin, $reg, true, $vsv);
								if(!empty($txtRes['data']['sma'])) $addArr = $txtRes['data']['sma'];
								if(!empty($txtRes['data']['error'])) $error = $txtRes['data']['error'];
							}
							$runCount++;
							echo $site.'['.$runCount.']=>'.$vin.'=>'.(!empty($addArr)? 'ok': 'no').' '.ceil((microtime(true) - $btime)*1000), "ms\n";
							$cacheArr = ['reg_lastid'=>$vsv['kid'], 'reg_lasttime'=>date('m-d H:i:s'), 'reg_lasterror'=>$error];
							if(!empty($OthPdfOcr->saveConf['minpath'])){
								$saveConf = $OthPdfOcr->saveConf;
								$pdfFile = $saveConf['minpath'].$vin.'.pdf';
								$txtPdf = $saveConf['minpath'].$vin.'.txt';
								$htmlPdf = $saveConf['minpath'].$vin.'.html';
								$imgFile = $saveConf['minpath'].$vin.'.jpg';
							}

							$YpwBase->YpwDb->Begin();
							//入总表
							if(!empty($addArr) && (!empty($addArr['sma_gxb_code_show']) || !empty($addArr['sma_engine6']) || !empty($addArr['sma_id'])))
							{
								//需要处理尚未入库的
								if(empty($addArr['sma_id']))
								{
									if(!empty($addArr['sma_tran']))
									{
										$res = $YpwVin->formatTran($addArr['sma_tran']);
										if(!empty($res['data']['tran'])){
											$addArr['sma_tran'] = $res['data']['tran'];
										}else{
											$renull = ['/--'=>'', 'æå¨/5'=>'', '/不适用'=>'', '/无'=>'', '/0'=>'', '	'=>''];
											$addArr['sma_tran'] = strtr($addArr['sma_tran'], $renull);
											if($addArr['sma_tran'] == '无') unset($addArr['sma_tran']);
										}
									}

									if(!empty($addArr['sma_xuhang']))
									{
										$renull = ['/不适用'=>'', '/无'=>'', '	'=>''];
										$addArr['sma_xuhang'] = strtr($addArr['sma_xuhang'], $renull);
										if($addArr['sma_xuhang'] == '无') unset($addArr['sma_xuhang']);
									}

									$addArr['sma_vin'] = $vin;
									if(isset($addArr['sma_gxb_code_show']))
									{
										$addArr['sma_gxb_code']  = LibFc::FormatNum($addArr['sma_gxb_code_show']);
										$addArr['sma_gtype'] = LibFc::getGxbCarType($addArr['sma_gxb_code']);
									}
									$addArr['sma_vin1_3'] = substr($addArr['sma_vin'], 0, 3);
									$addArr['sma_vin1_8'] = substr($addArr['sma_vin'], 0, 8);
									$addArr['sma_vin10'] = substr($addArr['sma_vin'], 9, 1);
									$addArr['sma_vin10_12'] = substr($addArr['sma_vin'], 9, 3);
									$addArr['sma_vin13_17'] = substr($addArr['sma_vin'], 12, 5);
									$addArr['sma_vin10_11'] = substr($addArr['sma_vin'], 9, 2);
									$addArr['sma_vin12_17'] = substr($addArr['sma_vin'], 11, 6);
									$addArr['sma_etime'] = time();
									$addArr['sma_from'] = 'catch';
									$addArr['sma_vyear'] = LibFc::VinYear($addArr['sma_vin10']);

									if($site == 'ZDAPI') $addArr['sma_from'] = 'ZDAPI';

									if(!empty($addArr['sma_year']) && abs(substr($addArr['sma_year'], 0, 4) - $addArr['sma_vyear']) > 2 || substr($addArr['sma_year'], 0, 4) > date('Y'))
									{//年份数据异常 LSGJA52U18H177706
										unset($addArr['sma_year']);
									}

									if(!empty($addArr['sma_brand']))
									{
										$res = $YpwVin->getWmiReBrand($addArr['sma_vin1_3'], $addArr['sma_brand']);
										$addArr['sma_brand'] = $res['data'];
									}
									
									$res = $YpwBase->get('stand_model_any', ['*'], sprintf(" and sma_vin = '%s'", $vin), true);
									$oldArr = $res['data'];
									if(!empty($oldArr['sma_id']))
									{
										$YpwBase->set('stand_model_any', $addArr, sprintf(" and sma_vin='%s'", $addArr['sma_vin']));
									}
									else
									{
										$YpwBase->add('stand_model_any', $addArr);
									}

									$YpwBase->set('stand_vin_imgs', ['vii_status'=>1, 'vii_check_time'=>time(), 'vii_check_uid'=>8], sprintf(" and vii_status in (0,-2,-3,-5) and vii_vin ='%s'", $addArr['sma_vin']));

									//大通官方的变速箱 和 工信部的 变速箱不一致，用发动机编码重新处理一次
									if((empty($addArr['sma_gxb_code']) || empty($addArr['sma_engine']) || in_array($site, ['saicmaxus', 'volvocars'])) && strlen($addArr['sma_engine6']) > 5)
									{
										$addTask = [
											'sce_reg_code'=>'engine6',
											'sce_vin'=>$addArr['sma_vin'],
											'sce_level'=>6666,
											'sce_engine6'=>$addArr['sma_engine6']
										];
										$YpwBase->add('stand_catch_list', $addTask);
									}
								}
								
								$dellist = sprintf(" and sce_vin='%s'",$vin);
								if($site != 'engine6') $dellist .= " and sce_reg_code != 'engine6'";
								$YpwBase->del('stand_catch_list', $dellist);
								
								if(!empty($OthPdfOcr->saveConf['minpath']))
								{
									//按照pdf txt  jpg 优先级只保留一种
									if(file_exists($saveConf['save'].$pdfFile))
									{
										$YpwBase->add('stand_vin_file', ['vf_vin'=>$vin, 'vf_url'=>$saveConf['host'].$pdfFile], 'replace');
										@unlink($saveConf['save'].$txtPdf);
										@unlink($saveConf['save'].$htmlPdf);
										@unlink($saveConf['save'].$imgFile);
									}
									else if(file_exists($saveConf['save'].$txtPdf))
									{
										$YpwBase->add('stand_vin_file', ['vf_vin'=>$vin, 'vf_url'=>$saveConf['host'].$txtPdf], 'replace');
										@unlink($saveConf['save'].$htmlPdf);
										@unlink($saveConf['save'].$imgFile);
									}
									else if(file_exists($saveConf['save'].$htmlPdf))
									{
										$YpwBase->add('stand_vin_file', ['vf_vin'=>$vin, 'vf_url'=>$saveConf['host'].$htmlPdf], 'replace');
										@unlink($saveConf['save'].$imgFile);
									}
									else if(file_exists($saveConf['save'].$imgFile))
									{
										$YpwBase->add('stand_vin_file', ['vf_vin'=>$vin, 'vf_url'=>$saveConf['host'].$imgFile], 'replace');
									}
								}
								$cacheArr['reg_waitcount'] = '#@reg_waitcount-1';
								$errorCount = 0;
							}
							else
							{
								//异常的清空下载的文件，防止文件本身有问题
								$res = $YpwBase->get('stand_model_any', ['*'], sprintf(" and sma_vin = '%s'", $vin), true);
								if(empty($res['data']))
								{
									@unlink($saveConf['save'].$pdfFile);
									@unlink($saveConf['save'].$txtPdf);
									@unlink($saveConf['save'].$htmlPdf);
									@unlink($saveConf['save'].$imgFile);
								}
								if(stripos($error, 'Failed to connect') !== false || stripos($error, ' Timed out') !== false || stripos($error, 'Operation timed out') !== false){
									$error = str_replace('#error#', '#again#', $error);
								}
								if(stripos($error, '#end#') !== false)
									$sce_status = -2;
								else if(stripos($error, '#again#') !== false)
									$sce_status = 1;
								else if(stripos($error, '#error#') !== false)
									$sce_status = -1;
								else
									$sce_status = -3;

								//当前site是否存在此车架号任务
								$chkwhere = sprintf(" and sce_vin = '%s' and sce_reg_code = '%s'", $vin, $site);
								if($site == 'engine6') $chkwhere .= sprintf(" and sce_engine6 = '%s'", $vsv['engine6']);
								$res = $YpwBase->get('stand_catch_list', ['sce_id'], $chkwhere, true);
								if(!empty($res['data']))
								{
									$clset = [
										'sce_status'=>$sce_status,
										'sce_catch_count'=>'#@sce_catch_count+1',
										'sce_etime'=>time(),
										'sce_error'=>LibFc::msubstr($error, 0, 100)
									];
									$YpwBase->set('stand_catch_list', $clset, $chkwhere);
								}
								else
								{
									$clset = [
										'sce_status'=>$sce_status,
										'sce_reg_code'=>$site,
										'sce_vin'=>$vin,
										'sce_catch_count'=>1,
										'sce_etime'=>time(),
										'sce_error'=>LibFc::msubstr($error, 0, 100)
									];
									$YpwBase->add('stand_catch_list', $clset);
								}
								if(in_array($sce_status, [1,-1,-3])) $errorCount++;
							}
							$YpwBase->set('stand_scqd_reg', $cacheArr, sprintf(" and reg_code='%s'", $site));
							$YpwBase->YpwDb->End();
							
							if(in_array($sce_status, [1])){
								sleep(rand(1, 2));
							}if(in_array($site, ['engine6'])){
								usleep(100000);
							}else if($reg['reg_sleep']){
								usleep(500000);
							}
						}
						//错误次数过多进行下一个站点任务
						if($errorCount > $maxError){
							echo $site.'=>maxError=>'.$maxError."\n";
							break;
						}else if(($tk+1) == count($tableArr)){
							//长任务
							if($keepRun){
								if($runCount > 1000){
									$maxTaskSite[] = $site;
									echo $site."=>单次已执行任务".$runCount."次，换下一个站点\n";
									break;
								}else if(count($catchVinArr) < $per){
									echo $site."=>无任务\n";
									break;
								}
							}else{
								break;
							}
						}
					}
				}
			}

			if($keepRun){
				if($maxTaskSite){
					sleep(5);
				}else{
					$sleep = rand(120, 180);
					echo "无任务 sleep {$sleep}s\n";
					sleep($sleep);
				}
			}else{
				break;
			}
		}
		echo 'ok';
	}

	//计算丰田的EPC车架号
	function chkToyotaEpcVin()
	{
		if(!LibFc::hasFunLock(mvc::$URL_METHOD, 3600)) return true;
		$Ypc67Base = new BaseDb(mvc::$cfg['DB']['YPCAR67']);
		$YpwVin = new YpwVin();
		$YpwVinImg = new YpwVinImg();
		$YpcVin = new YpcVin();
		$maxcount = 4;
		$table = 'yp_model3 m3 JOIN yp_model2 ON m3_m2_id = m2_id JOIN yp_model1 ON m2_m1_id = m1_id
		LEFT JOIN yp_model3_gxb_num ON mg_m3_id = m3_id 
		LEFT JOIN yp_vin_model3_link ON vm3_m3_id = m3_id
		LEFT JOIN yp_vin ON vin_id = vm3_vin_id';
		$where = sprintf(" and m1_b_id=62 and m3_id not in (select mec_m3_id from yp_model3_etk_code where mec_epc_status in (2,3)) group by m3_id");
		//$where = ' and m3_id = 303423';
		$mres = $Ypc67Base->get($table, ['m3.*', 'GROUP_CONCAT(vin_full) vin18s', 'GROUP_CONCAT(mg_code) gxbs'], $where);
		foreach($mres['data'] as $v){
			if(empty($v['vin18s']) || empty($v['gxbs'])) continue;
			$v['vin18s'] = explode(',', $v['vin18s']);
			$v['gxbs'] = explode(',', $v['gxbs']);
			$res = $Ypc67Base->get('yp_model3_etk_code', ['mec_code', 'mec_epc_status'], sprintf(" and mec_m3_id=%d", $v['m3_id']));
			$v['etkcodes'] = [];
			$v['orgcodes'] = [];
			$v['e0'] = 0;
			foreach($res['data'] as $vv){
				$v['etkcodes'][] = $vv['mec_code'];
				if(preg_match('/^[A-Z][A-Z0-9]{3,}\-[A-Z0-9]{2,}$/i', $vv['mec_code'])){
					$v['orgcodes'][] = $vv['mec_code'];
				}else if(preg_match('/^[A-Z][A-Z0-9]{16}$/i', $vv['mec_code']) && $vv['mec_epc_status'] == 1){
					$v['e0']++;
				}
			}

			if(empty($v['orgcodes'])){
				$res = $Ypc67Base->get('yp_model3_modcode', ['mem_code'], sprintf(" and mem_m3_id=%d", $v['m3_id']));
				foreach($res['data'] as $tv){
					$tcode = explode('@', $tv['mem_code']);
					if(preg_match('/^[A-Z][A-Z0-9]{3,}\-[A-Z0-9]{2,}$/i', $tcode[0])){
						$v['orgcodes'][] = $tcode[0];
					}
				}
				//echo $v['m3_id'].'=>取原厂代码<br>';
			}
	
			if($v['e0'] >= $maxcount || empty($v['orgcodes'])) continue;
			$v['m3_zws'] = [];
			if(preg_match('/(\d*)[\-\,\/]?(\d+)?座/', $v['m3_body'], $match)){
				if($match[2]){
					for($mi = $match[1]; $mi <= $match[2]; $mi++){
						$v['m3_zws'][] = (int) $mi;
					}
				}else{
					$v['m3_zws'][] = (int) $match[1];
				}
			}
			
			$v['btime'] = 0; $v['etime'] = time();
			if(!empty($v['m3_start_month']) && !empty($v['m3_start_year'])){
				$v['btime'] = strtotime($v['m3_start_year'].'-'.$v['m3_start_month']);
			}else if(!empty($v['m3_start_year'])){
				$v['btime'] = strtotime($v['m3_start_year'].'-01');
			}
			if(!empty($v['m3_end_month']) && !empty($v['m3_end_year'])){
				$v['etime'] = strtotime('last day of '.$v['m3_end_year'].'-'.$v['m3_end_month'].' 23:59:59');
			}else if(!empty($v['m3_end_year'])){
				$v['etime'] = strtotime($v['m3_end_year'].'-12-31 23:59:59');
			}
			if($v['etime'] > time()) $v['etime'] = time();
			$v['etkvins'] = [];
			foreach($v['vin18s'] as $v18){
				foreach($v['gxbs'] as $gxb){
					foreach($v['orgcodes'] as $code){
						$swhere = sprintf(" and sma_vin1_8='%s' and sma_gxb_code='%s' and (vie_unicode='%s' OR vii_imgocr like '%%%s%%') group by sma_vin order by sma_vin10_12, sma_vin13_17", $v18, $gxb, LibFc::Escape($code), LibFc::Escape($code));
						$smafields = ['sma_vin,sma_vin1_8,sma_vin10_12, sma_vin13_17, sma_passenger, sma_weight, sma_engine, sma_wheel'];
						$sres = $YpwVin->get('stand_model_any JOIN stand_vin_imgs ON sma_vin=vii_vin LEFT JOIN stand_vin_epccode ON vie_vin = sma_vin', $smafields, $swhere);
						if(count($sres['data']) < 100){
							//数量不足把未识别的图片识别一次
							$res = $YpwVin->get('stand_model_any JOIN stand_vin_imgs vii ON sma_vin=vii_vin', ['vii.*'], sprintf(" and sma_vin1_8='%s' and sma_gxb_code='%s' and vii_ocrstatus=0 order by rand() limit 100", $v18, $gxb));
							if($res['data']){
								foreach($res['data'] as $tv){
									$cfg = ['rotate'=>[0], 'timeout'=>10];
									$YpwVinImg->ocrViiImg($tv, $cfg);
								}
								$sres = $YpwVin->get('stand_model_any JOIN stand_vin_imgs ON sma_vin=vii_vin', $smafields, $swhere);
							}
						}
					
						foreach($sres['data'] as $tv){
							$tv['match_count'] = 0;
							$tv['matches'] = [];
							
							if($v['m3_zws'] && $tv['sma_passenger']){
								if(in_array($tv['sma_passenger'], $v['m3_zws'])){
									$tv['match_count']++;
									$tv['matches'][] = 'sma_passenger';
								}else{
									continue;
								}
							}

							if($v['m3_wheel'] && $tv['sma_wheel']){
								if($v['m3_wheel'] == $tv['sma_wheel']){
									$tv['match_count']++;
									$tv['matches'][] = 'sma_wheel';
								}else{
									continue;
								}
							}

							if($v['m3_weight'] && $tv['sma_weight']){
								if($v['m3_weight'] == $tv['sma_weight']){
									$tv['match_count']++;
									$tv['matches'][] = 'sma_weight';
								}else{
									continue;
								}
							}

							//排序
							$uni = substr($tv['sma_vin'], 0, 8).substr($tv['sma_vin'], -8);
							//日期是否在区间范围内
							$tres = $YpcVin->getVinBaseInfo($tv['sma_vin'], 'onlydate');
							$vdate = $tres['data'];
							if(strlen($vdate['vin_year']) >= 4){
								if(strlen($vdate['vin_year']) == 4){
									if($vdate['vin_year'] >= $v['m3_start_year'] && ($vdate['vin_year'] <= $v['m3_end_year'] || empty($v['m3_end_year']))){
										$v['etkvins'][$tv['match_count']][$uni] = $tv;
									}
								}else{
									$vdate['vtime'] = strtotime($vdate['vin_year']);
									if($vdate['vtime'] >= $v['btime'] && $vdate['vtime'] <= $v['etime']){
										$v['etkvins'][$tv['match_count']][$uni] = $tv;
									}
								}
							}
						}
					}
				}
			}
				
			if($v['etkvins']){
				krsort($v['etkvins']);
				foreach($v['etkvins'] as $evs){
					ksort($evs);
					$evins = array_column($evs, 'sma_vin');
					$evins = $this->midWalk($evins);
					foreach($evins as $tvin){
						if(!in_array($tvin, $v['etkcodes'])){
							$add = [
								'mec_m3_id'=>$v['m3_id'],
								'mec_code'=>$tvin,
								'mec_epc_status'=>1,
								'mec_remark'=>'系统计算VIN',
							];
							$Ypc67Base->add('yp_model3_etk_code', $add);
							$v['etkcodes'][] = $tvin;
							$v['e0']++;
						}
						if($v['e0'] >= $maxcount) break;
					}
					if($v['e0'] >= $maxcount) break;
				}

			}else{
				echo $v['m3_id'].'=>无识别图VIN<br>';
			}
		}
		LibFc::delFunLock(mvc::$URL_METHOD);
		echo 'ok';
	}
	
	//从中间开始向两侧遍历形成新数组
	function midWalk($a){
		$r=[];$l=intdiv(count($a)-1,2);$r2=$l+1;
		for($r[]=$a[$l];$l>0||$r2<count($a);){
			$l>0 && $r[]=$a[--$l];
			$r2<count($a) && $r[]=$a[$r2++];
		}
		return $r;
	}

	public function vin()
	{
		$Params = mvc::$URL_PARAMS;
		$YpcVin = new YpcVin();
		$vin = 'LSGUA82L6MG000008';
		$res = $YpcVin->decodeVin($vin);
		var_dump($res['data']);
	}


	
	//车架号文件入库
	public function initVinfile()
	{
		$rdir = mvc::$cfg['HuanbaoScqdPath'];
		$level1 = $this->getFile($rdir);
		$YpwBase = new YpwBase();
		//第一级
		foreach($level1['dir'] as $lv1)
		{
			$cacheFile = mvc::$cfg['PATH_CACHE'].'vinfile.php';
			if(file_exists($cacheFile)) $cacheArr = include($cacheFile);

			$level2 = $this->getFile($lv1);
			//重整路径
			foreach($level2['file'] as $fv2)
			{
				$vin = substr($fv2['file'], 0, stripos($fv2['file'], '.'));
				$newFile = $fv2['dir'].substr($vin, 0, 8).'/'.substr($vin, -3).'/';
				LibDir::CreateDir($newFile);
				$newFile .= $fv2['file'];
				rename($fv2['dir'].$fv2['file'], $newFile);
			}
			foreach($level2['dir'] as $dv2)
			{
				$level3 = $this->getFile($dv2);
				foreach($level3['file'] as $fv3)
				{
					$vin = substr($fv3['file'], 0, stripos($fv3['file'], '.'));
					$newFile = $fv3['dir'].'/'.substr($vin, -3).'/';
					LibDir::CreateDir($newFile);
					$newFile .= $fv3['file'];
					rename($fv3['dir'].$fv3['file'], $newFile);
				}

				foreach($level3['dir'] as $dv3)
				{
					if(!empty($cacheArr[$dv3])) continue;
					$level4 = $this->getFile($dv3);
					$addArr = [];
					foreach($level4['file'] as $fv4)
					{
						$vin = substr($fv4['file'], 0, stripos($fv4['file'], '.'));
						if(strlen($vin) != 17) continue;
						if(empty($addArr[$vin]) || stripos($fv4['file'], '.pdf'))
							$addArr[$vin] = str_replace($rdir, '', $fv4['dir']).$fv4['file'];
					}

					foreach($addArr as $vin=>$pdfFile)
					{
						$YpwBase->add('stand_vin_file', ['vf_vin'=>$vin, 'vf_url'=>mvc::$cfg['SCQDHost'].$pdfFile], 'replace');
					}

					$cacheArr[$dv3] = 1;
					LibFc::ArraySave($cacheArr, $cacheFile);
				}
			}
		}
		echo 'ok';
	}


	public function initToVinFile()
	{
		$Params = mvc::$URL_PARAMS;
		$YpwBase = new YpwBase();
		$res = $YpwBase->get('stand_scqd_reg', ['reg_code'], '');
		$hascodes = array_column($res['data'], 'reg_code');
		$fromdir = $Params['from'].':/';
		$todir = 'E:/';
		$toHost = 'http://192.168.1.116:88/';
		$ignores = '';
		$dir1s = scandir($fromdir);
		shuffle($dir1s);
		$count = 0;
		foreach($dir1s as $d1)
		{
			if($d1 == '.' || $d1 == '..' || !in_array($d1, $hascodes)) continue;
			$path1 = $d1.'/';
			$dir2s = scandir($fromdir.$path1);
			shuffle($dir2s);
			foreach($dir2s as $d2)
			{
				$path2 = $d1.'/'.$d2.'/';
				if($d2 == '.' || $d2 == '..' || !is_dir($fromdir.$path2)) continue;
				//echo $fromdir.$path2, '<br>';

				$dir3s = scandir($fromdir.$path2);
				shuffle($dir3s);
				foreach($dir3s as $d3)
				{
					$path3 = $d1.'/'.$d2.'/'.$d3.'/';
					if($d3 == '.' || $d3 == '..' || !is_dir($fromdir.$path3)) continue;
					$dir4s = scandir($fromdir.$path3);
					$files = [];
					$dels = [];
					$count++;
					foreach($dir4s as $d4)
					{
						$path4 = $d1.'/'.$d2.'/'.$d3.'/'.$d4;
						if(!is_file($fromdir.$path4)) continue;
						$filesize = filesize($fromdir.$path4);
						$ti = pathinfo($d4);
						$ti['extension'] = strtolower($ti['extension']);
						if($filesize > 100 && stripos($d4, 'makop') === false && preg_match('/^[0-9a-zA-Z]{17}$/', $ti['filename'], $match)){
							$files[$ti['extension']][] = ['vin'=>$ti['filename'],'path4'=>$path4];
						}else{
							$dels[] = $fromdir.$path4;
						}
					}
					
					$realExt = null;
					foreach(['pdf','txt', 'html', 'jpg'] as $ext)
					{
						if(empty($files[$ext])) continue;
						if($realExt === null) $realExt = $ext;
						$newDir = $todir.$path3;
						LibDir::CreateDir($newDir);
						foreach($files[$ext] as $tf)
						{
							if($realExt === $ext){
								if(rename($fromdir.$tf['path4'], $todir.$tf['path4'])){
									$YpwBase->add('stand_vin_file', ['vf_vin'=>$tf['vin'], 'vf_url'=>$toHost.$tf['path4']], 'replace');
								}/*else if(file_exists($todir.$tf['path4'])){

								}*/else{
									echo $tf['path4'], ' rename error<br>';
								}
							}else{
								$dels[] = $fromdir.$tf['path4'];
							}
						}
					}
	
					foreach($dels as $df){
						@unlink($df);
					}
					@rmdir($fromdir.$path3);
					if($count > 1000) exit('max file');
				}
				@rmdir($fromdir.$path2);
			}
			@rmdir($fromdir.$path1);
		}
		echo 'ok';
	}

	//长安车架号文件入库
	public function initChanganVinfile()
	{
		$orgdir = 'E:\changan_ast/';
		$site = 'changan';
		$SCQD = mvc::$cfg['SCQD']['h1'];
		$level1 = $this->getFile($orgdir);
		$YpwBase = new YpwBase();
		shuffle($level1['dir']);
		foreach($level1['dir'] as $lv1)
		{
			$cacheFile = mvc::$cfg['PATH_CACHE'].'vinfile.php';
			if(file_exists($cacheFile)) $cacheArr = include($cacheFile);
			//if($cacheArr[$lv1]) continue;
			$level2 = $this->getFile($lv1);
			//重整路径
			foreach($level2['file'] as $fv2)
			{
				$vin = substr($fv2['file'], 0, stripos($fv2['file'], '.'));
				$path = $site.'/'.substr($vin, 0, 8).'/'.substr($vin, -3).'/';
				LibDir::CreateDir($SCQD['save'].$path);
				$newFile = $SCQD['save'].$path.$fv2['file'];
				rename($fv2['dir'].$fv2['file'], $newFile);
				$YpwBase->add('stand_vin_file', ['vf_vin'=>$vin, 'vf_url'=>$SCQD['host'].$path.$fv2['file']], 'replace');
			}
			$cacheArr[$lv1] = 1;
			LibFc::ArraySave($cacheArr, $cacheFile);
		}
		echo 'ok';
	}

	
	//获取文件夹下的文件
	private function getFile($dir)
	{
		$arr = ['dir'=>[], 'file'=>[]];
        if(is_dir($dir) && $handle = opendir($dir))
		{
            while(($file = readdir($handle))!==false)
			{
                if($file !='.' && $file !='..')
				{
                    if(is_dir($dir.$file))
					{
                        $arr['dir'][] = $dir.$file.'/';
                    }
					else if(filesize($dir.$file) > 100)
					{
                       $arr['file'][] = ['dir'=>$dir, 'file'=>$file];
                    }
                }
            }
            closedir($handle);
            @clearstatcache();
        }
		return $arr;
	}

	//根据已有数据补齐发动机编码
	function buengine6()
	{
		$YpwBase = new YpwBase();
		$ires = $YpwBase->get('stand_model_any', ['sma_vin1_8, sma_vin10_12'], sprintf(" and sma_vyear >= 2017 AND sma_engine6 != '' AND sma_year = '' GROUP BY sma_vin1_8, sma_vin10_12 order by count(*) desc"));
		foreach($ires['data'] as $iv)
		{
			for($len = 1; $len <= 3; $len++)
			{
				$haslen = 6-$len;
				//可能的
				$where =  sprintf(" and sma_vin1_8='%s' and sma_vin10_12 = '%s' and sma_vyear >= 2017 AND length(sma_engine6) >= 6", $iv['sma_vin1_8'], $iv['sma_vin10_12']);
				$tres = $YpwBase->get('stand_model_any', ['distinct(left(right(sma_engine6, 6), '.$len.')) as buenging6'], $where);
				$addSqlArr = [];
				foreach($tres['data'] as $tvv)
				{
					
					$addSqlArr[] = "INSERT INTO stand_catch_list (sce_reg_code, sce_vin, sce_engine6, sce_level) 
					SELECT 'engine6', sma_vin, concat('{$tvv['buenging6']}', sma_engine6), {$haslen} FROM stand_model_any
						WHERE sma_vin1_8='{$iv['sma_vin1_8']}' and sma_vin10_12 = '{$iv['sma_vin10_12']}' and sma_vyear >= 2017 AND length(sma_engine6) = {$haslen}
						AND concat(sma_vin, '{$tvv['buenging6']}', sma_engine6) NOT IN (
							SELECT concat(sce_vin, sce_engine6) FROM stand_catch_list where sce_reg_code = 'engine6'
							and sce_vin like '{$iv['sma_vin1_8']}_{$iv['sma_vin10_12']}%'
					)";
				}
				if(!empty($addSqlArr))
					$YpwBase->exeAnySql($addSqlArr, false);	
			}
		}
		echo 'ok';
	}

	
	//车架号日期图像识别 指定wmi 链接加wmi=LS4,LS5,LS6,LSC
	public function initVinDateImg()
	{
		$Params = MVC::$URL_PARAMS;
		$wmiArr = ['LFM', 'LS4', 'LS5', 'LS6', 'LSC', 'LB1', 'LGB'];
		if(!empty($Params['wmi'])) $wmiArr = explode(',', $Params['wmi']);
		$per = 200;
		$YpwBase = new YpwBase();
		$LibHttp = new LibHttp(false, false);
		$tempDir = mvc::$cfg['PATH_CACHE'];
		$OthPdfOcr = new OthPdfOcr();
		$LibImage = new LibImage();
		$LibYpApi = new LibYpApi();
		foreach($wmiArr as $wmi){
			$tableArr = [
				sprintf("(
					select 0 as svdl_id, sma_vin as vin, vf_url, 0 as cutcount from stand_vin_file
					JOIN stand_model_any ON sma_vin = vf_vin 
					LEFT JOIN stand_vin_dateocr_list ON vf_vin = svdl_vin
					where sma_year = '' AND sma_vin1_3 ='%s' and sma_etime > %d AND svdl_id IS NULL limit 1000
				) as a", $wmi, strtotime('-3 day')),
				//处理异常的
				sprintf("(
					select svdl_id, sma_vin AS vin, vf_url, svdl_cutcount AS cutcount from stand_vin_dateocr_list
					JOIN stand_vin_dateocr ON svdl_svd_imgmd5 = svd_imgmd5 
					JOIN stand_vin_file  ON svdl_vin = vf_vin 
					JOIN stand_model_any ON sma_vin = vf_vin 
					where svd_status = -1 AND sma_year = '' AND sma_vin1_3 ='%s' and svdl_cutcount < 3 GROUP BY sma_vin LIMIT %d
				) as a", $wmi, $per)
			];
			foreach($tableArr as $table)
			{
				$vinres = $YpwBase->get($table, ['*'], ' order by rand() limit '.$per);
				if(empty($vinres['data'])) continue;
				foreach($vinres['data'] as $tv)
				{
					$vin = $tv['vin'];
					$ext = substr($tv['vf_url'], strrpos($tv['vf_url'], '.')+1);
					$html = $LibHttp->fetch($tv['vf_url']);
					if(strlen( $html) < 10*1024) continue;
					$orgfile = $tempDir.$vin.'.'.$ext;
					$dateImg = $tempDir.$vin.'_date.jpg';
					file_put_contents($orgfile, $html);
					$jpgArr = [];
					$ignore = 0;
					switch(substr($vin, 0, 3))
					{
						case 'LFM':
							$res = $OthPdfOcr->pdfToJpg($orgfile, 'onlyLast');
							$jpgArr = $res['data'];
							if(empty($jpgArr['img'])) break;
							if($jpgArr['count'] == 1)
							{//固定不能改
								$cutSize = ['year'=>[0.68, 0.96,0.92, 0.95]];
							}
							else
							{//固定不能改
								$cutSize = ['year'=>[0.68, 0.96,0.93, 0.95]];
							}
						break;
						case 'LS4':
						case 'LS5':
						case 'LS6':
						case 'LSC':
							$jpgArr = ['count'=>1, 'img'=>[$orgfile]];
							$imgInfo = getimagesize($orgfile);
							if($imgInfo[0] < 1000)
							{//LS5A2ABE1HA014277 固定不能改
								$cutSize = ['year'=>[0.61, 0.94,0.91, 0.96]];
							}
							else
							{//LS5A2ABE0LA002937 固定不能改
								$cutSize = ['year'=>[0.82, 0.96,0.90, 0.95]];
							}
						break;
						case 'LB1':
							$res = $OthPdfOcr->pdfToJpg($orgfile, 'onlyLast');
							$jpgArr = $res['data'];
							if(empty($jpgArr['img'])) break;
							$imgInfo = getimagesize($jpgArr['img'][0]);
							
							if($imgInfo[0] < 1650)
							{//LB1WG2E13J8030128 固定不能改
								$cutSize = ['year'=>[0.55, 0.94,0.12, 0.18]];
								//人工盖章，不处理
								$ignore = 1;
							}
							else
							{//LB1WG2E10K8067784 固定不能改
								$cutSize = ['year'=>[0.62, 0.96,0.905, 0.94]];
							}
						break;
						case 'LGB':
							$res = $OthPdfOcr->pdfToJpg($orgfile, 'onlyLast');
							$jpgArr = $res['data'];
							if(empty($jpgArr['img'])) break;
							if($jpgArr['count'] == 1)
							{//固定不能改
								$cutSize = ['year'=>[0.72, 0.96,0.95, 0.99]];
							}
							else
							{//固定不能改
								$cutSize = ['year'=>[0.68, 0.96,0.93, 0.97]];
							}
						break;
					}
					if(empty($jpgArr['img'])) continue;
					
					//异常的放大区域
					if(!empty($tv['cutcount']))
					{
						foreach($cutSize as $ck=>$cv)
						{
							$rate = round($tv['cutcount']/10, 2);
							$cv[0] = $cv[0]-$rate;
							if($cv[0] <= 0.4) $cv[0] = 0.4;
							$cv[1] = $cv[1]+$rate;
							if($cv[1] >= 1) $cv[1] = 1.0;

							$cv[2] = $cv[2]-$rate;
							if($cv[2] <= 0.7) $cv[2] = 0.7;
							$cv[3] = $cv[3]+$rate;
							if($cv[3] >= 1) $cv[3] = 1.0;
							$cutSize[$ck] = $cv;
						}
					}
				
					if(!empty($jpgArr['img'][0]))
					{
						$LibImage->thumb($jpgArr['img'][0], $cutSize, $dateImg, 10);
						$thumbData = base64_encode(file_get_contents($dateImg));
						$imgmd5 = md5($thumbData);
						$res = $YpwBase->get('stand_vin_dateocr', ['svd_imgmd5'], sprintf(" and svd_imgmd5 ='%s' limit 1", $imgmd5), true);
						$ocrData = '';
						if(empty($res['data']))
						{
							$MainOcr = new MainOcr();
							$res = $MainOcr->paddleOcr($thumbData);
							if(!empty($res['data'])) $ocrData = implode("\n", $res['data']);
							$addArr = [
								'svd_imgmd5'=>$imgmd5,
								'svd_imgdata'=>$thumbData,
								'svd_fromvin'=>$vin,
								'svd_fromurl'=>$tv['vf_url'],
								'svd_ocr'=>$ocrData
							];
							//忽略的部分
							if($ignore == 1) $addArr['svd_status'] = -2;

							$YpwBase->add('stand_vin_dateocr', $addArr);
						}
						$setArr = ['svdl_vin'=>$vin, 'svdl_svd_imgmd5'=>$imgmd5];
						if(empty($tv['svdl_id']))
						{
							$setArr['svdl_cutcount'] = 1;
							$YpwBase->add('stand_vin_dateocr_list', $setArr);
						}
						else
						{
							$setArr['svdl_cutcount'] = $tv['cutcount'] + 1;
							if(stripos($ocrData, '年') && stripos($ocrData, '日期')) $setArr['svdl_cutcount'] = 99;
							$YpwBase->set('stand_vin_dateocr_list', $setArr, sprintf(" and svdl_vin='%s'", $vin));
						}
					}
					@unlink($orgfile);
					@unlink($dateImg);
					foreach($jpgArr['img'] as $ti)
					{
						@unlink($ti);
					}
				}
			}
		}
		
		$idres = $YpwBase->get('stand_vin_dateocr', ['svd_id, svd_imgmd5, svd_ocr, svd_fromvin, svd_status'], " and svd_status != 1 and svd_date = '' and svd_ocr REGEXP '20[0-9]{2}' AND svd_ocr REGEXP '[0-1][0-9]月' AND svd_ocr REGEXP '月[0-3][0-9]'");
		foreach($idres['data'] as $tv)
		{
			if(preg_match('/(\d{4}) *年 *([0-1][0-9]) *月 *([0-3][0-9])/', $tv['svd_ocr'], $match))
			{
				$time = strtotime($match[1].'-'.$match[2].'-'.$match[3]);
				//解码的日期
				$res = $LibYpApi->Get('vin/getVinBaseInfo', ['vin'=>$tv['svd_fromvin']]);
				if(!empty($res['data']['vin_year']) && strlen($res['data']['vin_year']) >= 7)
				{
					if(strlen($res['data']['vin_year']) == 7) $res['data']['vin_year'] = $res['data']['vin_year'].'-01';
					//不能相差365天
					if(abs(strtotime($res['data']['vin_year']) - $time) > 3600*24*365) continue;
				}
				if($time < 946656000) continue;
				//识别出来，需要人工核对一次
				$setArr = [
					'svd_status'=>$tv['svd_status'] == -2? 0: $tv['svd_status'], 
					'svd_date'=>date('Y-m-d', $time),
					'svd_date_type'=>stripos($tv['svd_ocr'], '进口') !== false? 2: 1,
					'svd_by'=>8,
					'svd_etime'=>time()
				];
				$YpwBase->set('stand_vin_dateocr', $setArr, sprintf(" and svd_imgmd5='%s'", $tv['svd_imgmd5']));
			}
		}
		echo 'ok';
	}

	//从清单补充长安的发动机
	function fitChanganEng()
	{
		$YpwBase = new YpwBase();
		$LibHttp = new LibHttp();
		$OthPdfOcr = new OthPdfOcr();
		$MainOcr = new MainOcr();
		$table = '`ypdb_write`.`stand_model_any` 
		JOIN `yp_car`.`temp_changan` ON cha_vin = sma_vin 
		JOIN stand_vin_file ON vf_vin = sma_vin';
		$eres = $YpwBase->get($table, ['lnk_extend_code, vf_vin, vf_url'], " and sma_vin1_3 IN ('LS4','LS5','LS6','LSC') AND sma_vyear > 2016 AND sma_engine = '' GROUP BY lnk_extend_code");
		foreach($eres['data'] as $v){
			$vin = $v['vf_vin'];
			$imghtml = $LibHttp->fetch($v['vf_url']);
			$imgdata = base64_encode($imghtml);
			$res = $MainOcr->paddleOcr($imgdata);
			$txt = implode("\r\n", $res['data']);
			$smares = $OthPdfOcr->getHbqdData($vin, $txt, ['reg_code'=>'changan']);
			$set = [];
			if($smares['data']['sma']['sma_engine']){
				$match = $smares['data']['sma'];
				$set = [
					'sma_engine'=>$match['sma_engine'],	
					'sma_kw'=>$match['sma_kw'],	
					'sma_cc'=>$match['sma_cc'],	
					'sma_etime'=>time()
				];
				
			}else{
				$res = $YpwBase->get('`ypdb_write`.`stand_model_any` JOIN `yp_car`.`temp_changan` ON cha_vin = sma_vin', ['*'], sprintf(" and lnk_extend_code = '%s' and sma_engine != '' and sma_from in ('manual','catch','epc') limit 1", $v['lnk_extend_code']), true);
				if(!empty($res['data'])){
					$match = $res['data'];
					$set = [
						'sma_engine'=>$match['sma_engine'],	
						'sma_kw'=>$match['sma_kw'],	
						'sma_cc'=>$match['sma_cc'],	
						'sma_etime'=>time()
					];
				}else{
					echo $vin, '<br>';
				}
			}
			if($set){
				$YpwBase->set('stand_model_any, `yp_car`.`temp_changan`', $set, sprintf(" and cha_vin = sma_vin and lnk_extend_code = '%s' and sma_engine = ''", $v['lnk_extend_code']));
			}
		}
		echo 'ok';
	}
	
	//
	public function checkVinRes()
	{
		$dir = './cache/chkvin/';
		$vins = file_get_contents($dir.'vins.txt');
		$vins = explode("\n", $vins);
		$YpcVin = new YpcVin();
		foreach($vins as $vin)
		{
			$vin = LibFc::FormatVin($vin);
			$file = $dir.$vin.'.json';
			if(strlen($vin) != 17 || file_exists($file)) continue;
			$res = $YpcVin->decodeVin($vin);
			file_put_contents($file, json_encode($res, JSON_UNESCAPED_UNICODE));
		}
		echo 'ok';
	}
	
	//从采集文本补五菱的发动机号码
	public function buWlEngine6()
	{
		$YpwBase = new YpwBase();
		$LibHttp = new LibHttp();
		$per = 1000;
		$table = "(SELECT sma_vin vin, vf_url FROM stand_vin_file JOIN stand_model_any ON sma_vin = vf_vin 
		WHERE sma_engine6 = '' AND sma_vin1_3 IN ('LZW', 'LK6') AND vf_url LIKE '%.txt' limit ".($per*100).") as a";
		$res = $YpwBase->get($table, ['*'], ' order by rand() limit '.$per);
		foreach($res['data'] as $tv)
		{
			$addArr = [];
			$htmlArr = '';
			foreach(['h1', 'h3'] as $ht)
			{
				if(stripos($tv['vf_url'], mvc::$cfg['SCQD'][$ht]['host']) !== false)
				{
					$dirfile = str_replace(mvc::$cfg['SCQD'][$ht]['host'], mvc::$cfg['SCQD'][$ht]['save'], $tv['vf_url']);
					$htmlArr = file_get_contents($dirfile);
					break;
				}
			}
			if(stripos($htmlArr, 'SUCCESS') === false)
				$htmlArr = $LibHttp->fetch($tv['vf_url']);
			$htmlArr = json_decode($htmlArr, true);
			if(!empty($htmlArr['info']['EngineCode']) && strlen($htmlArr['info']['EngineCode']) > 5)
				$addArr['sma_engine6'] = $htmlArr['info']['EngineCode'];
			else if(!empty($htmlArr['info']['EngineNumber']) && strlen($htmlArr['info']['EngineNumber']) > 5)
				$addArr['sma_engine6'] = $htmlArr['info']['EngineNumber'];
			if(!empty($htmlArr['info']['MMufflerBarcode']))
				$addArr['sma_xuhang'] = $htmlArr['info']['MMufflerBarcode'];

			if(!empty($addArr))
			{
				$YpwBase->set('stand_model_any', $addArr,sprintf(" and sma_vin ='%s'", $tv['vin']));
			}
		}
		echo 'ok';
	}

	//初始化WMI和brand的关系 stand_wmi_brand
	public function initWmiBrand()
	{
		$YpwBase = new YpwBase();
		/*$wres = $YpwBase->get('stand_model_any', ['sma_vin1_3', 'sma_brand'], " and left(sma_vin1_3, 1) in ('L', 'H') and sma_brand !='' group by sma_vin1_3, sma_brand order by length(sma_brand) desc");
		$wmiArr = [];
		foreach($wres['data'] as $v)
		{
			if(!empty($wmiArr[$v['sma_vin1_3']][$v['sma_brand'].'牌']))
				$wmiArr[$v['sma_vin1_3']][$v['sma_brand'].'牌'][] = $v['sma_brand'];
			else if(empty($wmiArr[$v['sma_vin1_3']][$v['sma_brand']]))
				$wmiArr[$v['sma_vin1_3']][$v['sma_brand']][] = $v['sma_brand'];

		}
		foreach($wmiArr as $k=>$v)
		{
			$addArr = [];
			foreach($v as $kk=>$vv)
			{
				sort($vv);
				$addArr[] = [
					'swb_wmi'=>$k,
					'swb_brand'=>$kk,
					'swb_word'=>','.implode(',', $vv).',',
					'swb_etime'=>time(),
				];
			}
			$YpwBase->addAny('stand_wmi_brand', array_keys($addArr[0]), $addArr);
		}*/
		$wres = $YpwBase->get('stand_wmi_brand', ['*'], " and swb_word LIKE '%_,_%'");
		foreach($wres['data'] as $v)
		{
			$twords = explode(',', trim($v['swb_word'], ','));
			foreach($twords as $tw)
			{
				if(!empty($tw) && $tw != $v['swb_brand'])
				{
					$where = sprintf(" and sma_vin1_3='%s' and sma_brand='%s' and sma_brand != '%s'", $v['swb_wmi'], LibFc::Escape($tw), LibFc::Escape($v['swb_brand']));
					$YpwBase->set('stand_model_any', ['sma_brand'=>$v['swb_brand']], $where);
				}
			}
		}
		echo 'ok';
	}

	//通过统计表 查找发动机型号和工信部公布信息不一致的发动机信息
	public function resetGxbErrorEngine()
	{
		$file = mvc::$cfg['LOGS'].'resetGxbErrorEngine.txt';
		$filesql = mvc::$cfg['LOGS'].'resetGxbErrorEngine2.sql';
		if(file_exists($file) && filemtime($file) < time()-3600*24*2){
			@unlink($file);
			@unlink($filesql);
		}
		$cacheTxt = '';
		if(file_exists($file)) $cacheTxt = @file_get_contents($file);

		$YpwVin = new YpwVin();
		$LibYpApi = new LibYpApi();
		$LibFile = new LibFile();
		$wres = $YpwVin->get('stand_model_tj', ['smt_vin1_8, smt_gxb_code, smt_gxb_code_show, GROUP_CONCAT(DISTINCT smt_engine) engs'], " and LEFT(smt_vin1_8, 1) IN ('L','H') AND smt_engine !='' AND smt_engine IS NOT NULL GROUP BY smt_vin1_8, smt_gxb_code");
		foreach($wres['data'] as $wv)
		{
			$unikey = $wv['smt_vin1_8'].'@'.$wv['smt_gxb_code_show'].'@';
			if(stripos($cacheTxt, $unikey) !== false) continue;
			$engs = explode(',', $wv['engs']);
			$engs = array_unique($engs);
			$res = $YpwVin->catchGxbcodeInfo($wv['smt_gxb_code_show'], 1, $wv['smt_vin1_8'],[], true);
			if(!empty($res['data']['merge']['sma_engine']))
			{
				$merge = $res['data']['merge'];
				$hasengs = [];
				foreach(explode(',', $merge['sma_engine']) as $tempv)
				{
					$t = explode('#', $tempv);
					if(!empty($t[0]))
						$hasengs[] = $t[0];
				}
				$hasengs = array_unique($hasengs);
				foreach($engs as $ev)
				{
					if(!in_array($ev, $hasengs))
					{
						//echo $wv['smt_gxb_code_show'], '=>', $ev, '=>', $merge['sma_engine'], '<br>';
						$sql = sprintf("UPDATE stand_model_any SET sma_brand='', sma_etime=%d WHERE sma_gxb_code='%s' AND sma_engine='%s' and sma_from in ('buy01', 'buy02', 'ocr', 'manual');", time(), $wv['smt_gxb_code_show'], LibFc::Escape($ev));
						$LibFile->WriteData($filesql, 'a', $sql);
					}
				}
				LibLog::write($unikey, $file);
			}
		}
		echo $filesql, 'ok';
	
	}


	public function chkDflPdf()
	{
		$OthPdfOcr = new OthPdfOcr();
		$YpwVin = new YpwVin();
		$LibYpApi = new LibYpApi();
		$LibFile = new LibFile();
		$wres = $YpwVin->get('zz_dfl_pdfurl', ['sma_vin'], " and sma_url = '' order by rand() limit 50");
		foreach($wres['data'] as $wv)
		{
			$res = $OthPdfOcr->getDflVin($wv['sma_vin'], 5);
			if(!empty($res['pdf']))
			{
				$YpwVin->set('zz_dfl_pdfurl', ['sma_url'=>$res['pdf']], sprintf(" and sma_vin = '%s'", $wv['sma_vin']));
			}
		}
		echo 'ok';
	}

	//提取校验的车架号
	public function getCheckDiffVin()
	{
		$wmiArr = ['LSG', 'LGW', 'LFV','LS4','LS5','LZW','LVB','LVV','LVT','LNX','LGG','LEF','LJX','LZZ']; 
		$vin10Arr = ['M','N','P','R']; 
		$YpwVin = new YpwVin();
		foreach($wmiArr as $wmi)
		{
			foreach($vin10Arr as $vin10)
			{
				$diffArr = [];
				$where = sprintf(" and smt_vin1_8 like '%s%%' and smt_vin10 like '%%%s%%' group by smt_vin1_8 having count(distinct smt_gxb_code) > 1 order by rand()", $wmi, $vin10);
				$v8res = $YpwVin->get('stand_model_tj', ['smt_vin1_8'], $where);
				foreach($v8res['data'] as $v8)
				{
					$where = sprintf(" and sma_vin1_8='%s' and sma_vin10='%s' group by sma_vin1_8, sma_vin10_12 having count(distinct sma_gxb_code) > 1 order by rand()", $v8['smt_vin1_8'], $vin10);
					$v12res = $YpwVin->get('stand_model_any', ['sma_vin1_8', 'sma_vin10_12'], $where);
					foreach($v12res['data'] as $v12)
					{
						$where = sprintf(" and sma_vin1_8='%s' and sma_vin10_12='%s'
						and sma_gxb_code in (SELECT sma_gxb_code FROM stand_model_any WHERE sma_vin1_8='%s' AND sma_vin10_12='%s' AND sma_length > 0 GROUP BY sma_gxb_code HAVING COUNT(DISTINCT sma_length) > 1) order by sma_vin13_17", $v12['sma_vin1_8'], $v12['sma_vin10_12'], $v12['sma_vin1_8'], $v12['sma_vin10_12']);
						$where = sprintf(" and sma_vin1_8='%s' and sma_vin10_12='%s' and sma_from in ('catch', 'ZDAPI') order by sma_vin13_17", $v12['sma_vin1_8'], $v12['sma_vin10_12']);
						$vres = $YpwVin->get('stand_model_any', ['sma_vin', 'sma_gxb_code', 'sma_length', 'sma_vin13_17'], $where);
						$last = null;
						foreach($vres['data'] as $tv){
							if($last === null){
								$last = $tv;
								continue;
							}
							/*if($last['sma_gxb_code'] != $tv['sma_gxb_code'] 
								&& (
									(!empty($last['sma_length']) && !empty($tv['sma_length']) && $last['sma_length'] != $tv['sma_length']) ||
									(!empty($last['sma_wheel']) && !empty($tv['sma_wheel']) && $last['sma_wheel'] != $tv['sma_wheel'])
								)
							)*/
							if($last['sma_gxb_code'] != $tv['sma_gxb_code']){
								//第一个也纳入
								$abs = abs($last['sma_vin13_17'] - $tv['sma_vin13_17']);
								$diffArr[] = ['vin'=>$last['sma_vin'], 'abs'=>$abs];
								$diffArr[] = ['vin'=>$tv['sma_vin'], 'abs'=>$abs];
								if(count($diffArr) > 2000) break;
							}
							$last = $tv;
						}
						if(count($diffArr) > 2000) break;
					}
					if(count($diffArr) > 2000) break;
				}

				if(!empty($diffArr)){
					$YpwVin->del('zz_check_diff_vin', sprintf(" and vin in ('%s')", implode(',', array_column($diffArr, 'vin'))));
					$YpwVin->addAny('zz_check_diff_vin', array_keys($diffArr[0]), $diffArr);
				}
			}
		}
	}

	//验证第三方数据准确性
	function checkDiffVin()
	{
		$LibYpApi = new LibYpApi();
		$YpwVin = new YpwVin();

		/*$LibYpApi = new LibYpApi();
		$res = $YpwVin->get('zz_temp2', ['a vin'], ' and k ="" and l = "" order by rand() limit 100');
		foreach($res['data'] as $v){
			$tres = $LibYpApi->Get('vin/decodeVin', $v);
			if($tres['data']['from'] == 'ypc'){
				$tran = implode(',', array_unique(array_column($tres['data']['model'], 'mod3_transmission')));
				$YpwVin->set('zz_temp2', ['k'=>$tran, 'l'=>$tres['data']['model'][0]['paifang']], sprintf(" and a='%s'", $v['vin']));
			}
		}
		exit;*/

		$chks = [];
		$fields = ['d'=>'sma_gxb_code', 'k'=>'sma_engine', 'f'=>'sma_engine6', 'g'=>'sma_wheel', 'h'=>'sma_length', 'i'=>'sma_width', 'j'=>'sma_height', 'm'=>'sma_cc', 'b'=>'sma_year'];
		$fields = ['d'=>'sma_gxb_code', 'e'=>'sma_engine','f'=>'sma_cc', 'i'=>'l', 'h'=>'sma_tran'];
		$fields = ['d'=>'sma_gxb_code', 'e'=>'sma_engine'];
		$refields = array_flip($fields);
		$tres = $YpwVin->get('zz_temp3 join stand_model_any on sma_vin = a', ['*']);
		$total = count($tres['data']);
		foreach($tres['data'] as $v)
		{
			/*if(stripos($v['h'], ';') !== false) $v['h'] = '';
			else if(stripos($v['h'], '双离合') !== false) $v['h'] = 'DCT';
			else if(stripos($v['h'], '固定齿比') !== false) $v['h'] = 'CVT';
			else if(stripos($v['h'], '手自一体') !== false) $v['h'] = 'AMT';
			else if(stripos($v['h'], '手动') !== false) $v['h'] = 'MT';
			else if(stripos($v['h'], '自动') !== false) $v['h'] = 'AT';
			$v['sma_tran'] = preg_replace('/\d/', '', $v['k']);
			if(stripos($v['sma_tran'], ',') !== false) $v['sma_tran'] = '';
			$v['sma_tran'] = strtr($v['sma_tran'], ['A/MT'=>'AMT', '电动车单速'=>'CVT']);*/

			/*if(trim($v[$refields['sma_engine6']]) == trim($v[$refields['sma_engine']])) $v[$refields['sma_engine6']] = '';
			$v[$refields['sma_year']] = $v[$refields['sma_year']] != ''? date('Y-m-d', strtotime($v[$refields['sma_year']])): '';
			
			//5天以内算一样
			if($v[$refields['sma_year']] && $v['sma_year'] && abs(strtotime($v[$refields['sma_year']]) - strtotime($v['sma_year'])) < 24*3600*5){
				$v[$refields['sma_year']] = $v['sma_year'];
			}*/

			$v[$refields['sma_gxb_code']] = LibFc::FormatNum($v[$refields['sma_gxb_code']]);

			$res = $YpwVin->catchGxbcodeInfo($v[$refields['sma_gxb_code']], 1, $v['sma_vin']);
			$gxbInfo = $res['data']['merge'];

			foreach($fields as $ff=>$tf){
				if($tf == 'sma_gxb_code' && $v[$ff] != $v[$tf]){
					//是否为底盘
					$res = $YpwVin->get('gxb_base JOIN gxb_dipan ON gd_gb_id = gb_id', ['gb_id'], sprintf(" and gb_type='gxb' and gb_gxb_code='%s' and gd_dpgxb_code = '%s'", $v[$ff], $v[$tf]));
					if(empty($res['data'])){
						$res = $YpwVin->get('gxb_base JOIN gxb_dipan ON gd_gb_id = gb_id', ['gb_id'], sprintf(" and gb_type='gxb' and gb_gxb_code='%s' and gd_dpgxb_code = '%s'", $v[$tf], $v[$ff]));
					}
					if(!empty($res['data'])) $v[$ff] = $v[$tf];
				}
				if(empty($v[$ff])) $chks[$tf]['null']++;
				if(!empty($v[$ff]) && !empty($v[$tf]))  $chks[$tf]['notnull']++;
				if(!empty($v[$ff]) && !empty($v[$tf]) && $v[$ff] != $v[$tf]){
					//if($tf == 'sma_tran') echo $v[$ff], '=>', $v[$tf], '<br>';
					$chks[$tf]['diff']++;
				}
				if(!empty($v[$ff]) && !empty($v[$tf]) && $v[$ff] == $v[$tf]){
					$chks[$tf]['same']++;
					if(!empty($gxbInfo[$tf]) && count(explode(',', $gxbInfo[$tf])) == 1){
						$chks[$tf]['uni_same']++;
					}
				}
			}
		}

		echo $total.'<br><table border="1">';
		echo '<tr><td>字段</td><td>有值</td><td>都有值</td><td>相同</td><td>相同唯一</td><td>不同</td><td>空缺</td>';
		foreach($chks as $field=>$com)
		{
			echo '<tr>
			<td>'.$field.'</td>
			<td>'.($total-$com['null']).'['.round(($total-$com['null'])/$total*100, 2).'%]</td>
			<td>'.$com['notnull'].'['.round($com['notnull']/$total*100, 2).'%]</td>
			<td>'.$com['same'].'['.round($com['same']/$com['notnull']*100, 2).'%]</td>
			<td>'.$com['uni_same'].'['.round($com['uni_same']/$com['same']*100, 2).'%]</td>
			<td>'.$com['diff'].'['.round($com['diff']/$com['notnull']*100, 2).'%]</td>
			<td>'.$com['null'].'['.round($com['null']/$total*100, 2).'%]</td>';
		}
		echo '</table>';
	}


	//格式化变速箱 ?type=all  否则最近7天
	public function formatSmaTran()
	{
		$Params = mvc::$URL_PARAMS;
		$where = " and sma_tran != ''";
		$comwhere = empty($Params['type']) || $Params['type'] != 'all'?sprintf(" and sma_etime >= %d", strtotime('-7 day')): '';

		$YpwVin = new YpwVin();
		$wres = $YpwVin->get('stand_model_any', ['distinct sma_tran'], $where.$comwhere);
		foreach($wres['data'] as $wv)
		{
			$res = $YpwVin->formatTran($wv['sma_tran']);
			if(!empty($res['data']['tran']) && $res['data']['tran'] != $wv['sma_tran'])
			{
				$YpwVin->set('stand_model_any', ['sma_tran'=>$res['data']['tran']], sprintf(" and sma_tran = '%s'", $wv['sma_tran']).$comwhere);
			}
		}

		$wres = $YpwVin->get('stand_model_tj', ['smt_vin1_8', 'smt_gxb_code'], " and smt_tran LIKE '%,%'");
		foreach($wres['data'] as $wv)
		{
			$where = sprintf(" and sma_vin1_8='%s' and sma_gxb_code='%s' and sma_tran !='' group by sma_tran", $wv['smt_vin1_8'], $wv['smt_gxb_code']);
			$res = $YpwVin->get('stand_model_any', ['sma_tran', 'count(*) vin_count'], $where);
			$total = 0;
			$tranArr = [];
			foreach($res['data'] as $tvv)
			{
				$tranArr[$tvv['sma_tran']] = $tvv;
				$total += $tvv['vin_count'];
			}
			
			$vins = [];
			foreach($tranArr as $tkk=>$tvv)
			{
				if($tvv['vin_count'] < 10 || ($tvv['vin_count']< 20 && ($tvv['vin_count']/$total) < 0.1))
				{
					$where = sprintf(" and sma_vin1_8='%s' and sma_gxb_code='%s' and sma_tran ='%s'", $wv['smt_vin1_8'], $wv['smt_gxb_code'], LibFc::Escape($tkk));
					$res = $YpwVin->get('stand_model_any', ['sma_vin'], $where);
					$vins = array_merge($vins, array_column($res['data'], 'sma_vin'));
				}
			}
			if(!empty($vins))
				echo $wv['smt_vin1_8'],'=>',$wv['smt_gxb_code'],'<br>',implode("<br>", $vins), '<hr>';
		}
		echo 'ok';
	}

	//
	public function addBuy01()
	{
		//exit;
		if(!LibFc::hasFunLock(mvc::$URL_METHOD, 600)) return true;
		$YpwBase = new YpwBase();
		$res = $YpwBase->get('ztemp.vin_buy', ['max(cat_id) cat_id'], '', true);
		$maxId = $res['data']['cat_id'];
		$cacheFile = mvc::$cfg['LOGS'].'cache_'.mvc::$URL_METHOD.'.txt';
		$lastid = 0;
		if(file_exists($cacheFile)) $lastid = (int) file_get_contents($cacheFile);
		$per = 3000;
		for($page = 1; $page <= 2000; $page++){
			$bid = $lastid;
			$eid = $bid + $per;
			$sql = sprintf("INSERT INTO `ypdb_write`.`stand_model_any` (
sma_vin, 
sma_vin1_3, 
sma_vin1_8,
sma_vin10,
sma_vin10_11,
sma_vin12_17,
sma_vin10_12,
sma_vin13_17,
sma_vyear, sma_gxb_code, sma_gxb_code_show, sma_engine, sma_engine6, sma_tran, sma_xuhang, sma_year, sma_etime, sma_from)
SELECT cat_vin, 
LEFT(cat_vin, 3), 
LEFT(cat_vin, 8),
RIGHT(LEFT(cat_vin, 10), 1),
RIGHT(LEFT(cat_vin, 11), 2),
RIGHT(cat_vin, 6),
RIGHT(LEFT(cat_vin, 12), 3),
RIGHT(cat_vin, 5),
vin_year, cat_gxbcode, cat_gxbcode, cat_engine, cat_engine_num, cat_gearbox, cat_battery, cat_scrq, %d, 'buy01' FROM ztemp.`vin_buy` 
 JOIN `ypdb_write`.`yp_vin_year` ON vin_10 = RIGHT(LEFT(cat_vin, 10), 1) 
 LEFT JOIN `ypdb_write`.stand_model_any on sma_vin = cat_vin 
 WHERE cat_id > %d and cat_id <=%d and sma_vin is null GROUP BY cat_vin", time(), $bid, $eid);
			$YpwBase->exeAnySql([$sql], false);
			$lastid = $eid;
			file_put_contents($cacheFile, $lastid);
		}
		LibFc::delFunLock(mvc::$URL_METHOD);
		echo 'ok';
	}

	public function addBuy02()
	{
		exit;
		if(!LibFc::hasFunLock(mvc::$URL_METHOD, 600)) return true;
		$YpwBase = new YpwBase();
		$res = $YpwBase->get('ztemp.vins_pur', ['max(id) id'], '', true);
		$maxId = $res['data']['id'];
		$cacheFile = mvc::$cfg['LOGS'].'cache_'.mvc::$URL_METHOD.'.txt';
		$lastid = 0;
		if(file_exists($cacheFile)) $lastid = (int) file_get_contents($cacheFile);
		$per = 3000;
		for($page = 1; $page <= 50; $page++){
			$bid = $lastid;
			$eid = $bid + $per;
			$sql = sprintf("INSERT INTO `ypdb_write`.`stand_model_any`(
sma_vin, 
sma_vin1_3, 
sma_vin1_8,
sma_vin10,
sma_vin10_11,
sma_vin12_17,
sma_vin10_12,
sma_vin13_17,
sma_vyear,
sma_gxb_code, 
sma_gxb_code_show, 
sma_engine, 
sma_etime,
sma_from)
SELECT vin, 
LEFT(vin, 3), 
LEFT(vin, 8),
RIGHT(LEFT(vin, 10), 1),
RIGHT(LEFT(vin, 11), 2),
RIGHT(vin, 6),
RIGHT(LEFT(vin, 12), 3),
RIGHT(vin, 5),
vin_year,
gonggao, 
gonggao, 
engine, %d, 'buy02' FROM ztemp.vins_pur
JOIN `ypdb_write`.`yp_vin_year` ON vin_10 = RIGHT(LEFT(vin, 10), 1)
LEFT JOIN `ypdb_write`.stand_model_any on sma_vin = vin
WHERE id > %d and id <=%d and sma_vin is null GROUP BY vin", time(), $bid, $eid);
			$YpwBase->exeAnySql([$sql], false);
			$lastid = $eid;
			file_put_contents($cacheFile, $lastid);
		}
		LibFc::delFunLock(mvc::$URL_METHOD);
		echo 'ok';
	}

	//核查buy的存疑数据
	public function checkBuy()
	{
		$YpwBase = new YpwBase();
		$YpwVin = new YpwVin();
		$res = $YpwBase->get('stand_model_tj', ['distinct smt_vin1_8'], " and (smt_vin1_8 LIKE 'L%' OR smt_vin1_8 LIKE 'H%')");
		$vin8Arr = array_column($res['data'], 'smt_vin1_8');
		shuffle($vin8Arr);
		$from = 'buy02';
		$cacheFile = mvc::$cfg['LOGS'].'checkBuy.php';
		$cacheArr = [];
		$count = 500;
		foreach($vin8Arr as $tk=>$vin8){
			//if($tk == 10) break;
			if(file_exists($cacheFile)) $cacheArr = include($cacheFile);
			if(!is_array($cacheArr)) $cacheArr = [];
			if(in_array($vin8, $cacheArr)) continue;

			$vins = [];

			//若V8+V10-12对应的型号，不能在原厂，人工，采集，折达中找到，若年份>2020,直接删除掉，若年份<=2020,折达取样，至少应该取到1个，若无法取到，整体删除
			$where = sprintf(" and sma_vin1_8='%s' AND sma_from LIKE 'buy%%' 
			AND (sma_vin1_8,sma_vin10_12,sma_gxb_code) NOT IN (SELECT sma_vin1_8,sma_vin10_12,sma_gxb_code FROM stand_model_any WHERE sma_vin1_8='%s' AND sma_from IN ('epc', 'manual', 'catch', 'ZDAPI')) GROUP BY sma_vin1_8,sma_vin10_12,sma_gxb_code", $vin8, $vin8);
			$tjres = $YpwBase->get('stand_model_any', ['sma_vin1_8','sma_vin10_12', 'sma_gxb_code', 'sma_vyear'], $where);
			foreach($tjres['data'] as $tv){
				//是否为底盘
				$gxbs = [];
				$res = $YpwVin->get('gxb_base JOIN gxb_dipan ON gd_gb_id = gb_id', ['distinct gd_dpgxb_code'], sprintf(" and gb_type='gxb' and gb_gxb_code='%s'", $tv['sma_gxb_code']));
				if(!empty($res['data'])){
					$gxbs = array_column($res['data'], 'gd_dpgxb_code');
					$res = $YpwBase->get('stand_model_any', ['sma_vin'], sprintf(" and sma_vin1_8='%s' and sma_vin10_12='%s' and sma_gxb_code in ('%s') and sma_from IN ('epc', 'manual', 'catch', 'ZDAPI')", $tv['sma_vin1_8'], $tv['sma_vin10_12'], implode("','", $gxbs)));
					if(!empty($res['data'])) continue;
				}
				$gxbs[] = $tv['sma_gxb_code'];

				$delete = true;
				/*$vres = $YpwBase->get('stand_model_any', ['sma_vin', 'sma_year', 'sma_engine6'], sprintf(" and sma_vin1_8='%s' and sma_vin10_12='%s' and sma_gxb_code='%s' and sma_from LIKE 'buy%%' order by sma_vin13_17", $tv['sma_vin1_8'], $tv['sma_vin10_12'], $tv['sma_gxb_code']));
				$zdCount = 0;
				foreach($vres['data'] as $tvv){
					//有发动机号码+日期的不删除
					if($tv['sma_vyear'] >= 2017 && (strlen($tvv['sma_engine6']) >= 6 || !empty($tvv['sma_year']))){
						$delete = false;
						break;
					}
				}
				if($delete){
					foreach($vres['data'] as $tvv){
						$vin = $tvv['sma_vin'];
						if($tv['sma_vyear'] <= 2020){
							$res = $YpwVin->catchAnyVinfromZdApi([$vin], 20, 'buy');
							if(!empty($res['data'][$vin])){
								$zdCount++;
								//型号相同
								if(in_array($res['data'][$vin]['viz_gxb_code'], $gxbs)){
									$delete = false;
									break;
								}
								break;
							}
						}
					}
				}*/

				if($delete){
					$sql = sprintf("INSERT INTO zbuyerr select distinct sma_vin from stand_model_any where sma_vin1_8='%s' and sma_vin10_12='%s' and sma_gxb_code='%s' and sma_from LIKE 'buy%%' and sma_vin not in (select vin from zbuyerr)", $tv['sma_vin1_8'], $tv['sma_vin10_12'], $tv['sma_gxb_code']);
					$YpwBase->exeAnySql([$sql]);
				}
			}

			//v1-12只有自己
			/*$where = sprintf(" and sma_vin1_8='%s' AND sma_from='%s' AND (sma_vin1_8, sma_vin10_12) IN (
			SELECT sma_vin1_8, sma_vin10_12 FROM stand_model_any WHERE sma_vin1_8='%s' GROUP BY sma_vin1_8, sma_vin10_12 HAVING GROUP_CONCAT(DISTINCT sma_from) = '%s')", $vin8, $from, $vin8, $from);
			$res = $YpwBase->get('stand_model_any', ['sma_vin'], $where);
			foreach($res['data'] as $tvv){
				$vins[] = $tvv['sma_vin'];
			}*/

			$v12res = $YpwBase->get('stand_model_any', ['sma_vin1_8,sma_vin10_12'], sprintf(" and sma_vin1_8='%s' group by sma_vin1_8,sma_vin10_12", $vin8));
			foreach($v12res['data'] as $tv){
				//后4位包含字母
				/*$where = sprintf(" and sma_vin1_8='%s' and sma_vin10_12='%s' AND sma_from='%s' AND sma_vin13_17 REGEXP '[^0-9]'
				AND (sma_vin1_8, sma_vin10_12) NOT IN (
				SELECT sma_vin1_8, sma_vin10_12 FROM stand_model_any WHERE sma_vin1_8='%s' AND sma_vin10_12='%s' AND sma_from!='%s' GROUP BY sma_vin1_8, sma_vin10_12)", $tv['sma_vin1_8'], $tv['sma_vin10_12'], $from, $tv['sma_vin1_8'], $tv['sma_vin10_12'], $from);
				$res = $YpwBase->get('stand_model_any', ['sma_vin'], $where);
				foreach($res['data'] as $tvv){
					$vins[] = $tvv['sma_vin'];
				}*/

				//上下限取泽达
				/*$comwhere = sprintf(" and sma_vin1_8='%s' and sma_vin10_12='%s'", $tv['sma_vin1_8'], $tv['sma_vin10_12']);
				//上方最大值
				$res = $YpwBase->get('stand_model_any', ['sma_vin', 'sma_from', 'sma_year', 'sma_engine6'], $comwhere.' order by sma_vin13_17 desc limit 1', true);
				if(!empty($res['data']) && $res['data']['sma_from'] == $from && empty($res['data']['sma_year']) && empty($res['data']['sma_engine6']))
					$vins[] = $res['data']['sma_vin'];
				
				//下方最大值
				$res = $YpwBase->get('stand_model_any', ['sma_vin', 'sma_from', 'sma_year', 'sma_engine6'], $comwhere.' order by sma_vin13_17 asc limit 1', true);
				if(!empty($res['data']) && $res['data']['sma_from'] == $from && empty($res['data']['sma_year']) && empty($res['data']['sma_engine6']))
					$vins[] = $res['data']['sma_vin'];*/
				
				/*$comwhere = sprintf(" and sma_vin1_8='%s' and sma_vin10_12='%s' and sma_from !='%s'", $tv['sma_vin1_8'], $tv['sma_vin10_12'], $from);
				//上方最大值
				$res = $YpwBase->get('stand_model_any', ['sma_vin13_17', 'sma_from'], $comwhere.' order by sma_vin13_17 desc limit 1', true);
				if(!empty($res['data'])){
					$sql = sprintf("INSERT INTO zbuyerr select distinct sma_vin from stand_model_any where sma_vin1_8='%s' and sma_vin10_12='%s' and sma_vin13_17 > '%s' and sma_from='%s' and sma_vin not in (select vin from zbuyerr)", $tv['sma_vin1_8'], $tv['sma_vin10_12'], $res['data']['sma_vin13_17'], $from);
					$YpwBase->exeAnySql([$sql]);
				}

				//下方最大值
				$res = $YpwBase->get('stand_model_any', ['sma_vin13_17', 'sma_from'], $comwhere.' order by sma_vin13_17 asc limit 1', true);
				if(!empty($res['data'])){
					$sql = sprintf("INSERT INTO zbuyerr select distinct sma_vin from stand_model_any where sma_vin1_8='%s' and sma_vin10_12='%s' and sma_vin13_17 < '%s' and sma_from='%s' and sma_vin not in (select vin from zbuyerr)", $tv['sma_vin1_8'], $tv['sma_vin10_12'], $res['data']['sma_vin13_17'], $from);
					$YpwBase->exeAnySql([$sql]);
				}*/
			}
			if(!empty($vins)){
				$vins = array_unique($vins);
				$res = $YpwBase->get('zbuyerr', ['vin'], sprintf(" and vin in ('%s')", implode("','", $vins)));
				$hasArr = array_column($res['data'], 'vin');
				$addArr = [];
				foreach($vins as $vin){
					if(!in_array($vin, $hasArr)) $addArr[] = ['vin'=>$vin];
				}
				if($addArr) $YpwBase->addAny('zbuyerr', array_keys($addArr[0]), $addArr);
			}

			if(file_exists($cacheFile)) $cacheArr = include($cacheFile);
			if(!is_array($cacheArr)) exit;
			$cacheArr[] = $vin8;
			LibFc::ArraySave($cacheArr, $cacheFile);
			$count--;
			if($count == 0) break;
			//LibLog::write($vin8);
		}
		echo 'ok';
	}

	//计算ETK VIN
	public function jsEtkVin()
	{
		$Ypc67Base = new BaseDb(mvc::$cfg['DB']['YPCAR67']);
		$YpcVin = new YpcVin();
		$YpwVin = new YpwVin();
		$table = "yp_model3 a
		JOIN yp_model2 ON m2_id = m3_m2_id
		JOIN yp_model1 ON m1_id = m2_m1_id
		JOIN yp_brand ON b_id = m1_b_id
		join yp_model3_gxb_num ON mg_m3_id = m3_id
		join yp_vin_model3_link ON vm3_m3_id = m3_id
		join yp_vin on vin_id = vm3_vin_id
		LEFT JOIN yp_model3_size ON m3s_m3_id = m3_id
		LEFT JOIN yp_model3_etkvin_demos ON med_m3_id = m3_id
		LEFT JOIN yp_model3_etk_code ON mec_m3_id = m3_id";
		$where = " and m3_id not in (select med_m3_id from yp_model3_etkvin_demos where med_status in (0,1)) and b_etk_id = 18 AND (mec_id IS NULL OR mec_epc_status != 3 OR mec_epc_date = '1970-01-01') group by m3_id";
		$tres = $Ypc67Base->get($table, ['a.*', 'group_concat(distinct mg_code) as gxbs','group_concat(distinct mec_code) as mec_codes','group_concat(distinct vin_full) as vin18s','group_concat(distinct m3s_length) as length','group_concat(distinct m3s_width) as width','group_concat(distinct m3s_height) as height','group_concat(distinct med_vin) as med_vin'], $where);
		$arr = [];
		foreach($tres['data'] as $v){
			$fromArr = ['ZDAPI','catch','manual','ocr','rgany','epc','org','buy01'];
			$haschkVins = $v['med_vin']? explode(',', $v['med_vin']): [];
			$isok = false;
			foreach($fromArr as $from){
				$comwhere = sprintf(" and sma_vin1_8 in ('%s') and sma_gxb_code in ('%s') AND sma_engine ='%s' AND sma_from = '%s'", implode("','", explode(',', $v['vin18s'])), implode("','", explode(',', $v['gxbs'])), $v['m3_engine'], $from);
				if(!empty($v['m3_cc'])) $comwhere .= sprintf(" AND sma_cc='%s'", $v['m3_cc']);
				if(!empty($v['m3_start_month'])) 
					$comwhere .= sprintf(" and length(sma_year) >= 7 AND left(sma_year, 7) >= '%s'", $v['m3_start_year'].'-'.$v['m3_start_month']);
				else if(!empty($v['m3_start_year'])) 
					$comwhere .= sprintf(" and length(sma_year) >= 4 AND left(sma_year, 4) >= %d", $v['m3_start_year']);

				if(!empty($v['m3_end_month'])) 
					$comwhere .= sprintf(" and length(sma_year) >= 7 AND left(sma_year, 7) <= '%s'", $v['m3_end_year'].'-'.$v['m3_end_month']);
				else if(!empty($v['m3_end_year'])) 
					$comwhere .= sprintf(" and length(sma_year) >= 4 AND left(sma_year, 4) <= %d", $v['m3_end_year']);

				if(!empty($v['m3_vin10'])) $comwhere .= sprintf(" AND sma_vin10 in ('%s')", implode("','", str_split($v['m3_vin10'])));
				if(!empty($v['m3_vin11'])) $comwhere .= sprintf(" AND right(sma_vin10_11, 1) in ('%s')", implode("','", str_split($v['m3_vin11'])));
				if(!empty($v['m3_vin12'])) $comwhere .= sprintf(" AND right(sma_vin10_12, 1) in ('%s')", implode("','", str_split($v['m3_vin12'])));
				
				$twhere = [];
				if(!empty($v['m3_wheel'])) $twhere[] = sprintf(" AND sma_wheel = %d", $v['m3_wheel']);
				if(!empty($v['m3_weight'])) $twhere[] = sprintf(" AND sma_weight = %d", $v['m3_weight']);
				$size = '';
				if(!empty($v['length'])) $size .= sprintf(" and sma_length in (%s) and sma_length > 0", $v['length']);
				if(!empty($v['width'])) $size .= sprintf(" and sma_width in (%s) and sma_width > 0", $v['width']);
				if(!empty($v['height'])) $size .= sprintf(" and sma_height in (%s) and sma_height > 0", $v['height']);
				if($size) $twhere[] = $size;
				if($twhere){
					$twhereList = $this->getWhereCombinations($twhere);
				}else{
					$twhereList = [''];
				}
				foreach($twhereList as $tw){
					$ewhere = $comwhere.$tw;
					if(!empty($haschkVins)) $ewhere .= sprintf(" AND sma_vin not in ('%s')", implode("','", $haschkVins));
					$res = $YpwVin->get('stand_model_any', ['count(*) as total'], $ewhere, true);
					$total = $res['data']['total'];
					if($total == 0) continue;
					$mid = max(0, intval(($total - $per) / 2));
					$offsets = [$mid];
					$per = 100;
					for ($i = $per; $i < $total; $i += $per) {
						if ($mid - $i >= 0) {
							$offsets[] = $mid - $i;
						}
						if ($mid + $i < $total) {
							$offsets[] = $mid + $i;
						}
					}
					foreach ($offsets as $offset) {
						$vres = $YpwVin->get('stand_model_any', ['sma_vin'], $ewhere . " LIMIT {$offset},{$per}");
						foreach($vres['data'] as $tk=>$tv){
							if($tk%10 !== 0) continue;//取1/10
							$haschkVins[] = $tv['sma_vin'];
							$res = $YpcVin->decodeVin($tv['sma_vin']);
							if($res['data']['from'] == 'ypc' && !empty($res['data']['model']) && in_array($v['m3_id'], array_column($res['data']['model'], 'mod3_id'))){
								$Ypc67Base->add('yp_model3_etkvin_demos', ['med_vin'=>$tv['sma_vin'], 'med_atime'=>time(), 'med_m3_id'=> $v['m3_id'], 'med_remark'=>$comwhere.$tw]);
								$isok = true;
								break;
							}
						}
						if($isok || count($haschkVins) > 500) break;
					}
					if($isok || count($haschkVins) > 500) break;
				}
				if($isok || count($haschkVins) > 500) break;
			}
		}
		echo 'ok';
	}


	function getWhereCombinations($arr){
		$res = [];
		$n = count($arr);
		for ($i = 1; $i < (1 << $n); $i++) {
			$tmp = [];
			for ($j = 0; $j < $n; $j++) {
				if ($i & (1 << $j)) {
					$tmp[] = $arr[$j];
				}
			}
			$res[count($tmp)][] = implode('', $tmp);
		}
		krsort($res);
		return array_merge(...$res);
	}
}