<?php
use GuzzleHttp\Client;
use GuzzleHttp\TransferStats;
use GuzzleHttp\Psr7\Uri;
use GuzzleHttp\Cookie\CookieJar;
use Illuminate\Database\Capsule\Manager as Capsule;
include(mvc::$cfg['PATH_MVC'].'lib/lib/Sunra/PhpSimple/HtmlDomParser.php');
use Sunra\PhpSimple\HtmlDomParser;
use Nesk\Puphpeteer\Puppeteer;
use Nesk\Rialto\Data\JsFunction;
/**
  * @method 600w表
  * @author soul
  * @copyright 2016/3/31
  */
class YpwVin extends YpwBase
{
	//需要转换的发动机
	public $replaceEngines = [
		'-4G15'=>'JLγ-4G15'	
	];
	public function __construct()
	{
		parent::__construct();
		LibFc::useMainDb();
	}

	/**
	  * @method 车架号扫描图 //2024/8/16 交由消息队列处理
	  * @param  $imgdata            string  [必填] 图片内容信息base64 base64_encode(file_get_contents('D:\www\ocr/ocr.jpg'))
	  * @param  $vin                string [必填] 车架号
	  * @param  $othArr            string  [选填] ['imgname'=>'vin.jpg', 'vinocr'=>'wt:文通  yt:译图(默认)']
	  * @author soul
	  * @copyright 2017/9/30
	  * @return 
	  {"status":true,"data": [],"code":""}
	  {"status":false,"data":'失败原因',"code":''}
	  */
	public function collOcrVinImg($vin, $imgdata, $othArr = [])
	{
		//return $this->addCollVinImg($vin, $imgdata, $othArr);
		$temp = [
			'DTYPE'=>'VINIMG',	
			'vin'=>$vin,
			'imgdata'=>$imgdata,
			'othdata'=>$othArr,
			'atime'=>time()
		];
		$allTjArr = [json_encode($temp)];
		$MainRabbit = new MainRabbit('TJ_OTH');
		$MainRabbit->send($allTjArr);
		return LibFc::ReturnData(true);
	}


	/**
	  * @method 车架号扫描图入库
	  * @param  $imgdata            string  [必填] 图片内容信息base64 base64_encode(file_get_contents('D:\www\ocr/ocr.jpg'))
	  * @param  $vin                string [必填] 车架号
	  * @param  $othArr            string  [选填] ['imgname'=>'vin.jpg', 'vinocr'=>'wt:文通  yt:译图(默认)']
	  * @author soul
	  * @copyright 2017/9/30
	  * @return 
	  {"status":true,"data": [],"code":""}
	  {"status":false,"data":'失败原因',"code":''}
	  */
	public function addCollVinImg($vin, $imgdata, $othArr = [])
	{
		
		$vin = LibFc::FormatVin($vin);
		if(strlen($vin) != 17) return LibFc::ReturnData(true);
		$vin1 = substr($vin, 0, 1);
		$isJinkou = !in_array($vin1, ['L', 'H'])? true: false;
		if(!$isJinkou){
			$check = LibFc::VinCheckCode($vin);
			if(!$check['ok']) return LibFc::ReturnData(true);
		}

		$wmi = substr($vin, 0, 3);
		$v18 = substr($vin, 0, 8);
		$year = LibFc::VinYear(substr($vin, 9, 1));
		
		//在错误规则里？
		$res = $this->get('stand_vin_errreg', ['vrr_wmi'], sprintf(" and vrr_wmi='%s' and vrr_max_year >= %d", $wmi, $year), true);
		if(!empty($res['data'])) return LibFc::ReturnData(true);
		
		$vii_status = 0;
		//总表是否有
		$res = $this->get('stand_model_any', ['sma_id'], sprintf(" and sma_vin='%s'", $vin), true);
		if(!empty($res['data']))
		{
			$vii_status = 1;
			//保留一张图片
			$res = $this->get('stand_vin_imgs', ['vii_vin'], sprintf(" and vii_vin='%s' limit 1", $vin), true);
			if(!empty($res['data'])) return LibFc::ReturnData(true);
		}
		if(empty($othArr['imgname'])) $othArr['imgname'] = getimagesizefromstring(base64_decode($imgdata)) == 'image/png'? 'vin.png':'vin.jpg';
		$atime = $othArr['atime']? (int) $othArr['atime']: time();
		if(!empty($imgdata))
		{
			$MainOcr = new MainOcr();
			try {

				$res = $MainOcr->vinCls($imgdata);
				$imgcls = $res['data'];
				$imgtype = 0;
				if(in_array($imgcls, ['xsz','hgz', 'djzs'])){
					$imgtype = 1;
				}else if($imgcls == 'mp'){
					$imgtype = 2;
				}else{
					return LibFc::ReturnData(true);
				}

				//是否需要旋转角度
				$res = $MainOcr->getAngle($imgdata);
				$angle = null;
				if($res['status']){
					$angle = $res['data'];
					if($angle != 0){
						$res = LibFc::rotateImg($angle, $imgdata, 'base64', 'base64');
						if($res['status'] && !empty($res['data'])){
							$imgdata = $res['data'];
						}else{
							$angle = null;
						}
					}
				}

				$res = $MainOcr->getVinInfoArea($imgdata);
				$detres = $res['data'];
				if($detres['pos']){
					if($detres['match'] >= 0.6){
						$res = LibFc::cropImage($imgdata, $detres['pos'], 'base64', 'base64');
						if($res['status'] && !empty($res['data'])){
							$imgdata = $res['data'];
							$crop = 1; //裁剪失败
						}else{
							$crop = -1; //裁剪失败
						}
					}else{
						$crop = -3;//准确率过低
					}
				}else{
					$crop = -2;//检测不到
				}
				
				//验证VIN前8
				if($vii_status == 0){
					$res = $this->get('stand_model_any', ['sma_id'], sprintf(" and sma_vin1_8='%s' limit 1", $v18), true);
					if(empty($res['data'])){
						foreach(['yt', 'ocr'] as $vtype){
							$tvin = '';
							if($vtype == 'yt'){
								$res = $MainOcr->vin($imgdata, ['site'=>'yt', 'nocoll'=>true]);
								$tvin = $res['data'];
							}else{
								$res = $MainOcr->paddleOcr($image);
								$ocrtxt = implode("\n", $res['data']);
								if(preg_match_all('/[0-9A-Z]{14}\d{3}/i', $ocrtxt, $matches)){
									foreach($matches[0] as $tvin){
										$check = LibFc::VinCheckCode($tvin);
										if($check['ok']) break;
									}
								}
							}
							if(strlen($tvin) == 17 && $tvin != $vin){
								$res = $this->get('stand_model_any', ['sma_id'], sprintf(" and sma_vin1_8='%s' limit 1", substr($tvin, 0, 8)), true);
								if(!empty($res['data'])){
									$vin = $tvin;
									$wmi = substr($vin, 0, 3);
									$v18 = substr($vin, 0, 8);
									$year = LibFc::VinYear(substr($vin, 9, 1));
									$othArr['vinocr'] = $vtype;
									break;
								}
							}
						}
					}
				}
				$toSite = 'yp';
				$cfg = mvc::$cfg['FILE_CENTER'][$toSite];
				$dataArr = [
					'token'=>$cfg['token'],
					'cate'=>'vinimg',
					'file'=>[
						'name'=>$othArr['imgname'],
						'data'=>base64_decode($imgdata),
					]
				];
				$LibHttp = new LibHttp(false,false);
				$ires = $LibHttp->upload($cfg['url_put'], $dataArr);
				if($ires['status']){
					$img = $ires['data'];
					$res = $this->get('yp_allvin_base', ['alb_vin'], sprintf(" and alb_vin='%s' and alb_date != '' and alb_from != 'ocr'", $vin), true);
					if(empty($vii_status) && !empty($res['data'])) $vii_status = -3;
					$add = [
						'vii_vin'=>$vin,
						'vii_status'=>$vii_status,
						'vii_vin1_3'=>$wmi,
						'vii_vin1_8'=>$v18,
						'vii_vin10_12'=>substr($vin, 9, 3),
						'vii_vin13_17'=>substr($vin, 12, 5),
						'vii_year'=>$year,
						'vii_img'=>$img['path'].$img['small'].$img['name'].'.'.$img['ext'],
						'vii_imgtype'=>$imgtype,
						'vii_atime'=>$atime,
						'vii_vinocr'=>empty($othArr['vinocr'])? '': $othArr['vinocr'],
					];
					if($crop !== null) $add['vii_crop'] = $crop;
					if($vii_status == 1){
						$add['vii_check_uid'] = 8;
						$add['vii_check_time'] = $atime;
					}
					$this->YpwDb->Begin();
					$this->add('stand_vin_imgs', $add);
					$YpcVin = new YpcVin();
					$YpcVin->tongjiVin($vin, '');
					$this->YpwDb->End();
					return LibFc::ReturnData(true, $add);
				}
			}catch (Exception $e) {
				//echo $e->getMessage();
				return LibFc::ReturnData(true);
			}
		}
		return LibFc::ReturnData(true);
	}

	/**
	  * @method get 采集环保信息随车清单
	  * @param  token              string [必填] 调用接口凭证 (post|get)
	  * @param  vin            string  [必填] 车架号
	  * @param  engine6     string  [必填] 行驶证的发动机编码后6位
	  * @author soul
	  * @copyright 2020/6/5
	  * @return 
	  */
	public function catchVinQingdan($vin, $engine6 = '', $run = 0, $usecache = 1, $realUrls = [])
	{
		$usecache = $usecache == -1? false: true;
		$run++;
		$vin = LibFc::FormatVin($vin);
		$arr = [];
		if(strlen($vin) != 17) return LibFc::ReturnData(false, '请提供17位的车架号');
		
		$reArr = [
			"\r\n"=>"\n",
			"："=>":",
			'&nbsp;'=>' ',
			'&#160;'=>'',
			'（'=>'(',
			'）'=>')',
			'<<'=>'<'
		];
		
		$h = date('H');
		if($h < 7 || $h >= 20) return LibFc::ReturnData(false, '可查询时间为7:00~20:00', 'nowork');

		$engine6 = LibFc::FormatNum($engine6, '-');
		if(strlen($engine6) < 6) return LibFc::ReturnData(false, '请提供发动机编号后6位');
		$html = '';
		$jsonData = [];
		if($realUrls['api']){
			$url = $realUrls['api'];
			for($i = 1; $i <= 3;$i++){
				$LibHttp = new LibHttp();
				$LibHttp->timeout = 20;
				$html = $LibHttp->fetch($url);
				$jsonData = json_decode($html, true);
				if(is_array($jsonData)){
					break;
				}else{
					usleep(300000);
				}
			}
		}else if($realUrls['url']){		
			for($i = 1; $i <= 3;$i++){
				$LibHttp = new LibHttp();
				$LibHttp->timeout = 20;
				$html = $LibHttp->fetch($realUrls['url']);
				if(!empty($html)){
					break;
				}else{
					usleep(300000);
				}
			}
		}
		if(empty($html)){
			$oClient = new Client([
				'debug' => false,
				'timeout' => 10,
				'cookies' => true,
				'verify'=>false,
				'base_uri' => 'https://info.vecc.org.cn',
			]);

			$header = [
				'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36',
				'Host' => 'info.vecc.org.cn',
				'Origin' => 'https://info.vecc.org.cn',
				'Pragma' => 'no-cache',
				'Referer' => 'https://info.vecc.org.cn/ve/vin/index',
				'sec-ch-ua' => '" Not;A Brand";v="99", "Google Chrome";v="97", "Chromium";v="97"',
				'sec-ch-ua-mobile' => '?0',
				'sec-ch-ua-platform' => '"Windows"',
				'Sec-Fetch-Dest' => 'document',
				'Sec-Fetch-Mode' => 'navigate',
				'Sec-Fetch-Site' => 'same-origin',
				'Sec-Fetch-User' => '?1',
				'Upgrade-Insecure-Requests' => '1',
			];
			
			$sCache = '';
			$oCookie = new CookieJar();
			try {
				$oGuzzle = $oClient->get(sprintf('/ve/kaptcha.jpg?t=%d', time()), [
					'cookies' => $oCookie,
					'headers' => $header
				]);
				if (200 != $oGuzzle->getStatusCode()){
					if($run < 3) return $this->catchVinQingdan($vin, $engine6, $run, $usecache, $realUrls);
					return LibFc::ReturnData(false, '验证码获取失败1，请重试');
				}
			} catch (\GuzzleHttp\Exception\TransferException $oTransfer) {
				 if($run < 3) return $this->catchVinQingdan($vin, $engine6, $run, $usecache, $realUrls);
				 return LibFc::ReturnData(false, '验证码获取失败2，请重试');
			}
		
			$sCache = $oGuzzle->getBody()->getContents();
			// 第二步识别验证码
			$OthCodeOcr = new OthCodeOcr();
			$imgcodedata = base64_encode($sCache);
			$aOther = $OthCodeOcr->getCodeOcr($imgcodedata, 'vecc2', 'self');
			$imgocr = $aOther['data'];
			// 第三步请求信息
			if (empty($imgocr['imgcode'])) return LibFc::ReturnData(false, '验证码识别失败3，请重试');
			try {
				$oGuzzle = $oClient->post('/ve/vin/index', [
					'cookies' => $oCookie,
					'form_params' => [
						'vaild' => $imgocr['jscode'],
						'fdjh' => substr($engine6, -6),
						'vin' => $vin
					],
					'headers' => $header,
					'on_stats' => function (TransferStats $stats) use (&$realUrls) {
						if ($stats->hasResponse()) {
							$turl = (string)$stats->getEffectiveUri();
							if(stripos($turl, 'key1=')) $realUrls['url'] = $turl;
							if(stripos($turl, '/scqd/') && preg_match('/\/([0-9a-zA-Z]{48})$/', $turl, $match))
								$realUrls['api'] = 'http://xxgk.vecc.org.cn/prod-api/server/getVinInfo/'.$match[1];
						}
					},
					'allow_redirects' => ['max' => 3,'track_redirects' => true]
				]);
				if (200 != $oGuzzle->getStatusCode()){
					if($run < 3) return $this->catchVinQingdan($vin, $engine6, $run, $usecache, $realUrls);
					return LibFc::ReturnData(false, '清单获取失败2，请重试');
				}
			}catch (\GuzzleHttp\Exception\TransferException $oTransfer) {
				if($run < 3) return $this->catchVinQingdan($vin, $engine6, $run, $usecache, $realUrls);
				return LibFc::ReturnData(false, '清单获取失败1，请重试');
			}
			$html = $oGuzzle->getBody()->getContents();
		}
		
		if($realUrls['url']) $arr['url'] = $realUrls['url'];
		$isGuochan = in_array(substr($vin, 0, 1), ['L','H'])? true: false;
		if($jsonData){
			//json模式
			if(!empty($jsonData['data']['clsVin']['vin']) && $jsonData['data']['clsVin']['vin'] == $vin){
				$clsVin = $jsonData['data']['clsVin'];
				$o3xxgk = $jsonData['data']['o3xxgk'];
				$hzbs = $jsonData['data']['hzbs'][0];
				if(!$isGuochan && $clsVin['sb']){
					$arr['sma_brand'] = $clsVin['sb'];
					if(preg_match('/([^\n]+)\([^\)]*\)/iUs', $arr['sma_brand'], $match)){
						$arr['sma_brand'] = $match[1];
					}
				}
				if($o3xxgk['clxh']) $arr['sma_gxb_code_show'] = $o3xxgk['clxh'];
				if($o3xxgk['fdjxh']){
					$arr['sma_engine'] = $o3xxgk['fdjxh'];
					$arr['sma_engine'] = strtr($arr['sma_engine'], ['前:'=>'', '后:'=>'','前左:'=>'','前右:'=>'','后左:'=>'','后右:'=>'','前'=>'', '后'=>'', ','=>'/', ';'=>'/', '，'=>'/', '；'=>'/']);
				}

				if($hzbs['BSQXS']) $arr['sma_tran'] = $hzbs['BSQXS'].'/'.$hzbs['DWS'];
				if($clsVin['zcdl'] && !in_array($clsVin['zcdl'], ['无', '不适用'])) $arr['sma_xuhang'] = $clsVin['zcdl'].'/'.$clsVin['xslcgk'];
				
				$gbArr = [1=>'一',2=>'二',3=>'三',4=>'四',5=>'五',6=>'六',7=>'七'];
				if($o3xxgk['pf']) $arr['paifang'] = $gbArr[$o3xxgk['pf']]? '国'.$gbArr[$o3xxgk['pf']] : '国'.$o3xxgk['pf'];
				if(preg_match('/(\d{4})[-年](\d{1,2})[-月](\d{1,2})[日]?/', $clsVin['scdate'], $match)){
					$date = new DateTime($clsVin['scdate']);
					$date->setTimezone(new DateTimeZone('Asia/Shanghai'));
					$arr['sma_year'] = $date->format('Y-m-d');
					if(strtotime($arr['sma_year']) > strtotime('+7 day')) unset($arr['sma_year']);
					if(!$isGuochan && strlen($arr['sma_year']) == 10 && substr($arr['sma_year'], -2) == '01')
						$arr['sma_year'] = date('Y-m', strtotime($arr['sma_year']));
				}
				foreach($arr as $filed=>$fval){
					if($filed == 'sma_tran'){
						$renull = ['/--'=>'', 'æå¨/5'=>'', '/不适用'=>'', '/无'=>'', '/0'=>'', '	'=>''];
						$fval = strtr($fval, $renull);
					}
					if($filed == 'sma_xuhang'){
						$renull = ['/不适用'=>'', '/无'=>'', '	'=>''];
						$fval = strtr($fval, $renull);
					}
					if(in_array($fval, ['空', '无', '无Ah', '无Ah/无', 'Ah/km'])) $fval = '';

					if(!empty($fval)){
						$arr[$filed] = $fval;
					}else{
						unset($arr[$filed]);
					}
				}
			}else{
				return LibFc::ReturnData(false, '清单VIN不符'.$html);
			}
		}else{
			//html模式
			if(stripos($html, 'gb2312'))
			{
				$t = iconv("gb2312","utf-8", $html);
				$html = !$t || strlen($t) < 100 ? iconv("gbk","utf-8//IGNORE", $html): $t;
			}
			$html = strip_tags(strtr($html, $reArr));
			//是否有错误
			if(preg_match('/f\(\'([^\']+)\'\)\{\s*alert\(\'/', $html, $match))
			{
				$t = '{"str":"'.$match[1].'"}';
				$t = json_decode($t,true);

				//验证码错误，重新回调一次
				if(stripos($t['str'], '验证码错误') !== false)
				{
					if($run < 3) return $this->catchVinQingdan($vin, $engine6, $run, $usecache, $realUrls);
				}
				//错误汇总
				if(stripos($t['str'], '未做信息公开') !== false || stripos($t['str'], '未信息公开') !== false) 
				{
					$t['str'] = '车辆信息未公开';
				}
				else if(stripos($t['str'], '公开不符') !== false) 
				{
					$t['str'] = '发动机编号不符';
				}
				return LibFc::ReturnData(false, $t['str']);
			}
			if(stripos($html, $vin) === false || strlen($html) < 100){
				if($run < 3) return $this->catchVinQingdan($vin, $engine6, $run, $usecache, $realUrls);
				return LibFc::ReturnData(false, '清单获取失败3，请重试');
			}

			$html = strip_tags(strtr($html, $reArr));
			//\n \n \n=>\n
			$html = preg_replace('/( *\n *){2,}/', "\n", $html);
			//echo $html;
			$matchErr = '';

			$allTempReg = [
				//车辆型号: \n \n \n SGM7100JBA1\n \n \n \n \n \n  车辆型号:BAW2033CGA1
				'sma_gxb_code_show'=>[
					'/车辆型号:\s*([a-zA-Z]{1,2}[\S ]+)\s*/i',
					'/车辆型号:\s*([\S ]+)\s*/i'
				],
				'sma_engine'=>[
					'/发动机型号[^:\n]*:\s+([\S ]+)\s*/i',
					'/电动机型号\/生产[^:\n]*:\s+([\S ]+)\s*/i',
				],
				'engine_b'=>[
					'/电动机型号\/生产企业[^:\n]*:\s+([\S ]+)\s*/i',
					'/驱动电机型号\/生产企业[^:\n]*:\s+([\S ]+)\s*/i',
				],
				'sma_tran'=>[
					'/变速器型式[^:\n]*:\s+([\S ]+)\s*/i',
				],
				'sma_xuhang'=>[
					'/电池容量[^:\n]*:\s+([\S ]+)\s*/i',
				],
				'paifang'=>[
					'/排放阶段[^:\n]*:\s+([\S ]+)\s*/i',
				]
			];
			
			foreach($allTempReg as $filed=>$tRegArr)
			{
				if($filed == 'sma_engine' && !empty($arr['sma_gxb_code_show']))
				{
					$eres = $this->getGxbEngs($arr['sma_gxb_code_show']);
					foreach($eres['data'] as $eng)
					{
						if(strlen($eng) > 2 && stripos($html, $eng) !== false)
						{
							$arr[$filed] = $eng;
							break;
						}
					}
					if(!empty($arr[$filed])) continue;
				}

				foreach($tRegArr as $tReg)
				{
					if(empty($tReg)) continue;
					if(preg_match($tReg, $html, $match))
					{
						$fval = trim($match[1]);
						if(in_array($filed, ['sma_engine', 'engine_b']))
						{
							//LC0CF4CD9K1012037 001177 前BYD-2018TZ-XS-A/后BYD-2018TZ-XS-B/长沙市比亚迪汽车有限公司
							//LE48P9AB4LL000406 002866 前:EM0016,后:EM0021/前:ZF,后:ZF
							//LJ1E6A2U1L7710753 D519037 前:TZ160S001/后:YS240S001/前:蔚然(南京)动力科技有限公司/后:蔚然(南京)动力科技有限公司
							//LRDV7PEC1KR032778 000817  OM457 LA.V/31
							//LFMA854K5MS009368 944833  A25B/TOYOTA MOTOR CORPORATION
							if(strrpos($fval, '/'))
							{
								$exArr = explode('/', $fval);
								$tevals = [];
								foreach($exArr as $ek=>$ev)
								{
									if($ek > 0)
									{
										if(!preg_match('/[a-zA-Z0-9]{2,}/', $ev, $match)) break;
										if(stripos($ev, 'TOYOTA') !== false) break;
										//最后一个有中文的直接剔除
										if(count($exArr) == ($ek +1) && (
												!$isGuochan || 
												($isGuochan && preg_match('/[\x{4e00}-\x{9fa5}]/ui', $ev, $match))
											)
										) break;
									}
									$tevals[] = $ev;
								}
								$fval = implode('/', $tevals);
							}
							$fval = strtr($fval, ['前:'=>'', '后:'=>'','前左:'=>'','前右:'=>'','后左:'=>'','后右:'=>'','前'=>'', '后'=>'', ','=>'/', ';'=>'/', '，'=>'/', '；'=>'/']);
							if(!preg_match('/[a-zA-Z0-9]{'.($isGuochan? 2: 1).',}/', $fval, $match)) $fval = '';
						}
						else if($filed == 'sma_gxb_code_show' && (strlen(LibFc::FormatNum($fval)) > 48 || empty(LibFc::FormatNum($fval))))
						{
							$fval = '';
						}

						if($filed == 'sma_tran')
						{
							$renull = ['/--'=>'', 'æå¨/5'=>'', '/不适用'=>'', '/无'=>'', '/0'=>'', '	'=>''];
							$fval = strtr($fval, $renull);
						}

						if($filed == 'sma_xuhang')
						{
							$renull = ['/不适用'=>'', '/无'=>'', '	'=>''];
							$fval = strtr($fval, $renull);
						}
						if(in_array($fval, ['空', '无', '无Ah', '无Ah/无', 'Ah/km'])) $fval = '';

						if(!empty($fval))
						{
							$arr[$filed] = $fval;
							break;
						}
					}
				}
			}

			//进口车
			if(!$isGuochan)
			{
				if(preg_match('/商 *标 *:\s*([^\n]+)\([^\n]*\n/iUs', $html, $match))
					$arr['sma_brand'] = $match[1];
				else if(preg_match('/商 *标 *:\s*([^\n]+)\n/iUs', $html, $match))
					$arr['sma_brand'] = $match[1];
			}

			//车辆生产日期:2019-05-29
			if(preg_match('/生产日期:?\s*(\d{4})[-年](\d{1,2})[-月](\d{1,2})[日]?/', $html, $match))
			{
				$arr['sma_year'] = date('Y-m-d', strtotime($match[1].'-'.$match[2].'-'.$match[3]));
				if(strtotime($arr['sma_year']) > strtotime('+7 day')) unset($arr['sma_year']);

				if(!$isGuochan && strlen($arr['sma_year']) == 10 && substr($arr['sma_year'], -2) == '01')
					$arr['sma_year'] = date('Y-m', strtotime($arr['sma_year']));
			}
			
			if(preg_match('/进口日期:?\s*(\d{4})[-年](\d{1,2})[-月](\d{1,2})[日]?/', $html, $match))
			{
				$arr['sma_jkyear'] = date('Y-m-d', strtotime($match[1].'-'.$match[2].'-'.$match[3]));
				if(strtotime($arr['sma_jkyear']) > strtotime('+7 day')) unset($arr['sma_jkyear']);
			}
		}
		if(empty($arr['sma_gxb_code_show'])) return LibFc::ReturnData(false, '车辆型号无法匹配，请重试');

		$res = $this->get('stand_vin_file', ['vf_id'], sprintf(" and vf_vin='%s' and (vf_url like '%%key1=%%' or vf_url like '%%/scqd/%%')", $vin));
		if(empty($res['data']))
			$this->add('stand_vin_file', ['vf_vin'=>$vin, 'vf_url'=>$arr['url']]);

		if($matchErr != '')
		{
			return LibFc::ReturnData(false, $matchErr);
		}
		if(!empty($arr['sma_gxb_code_show'])&& empty($arr['sma_engine6'])) $arr['sma_engine6'] = $engine6;

		if(!empty($arr['sma_tran']))
		{
			$res = $this->formatTran($arr['sma_tran']);
			if(!empty($res['data']['tran']))
				$arr['sma_tran'] = $res['data']['tran'];
		}

		$YpwGxb = new YpwGxb();
		$res = $YpwGxb->formatPaifang($arr['paifang']);
		$arr['paifang'] = $res['data']['format'];
		return LibFc::ReturnData(true, $arr);
	}


	/**
	  * @method 从泽达API获取车架号信息
	  * @param  $vinArr  array [必填] 车架号 ["LA69BAA3XHB512452","LEFDJ3BB8HTP40468"]
	  * @author soul
	  * @copyright 2021/1/7
	  * @return 
	  */
	public function catchAnyVinfromZdApi($vinArr, $timeout = 10, $from = '')
	{
		$arr = [];
		foreach($vinArr as $v)
		{
			$v = LibFc::FormatVin($v);
			if(strlen($v) == 17) $arr[$v] = [];
		}
		if(empty($arr)) return LibFc::ReturnData(true, $arr);
		
		//已有的
		$filed = ['viz_id,viz_vin,viz_vin1_8,viz_vin10_12,viz_vin13_17,viz_gxb_code,viz_gxb_code_show,viz_brand,viz_mod1,viz_engine,viz_cc,viz_kw,viz_length,viz_width,viz_height,viz_wheel,viz_axle,viz_weight,viz_passenger,viz_vtype,viz_year,viz_fzrq,viz_pfbz,viz_zgcs,viz_ltgg,viz_jsszcrs,viz_atime,sma_id'];
		$res = $this->get('stand_vin_zdapi as a join stand_model_any on viz_vin=sma_vin', $filed, sprintf(" and viz_vin in ('%s')", implode("','", array_keys($arr))));
		foreach($res['data'] as $tv)
		{
			$arr[$tv['viz_vin']] = $tv;
		}
		
		//需要采集的 10个一组
		$needCatchVin = [];
		$i = 0;
		foreach($arr as $tk=>$tv)
		{
			if(empty($tv))
			{
				$needCatchVin[$i][] = $tk;
				if(count($needCatchVin[$i]) == 10) $i++;
			}
		}
		
		$addCatchArr = [];
		if(!empty($needCatchVin[0]))
		{
			$catchArr = [];
			$LibHttp = new LibHttp();
			$LibHttp->timeout = $timeout;
			$LibHttp->httpheader = ['Content-Type:application/x-www-form-urlencoded'];
			foreach($needCatchVin as $pv)
			{
				//接口不支持一个，临时使用
				if(count($pv) == 1) $pv[] = $pv[0];
				$post = [
					'key'=>	mvc::$cfg['ZDAPI']['key'],
					'vin'=>	implode(',', $pv),
				];
				try {
					$res = $LibHttp->fetch(mvc::$cfg['ZDAPI']['url'].'VinInterfaceZD1229', $post);
					$resArr = json_decode($res, true);
					if(!is_array($resArr) || $resArr['code'] != 0 || !is_array($resArr['data'])) return LibFc::ReturnData(true, $arr);
					foreach($resArr['data'] as $tv)
					{
						$catchArr[] = $tv;
					}
				}catch (Exception $e) {
					//echo implode(',', $pv).$e->getMessage();
					return LibFc::ReturnData(false, 'zderror'.$e->getMessage());
				}
			}
			
			foreach($catchArr as $tv)
			{
				$vin = LibFc::FormatVin($tv['CLSBDH']);
				if(empty($tv['CLXH']) || strlen($vin) != 17) continue;
				//核定载客 WBAKR010100J25096
				if(!empty($tv['EDZK']) && $tv['EDZK'] > 100) $tv['EDZK'] = 0;
				//LJ1EFKRN5A4227978
				if(preg_match('/(.{2,})\(电/i', $tv['FDJXH'], $match))
					$tv['FDJXH'] = $match[1];
				$arr[$vin] = [
					'viz_vin'=>$vin,
					'viz_vin1_8'=>substr($vin, 0, 8),
					'viz_vin10_12'=>substr($vin, 9, 3),
					'viz_vin13_17'=>substr($vin, 12, 5),
					'viz_gxb_code'=>LibFc::FormatNum($tv['CLXH']),
					'viz_gxb_code_show'=>$tv['CLXH'],
					'viz_brand'=>$tv['CLPP'],
					'viz_mod1'=>$tv['ModelName'],
					'viz_engine'=>$tv['FDJXH'],
					'viz_cc'=>$tv['PL'],
					'viz_kw'=>$tv['GL'],
					'viz_length'=>$tv['WKC'],
					'viz_width'=>$tv['WKK'],
					'viz_height'=>$tv['WKG'],
					'viz_wheel'=>$tv['ZJ'],
					'viz_axle'=>$tv['ZS'] < 20? $tv['ZS']: 0,
					'viz_weight'=>$tv['ZBZL'],
					'viz_passenger'=>$tv['EDZK'],
					'viz_vtype'=>$tv['CLLX'],
					'viz_fzrq'=>strlen($tv['FZRQ']) >= 10? date('Y-m-d', strtotime($tv['FZRQ'])): '',
					'viz_passenger'=>$tv['EDZK'],
					'viz_pfbz'=>$tv['PFBZ'],
					'viz_zgcs'=>$tv['ZGCS'],
					'viz_ltgg'=>$tv['LTGG'],
					'viz_jsszcrs'=>$tv['JSSZCRS'],
					'viz_year'=>strlen($tv['CLZZRQ']) >= 10? date('Y-m-d', strtotime($tv['CLZZRQ'])): '',
					'viz_atime'=>time(),
					'viz_json'=>json_encode($tv),
					'viz_from'=>$from
				];
				$addCatchArr[] = $arr[$vin];
			}
		}

		$this->YpwDb->Begin();

		//入库 泽达表
		if(!empty($addCatchArr)) 
			$this->addAny('stand_vin_zdapi', array_keys($addCatchArr[0]), array_values($addCatchArr));
		
		//更新到总库
		foreach($arr as $vin=>$zdAddArr)
		{
			if(empty($zdAddArr['viz_gxb_code'])) continue;

			//重置品牌和车辆类型
			$vin1_8 = substr($vin, 0, 8);
			$res = $this->getGxbBrandType($zdAddArr['viz_gxb_code_show'], $vin1_8);
			$gxbInfoArr = $res['data'];
			if(!empty($gxbInfoArr['sma_brand']))
				$zdAddArr['viz_brand'] = $gxbInfoArr['sma_brand'];
			if(!empty($gxbInfoArr['sma_vtype']))
				$zdAddArr['viz_vtype'] = $gxbInfoArr['sma_vtype'];
			
			if(!empty($zdAddArr['viz_engine']))
			{
				$ret = ['"'=>'','（'=>'(','）'=>')', '(('=>'(','(驱动电机)'=>'', '(电动机)'=>'', '（电动机）'=>'','(汽油)'=>'', '(CNG)'=>'',';'=>'<br>', '；'=>'<br>', '，'=>',','N/A'=>'', '–'=>'-'];
				$zdAddArr['viz_engine'] = strtr($zdAddArr['viz_engine'], $ret);
			}

			//入到600w总库
			$filedArr = [
				'sma_gxb_code_show'=>'viz_gxb_code_show',
				'sma_brand'=>'viz_brand',
				'sma_engine'=>'viz_engine',
				'sma_cc'=>'viz_cc',
				'sma_kw'=>'viz_kw',
				'sma_length'=>'viz_length',
				'sma_width'=>'viz_width',
				'sma_height'=>'viz_height',
				'sma_wheel'=>'viz_wheel',
				'sma_axle'=>'viz_axle',
				'sma_passenger'=>'viz_passenger',
				'sma_weight'=>'viz_weight',
				'sma_vtype'=>'viz_vtype',
				'sma_year'=>'viz_year'
			];
			// 整形字段
			$intFiled = ['sma_length','sma_width','sma_height','sma_wheel', 'sma_axle','sma_weight','sma_passenger'];
			$res = $this->get('stand_model_any', ['*'], sprintf(" and sma_vin='%s'", $vin), true);
			if(empty($res['data']))
			{
				$stAddArr = [
					'sma_vin'=>$zdAddArr['viz_vin'],
					'sma_vin1_3'=>substr($zdAddArr['viz_vin'], 0, 3),
					'sma_vin1_8'=>substr($zdAddArr['viz_vin'], 0, 8),
					'sma_vin10'=>substr($zdAddArr['viz_vin'], 9, 1),
					'sma_vin10_12'=>substr($zdAddArr['viz_vin'], 9, 3),
					'sma_vin13_17'=>substr($zdAddArr['viz_vin'], 12, 5),
					'sma_vin10_11'=>substr($zdAddArr['viz_vin'], 9, 2),
					'sma_vin12_17'=>substr($zdAddArr['viz_vin'], 11, 6),
					'sma_from'=>'ZDAPI',
					'sma_etime'=>time()
				];
				$stAddArr['sma_vyear'] = LibFc::VinYear($stAddArr['sma_vin10']);
				foreach($filedArr as $sf=>$zf)
				{
					if(!empty($zdAddArr[$zf]) && !in_array($zdAddArr[$zf], ['-','/', '*'])) 
						$stAddArr[$sf] = in_array($sf, $intFiled)? (int) $zdAddArr[$zf]: $zdAddArr[$zf];
				}
				if(isset($stAddArr['sma_gxb_code_show']))
				{
					$stAddArr['sma_gxb_code'] = LibFc::FormatNum($stAddArr['sma_gxb_code_show']);
					$stAddArr['sma_gtype'] = LibFc::getGxbCarType($stAddArr['sma_gxb_code']);
				}
				if(!empty($stAddArr['sma_kw']) && stripos($stAddArr['sma_kw'], '/'))
					$stAddArr['sma_kw'] = substr($stAddArr['sma_kw'], 0, stripos($stAddArr['sma_kw'], '/'));
				if(!empty($stAddArr['sma_year']) && abs(substr($stAddArr['sma_year'], 0, 4) - LibFc::VinYear($vin)) > 2 || substr($stAddArr['sma_year'], 0, 4) > date('Y'))
				{//年份数据异常 LSGJA52U18H177706
					unset($stAddArr['sma_year']);
				}
				$tres = $this->add('stand_model_any', $stAddArr);
				$zdAddArr['sma_id'] = $tres['data'];
			}
			else
			{
				$oldArr = $res['data'];
				$zdAddArr['sma_id'] = $oldArr['sma_id'];
				//更新
				$stAddArr = ['sma_from'=>'ZDAPI', 'sma_etime'=>time()];
				foreach($filedArr as $sf=>$zf)
				{
					if(!empty($zdAddArr[$zf])) 
						$stAddArr[$sf] = in_array($sf, $intFiled)? (int) $zdAddArr[$zf]: $zdAddArr[$zf];
				}
				if(isset($stAddArr['sma_gxb_code_show']))
				{
					$stAddArr['sma_gxb_code'] = LibFc::FormatNum($stAddArr['sma_gxb_code_show']);
					$stAddArr['sma_gtype'] = LibFc::getGxbCarType($stAddArr['sma_gxb_code']);
				}
				if(!empty($stAddArr['sma_kw']) && stripos($stAddArr['sma_kw'], '/'))
					$stAddArr['sma_kw'] = substr($stAddArr['sma_kw'], 0, stripos($stAddArr['sma_kw'], '/'));
				if(!empty($stAddArr['sma_year']) && abs(substr($stAddArr['sma_year'], 0, 4) - LibFc::VinYear($vin)) > 2 || substr($stAddArr['sma_year'], 0, 4) > date('Y'))
				{//年份数据异常 LSGJA52U18H177706
					unset($stAddArr['sma_year']);
				}
				if(!empty($stAddArr)) $this->set('stand_model_any', $stAddArr, sprintf(" and sma_vin='%s'", $zdAddArr['viz_vin']));
			}

			//日期更新
			if(!empty($stAddArr['sma_year']))
			{
				$res = $this->get('yp_allvin_base', ['alb_date'], sprintf(" and alb_vin ='%s'", $stAddArr['sma_vin']));
				if(!empty($res['data']))
				{
					$this->set('yp_allvin_base', ['alb_date'=>$stAddArr['sma_year']], sprintf(" and alb_vin ='%s' and alb_from ='manual'", $stAddArr['sma_vin']));
				}
				else
				{
					$addDate = [
						'alb_vin'=>$stAddArr['sma_vin'],
						'alb_vin1_3'=>$stAddArr['sma_vin1_3'],
						'alb_vin4_8'=>substr($stAddArr['sma_vin'], 3, 5),
						'alb_vin10_11'=>substr($stAddArr['sma_vin'], 9, 2),
						'alb_vin12'=>substr($stAddArr['sma_vin'], 11, 1),
						'alb_vin13_17'=>$stAddArr['sma_vin13_17'],
						'alb_date'=>$stAddArr['sma_year'],
						'alb_from'=>'manual',
					];
					$this->add('yp_allvin_base', $addDate);
				}
			}
			
			$this->set('stand_vin_imgs', ['vii_status'=>1, 'vii_check_time'=>time(), 'vii_check_uid'=>8], sprintf(" and vii_status != 1 and vii_vin ='%s' and vii_check_uid in (0,8)", $zdAddArr['viz_vin']));

			$this->set('yp_paojieling.pl_vin_error', ['ve_status'=>1, 've_check'=>'{"uid":8,"remark":"谢谢您的建议，已处理","time":'.time().'}'], sprintf(" and ve_status != 1 and ve_vin ='%s'", $zdAddArr['viz_vin']));
			
			$arr[$vin] = $zdAddArr;
		}
		$this->YpwDb->End();
		foreach($arr as $tk=>$tv)
		{
			if(isset($tv['viz_json'])) unset($arr[$tk]['viz_json']);
		}
		return LibFc::ReturnData(true, $arr);
	}

	
	/**
	  * @method 计算车架号的工信部型号
	  * @param  $vin  string [必填] 车架号
	  * @author soul
	  * @copyright 2020/10/22
	  * @return 
	  */
	public function getVinGxbByJiSuan($vin)
	{
		$vin = LibFc::FormatVin($vin);
		if(strlen($vin) != 17) return LibFc::ReturnData(false, '请提供17位的车架号');
		$vin18 = substr($vin, 0, 8);
		$v10_11 = substr($vin, 9, 2);
		$v10_12 = substr($vin, 9, 3);
		$v12_17 = substr($vin, 11, 6);
		$v13_17 = substr($vin, 12, 5);
		$whereArr = [];
		if(preg_match('/\d{5}/', $v13_17, $match))
			$whereArr[] = ['sma_vin13_17', $v13_17, sprintf(" and sma_vin1_8='%s' and sma_vin10_12='%s' and sma_gxb_code != '' ORDER BY ABS(sma_vin13_17-%d) ASC limit 1", $vin18, $v10_12, $v13_17)];

		if(preg_match('/\d{6}/', $v12_17, $match))
			$whereArr[] = ['sma_vin12_17', $v12_17, sprintf(" and sma_vin1_8='%s' and sma_vin10_11='%s' and sma_gxb_code != '' ORDER BY ABS(sma_vin12_17-%d) ASC limit 1", $vin18, $v10_11, $v12_17)];
		$minArr = [];
		foreach($whereArr as $tv)
		{
			$res = $this->get('stand_model_any', ['sma_vin', 'sma_gxb_code_show', 'abs('.$tv[0].'-'.$tv[1].') as minval'], $tv[2], true);
			if(!empty($res['data'])) return $res;
		}
		return LibFc::ReturnData(true, $Arr);
	}

				
	


	/**
	  * @method 从外调SP获取车架号信息
	  * @param  $vin  string [必填] 车架号
	  * @param  $addToSma  int [必填] 默认0不纳入 是否纳入600w总表
	  * @author soul
	  * @copyright 2020/10/22
	  * @return 
	  */
	public function catchVinfromWdspApi($vin, $addToSma = 0)
	{
		$vin = LibFc::FormatVin($vin);
		if(strlen($vin) != 17) return LibFc::ReturnData(false, '请提供17位的车架号');
		$arr = [];
		
		$res = $this->get('stand_gxb_soupei', ['sgs_id, sgs_gxb_soupei, sgs_gxb_yp'], sprintf(" and sgs_vin = '%s' and sgs_gxb_soupei != '' order by sgs_id desc limit 1", $vin), true);
		if(empty($res['data']))
		{
			$LibHttp = new LibHttp();
			$LibHttp->timeout = 3;
			$url = 'https://robot.paojd.cn/robot/index.php?from=sopei&search='.$vin;
			$url = 'http://crm.yiparts.com:3009/Admin/tools/robot/robot/index.php?from=sopei&search='.$vin;
			
			$html = $LibHttp->fetch($url);
			$htmlArr = json_decode($html, true);
			if(is_array($htmlArr) && !empty($htmlArr['data']['result']))
			{
				//自己计算工信部型号
				$res = $this->getVinGxbByJiSuan($vin);
				$jsArr = $res['data'];

				$spGxbArr = array_unique(array_column($htmlArr['data']['result'], 'code'));
				$spArr = [
					'sgs_vin'=>	$vin,
					'sgs_gxb_soupei'=>implode(',', $spGxbArr),
					'sgs_gxb_yp'=>!empty($jsArr['sma_gxb_code_show'])? $jsArr['sma_gxb_code_show']: '',
					'sgs_atime'=>time()
				];
				$spArr['sgs_gxb_soupei_format'] = LibFc::FormatNum($spArr['sgs_gxb_soupei'], ',');
				$spArr['sgs_gxb_yp_format'] = LibFc::FormatNum($spArr['sgs_gxb_yp']);
				$arr = [
					'sgs_gxb_soupei'=>$spArr['sgs_gxb_soupei'],	
					'sgs_gxb_yp'=>$spArr['sgs_gxb_yp'],	
				];
			}
		}
		else
		{
			$arr = $res['data'];
		}
		$this->YpwDb->Begin();
		if(!empty($spArr))
		{
			$res = $this->add('stand_gxb_soupei', $spArr);
			$arr['sgs_id'] = $res['data'];
		}

		//只有一个型号，有入库要求
		if($addToSma && !empty($arr['sgs_gxb_soupei']) && stripos($arr['sgs_gxb_soupei'], ',') === false)
		{
			//是否已经存在于600w
			$res = $this->get('stand_model_any', ['sma_id'], sprintf(" and sma_vin='%s'", $vin), true);
			if(empty($res['data']))
			{
				$addArr = [
					'sma_vin'=>$vin,
					'sma_gxb_code_show'=>$arr['sgs_gxb_soupei'],
					'sma_gxb_code'=>LibFc::FormatNum($arr['sgs_gxb_soupei']),
					'sma_vin1_3'=>substr($vin, 0, 3),
					'sma_vin1_8'=>substr($vin, 0, 8),
					'sma_vin10'=>substr($vin, 9, 1),
					'sma_vin10_12'=>substr($vin, 9, 3),
					'sma_vin13_17'=>substr($vin, 12, 5),
					'sma_vin10_11'=>substr($vin, 9, 2),
					'sma_vin12_17'=>substr($vin, 11, 6),
					'sma_etime'=>time(),
					'sma_from'=>'wdsp',
				];
				$addArr['sma_vyear'] = LibFc::VinYear($addArr['sma_vin10']);
				$addArr['sma_gtype'] = LibFc::getGxbCarType($addArr['sma_gxb_code']);
				$OthPdfOcr = new OthPdfOcr();
				$txtRes = $OthPdfOcr->fillGxbInfo($vin, $addArr);
				if(!empty($txtRes['data']['sma']))
				{
					$addArr = $txtRes['data']['sma'];
					$res = $this->add('stand_model_any', $addArr);
					$arr['sma_id'] = $res['data'];

					$this->set('stand_vin_imgs', ['vii_status'=>1, 'vii_check_time'=>time(), 'vii_check_uid'=>8], sprintf(" and vii_status != 1 and vii_vin ='%s' and vii_check_uid = 0", $vin));
				}
				else
				{
					return LibFc::ReturnData(false, $txtRes['data']['error']);
				}
			}
			else
			{
				$arr['sma_id'] = $res['data']['sma_id'];
			}
		}
		$this->YpwDb->End();
		return LibFc::ReturnData(true, $arr);
	}

	//
	/**
	  * @method 批量添加到总表
	  * @param  $addAnyArr  string [必填] [['sma_vin'=>''...,'oth'=>[...]]]  oth额外的数据
	  * @param  $replace  bool [必填] 如果存在是否更新 默认不更新
	  * @author soul
	  * @copyright 2020/10/22
	  * @return 
	  */
	public function addAnySma($addAnyArr, $replace = false)
	{
		$hasArr = [];
		if(!empty($addAnyArr))
		{
			$this->YpwDb->Begin();
			$addAnyArr = array_column($addAnyArr, null, 'sma_vin');
			$res = $this->getSmaGxb(array_keys($addAnyArr), ['sma_id', 'sma_vin']);
			$hasArr = array_column($res['data'], 'sma_id', 'sma_vin');
			foreach($addAnyArr as $add)
			{
				// 整形字段
				$intfileds = ['sma_length','sma_width','sma_height', 'sma_wheel','sma_axle','sma_weight','sma_passenger'];
				foreach ($intfileds as $ifiled) 
				{
					if(isset($add[$ifiled]))
					{
						$add[$ifiled] = (int) $add[$ifiled];
					}
				}

				$vin = $add['sma_vin'];
				$oth = [];
				if(isset($add['oth']))
				{
					$oth = $add['oth'];
					unset($add['oth']);
				}
				if(empty($add['sma_etime'])) $add['sma_etime'] = time();
				if(isset($add['sma_gxb_code_show']))
				{
					$add['sma_gxb_code'] = LibFc::FormatNum($add['sma_gxb_code_show']);
					$add['sma_gtype'] = LibFc::getGxbCarType($add['sma_gxb_code']);
				}
				if(!empty($hasArr[$vin]))
				{
					if($replace)
						$this->set('stand_model_any', $add, sprintf(" and sma_vin='%s'", $vin));
				}
				else
				{
					$add['sma_vin1_3'] = substr($vin, 0, 3);
					$add['sma_vin1_8'] = substr($vin, 0, 8);
					$add['sma_vin10'] = substr($vin, 9, 1);
					$add['sma_vin10_12'] = substr($vin, 9, 3);
					$add['sma_vin13_17'] = substr($vin, 12, 5);
					$add['sma_vin10_11'] = substr($vin, 9, 2);
					$add['sma_vin12_17'] = substr($vin, 11, 6);
					$add['sma_vyear'] = LibFc::VinYear($add['sma_vin10']);
					$res = $this->add('stand_model_any', $add);
					$hasArr[$vin] = $res['data'];
				}
				$viiwhere = sprintf(" and vii_status != 1 and vii_vin ='%s'", $vin);
				$res = $this->get('stand_vin_imgs', ['vii_id'], $viiwhere);
				if(!empty($res['data']))
				{
					$viiIdArr = array_column($res['data'], 'vii_id');
					$okvii = !empty($oth['vii_id']) && in_array($oth['vii_id'], $viiIdArr)? $oth['vii_id']: $viiIdArr[0];
					$set = [
						'vii_status'=>1,
						'vii_check_time'=>time(),
						'vii_check_uid'=>8,
						'vii_smastatus'=>'ok',
						'vii_smatime'=>time(),
					];
					$this->set('stand_vin_imgs', $set, sprintf(" and vii_status != 1 and vii_id=%d", $okvii));
					if(count($viiIdArr) > 1)
					{
						$ervii = sprintf(" and vii_status != 1 and vii_id !=%d and vii_id in (%s)", $okvii, implode(',', $viiIdArr));
						$this->set('stand_vin_imgs', ['vii_status'=>-4, 'vii_check_time'=>time(), 'vii_check_uid'=>8], $ervii);
					}
				}
			}
			$this->YpwDb->End();
		}
		return LibFc::ReturnData(true, $hasArr);
	}


	/**
	  * @method 获取工信部型号的品牌和车辆类型
	  * @param  $gxbNum  string [必填] 工信部型号
	  * @param  $vin18  string [选填] 车架号前8
	  * @author soul
	  * @copyright 2020/9/22
	  * @return 
	  */
	public function getGxbBrandType($gxbNum, $vin18)
	{
		$arr = [];
		$formatGxbNum = LibFc::FormatNum($gxbNum);
		$vin18 = LibFc::FormatNum($vin18);
		if(substr($vin18, 0, 1) == 'L')
		{
			$whereArr = [];
			if(strlen($vin18) >= 8)
			{
				$vin18 = substr($vin18, 0, 8);
				$whereArr[] = sprintf(" and sgi_gxb_code='%s' and sgi_vin1_8='%s'", $formatGxbNum, $vin18);
			}
			$whereArr[] = sprintf(" and sgi_gxb_code='%s'", $formatGxbNum);
			foreach($whereArr as $where)
			{
				$res = $this->get('stand_gxb_info', ['sgi_data'], $where, true);
				if(!empty($res['data']))
				{
					$sgi_data = json_decode($res['data']['sgi_data'], true);
					if(is_array($sgi_data) && !empty($sgi_data['merge']['sma_brand']))
					{
						$arr = $sgi_data['merge'];
						return LibFc::ReturnData(true, $arr);
					}
				}
			}
		}
		$whereArr = [];
		if(strlen($vin18) == 8)
		{
			$whereArr[] = sprintf(" and sma_vin1_8='%s' and sma_gxb_code='%s' and sma_brand != '' and sma_vtype != '' AND sma_from in ('manual', 'catch') limit 1", $vin18, $formatGxbNum);
		}
		$whereArr[] = sprintf(" and sma_gxb_code='%s' and sma_brand != '' and sma_vtype != '' AND sma_from in ('manual', 'catch') limit 1", $formatGxbNum);
		foreach($whereArr as $where)
		{
			$res = $this->get('stand_model_any', ['sma_brand, sma_vtype'], $where, true);
			if(!empty($res['data']))
			{
				$arr = $res['data'];
				return LibFc::ReturnData(true, $arr);
			}
		}
		if(substr($vin18, 0, 1) == 'L' && empty($arr['sma_brand']))
		{
			$res = $this->catchGxbcodeInfo($gxbNum, 1, $vin18);
			$gxbInfoArr = $res['data'];
			if(!empty($gxbInfoArr['merge'])) $arr = $gxbInfoArr['merge'];
		}
		return LibFc::ReturnData(true, $arr);
	}


	/**
	  * @method 获取wmi替换后的品牌
	  * @param  $wmi  string [必填] wmi
	  * @param  $brand  string [必填] 原始品牌名称
	  * @author soul
	  * @copyright 2022/6/7
	  * @return ['status'=>true, 'data'=>替换后的名称, 'code'=>'']
	  */
	public function getWmiReBrand($wmi, $brand)
	{
		if(!empty($wmi) && !empty($brand))
		{
			$brand = LibFc::Escape($brand);
			$res = $this->get('stand_wmi_brand', ['swb_brand'], sprintf(" and swb_wmi='%s' and (swb_brand = '%s' or swb_word like'%%,%s,%%') LIMIT 1", LibFc::FormatNum($wmi), $brand, $brand), true);
			if(!empty($res['data']))
				$brand = $res['data']['swb_brand'];
		}
		return LibFc::ReturnData(true, $brand);
	}


	
	/**
	  * @method 从中车网 商车网 查询工信部型号信息
	  * @param  $gxbNum  string [必填] 工信部型号
	  * @param  $gxbAllMatch  string [选填] 是否精准匹配 默认1
	  * @param  $vin  string [选填] 车架号或者车架号前8 最好是完整车架号
	  * @param  $othArr array [选填] ["sma_weight":"",...]
	  * @author soul
	  * @copyright 2020/9/22
	  * @return 
	  */
	public function catchGxbcodeInfo($gxbNum, $gxbAllMatch = 1, $vin = '', $othArr = [], $cache = true)
	{
		$arr = [];
		$formatGxbNum = LibFc::FormatNum($gxbNum);
		$vin = LibFc::FormatNum($vin);
		$vin18 = strlen($vin) >= 8? substr($vin, 0, 8): '';
		//缓存30天
		$outTime = time() - 3600*24*30;
		$uniKey = $formatGxbNum.'@'.$gxbAllMatch.'@'.$vin18.'@'.json_encode($othArr);
		$res = $this->get('stand_gxb_info', ['sgi_data', 'sgi_atime', 'sgi_count'], sprintf(" and sgi_unikey='%s'", $uniKey), true);
		$hasArr = $res['data'];
		if(!empty($hasArr))
		{
			$hasArr['sgi_data'] = json_decode($hasArr['sgi_data'], true);
			//&& $hasArr['sgi_atime'] >= $outTime
			if(is_array($hasArr['sgi_data']) && !empty($hasArr['sgi_data']['merge']['sma_brand']))
			{
				return LibFc::ReturnData(true, $this->formatGxbcodeInfo($hasArr['sgi_data'], $formatGxbNum, $vin));
			}
			if($cache && $hasArr['sgi_count'] > 10) return LibFc::ReturnData(true, $this->formatGxbcodeInfo($hasArr['sgi_data'], $formatGxbNum, $vin));
		}
		
		//通过工信部型号采集数据
		$siteArr = [
			'chinacar'=>[
				'name'=>'中车网',
				'vals'=>[]
			],
			'cn357'=>[
				'name'=>'商车网',
				'vals'=>[]
			],
			'cntruck'=>[
				'name'=>'王力网',
				'vals'=>[]
			],
			'miitgov'=>[
				'name'=>'工信部',
				'vals'=>[]
			],
			'miiteidc'=>[
				'name'=>'工信查',
				'vals'=>[]
			]
		];
		$arr['merge'] = [];
		
		$table .= 'gxb_base';
		foreach(['gxb', 'dipan'] as $gbtype){
			$where = sprintf(" and gb_type='%s'", $gbtype);
			$where .= $gxbAllMatch? sprintf(" and gb_gxb_code='%s'", $formatGxbNum) : sprintf(" and gb_gxb_code like '%s%%'", $formatGxbNum);
			$where .= sprintf(" and gb_from in ('%s')", implode("','", array_keys($siteArr)));
			
			if(!empty($othArr['sma_weight'])) 
			{
				$table .= " JOIN gxb_params weight ON weight.gp_gb_id = gb_id AND gp_gl_code = 'weight'"; 
				$where .= sprintf(" and gp_value='%s'", LibFc::Escape($othArr['sma_weight']));
			}

			if(!empty($othArr['max_weight'])) 
			{
				$table .= " JOIN gxb_params maxweight ON maxweight.gp_gb_id = gb_id AND gp_gl_code = 'maxweight'"; 
				$where .= sprintf(" and gp_value='%s'", LibFc::Escape($othArr['max_weight']));
			}
			$fileds = ['gb_id', 'gb_from', 'gb_url url', 'gb_brand sma_brand', 'gb_gxb_code sma_gxb_code', 'gb_gxb_code_show sma_gxb_code_show', 'gb_vtype sma_vtype', 'gb_from_url from_url'];
			$gbres = $this->get($table, $fileds, $where.sprintf(" group by gb_id order by FIELD(gb_from, '%s')", implode("','", array_keys($siteArr))));
			if(!empty($gbres['data'])) break;
		}
		if(empty($gbres['data'])) return LibFc::ReturnData(true, $arr);
		$gbids = array_column($gbres['data'], 'gb_id');
		$mergens = [];
		$engsArr = [];
		$res = $this->get('gxb_engine', ['ge_gb_id', 'ge_engine sma_engine', 'ge_kw sma_kw', 'ge_cc sma_cc'], sprintf(" and ge_gb_id in (%s) order by length(ge_engine) desc", implode(',', $gbids)));
		foreach($res['data'] as $ev)
		{
			$gbid = $ev['ge_gb_id'];
			if(empty($engsArr[$gbid])) 
				$engsArr[$gbid] = [
					'sma_engines'=>[],
					'sma_engine'=>[],
					'sma_kw'=>[],
					'sma_cc'=>[],
				];
			$engsArr[$gbid]['sma_engine'][$ev['sma_engine']] = $ev['sma_engine'];
			//4DW93-84E4#64#2540
			$teng = $ev['sma_engine'];
			if(!empty($ev['sma_kw']))
			{
				$teng .= '#'.$ev['sma_kw'];
				$engsArr[$gbid]['sma_kw'][$ev['sma_kw']] = $ev['sma_kw'];
			}
			if(!empty($ev['sma_cc']))
			{
				$teng .= '#'.$ev['sma_cc'];
				$engsArr[$gbid]['sma_cc'][$ev['sma_cc']]  = $ev['sma_cc'];
			}
			$engsArr[$gbid]['sma_engines'][$teng]  = $teng;
			$mergens[strtoupper($teng)]  = $teng;
		}

		$paramsArr = [];
		$labels = [
			'vin18'=>'sma_vin_full',	
			'length'=>'sma_length',	
			'width'=>'sma_width',	
			'height'=>'sma_height',	
			'wheel'=>'sma_wheel',	
			'weight'=>'sma_weight',	
			'maxweight'=>'max_weight',	
			'passenger'=>'sma_passenger',	
			'axle'=>'sma_axle',	
		];
		$where = sprintf(" and gp_gb_id in (%s) and gp_gl_code in ('%s') group by gp_gb_id, gp_gl_code", implode(',', $gbids), implode("','", array_keys($labels)));
		$res = $this->get('gxb_params', ['gp_gb_id', 'gp_gl_code', 'group_concat(distinct gp_value) gp_values'], $where);
		foreach($res['data'] as $ev)
		{
			$tvals = explode(',', $ev['gp_values']);
			sort($tvals);
			$paramsArr[$ev['gp_gb_id']][$ev['gp_gl_code']] = implode(',', $tvals);
		}
		foreach($gbres['data'] as $sv)
		{
			$gbid = $sv['gb_id'];
			$sv['sma_engine'] = '';
			if(!empty($engsArr[$gbid]))
				$sv['sma_engine'] = count($engsArr[$gbid]['sma_kw']) > 1 || count($engsArr[$gbid]['sma_cc']) > 1? implode(',', $engsArr[$gbid]['sma_engines']): implode(',', $engsArr[$gbid]['sma_engine']);

			$sv['sma_kw'] = !empty($engsArr[$gbid]['sma_kw'])? implode(',', $engsArr[$gbid]['sma_kw']): '';
			$sv['sma_cc'] = !empty($engsArr[$gbid]['sma_cc'])? implode(',', $engsArr[$gbid]['sma_cc']): '';

			foreach($labels as $lk=>$lv)
			{
				$sv[$lv] = !empty($paramsArr[$gbid][$lk])? $paramsArr[$gbid][$lk]: '';
			}

			//非精准时 前八匹配剔除
			if(!$gxbAllMatch && !empty($vin18) && !empty($sv['sma_vin_full']) && stripos($sv['sma_vin_full'], $vin18) === false)
			{
				continue;
			}
			if(empty($arr['site'][$sv['gb_from']])) $arr['site'][$sv['gb_from']] = $siteArr[$sv['gb_from']];
			$arr['site'][$sv['gb_from']]['vals'][] = $sv;
		}
		
		//计算相同的参数
		$filedArr = ['sma_vin_full', 'sma_gxb_code_show', "sma_brand", "sma_engine", "sma_cc", "sma_kw", "sma_length", "sma_width","sma_height", "sma_wheel", "sma_axle","sma_weight","sma_passenger","sma_vtype", "max_weight"];
		foreach($arr as $type=>$v)
		{
			if($type == 'merge') continue;
			$t = $type == 'site' ? $v: [$v];
			foreach($t as $vv)
			{
				$daArr = isset($vv['vals']) ? array_values($vv['vals']): $vv;
				foreach($daArr as $da)
				{
					foreach($filedArr as $filed)
					{
						if(!empty($da[$filed]))
						{
							if(in_array($filed, ['sma_brand', 'sma_gxb_code_show']) && !empty($arr['merge'][$filed])) continue;
							foreach(explode(',', trim($da[$filed])) as $ttv)
							{
								if(!empty($ttv) && empty($arr['merge'][$filed][strtoupper($ttv)])) $arr['merge'][$filed][strtoupper($ttv)] = $ttv;
							}
						}
					}
				}
			}
		}
		
		//CAF7150N4
		if(count($mergens) > 1) $arr['merge']['sma_engine'] = $mergens;

		foreach($filedArr as $filed)
		{
			if($filed == 'sma_engine' && !empty($arr['merge'][$filed]))
			{
				usort($arr['merge'][$filed], function($a, $b) {
					$posA = strpos($a, '#');
					$posB = strpos($b, '#');
					$a_prefix = substr($a, 0, $posA);
					$b_prefix = substr($b, 0, $posB);
					$lenA = $posA;
					$lenB = $posB;
					if ($lenA !== $lenB) {
						return $lenB <=> $lenA;
					}
					return strcmp($a_prefix, $b_prefix);
				});
				
				$vals = array_values($arr['merge'][$filed]);
				if(count($vals) > 1)
				{
					$englink = [];
					$ten = [];
					foreach($vals as $tmv)
					{
						$te = stripos($tmv, '#') ? substr($tmv, 0, stripos($tmv,'#')): $tmv;
						$ten[] = $te;
						$englink[$te][$tmv] = $tmv;
					}
					$ten = array_unique($ten);
					if(count($ten) == 1) 
					{
						$arr['merge'][$filed] = [$ten[0]];
					}
					else
					{//SYM5310GJB1E
						$tvals = [];
						foreach($englink as $te=>$tes)
						{
							if(count($tes) == 2 && in_array($te, $tes))
							{
								unset($tes[$te]);
							}
							$tvals = array_merge($tvals, array_values($tes));
						}
						$arr['merge'][$filed] = $tvals;
					}
				}
				
			}
			$mergeVal = [];
			if(!empty($arr['merge'][$filed]))
			{
				$mergeVal = array_unique(array_values($arr['merge'][$filed]));
				if(count($mergeVal) > 1)
				{
					if(in_array($filed, ['sma_vtype'])){
						array_multisort(array_map('strlen', $mergeVal), SORT_ASC, $mergeVal);
					}else if(in_array($filed, ['sma_engine'])){
						//array_multisort(array_map('strlen', $mergeVal), SORT_DESC, $mergeVal);
					}
					if(in_array($filed, ['sma_vtype'])){
						$mergeVal = [$mergeVal[0]];
					}
				}
			}
			if(!in_array($filed, ['sma_vtype', 'sma_engine'])) sort($mergeVal);
			$arr['merge'][$filed] = implode(',', $mergeVal);
			
			//多轴不处理
			if($filed == 'sma_wheel' && stripos($arr['merge'][$filed], '+'))
				$arr['merge'][$filed] = '';
			
			//重置品牌名
			if($filed == 'sma_brand' && !empty($vin18))
			{
				$res = $this->getWmiReBrand(substr($vin18, 0, 3), $arr['merge'][$filed]);
				$arr['merge'][$filed] = $res['data'];
			}

		}
		if(empty($arr['merge'])) unset($arr['merge']);
		
		$addArr = [
			'sgi_unikey'=>$uniKey,	
			'sgi_gxb_code'=>$formatGxbNum,
			'sgi_vin1_8'=>$vin18,
			'sgi_data'=>json_encode($arr, JSON_UNESCAPED_UNICODE),	
			'sgi_atime'=>time(),
			'sgi_count'=>empty($hasArr['sgi_count'])? 1: $hasArr['sgi_count']+1
		];

		//计算最小长度
		if(!empty($arr['merge']['sma_length']))
		{
			$min = 0;
			foreach(explode(',', $arr['merge']['sma_length']) as $tv)
			{
				$tv = (int) $tv;
				if($tv < 1000) continue;
				if($min == 0 || $tv < $min) $min = $tv;
			}
			$addArr['sgi_length_min'] = $min;
		}

		//采集有时间差，防止并发发生错误，直接删除再加
		$this->YpwDb->Begin();
		$this->del('stand_gxb_info', sprintf(" and sgi_unikey='%s'", $uniKey));
		$this->add('stand_gxb_info', $addArr);
		$this->YpwDb->End();

		return LibFc::ReturnData(true, $this->formatGxbcodeInfo($arr, $formatGxbNum, $vin));
	}
	
	//catchGxbcodeInfo的结果是否有特殊处理
	private function formatGxbcodeInfo($arr, $formatGxbNum, $vin)
	{
		if(!empty($arr['merge']['sma_brand']))
		{
			//重置品牌名
			if(!empty($vin))
			{
				$res = $this->getWmiReBrand(substr($vin, 0, 3), $arr['merge']['sma_brand']);
				$arr['merge']['sma_brand'] = $res['data'];
			}
			
			//公告缺失 
			//FV7162XG LFV2A115 LFV2A115 4 A30 55078 前包括vin10=8,9,A BWH#74#1595   2010-06-28 需要处理
			//FV7162XG LFV2A115 LFV2A115 9 A30 63497 后 CLS#77#1598  2010-08-01 无需处理
			if($formatGxbNum == 'FV7162XG' && strlen($vin) == 17 && substr($vin, 0, 8) == 'LFV2A115')
			{
				$vinYear = LibFc::VinYear($vin);
				$vin13_17 = substr($vin, 12, 5);
				if($vinYear < 2010 || (substr($vin, 9, 3) == 'A30' && $vin13_17 <= 55078))
				{
					$arr['merge']['sma_engine'] = 'BWH#74#1595';
					$arr['merge']['sma_cc'] = '1595';
					$arr['merge']['sma_kw'] = '74';
					foreach($arr['site'] as $site=>$sv)
					{
						foreach($sv['vals'] as $skk=>$svv)
						{
							$svv['sma_engine'] = 'BWH#74#1595';
							$svv['sma_cc'] = '1595';
							$svv['sma_kw'] = '74';
							$arr['site'][$site]['vals'][$skk] = $svv;
						}
					}
				}
				else if(substr($vin, 9, 3) == 'A30' && $vin13_17 > 55078 && $vin13_17 < 63497)
				{//两个发动机
					$arr['merge']['sma_engine'] .= ',BWH#74#1595';
					$arr['merge']['sma_cc'] .= ',1595';
					$arr['merge']['sma_kw'] .= ',74';
					foreach($arr['site'] as $site=>$sv)
					{
						foreach($sv['vals'] as $skk=>$svv)
						{
							$svv['sma_engine'] .= ',BWH#74#1595';
							$svv['sma_cc'] .= ',1595';
							$svv['sma_kw'] .= ',74';
							$arr['site'][$site]['vals'][$skk] = $svv;
						}
					}
				
				}
			}
		}
		return $arr;
	}


	//采集中车网工信部型号详情页
	public function getChinacarGg($taridArr, $gxbAllMatch, $formatGxbNum)
	{
		$allArr = [];
		$LibHttp = new LibHttp();
		$LibHttp->timeout = 30;
		foreach($taridArr as $tk=>$tarid)
		{
			$html = '';
			$isCatch = false;
			$cacheDir = mvc::$cfg['ROOT'].'../CatchHtml/zcwhtml/'.substr($tarid, 0, 3).'/';
			@mkdir($cacheDir);
			$cacheFile = $cacheDir.$tarid.'.html';
			$url = 'http://www.chinacar.com.cn/Home/GonggaoSearch/GonggaoSearch/search_param/id/'.$tarid;
			$arr = ['url'=>'http://www.chinacar.com.cn/ggcx_new/search_view.html?id='.$tarid];
			if(file_exists($cacheFile) && (time() - filemtime($cacheFile)) < 3600*24*180)
				$html = file_get_contents($cacheFile);

			if(strlen($html) < 100)
			{
				$LibHttp->httpheader = [
					'Cookie: PHPSESSID=0n9mui8t8gk686d8tu16r97t34; Hm_lvt_6c1a81e7deb77ce536977738372f872a=1651717231,1653097678; rel_search=1; clcp_list=491924%7C562833%7C; Hm_lpvt_6c1a81e7deb77ce536977738372f872a=1653104103',
					'Referer: http://www.chinacar.com.cn/ggcx_new/search_view.html?id='.$tarid
				];
				$html = $LibHttp->fetch($url);
				$isCatch = true;
				usleep(200000);
				if(strlen($html) < 100 && file_exists($cacheFile))
				{
					$isCatch = false;
					$html = file_get_contents($cacheFile);
				}
			}
			if(preg_match('/<td[^>]*>公告型号：<\/td>\s*<td[^>]*>([^<]*)<\/td>/', $html, $match))
				 $arr['sma_gxb_code_show'] = $match[1];

			$arr['sma_gxb_code_show'] = trim(preg_replace('/([\x80-\xff]*)/i','', $arr['sma_gxb_code_show']));
			$tgxb = LibFc::FormatNum($arr['sma_gxb_code_show']);
			if($gxbAllMatch && $tgxb != $formatGxbNum) continue;
			
			//特殊处理
			if($tgxb == 'TV7121E6' && stripos($html, '>9NR8<br>NR<'))
			{
				$isCatch = true;
				$reHtml = ['>9NR8<br>NR<'=>'>9NR<br>8NR<'];
				$html = strtr($html, $reHtml);
			}

			if(preg_match('/<td[^>]*>外形尺寸：<\/td>\s*<td[^>]*>\s*<span[^>]*>([0-9,]+)+×([0-9,]+)×([0-9,]+)/', $html, $match))
			{
				$arr['sma_length'] = implode(',', array_unique(explode(',', $match[1])));
				$arr['sma_width'] = implode(',', array_unique(explode(',', $match[2])));
				$arr['sma_height'] = implode(',', array_unique(explode(',', $match[3])));
			}
			if(preg_match('/Vin车辆识别代码<\/a>：<\/td>\s*<td[^>]*>(.*)<\/td>/', $html, $match))
			{
				if(preg_match_all('/([0-9A-Z]{8})[×xX]+/', $match[1], $m2))
				{
					$arr['sma_vin_full'] = implode(',', array_unique($m2[1]));
				}
			}
		
			if(preg_match('/<td[^>]*>中文品牌：<\/td>\s*<td[^>]*><a[^>]*>([^<]*)<\/a><\/td>/', $html, $match))
				 $arr['sma_brand'] = $match[1];
		
			if(preg_match('/<td[^>]*>车辆名称：<\/td>\s*<td[^>]*><a[^>]*>([^<]*)<\/a>/', $html, $match))
				 $arr['sma_vtype'] = $match[1];

			if(preg_match('/<td[^>]*>轴数：<\/td>\s*<td[^>]*>([^<]*)<\/td>/', $html, $match))
				 $arr['sma_axle'] = $match[1];
		
			if(preg_match('/<td[^>]*>额定载客：<\/td>\s*<td[^>]*>([^<]*)<\/td>/', $html, $pmatch))
			{
				$pmatch[1] = strtr($pmatch[1], ['(人)'=>'', '/'=>',']);
				$tp = [];
				foreach(explode(',', $pmatch[1]) as $tmv)
				{
					if(preg_match('/(\d+)\-(\d+)/', $tmv, $match2))
					{
						for($i = $match2[1]; $i <= $match2[2]; $i++)
						{
							$tp[] = $i;
						}
					}
					else if(!empty($tmv))
					{
						$tp[] = (int) $tmv;
					}
				}
				$tp = array_unique($tp);
				sort($tp);
				$arr['sma_passenger'] = implode(',', $tp);
			}

			if(preg_match('/<td[^>]*>整备质量：<\/td>\s*<td[^>]*>\s*<span[^>]*>([0-9,\/]+)\(Kg\)<\/span>/', $html, $match))
				 $arr['sma_weight'] = strtr($match[1], ['/'=>',']);

			if(preg_match('/<td[^>]*>总质量：<\/td>\s*<td[^>]*>\s*<span[^>]*>([0-9,\/]+)\(Kg\)<\/span>/', $html, $match))
				 $arr['max_weight'] = strtr($match[1], ['/'=>',']);

			if(preg_match('/<td[^>]*>轴距：<\/td>\s*<td[^>]*>\s*<span[^>]*>([0-9,\/]+)\(mm\)<\/span>/', $html, $match))
				 $arr['sma_wheel'] = strtr($match[1], ['/'=>',']);
			
			if(preg_match('/<td[^>]*>燃料种类：<\/td>\s*<td[^>]*>([^<]*)<\/td>/', $html, $match))
				 $arr['fuel'] = $match[1];
			
			$reg = '/<tr[^>]*>\s*<td[^>]*>发动机<\/td>\s*<td[^>]*>发动机生产企业<\/td>\s*<td[^>]*>排量\(ml\)<\/td>\s*<td[^>]*>功率\(kw\)<\/td>\s*<\/tr>\s*<tr[^>]*>\s*<td[^>]*>(.*)<\/td>\s*<td[^>]*>.*<\/td>\s*<td[^>]*>(.*)<\/td>\s*<td[^>]*>(.*)<\/td>\s*<\/tr>/';
			if(preg_match($reg, $html, $match))
			{
				$ret = ['"'=>'', '(电动机)'=>'', '（电动机）'=>''];
				$match[1] = strtr(trim($match[1], '<br>'), $ret);
				$match[2] = strtr(trim($match[2], '<br>'), $ret);
				$match[3] = strtr(trim($match[3], '<br>'), $ret);
				$engkvccArr = [];
				$engArr = [];
				$match[1] = trim(strtr($match[1], [';'=>'<br>', '；'=>'<br>']), '<br>');
				foreach(explode('<br>', $match[1]) as $tk=>$tv)
				{
					$engArr[$tk] = trim($tv);
				}

				$ccArr = [];
				foreach(explode('<br>', $match[2]) as $tk=>$tv)
				{
					$ccArr[$tk] = empty($tv) || in_array($tv, ['_', '-', '/', ';']) || strlen($tv) > 8 ? '': trim($tv);
				}
				
				$kwArr = [];
				//SC7163CNG
				$match[3] = trim(strtr($match[3], [','=>'<br>']), '<br>');
				foreach(explode('<br>', $match[3]) as $tk=>$kv)
				{
					if(stripos($kv, '/') > 0) $kv = substr($kv, 0, stripos($kv, '/'));
					$kwArr[$tk]= trim($kv);
				}
				
				if(count($engArr) == count($kwArr))
				{
					foreach($engArr as $tk=>$tv)
					{
						if(!empty($this->replaceEngines[$tv])) $tv = $this->replaceEngines[$tv];
						if(!empty($tv)) $engkvccArr[] = $tv.'#'.$kwArr[$tk].'#'.$ccArr[$tk];
					}
					$engkvccArr = array_unique($engkvccArr);
					$arr['sma_engine'] = implode(',', $engkvccArr);
				}
				else
				{
					foreach($engArr as $tk=>$tv)
					{
						if(!empty($this->replaceEngines[$tv])) $tv = $this->replaceEngines[$tv];
						if(empty($tv)) unset($engArr[$tk]);
					}
					$arr['sma_engine'] = implode(',', array_unique($engArr));
				}
				
				foreach($ccArr as $tk=>$tv)
				{
					if(empty($tv)) unset($ccArr[$tk]);
				}
				$arr['sma_cc'] = implode(',', array_unique($ccArr));

				foreach($kwArr as $tk=>$tv)
				{
					if(empty($tv)) unset($kwArr[$tk]);
				}
				$arr['sma_kw'] = implode(',', array_unique($kwArr));
			}

			if($isCatch && !empty($arr['sma_brand']) && !empty($arr['sma_gxb_code_show'])) 
				file_put_contents($cacheFile, $html);

			$allArr[$tarid] = $arr;
		}
		return $allArr;
	}


	//采集商车网工信部型号详情页
	public function getCn357Gg($taridArr, $gxbAllMatch, $formatGxbNum)
	{
		$allArr = [];
		foreach($taridArr as $tk=>$tarid)
		{
			$tarToArr = explode('_', $tarid);
			//notice792350_CC6473GM05
			if($gxbAllMatch && $formatGxbNum && LibFc::FormatNum($tarToArr[1]) != $formatGxbNum) continue;

			$html = '';
			$isCatch = false;
			$cacheDir = mvc::$cfg['ROOT'].'../CatchHtml/scwhtml/'.substr($tarToArr[0], -3).'/';
			LibDir::CreateDir($cacheDir);
			$cacheFile = $cacheDir.$tarid.'.html';
			$url = 'https://www.cn357.com/'.$tarid;
			$arr = ['url'=>$url];
			if(file_exists($cacheFile) && (time() - filemtime($cacheFile)) < 3600*24*180)
				$html = file_get_contents($cacheFile);

			if(strlen($html) < 100)
			{
				$html = $this->catchCn357($url);
				$isCatch = true;
				usleep(200000);
				if(strlen($html) < 100 && file_exists($cacheFile))
				{
					$isCatch = false;
					$html = file_get_contents($cacheFile);
				}
			}
			if(preg_match('/<\/script>\s*<\/div>\s*(<table.*<\/table>)\s*<div class="itemUlPic"/iUs', $html, $match))
			{
				$html = $match[1];
			}
			
			$filedArr = [
				'sma_gxb_code_show'=>'公告型号',	
				'sma_length'=>'整车长',	
				'sma_width'=>'整车宽',	
				'sma_height'=>'整车高',	
				'sma_brand'=>'品牌',	
				'sma_vtype'=>'类型',	
				'sma_axle'=>'轴数',	
				'sma_passenger'=>'额定载客',	
				'sma_weight'=>'整备质量',	
				'max_weight'=>'总质量',	
				'sma_wheel'=>'轴距',	
				'fuel'=>'燃料种类',
			];

			foreach($filedArr as $filed=>$name)
			{
				if(preg_match('/<td[^>]*>'.$name.'<\/td>\s*<td[^>]*>([^<]*)<\/td>/', $html, $match))
				{
					$match[1] = str_replace('&quot;', '', $match[1]);
					if(in_array($filed, ['sma_length', 'sma_width', 'sma_height', 'sma_axle', 'sma_passenger','sma_weight', 'max_weight', 'sma_wheel']))
						$match[1] =  strtr($match[1], ['/'=>',']);
					$arr[$filed] = implode(',', array_unique(explode(',', $match[1])));
				}
				else if(preg_match('/<td[^>]*>'.$name.'<\/td>\s*<td[^>]*><a[^>]*>([^<]*)<\/a><\/td>/', $html, $match))
				{
					$match[1] = str_replace('&quot;', '', $match[1]);
					if(in_array($filed, ['sma_length', 'sma_width', 'sma_height', 'sma_axle', 'sma_passenger','sma_weight', 'max_weight', 'sma_wheel']))
						$match[1] =  strtr($match[1], ['/'=>',']);
					$arr[$filed] = implode(',', array_unique(explode(',', $match[1])));
				}
				
				//CLY5314GJB30E61
				if($filed == 'sma_wheel') $arr[$filed] = strtr($arr[$filed], ['+'=>',','-'=>',', '/'=>',']);

				if($filed == 'sma_passenger')
				{
					$arr[$filed] = strtr($arr[$filed], ['(人)'=>'', '/'=>',']);
					$tp = [];
					foreach(explode(',', $arr[$filed]) as $tmv)
					{
						if(preg_match('/(\d+)\-(\d+)/', $tmv, $match2))
						{
							for($i = $match2[1]; $i <= $match2[2]; $i++)
							{
								$tp[] = $i;
							}
						}
						else if(!empty($tmv))
						{
							$tp[] = (int) $tmv;
						}
					}
					$tp = array_unique($tp);
					sort($tp);
					$arr[$filed] = implode(',', $tp);
				}
			}
			$arr['sma_gxb_code_show'] = trim(preg_replace('/([\x80-\xff]*)/i','', $arr['sma_gxb_code_show']));
			$tgxb = LibFc::FormatNum($arr['sma_gxb_code_show']);
			if($gxbAllMatch && $formatGxbNum && $tgxb != $formatGxbNum) continue;
			
			if(preg_match('/<td[^>]*>识别代号<\/td>\s*<td[^>]*>([^<]*)<\/td>/', $html, $match))
			{
				if(preg_match_all('/([0-9A-Z]{8})[×xX]+/', $match[1], $m2))
				{
					$arr['sma_vin_full'] = implode(',', array_unique($m2[1]));
				}
			}
			
			$reg = '/<tr[^>]*>\s*<td[^>]*>发动机型号<\/td>\s*<td[^>]*>发动机生产企业<\/td>\s*<td[^>]*>发动机商标<\/td>\s*<td[^>]*>排量<\/td>\s*<td[^>]*>功率<\/td>\s*<\/tr>\s*<tr[^>]*>\s*<td[^>]*>(.*)<\/td>\s*<td[^>]*>.*<\/td>\s*<td[^>]*>.*<\/td>\s*<td[^>]*>(.*)<\/td>\s*<td[^>]*>(.*)<\/td>\s*<\/tr>/';
			if(preg_match($reg, $html, $match))
			{
				$ret = ['"'=>'', '(电动机)'=>'', '（电动机）'=>''];
				$match[1] = strtr(trim($match[1], '<br>'), $ret);
				$match[2] = strtr(trim($match[2], '<br>'), $ret);
				$match[3] = strtr(trim($match[3], '<br>'), $ret);
				$engkvccArr = [];
				$engArr = [];
				$match[1] = trim(strtr($match[1], [';'=>'<br>', '；'=>'<br>']), '<br>');
				foreach(explode('<br>', $match[1]) as $tk=>$tv)
				{
					//GHA6460RAC6B
					$engArr[$tk] = stripos($tv, '***') > 2? '': trim($tv);
				}

				$ccArr = [];
				//BH7140XMS
				$engc = substr_count($match[1], '<br>');
				if($engc > 0 && substr_count($match[2], '<br>') === 0)
				{
					$sp = strlen($match[2])/($engc+1);
					if(is_int($sp) && $sp > 3 && $sp < 6)
						$match[2] = implode('<br>', str_split($match[2], strlen($match[2])/($engc+1)));
				}

				foreach(explode('<br>', $match[2]) as $tk=>$tv)
				{
					$ccArr[$tk] = empty($tv) || in_array($tv, ['_', '-', '/', ';']) || strlen($tv) > 8 ? '': trim($tv);
				}
				
				$kwArr = [];
				foreach(explode('<br>', $match[3]) as $tk=>$kv)
				{
					if(stripos($kv, '/') > 0) $kv = substr($kv, 0, stripos($kv, '/'));
					$kwArr[$tk]= trim($kv);
				}
				
				if(count($engArr) == count($kwArr))
				{
					foreach($engArr as $tk=>$tv)
					{
						if(!empty($this->replaceEngines[$tv])) $tv = $this->replaceEngines[$tv];
						if(!empty($tv)) $engkvccArr[] = empty($kwArr[$tk]) && empty($ccArr[$tk]) ? $tv : $tv.'#'.$kwArr[$tk].'#'.$ccArr[$tk];
					}
					$engkvccArr = array_unique($engkvccArr);
					$arr['sma_engine'] = implode(',', $engkvccArr);
				}
				else
				{
					foreach($engArr as $tk=>$tv)
					{
						if(!empty($this->replaceEngines[$tv])) $tv = $this->replaceEngines[$tv];
						if(empty($tv)) unset($engArr[$tk]);
					}
					$arr['sma_engine'] = implode(',', array_unique($engArr));
				}

				foreach($ccArr as $tk=>$tv)
				{
					if(empty($tv)) unset($ccArr[$tk]);
				}
				$arr['sma_cc'] = implode(',', array_unique($ccArr));

				foreach($kwArr as $tk=>$tv)
				{
					if(empty($tv)) unset($kwArr[$tk]);
				}
				$arr['sma_kw'] = implode(',', array_unique($kwArr));
			}
			if($isCatch && !empty($arr['sma_brand']) && !empty($arr['sma_gxb_code_show'])) 
				file_put_contents($cacheFile, $html);
			$allArr[$tarid] = $arr;
		}
		return $allArr;
	}
	

	//采集商车网
	public function catchCn357($url, $post = [])
    {
		$LibHttp = new LibHttp();
		$LibHttp->timeout = 30;
		$html = $LibHttp->fetch($url);
		$html = iconv('GBK', 'UTF-8', $html);
		return $html;
        $oPuppeteer = new Puppeteer([
            //以秒为单位
            'idle_timeout' => 30,
            'read_timeout'=> 30,
        ]);
        $oBrowser = $oPuppeteer->launch([
            'headless' => true,
            'defaultViewport' => [
                'width' => 2560, 'height' => 1440,
            ],
            'args' => ['--no-sandbox', '--disable-setuid-sandbox']
        ]);

        try
        {
            $oLaunch = $oBrowser->newPage();
            $oLaunch->setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36');
            // 绕过反爬虫
            $oLaunch->evaluateOnNewDocument(JsFunction::createWithBody("
                Object.defineProperty(navigator, 'webdriver', {
                    get: () => false,
                });
            "));

            // 取消弹窗
            $oJsFunction = JsFunction::createWithAsync()
                ->parameters(['dialog'])
                ->body('await dialog.dismiss();');
            $oLaunch->on('dialog', $oJsFunction);

            $oLaunch->goto($url);
            $oLaunch->waitForNavigation(['timeout' => 30 * 1000]);
            $html = $oLaunch->content();
        } catch (Node\Exception $oException) {}
        $oBrowser->close();
		return $html;
    }
	
	//获取商车网的cookie
	public function getCn357GgCookie($cache = true)
	{
		//return 'cookie:';
		$cacheFile = mvc::$cfg['AUTOLOAD']['Ypw']['path'].'cache/getCn357GgCookie.txt';
		if($cache && file_exists($cacheFile) && (time() - filemtime($cacheFile)) < 60*2)
		{
			return file_get_contents($cacheFile);
		}
		else
		{
			$cookieArr = [];
			$LibHttp = new LibHttp(true);
			$LibHttp->returnheader = true;
			$url = 'https://www.cn357.com/?security_verify_data=313932302c31303830';
			$LibHttp->httpheader = ['cookie'=>'cookie:'.implode(';', $cookieArr)];
			for($i = 1; $i < 10; $i++)
			{
				$html = $LibHttp->fetch($url);
				if(preg_match_all('/Set-Cookie\:([^\=]+)\=([^;]+)/', $html, $match))
				{
					foreach($match[1] as $tk=>$tv)
					{
						$tv = trim($tv);
						$cookieArr[$tv] = $tv.'='.trim($match[2][$tk]);
					}
				}
				else
				{
					return 'cookie:';
				}
				if(!empty($cookieArr['security_session_verify']) && !empty($cookieArr['security_session_mid_verify']))
				{
					file_put_contents($cacheFile, 'cookie:'.implode(';', $cookieArr));
					break;
				}
			}
			return 'cookie:'.implode(';', $cookieArr);
		}
	}


	public function getTaskCount($site)
	{
		$count = 0;
		$res = $this->get('stand_catch_list', ['count(*) as count'], sprintf(" and sce_reg_code ='%s' and sce_status in (0,1)", $site), true);
		$count = $res['data']['count'];

		$res = $this->get('stand_catch_jsvin', ['count(*) as count'], sprintf(" and scl_reg_code ='%s'", $site), true);
		$count += $res['data']['count'];

		return $count;
	}


	//计算清单的采集任务 根据规则计算车架号加入采集任务
	public function addCatchJsvinByReg($site = '')
	{
		$minCount = 500000;
		$vinMaxyear = date('m') < 6 ? date('Y'): date('Y')+1;
		$res = $this->get('yp_vin_year', ['*'], sprintf(" and vin_year <=%d order by vin_year desc", $vinMaxyear));
		$yearArr = array_column($res['data'], 'vin_10', 'vin_year');
		$where = " and reg_status > -1 and reg_jsvin = 1 and reg_jsvin_reget = 1";
		if(!empty($site)) $where .= sprintf(" and reg_code in ('%s')", LibFc::Escape($site));
		$res = $this->get('stand_scqd_reg', ['*'], $where.' order by rand()');
		$regArr = array_column($res['data'], null, 'reg_code');
		
		foreach($regArr as $site=>$reg)
		{
			$reg['reg_jsvin_res'] = json_decode($reg['reg_jsvin_res'], true);
			if(empty($reg['reg_jsvin_res'])) $reg['reg_jsvin_res'] = [];
			if(empty($reg['reg_wmi'])) continue;
			$reg['reg_jsvin_res']['time'] = date('Y-m-d H:i');
			//当前的任务剩余超过20w不进行计算
			$wcount = $this->getTaskCount($site);
			$needCount = $minCount - $wcount;
			if($needCount < 10000) continue;

			$reg['reg_wmi'] = explode(',', $reg['reg_wmi']);
			$reg['vin10'] = [];
			foreach($yearArr as $y=>$vn)
			{
				//魏派 vin11 = H  年份 < 2020
				if($site == 'wey' && $y > 2019) continue; 
				if($y >= $reg['reg_min_year']) $reg['vin10'][] = $vn;
			}

			//特殊
			$othwhere = " and sma_from != 'buy02'";
			if($site == 'wey') $othwhere = " and right(sma_vin10_11, 1) = 'H' and sma_brand like '魏派%'";
			if($site == 'tftm') $othwhere = " and right(sma_vin10_11, 1) = '0'";
			if($site == 'sftm') $othwhere = " and right(sma_vin10_11, 1) = 'S'";
			if($site == 'caky') $othwhere .= "  and right(sma_vin10_11, 1) = 'E'";
			
			if(!$reg['reg_jsvin_res']['all']) $reg['reg_jsvin_res']['all'] = [];
			foreach($reg['vin10'] as $rvin10){
				if($needCount < 10000) break;
				if(!empty($reg['reg_jsvin_res']['all'][$rvin10]) && (time()-strtotime($reg['reg_jsvin_res']['all'][$rvin10])) < 3600*48) continue;

				$lockfile = mvc::$URL_METHOD.'_'.$site.'_'.$rvin10;
				if(!LibFc::hasFunLock($lockfile, 7200)) continue;

				$vinYear = LibFc::VinYear($rvin10);
				$isnew = $vinYear >= date('Y');
				foreach($reg['reg_wmi'] as $wmi){
					if($needCount < 10000) break;

					$where = $othwhere.sprintf(" and sma_vin1_8 LIKE '%s%%' AND sma_vin10_12 LIKE '%s%%' GROUP BY sma_vin1_8, sma_vin10_12", $wmi, $rvin10);
					$tRes = $this->get('stand_model_any', ["sma_vin1_8, sma_vin10_12"], $where);
					foreach($tRes['data'] as $tjv){
						if($needCount < 10000) break;

						$v18 = $tjv['sma_vin1_8']; $v1012 = $tjv['sma_vin10_12'];
						$jstype = 'all_shitan';
						$unikey = $v18.'_'.$v1012.'@'.$jstype;
						
						$where = sprintf(" and scj_reg_code='%s' and scj_vin1_8='%s' and scj_vin10_12='%s' and scj_reg_type='%s'", $site, $v18, $v1012, $jstype);
						$res = $this->get('stand_catch_jsvinreg', ['scj_id, scj_vin1_8, scj_vin10_12, scj_reg_type, scj_vin13_17_min, scj_vin13_17_max'], $where, true);
						$hasOkReg = $res['data'];
						if(!empty($hasOkReg) && time() - $hasOkReg['scj_etime'] < 3600*24) continue;

						$where = $othwhere.sprintf(" and sma_vin1_8='%s' AND sma_vin10_12='%s'", $v18, $v1012);
						$res = $this->get('stand_model_any', ['distinct LEFT(sma_vin13_17, 2) AS vin13_14'], $where);
						if(empty($res['data'])) continue;
						$v1314s = [];
						foreach($res['data'] as $tv1){
							$v1314 = $tv1['vin13_14'];
							$v1314s[$v1314] = ['v1314'=>$tv1['vin13_14'], 'end'=>999];
							//查找最后的日期
							$ismax = false;
							if($isnew){
								$res = $this->get('stand_model_any', ['sma_year'], sprintf(" and sma_vin1_8='%s' AND sma_vin10_12='%s' and sma_vin13_17 like '%s%%' and sma_year != '' order by sma_vin13_17 desc limit 10", $v18, $v1012, $v1314));
								foreach($res['data'] as $tv){
									if(strlen($tv['sma_year']) == 7 && date('Y-m') == $tv['sma_year']){//当前月
										$v1314s[$v1314]['sma_year'] = $tv['sma_year'];
										$ismax = true;
										break;
									}else if(strlen($tv['sma_year']) == 10 && time() - strtotime($tv['sma_year']) < 3600*24*10){//时间相差5天以内
										$v1314s[$v1314]['sma_year'] = $tv['sma_year'];
										$ismax = true;
										break;
									}
								}
								if($ismax){
									$res = $this->get('stand_model_any', ['right(sma_vin13_17, 3) maxv1517'], sprintf(" and sma_vin1_8='%s' AND sma_vin10_12='%s' and sma_vin13_17 like '%s%%' order by sma_vin13_17 desc limit 1", $v18, $v1012, $v1314), true);
									$v1314s[$v1314]['end'] = $res['data']['maxv1517'] + 100;
									if($v1314s[$v1314]['end'] > 1000) $v1314s[$v1314]['end'] = 999;
								}
							}

							//整数进行+1 -1扩张
							if(preg_match('/^\d+$/', $tv1['vin13_14'])){
								$toint = (int) $tv1['vin13_14'];
								if($toint > 0){
									$tv1314 = sprintf("%02d", $tv1['vin13_14']-1);
									if(empty($v1314s[$tv1314])) $v1314s[$tv1314] = ['v1314'=>$tv1314, 'end'=>999];
								}
								if(!$ismax && $toint < 99){
									$tv1314 = sprintf("%02d", $tv1['vin13_14']+1);
									if(empty($v1314s[$tv1314])) $v1314s[$tv1314] = ['v1314'=>$tv1314, 'end'=>999];
								}
							}
						}

						$recatch_min = strtotime('-2 month');
						//近2年的新数据如果不存在，VIN重采
						if($vinYear > (date('Y') -2)){
							$maxCatchCount = $isnew? 20: 5;
							$jgday = $isnew? 20: 40;
							$where = sprintf(" and sce_reg_code='%s' AND sce_status in (-2) and sce_vin like '%s_%s%%' AND sce_catch_count <= %d and sce_etime between %d and %d",
								$site, $v18, $v1012, $maxCatchCount, $recatch_min, strtotime('-'.$jgday.' day'));
							$this->set('stand_catch_list', ['sce_status'=>1], $where);
						}

						//失败的2天重采
						$where = sprintf(" and sce_reg_code='%s' AND sce_status in (-1) and sce_vin like '%s_%s%%' AND sce_catch_count <= %d and sce_etime between %d and %d",
								$site, $v18, $v1012, 20, $recatch_min, strtotime('-2 day'));
						$this->set('stand_catch_list', ['sce_status'=>1], $where);

						foreach($v1314s as $vtv){
							//进行1/10进行预采集
							$v1314 = $vtv['v1314']; $begin = 0; $end = $vtv['end']; $jg = 10; 
							$level = 1111;
							
							$allJsVinArr = [];
							for($v1517 = $begin; $v1517 <= $end; $v1517=$v1517+$jg){
								$tempVin = $v18.'X'.$v1012.$v1314.sprintf("%03d", $v1517);
								$vin9 =	LibFc::VinCheckCode($tempVin);
								$realVin = substr($tempVin, 0, 8).$vin9['real'].substr($tempVin, -8);
								$allJsVinArr[] = [
									'sce_vin'=>$realVin,	
									'sce_level'=>$level,	
									'sce_reg_code'=>$site
								];
							}
							$this->addCatchList($site, $allJsVinArr);

							$this->set('stand_catch_list', ['sce_level'=>$level], sprintf(" and sce_reg_code='%s' and sce_vin in ('%s') and sce_level < %d", $site, implode("','", array_column($allJsVinArr, 'scl_vin')), $level));
							
							//已有样本数上下扩
							$num = $reg['reg_jsvin_sxcount'];
							$hasres = $this->get('stand_model_any', ['sma_vin', 'right(sma_vin13_17, 3) v1517'], sprintf(" and sma_vin not in (select scj_vin from stand_catch_jsvin_near where scj_reg_code='%s' and scj_near>=%d) and sma_vin1_8='%s' AND sma_vin10_12='%s' and sma_vin13_17 like '%s%%'", $site, $num, $v18, $v1012, $v1314));
							$hasArr = array_column($hasres['data'], 'sma_vin', 'v1517');
							$allJsVinArr = [];
							foreach($hasArr as $hv1517=>$hVin){
								$begin = $hv1517 - $num >= 0? $hv1517 - $num: 0;
								$end = $hv1517 + $num <= 999? $hv1517 + $num: 999;
								for($v1517 = $begin; $v1517 <= $end; $v1517++){
									if($hasArr[$v1517] || $allJsVinArr[$v1517]) continue;
									$tempVin = $v18.'X'.$v1012.$v1314.sprintf("%03d", $v1517);
									$vin9 =	LibFc::VinCheckCode($tempVin);
									$realVin = substr($tempVin, 0, 8).$vin9['real'].substr($tempVin, -8);
									$allJsVinArr[$v1517] = [
										'sce_vin'=>$realVin,	
										'sce_level'=>$vinYear-3000,
										'sce_reg_code'=>$site
									];
								}
								$near = [
									'scj_reg_code'=>$site,
									'scj_vin'=>$hVin,
									'scj_near'=>$num,
									'scj_etime'=>time(),
								];
								$this->Add('stand_catch_jsvin_near', $near, 'replace');
							}
							if(!empty($allJsVinArr)){
								$allJsVinArr = array_values($allJsVinArr);
								$this->addCatchList($site, $allJsVinArr);
							}
							
							$wcount = $this->getTaskCount($site);
							$needCount = $minCount - $wcount;
							if($needCount < 10000) break;
						}

						if(!empty($hasOkReg)){
							$this->set('stand_catch_jsvinreg', ['scj_etime'=>time()], sprintf(" and scj_id=%d", $hasOkReg['scj_id']));
						}else{
							$ta = [
								'scj_reg_code'=>$site,
								'scj_vin1_8'=>$v18,
								'scj_vin10_12'=>$v1012,
								'scj_reg_type'=>$jstype,
								'scj_etime'=>time(),
							];
							$this->add('stand_catch_jsvinreg', $ta);
						}
					}
				}
				$reg['reg_jsvin_res']['all'][$rvin10] = date('Y-m-d H:i');
				$this->set('stand_scqd_reg',['reg_jsvin_res'=>json_encode($reg['reg_jsvin_res'])], sprintf(" and reg_code='%s'", $site));
				LibFc::delFunLock($lockfile);
			}
			
			//重采用户查询过但是上一次采集不到的车架号（距离上次时间超过1个月）
			$where = sprintf(" and sce_reg_code='%s' AND sce_status in (-1, -2) AND sce_catch_count < 5 and sce_etime between %d and %d AND vs_ip != '127.0.0.1' limit 1000", $site, strtotime('-2 month'), strtotime('-1 month'));
			for($page = 1; $page < 100; $page++){
				$sceres = $this->get('stand_catch_list JOIN yp_vin_search ON sce_vin = vs_vin', ['sce_id'], $where);
				if(empty($sceres['data'])) break;
				$reg['reg_jsvin_res']['user_again'] = $page;
				$this->set('stand_catch_list',['sce_status'=>1, 'sce_error'=>'#again#chk'], sprintf(" and sce_id in (%s)", implode(',', array_column($sceres['data'], 'sce_id'))));
			}
			$this->set('stand_scqd_reg',['reg_jsvin_res'=>json_encode($reg['reg_jsvin_res'])], sprintf(" and reg_code='%s'", $site));
		}
		return LibFc::ReturnData(true);
	}

	//计算发动机清单的采集任务
	public function addCatchJsvinByEng6($site)
	{
		$minCount = 200000;
		$chae = 20;
		$vinMaxyear = date('m') < 6 ? date('Y'): date('Y')+1;
		$res = $this->get('yp_vin_year', ['*'], sprintf(" and vin_year <=%d order by vin_year desc", $vinMaxyear));
		$yearArr = array_column($res['data'], 'vin_10', 'vin_year');
		switch($site)
		{
			case 'tran': 
				//发动机编码  同一个型号多变速箱
				$YPCAR67 = new BaseDb(mvc::$cfg['DB']['YPCAR67']);
				$gxbres = $YPCAR67->get('model_chinacar.all_model', ['clxh as sma_gxb_code'], " and bsqlx != '0' AND clxh REGEXP '^[a-zA-Z]'  GROUP BY clxh HAVING COUNT(DISTINCT bsqlx) > 1");
				foreach($gxbres['data'] as $gv)
				{
					$sql = sprintf("INSERT INTO stand_catch_list(sce_reg_code, sce_vin, sce_level, sce_engine6)
					SELECT 'engine6', sma_vin, sma_vyear-2000, RIGHT(sma_engine6, 6) FROM stand_model_any
					LEFT JOIN stand_catch_list ON sce_reg_code = 'engine6' AND sce_vin = sma_vin AND sce_engine6 = RIGHT(sma_engine6, 6) 
					WHERE sce_id IS NULL AND sma_gxb_code = '%s' AND sma_vyear > 2016 AND LENGTH(sma_engine6) >= 6 AND sma_tran = '' AND sma_xuhang = ''", $gv['sma_gxb_code']);		
					$this->exeAnySql([$sql]);
				}
			break;
			case 'gcsearch':
			case 'gcjs':
				$regArr = [
					'xiaopeng'=>['wmi'=>['LMV', 'L1N'], 'byear'=>2019, 'remark'=>'小鹏'],
					'fengshen'=>['wmi'=>['LGJ', 'LDP'], 'byear'=>2017, 'remark'=>'风神牌'],	
				];
				foreach($regArr as $en6Reg)
				{
					$where = sprintf("and sma_vin1_3 IN ('%s') AND sma_vyear >= %d AND LENGTH(sma_engine6) > 5 GROUP BY sma_vin1_8, eng6 HAVING COUNT(*) > 5 ORDER BY COUNT(*) DESC", implode("','", $en6Reg['wmi']), $en6Reg['byear']);
					$en6res = $this->get('stand_model_any', ['sma_vin1_8 vin1_8, RIGHT(sma_engine6, 6) eng6, count(*) total'], $where);
					foreach($en6res['data'] as $evv)
					{
						$engine6 = $evv['eng6'];
						if($site == 'gcsearch')
						{//用户查询过的
							$where = sprintf(" and vs_vin LIKE '%s%%' AND vin_year >= %d and sma_vin IS NULL", $evv['vin1_8'], $en6Reg['byear']);
							$table = sprintf("yp_vin_search 
							JOIN yp_vin_year ON vs_vin10=vin_10
							LEFT JOIN stand_model_any ON sma_vin=vs_vin AND sma_vyear >= %d and sma_vin1_8='%s'", $en6Reg['byear'], $evv['vin1_8']);
							$tres = $this->get($table, ['vs_vin vin'], $where);
							$addVinArr = [];
							foreach($tres['data'] as $rv)
							{
								$addVinArr[$rv['vin']] = [
									'sce_reg_code'=>'engine6',
									'sce_vin'=>$rv['vin'], 
									'sce_level'=>ceil($evv['total']/100)+2000,
									'sce_engine6'=>$engine6
								];
							}
							$this->addDbEng6Task($addVinArr, $engine6);
						}
						if($site == 'gcjs')
						{//计算
							$jsEn6RegCahceFile = mvc::$cfg['LOGS'].'jsEn6RegCahce.php';
							$jsEn6RegCacheArr = file_exists($jsEn6RegCahceFile)? include($jsEn6RegCahceFile): [];

							$where = sprintf(" and sma_vin1_8 = '%s' AND sma_vyear >= %d GROUP BY sma_vin1_8, vin10_14", $evv['vin1_8'], $en6Reg['byear']);
							$tres = $this->get('stand_model_any', ["sma_vin1_8, concat(sma_vin10_12, LEFT(sma_vin13_17, 2)) as vin10_14, '000' as vin15_17_min, MAX(RIGHT(sma_vin13_17, 3)) as vin15_17_max"], $where);
							foreach($tres['data'] as $rv)
							{
								$addVinArr = [];
								$vinYear = LibFc::VinYear(substr($rv['vin10_14'], 0, 1));
								$min = $rv['vin15_17_min'];
								$max = $rv['vin15_17_max'];
								$min = $min - $chae > 0? $min -$chae: 0;
								if($vinYear < $vinMaxyear) $max = $max + $chae < 999? $max + $chae: 999;
								$unikey = $rv['sma_vin1_8'].'_'.$rv['vin10_14'].'@'.$min.'@'.$max.'@'.$engine6;
								if(!empty($jsEn6RegCacheArr[$unikey])) continue;
								for($jsv = $min; $jsv < $max; $jsv++)
								{
									$tvin15_17 = str_pad($jsv, 3, '0', STR_PAD_LEFT);
									$tempVin = $rv['sma_vin1_8'].'X'.$rv['vin10_14'].$tvin15_17;
									$vin9 =	LibFc::VinCheckCode($tempVin);
									$realVin = $rv['sma_vin1_8'].$vin9['real'].$rv['vin10_14'].$tvin15_17;
									$addVinArr[$realVin] = [
										'sce_reg_code'=>'engine6',
										'sce_vin'=>$realVin, 
										'sce_level'=>ceil($evv['total']/100)-9000,
										'sce_engine6'=>$engine6
									];
								}
								$this->addDbEng6Task($addVinArr, $engine6);
								$jsEn6RegCacheArr[$unikey] = date('Y-m-d H:i:s');
								LibFc::ArraySave($jsEn6RegCacheArr, $jsEn6RegCahceFile);

								$res = $this->get('stand_catch_list', ['count(*) as count'], " and sce_reg_code ='engine6' and sce_status = 0", true);
								if($res['data']['count'] > $minCount) return LibFc::ReturnData(true);
							}
						}
					}
				}
			break;
			case 'jinkousearch':
			case 'jinkoujs':
				//发动机型号=发动机编码
				$jsEn6RegArr = [
					'right6'=>['wmi'=>['SCA','WBA','WBS','WBY','WBX','WMW','MMF','5UX'], 'byear'=>2017, 'bit'=>'right6', 'remark'=>'劳斯莱斯 宝马 迷你'],	
					'right5'=>['wmi'=>['SAD','SAJ','SAL'], 'byear'=>2017, 'eyear'=>2025, 'bit'=>'right5', 'bit1'=>'0123456789', 'remark'=>'捷豹路虎'],	
				];
				foreach($jsEn6RegArr as $ekey=>$en6Reg)
				{
					$fileds = [];
					$where = sprintf(" and sma_vin1_3 IN ('%s') AND sma_vyear >= %d AND sma_engine != ''", implode("','", $en6Reg['wmi']), $en6Reg['byear']);
					if($en6Reg['eyear']) $where .= sprintf(" and sma_vyear <= %d", $en6Reg['eyear']);
					if($en6Reg['bit'] == 'right6')
					{
						$fileds = ['sma_vin1_8', 'RIGHT(sma_engine, 6) eng6, count(*) total'];
						$where .= "  AND LENGTH(sma_engine) >= 6 group by sma_vin1_8, eng6";
					}
					else if($en6Reg['bit'] == 'right5')
					{
						$fileds = ['sma_vin1_8', 'RIGHT(sma_engine, 5) eng6, count(*) total'];
						$where .= "  AND LENGTH(sma_engine) >= 5 group by sma_vin1_8, eng6";
					}
					if(empty($fileds)) continue;
					$en6res = $this->get('stand_model_any', $fileds, $where);
					foreach($en6res['data'] as $evv)
					{
						$evv['eng6'] = LibFc::Escape($evv['eng6']);
						$engine6Arr = [];
						if($en6Reg['bit'] == 'right6')
						{
							$engine6Arr[] = $evv['eng6'];
						}
						else if($en6Reg['bit'] == 'right5')
						{
							//优先已有的
							$where = sprintf(" and sma_vin1_8='%s' AND sma_vyear >= %d and right(sma_engine6, 5)='%s' group by cb order by count(*) desc", $evv['sma_vin1_8'], $en6Reg['byear'], $evv['eng6']);
							$cbRes = $this->get('stand_model_any', ['distinct left(right(sma_engine6,6), 1) cb'], $where);
							$isChars = array_column($cbRes['data'], 'cb');
							foreach(str_split($en6Reg['bit1']) as $cv)
							{
								if(!in_array($cv, $isChars)) $isChars[] = $cv;
							}
							foreach($isChars as $ch)
							{
								$engine6Arr[] = $ch.$evv['eng6'];
							}
						}

						if($site == 'jinkousearch')
						{//用户查询过的
							$where = sprintf(" and vs_vin LIKE '%s%%' AND vin_year >= %d and sma_vin IS NULL", $evv['sma_vin1_8'], $en6Reg['byear']);
							$table = sprintf("yp_vin_search 
							JOIN yp_vin_year ON vs_vin10=vin_10
							LEFT JOIN stand_model_any ON sma_vin=vs_vin AND sma_vyear >= %d and sma_vin1_8='%s'", $en6Reg['byear'], $evv['sma_vin1_8']);
							$tres = $this->get($table, ['vs_vin vin'], $where);
							foreach($engine6Arr as $ekk=>$engine6)
							{
								$addVinArr = [];
								foreach($tres['data'] as $rv)
								{
									$addVinArr[$rv['vin']] = [
										'sce_reg_code'=>'engine6',
										'sce_vin'=>$rv['vin'], 
										'sce_level'=>ceil($evv['total']/100)+3000+count($engine6Arr)-$ekk,
										'sce_engine6'=>$engine6
									];
								}
								$this->addDbEng6Task($addVinArr, $engine6);
							}
						}

						if($site == 'jinkoujs' && $en6Reg['bit'] == 'right6')
						{//计算
							$jsEn6ByEngFile = mvc::$cfg['LOGS'].'jsEn6ByEng.php';
							$jsEn6ByEngArr = file_exists($jsEn6ByEngFile)? include($jsEn6ByEngFile): [];
							$where = sprintf(" and sma_vin1_8='%s' AND sma_vyear >= %d GROUP BY sma_vin1_8, vin10_14", $evv['sma_vin1_8'], $en6Reg['byear']);
							$jsRes = $this->get('stand_model_any', ["sma_vin1_8, concat(sma_vin10_12, LEFT(sma_vin13_17, 2)) as vin10_14, '000' as vin15_17_min, MAX(RIGHT(sma_vin13_17, 3)) as vin15_17_max"], $where);
							foreach($jsRes['data'] as $rv)
							{
								foreach($engine6Arr as $ekk=>$engine6)
								{
									$addVinArr = [];
									$vinYear = LibFc::VinYear(substr($rv['vin10_14'], 0, 1));
									$min = $rv['vin15_17_min'];
									$max = $rv['vin15_17_max'];
									$min = $min - $chae > 0? $min -$chae: 0;
									if($vinYear < $vinMaxyear) $max = $max + $chae < 999? $max + $chae: 999;
									$unikey = $rv['sma_vin1_8'].'_'.$rv['vin10_14'].'@'.$min.'@'.$max.'@'.$engine6;
									if(!empty($jsEn6ByEngArr[$unikey])) continue;
									for($jsv = $min; $jsv < $max; $jsv++)
									{
										$tvin15_17 = str_pad($jsv, 3, '0', STR_PAD_LEFT);
										$tempVin = $rv['sma_vin1_8'].'X'.$rv['vin10_14'].$tvin15_17;
										$vin9 =	LibFc::VinCheckCode($tempVin);
										$realVin = $rv['sma_vin1_8'].$vin9['real'].$rv['vin10_14'].$tvin15_17;
										$addVinArr[$realVin] = [
											'sce_reg_code'=>'engine6',
											'sce_vin'=>$realVin, 
											'sce_level'=>ceil($evv['total']/100)+$vinYear-3000-$ekk,
											'sce_engine6'=>$engine6
										];
									}
									$this->addDbEng6Task($addVinArr, $engine6);
									$jsEn6ByEngArr[$unikey] = date('Y-m-d H:i:s');
									LibFc::ArraySave($jsEn6ByEngArr, $jsEn6ByEngFile);

									$res = $this->get('stand_catch_list', ['count(*) as count'], " and sce_reg_code ='engine6' and sce_status = 0", true);
									if($res['data']['count'] > $minCount) return LibFc::ReturnData(true);
								}
							}
						}
					}
				}
			break;
			case 'vin1217search':
			case 'vin1217js':
				//VIN后6位等于发动机编码 
				$regArr = [
					['wmi'=>['1C4','2C4','1FD','1GD','1GY','1C6','1G1','2C3','MLY','3GT','1GN','3FM','1GK','1FT'], 'byear'=>2017, 'eyear'=>date('Y')+2, 'remark'=>'', 'eng6'=>'1217'],
					['wmi'=>['1FA','1LN','2LM','3LN','5LM','1FM','1FT'], 'byear'=>2025, 'eyear'=>date('Y')+2, 'remark'=>'', 'eng6'=>'1217'],
					['wmi'=>['1FA','1LN','2LM','3LN','5LM','1FM','1FT'], 'byear'=>2017, 'eyear'=>2025, 'remark'=>'林肯 福特 后5位加上第8位', 'eng6'=>'v8_1317']
				];
				foreach($regArr as $en6Reg)
				{
					if($site == 'vin1217search'){//用户查询过的
						foreach($en6Reg['wmi'] as $wmi){
							$where = sprintf(" and vs_vin1_3 = '%s' AND vin_year BETWEEN %d AND %d and sma_vin IS NULL", $wmi, $en6Reg['byear'], $en6Reg['eyear']);
							$table = sprintf("yp_vin_search 
							JOIN yp_vin_year ON vs_vin10=vin_10
							LEFT JOIN stand_model_any ON sma_vin=vs_vin AND sma_vyear BETWEEN %d AND %d and sma_vin1_3='%s'", $en6Reg['byear'], $en6Reg['eyear'], $wmi);
							$tres = $this->get($table, ['vs_vin vin', 'vin_year'], $where);
							foreach($tres['data'] as $rv)
							{
								$addVinArr = [];
								$engine6 = $en6Reg['eng6'] == 'v8_1317' ? substr($rv['vin'], -5).substr($rv['vin'], 7, 1): substr($rv['vin'], -6);
								$addVinArr[$rv['vin']] = [
									'sce_reg_code'=>'engine6',
									'sce_vin'=>$rv['vin'], 
									'sce_level'=>$rv['vin_year'],
									'sce_engine6'=>$engine6
								];
								$this->addDbEng6Task($addVinArr, $engine6);
							}
						}
					}else if($site == 'vin1217js'){//计算
						$where = sprintf("and sma_vin1_3 IN ('%s') AND sma_vyear BETWEEN %d AND %d GROUP BY sma_vin1_8 ORDER BY COUNT(*) DESC", implode("','", $en6Reg['wmi']), $en6Reg['byear'], $en6Reg['eyear']);
						$en6res = $this->get('stand_model_any', ['sma_vin1_8 vin1_8, count(*) total'], $where);
						foreach($en6res['data'] as $evv){

							$jsEn6RegCahceFile = mvc::$cfg['LOGS'].'jsEn6RegCahce.php';
							$jsEn6RegCacheArr = file_exists($jsEn6RegCahceFile)? include($jsEn6RegCahceFile): [];

							$where = sprintf(" and sma_vin1_8 = '%s' AND sma_vyear BETWEEN %d AND %d GROUP BY sma_vin1_8, vin10_14", $evv['vin1_8'], $en6Reg['byear'], $en6Reg['eyear']);
							$tres = $this->get('stand_model_any', ["sma_vin1_8, concat(sma_vin10_12, LEFT(sma_vin13_17, 2)) as vin10_14, '000' as vin15_17_min, MAX(RIGHT(sma_vin13_17, 3)) as vin15_17_max"], $where);
							foreach($tres['data'] as $rv)
							{
								$vinYear = LibFc::VinYear(substr($rv['vin10_14'], 0, 1));
								$min = $rv['vin15_17_min'];
								$max = $rv['vin15_17_max'];
								$min = $min - $chae > 0? $min -$chae: 0;
								if($vinYear < $vinMaxyear) $max = $max + $chae < 999? $max + $chae: 999;
								$unikey = $rv['sma_vin1_8'].'_'.$rv['vin10_14'].'@'.$min.'@'.$max;
								if(!empty($jsEn6RegCacheArr[$unikey])) continue;
								for($jsv = $min; $jsv < $max; $jsv++)
								{
									$addVinArr = [];
									$tvin15_17 = str_pad($jsv, 3, '0', STR_PAD_LEFT);
									$tempVin = $rv['sma_vin1_8'].'X'.$rv['vin10_14'].$tvin15_17;
									$vin9 =	LibFc::VinCheckCode($tempVin);
									$realVin = $rv['sma_vin1_8'].$vin9['real'].$rv['vin10_14'].$tvin15_17;
									$engine6 = $en6Reg['eng6'] == 'v8_1317' ? substr($realVin, -5).substr($realVin, 7, 1): substr($realVin, -6);
									$addVinArr[$realVin] = [
										'sce_reg_code'=>'engine6',
										'sce_vin'=>$realVin, 
										'sce_level'=>ceil($evv['total']/100)-9000,
										'sce_engine6'=>$engine6
									];
									$this->addDbEng6Task($addVinArr, $engine6);
								}
								$jsEn6RegCacheArr[$unikey] = date('Y-m-d H:i:s');
								LibFc::ArraySave($jsEn6RegCacheArr, $jsEn6RegCahceFile);

								$res = $this->get('stand_catch_list', ['count(*) as count'], " and sce_reg_code ='engine6' and sce_status = 0", true);
								if($res['data']['count'] > $minCount) return LibFc::ReturnData(true);
							}
						}
					}
				}
			break;
			case 'reset':
				$res = $this->get('stand_catch_list', ['count(*) as count'], " and sce_reg_code ='engine6' and sce_status = 0", true);
				$count = $minCount - $res['data']['count'];

				//验证码问题达到最大次数的重采
				$sqlArr = [
					sprintf("UPDATE stand_catch_list SET sce_status = 0, sce_catch_count = 0  WHERE sce_reg_code = 'engine6' AND sce_catch_count > 0 AND sce_level > 2000 AND sce_error LIKE '%%验证码%%' AND sce_etime <=%d  AND sce_etime >=%d", strtotime('-1 day'), strtotime('-7 day')),
					sprintf("UPDATE stand_catch_list SET sce_status = 0, sce_catch_count = 0  WHERE sce_reg_code = 'engine6' AND sce_catch_count >= 5 AND sce_error LIKE '%%验证码%%' AND sce_etime <=%d  AND sce_etime >=%d", strtotime('-1 day'), strtotime('-15 day')),
				];
				if($count > 0)
				{//buy01
					$sqlArr[] = "INSERT INTO stand_catch_list(sce_reg_code, sce_vin, sce_engine6, sce_level)
						SELECT 'engine6', sma_vin, RIGHT(sma_engine6, 6), 2 FROM stand_model_any 
						WHERE sma_vyear >= 2017 AND LENGTH(sma_engine6)> 5 AND sma_from = 'buy01' AND sma_tran = '' AND sma_xuhang = '' 
						AND (sma_vin, RIGHT(sma_engine6, 6)) NOT IN (SELECT sce_vin, RIGHT(sce_engine6, 6) FROM stand_catch_list WHERE sce_reg_code = 'engine6') limit ".$count;
				}

				//计算&用户查询过的近两年2个月重采未公开
				$sqlArr[] = sprintf("UPDATE stand_catch_list join yp_vin_year on right(left(sce_vin, 10), 1)=vin_10 SET sce_status = 0
				WHERE sce_reg_code = 'engine6' AND sce_status = -2 AND sce_etime <=%d and vin_year>=%d AND EXISTS (SELECT 1 FROM yp_vin_search WHERE sce_vin = vs_vin)
				AND LEFT(sce_vin, 3) IN ('1C4','2C4','1FD','1GD','1GY','1C6','1G1','2C3','MLY','3GT','1GN','3FM','1GK','1FT','1FA','1LN','2LM','3LN','5LM','1FM','1FT') AND sce_error = '#end#未公开'", strtotime('-2 month'), date('Y', strtotime('-2 year')));
				$this->exeAnySql($sqlArr);
			break;
		}
		
		return LibFc::ReturnData(true);
	}
	
	//发动机编码任务入库，含检测任务重复性
	private function addDbEng6Task($addVinArr, $engine6)
	{
		if(!empty($addVinArr))
		{
			$res = $this->get('stand_catch_list', ['sce_vin'], sprintf(" and sce_vin in ('%s') and sce_reg_code='engine6' and sce_engine6='%s'", implode("','", array_keys($addVinArr)), $engine6));
			foreach($res['data'] as $tvv)
			{
				unset($addVinArr[$tvv['sce_vin']]);
			}
		}

		if(!empty($addVinArr))
		{
			$res = $this->get('stand_model_any', ['sma_vin'], sprintf(" and sma_vin in ('%s')", implode("','", array_keys($addVinArr))));
			foreach($res['data'] as $tvv)
			{
				unset($addVinArr[$tvv['sma_vin']]);
			}
		}
		if(!empty($addVinArr))
		{
			$addVinArr = array_values($addVinArr);
			$this->addAny('stand_catch_list', array_keys($addVinArr[0]), $addVinArr);
		}
		return LibFc::ReturnData(true);
	}


	//通过600w表计算采集泽达的车架号
	public function addCatchZdvinByReg($site = '')
	{
		$cacheBTime = time()-3600*24;
		$res = $this->get('yp_vin_year', ['*'], ' order by vin_year desc');
		$yearArr = array_column($res['data'], 'vin_10', 'vin_year');
		$where = " and (vzr_status = 0 or vzr_code ='yiwen')";
		if(!empty($site)) $where .= sprintf(" and vzr_code in ('%s') order by vzr_id", implode("','", explode(',', $site)));
		$res = $this->get('stand_vin_zdapireg', ['*'], $where);
		$regArr = array_column($res['data'], null, 'vzr_code');
		foreach($regArr as $site=>$reg)
		{
			$res = $this->get('stand_vin_zdapireg', ['vzr_code'], sprintf(" and vzr_code='%s' and vzr_lasttime <%d", $site, time()-3600*24));
			if(empty($res['data'])) continue;

			if($site == 'yiwen')
			{
				$lockfile = mvc::$URL_METHOD.'_'.$site;
				if(!LibFc::hasFunLock($lockfile, 7200)) continue;
				$cacheFile = mvc::$cfg['LOGS'].'cache_zdvin_'.$site.'.php';

				if($reg['vzr_status'] != 1) continue;
				//一、找出人工处理异常的部分，找出需要处理的前8
				$minCount = 500;
				$table = 'stand_model_tj left join stand_gxb_info ON sgi_gxb_code = smt_gxb_code AND sgi_vin1_8 = smt_vin1_8';
				$vin8res = $this->get($table, ['smt_vin1_8'], sprintf(" and smt_vin1_8 LIKE 'L%%' GROUP BY smt_vin1_8 HAVING SUM(smt_vin_count) >= %d", $minCount));
				$addVinArr = [];
				foreach($vin8res['data'] as $xk=>$xv)
				{
					//找出1_8+10_12数量超过的
					$twhere = sprintf(" and sma_gxb_code != '' and sma_vin1_8='%s' group by sma_vin1_8, sma_vin10_12 having count(*) >= %d", $xv['smt_vin1_8'], $minCount);
					$x1res = $this->get('stand_model_any', ['sma_vin1_8, sma_vin10_12, count(*) as vin_count'], $twhere);
					foreach($x1res['data'] as $x1v)
					{
						//超过的这部分某个型号<3个的
						$table = sprintf("stand_model_any AS a 
						JOIN (SELECT sma_gxb_code, sma_vin1_8, sma_vin10_12 FROM stand_model_any where sma_gxb_code != '' and sma_vin1_8='%s' and sma_vin10_12='%s' group by sma_gxb_code, sma_vin1_8, sma_vin10_12 having count(*) < 3) as b ON a.sma_gxb_code = b.sma_gxb_code AND a.sma_vin1_8=b.sma_vin1_8 AND a.sma_vin10_12 = b.sma_vin10_12", $x1v['sma_vin1_8'], $x1v['sma_vin10_12']);
						$res = $this->get($table , ['a.sma_vin'], sprintf(" and a.sma_from in ('manual')"));
						if(!empty($res['data']))
							$this->catchAnyVinfromZdApi(array_column($res['data'], 'sma_vin'));
					}
				}
			}
			else if($site == 'date')
			{
				$lockfile = mvc::$URL_METHOD.'_'.$site;
				if(!LibFc::hasFunLock($lockfile, 7200)) continue;
				$cacheFile = mvc::$cfg['LOGS'].'cache_zdvin_'.$site.'.php';

				//sma_vin1_8 + sma_gxb_code 取最小 最大 && 日期为空
				$table = 'stand_model_tj left join stand_gxb_info ON sgi_gxb_code = smt_gxb_code AND sgi_vin1_8 = smt_vin1_8';
				$vin8res = $this->get($table, ['smt_vin1_8, sgi_gxb_code'],  " and smt_vin1_8 LIKE 'L%' GROUP BY smt_vin1_8, sgi_gxb_code");
				$allJsVinArr = [];
				foreach($vin8res['data'] as $xk=>$xv)
				{
					$unikey = $xv['smt_vin1_8'].'_'.$xv['sgi_gxb_code'];
					$cacheArr = file_exists($cacheFile)? include($cacheFile): [];
					if(!empty($cacheArr[$unikey]) && $cacheArr[$unikey] > $cacheBTime) continue;

					//找出1_8+10_12数量超过的
					$twhere = sprintf(" and sma_vin1_8 = '%s' and sma_gxb_code = '%s' AND sma_year = '' and 
					(
						RIGHT(sma_vin, 8) in (select MIN(RIGHT(sma_vin, 8)) from stand_model_any where sma_vin1_8='%s' and sma_gxb_code = '%s')
					or  RIGHT(sma_vin, 8) in (select max(RIGHT(sma_vin, 8)) from stand_model_any where sma_vin1_8='%s' and sma_gxb_code = '%s')
					)", $xv['smt_vin1_8'], $xv['sgi_gxb_code'], $xv['smt_vin1_8'], $xv['sgi_gxb_code'], $xv['smt_vin1_8'], $xv['sgi_gxb_code']);
					$x1res = $this->get('stand_model_any', ['sma_vin'], $twhere);
					foreach($x1res['data'] as $xvv)
					{
						$allJsVinArr[] = [
							'scl_vin'=>$xvv['sma_vin'],	
							'scl_year'=>3000,	
							'scl_reg_code'=>'ZDAPI',
							'scl_unikey'=>$unikey,
							'scl_scode'=>$site
						];
					}
					if(!empty($allJsVinArr) && count($allJsVinArr) >= 300)
					{
						$this->addVinToJsTable($site, $allJsVinArr, false);
						$allJsVinArr = [];
					}
			
					$cacheArr = file_exists($cacheFile)? include($cacheFile): [];
					$cacheArr[$unikey] = time();
					LibFc::ArraySave($cacheArr, $cacheFile);
				}
				if(!empty($allJsVinArr)) $this->addVinToJsTable($site, $allJsVinArr, false);
			}
			else if(stripos($site, 'atmt') !== false)
			{
				$lockfile = mvc::$URL_METHOD.'_'.$site;
				if(!LibFc::hasFunLock($lockfile, 7200)) continue;
				$cacheFile = mvc::$cfg['LOGS'].'cache_zdvin_'.$site.'.php';

				//变速箱 提供前8
				$reg['vzr_wmi'] = explode(',', $reg['vzr_wmi']);
				$reg['vinyear'] = [];
				$byear = 2006;
				foreach($yearArr as $y=>$vn)
				{
					if($y > $byear && ($reg['vzr_eyear'] == 0 || $y <= $reg['vzr_eyear']) && $y <= date('Y')+1)
						$reg['vinyear'][] = $y;
				}
				//根据不同的wmi指定特殊条件
				$othwhere = '';
				$where = $othwhere.sprintf(" and sma_vin1_8 in ('%s') and sma_vyear IN (%s) and sma_gxb_code != '' GROUP BY sma_vin1_8, sma_vin10_12 HAVING COUNT(DISTINCT sma_gxb_code) > 1", implode("','", $reg['vzr_wmi']), implode(',', $reg['vinyear']));
				//vin18+vin10_12
				$table = 'stand_model_any';
				$jsRes = $this->get($table, ['sma_vin1_8, concat(sma_vin10_12, left(sma_vin13_17, 2)) as vin10_14, min(right(sma_vin13_17, 3)) as vin15_17_min, max(right(sma_vin13_17, 3)) as vin15_17_max'], $where);
				foreach($jsRes['data'] as $rv)
				{
					$allJsVinArr = [];
					$unikey = $rv['sma_vin1_8'].'_'.$rv['vin10_14'];
					$cacheArr = file_exists($cacheFile)? include($cacheFile): [];
					if(!empty($cacheArr[$unikey]) && $cacheArr[$unikey] > $cacheBTime) continue;

					$vinYear = LibFc::VinYear(substr($rv['vin10_14'], 0, 1));
					$comWhere = sprintf(" and sma_gxb_code !='' and sma_vin1_8='%s' and sma_vin10_12='%s' and sma_vin13_17 like '%s%%'", $rv['sma_vin1_8'], substr($rv['vin10_14'], 0, 3), substr($rv['vin10_14'], -2));
					$res = $this->get('stand_model_any', ['sma_vin, sma_vin13_17, sma_gxb_code'], $comWhere.sprintf(" and sma_vin13_17 >= '%s' order by sma_vin13_17 asc limit 1", $rv['vin13_17_min']), true);

					exit('atmt');
					$startArr = $res['data'];
					while(!empty($startArr['sma_vin13_17']) && $startArr['sma_vin13_17'] < $rv['vin13_17_max'])
					{
						//和start的型号不同最小vin
						$res =  $this->get('stand_model_any', ['sma_vin, sma_vin13_17, sma_gxb_code'], $comWhere.sprintf(" and sma_gxb_code != '%s' and sma_vin13_17 > '%s' order by sma_vin13_17 asc limit 1", $startArr['sma_gxb_code'], $startArr['sma_vin13_17']), true);
						$nextArr = $res['data'];

						//和nextArr的型号不同最大vin
						$res =  $this->get('stand_model_any', ['sma_vin, sma_vin13_17, sma_gxb_code'], $comWhere.sprintf(" and sma_gxb_code != '%s' and sma_vin13_17 < '%s' order by sma_vin13_17 desc limit 1", $nextArr['sma_gxb_code'], $nextArr['sma_vin13_17']), true);
						$startArr = $res['data'];

						if($nextArr['sma_vin13_17'] - $startArr['sma_vin13_17'] > 1)
						{
							//查询总表查询这个区间的24小时前的车架号
							$vres =  $this->get('yp_vin_search', ['vs_vin as vin'], sprintf(" and vs_last_time < %d and vs_vin like '%s_%s%%' and vs_vin9 = vs_checkcode and right(vs_vin, 5) > %d and right(vs_vin, 5) < %d order by right(vs_vin, 5)", time()-3600*24, $rv['sma_vin1_8'], $rv['vin10_14'], $startArr['sma_vin13_17'], $nextArr['sma_vin13_17']));
							if(!empty($vres['data']))
							{
								$vinCount = count($vres['data']);
								$rate = 50;
								//根据数量决定采集的比例
								if($vinCount < 10) $rate = 3;
								else if($vinCount < 50) $rate = 5;
								else if($vinCount < 150) $rate = 10;
								else if($vinCount < 500) $rate = 20;
								//echo $rv['sma_vin1_8'],'_',$rv['vin10_14'],'%=>', $startArr['sma_vin13_17'],'=>',$nextArr['sma_vin13_17'],'=>',$rate,'<br>';
								foreach($vres['data'] as $xkk=>$xvv)
								{
									if( $xkk % $rate > 0) continue;
									$allJsVinArr[] = [
										'scl_vin'=>$xvv['vin'],	
										'scl_year'=>$vinYear,	
										'scl_reg_code'=>'ZDAPI',
										'scl_unikey'=>$unikey,
										'scl_scode'=>$site
									];
								}
							}
						}
						//交换开始结束
						$startArr = $nextArr;
						$nextArr = [];
					}
					$this->addVinToJsTable($site, $allJsVinArr);

					$cacheArr = file_exists($cacheFile)? include($cacheFile): [];
					$cacheArr[$unikey] = time();
					LibFc::ArraySave($cacheArr, $cacheFile);
				}
			}
			else
			{
				//二、year>2006  &&  length<=5500  &&  gxb_count >= 2
				$reg['vzr_wmi'] = explode(',', $reg['vzr_wmi']);
				$byear = 2006;
				if($site == 'ford') $byear = 2017;
				foreach($yearArr as $y=>$vn)
				{
					if($y < $byear || ($reg['vzr_eyear'] > 0 && $y > $reg['vzr_eyear']) || $y > (date('Y')+1))
						continue;

					//根据不同的wmi指定特殊条件
					$othwhere = '';
					if($site == 'changcheng') $othwhere = " and ( vin_year < 2017 OR (vin_year >= 2017 AND sma_brand not like '魏派%') )";
					shuffle($reg['vzr_wmi']);
					foreach($reg['vzr_wmi'] as $wmi)
					{
						$lockfile = mvc::$URL_METHOD.'_'.$site.'_'.$wmi.$vn;
						if(!LibFc::hasFunLock($lockfile, 1200)) continue;
						$cacheFile = mvc::$cfg['LOGS'].'cache_zdvin_'.$site.'.php';
						$unikey = $wmi.$vn;
						$cacheArr = file_exists($cacheFile)? include($cacheFile): [];
						if(!empty($cacheArr[$unikey]) && $cacheArr[$unikey] > $cacheBTime) continue;

						//$where = $othwhere.sprintf(" and sma_vin1_3 = '%s' and sma_vin10 ='%s' and sma_gxb_code != '' and ((sma_length > 0 AND sma_length <= 5500) OR (sgi_length_min > 0 AND sgi_length_min < 5500)) GROUP BY sma_vin1_8, vin10_12 HAVING COUNT(DISTINCT sma_gxb_code) > 1", $wmi, $vn);
						$where = $othwhere.sprintf(" and sma_vin1_3 = '%s' and sma_vin10 ='%s' and sma_gxb_code != ''  GROUP BY sma_vin1_8, vin10_12 HAVING COUNT(DISTINCT sma_gxb_code) > 1", $wmi, $vn);
						//vin18+vin10_12
						$table = 'stand_model_any JOIN yp_vin_year on vin_10 = sma_vin10 LEFT JOIN stand_gxb_info ON sgi_gxb_code = sma_gxb_code AND sgi_vin1_8 = sma_vin1_8';
						$jsRes = $this->get($table, ['sma_vin1_8, sma_vin10_12 as vin10_12, MIN(sma_vin13_17) as vin13_17_min, MAX(sma_vin13_17) as vin13_17_max'], $where);
						foreach($jsRes['data'] as $rv)
						{
							$allJsVinArr = [];
							$unikey = $rv['sma_vin1_8'].'_'.$rv['vin10_12'];
							$cacheArr = file_exists($cacheFile)? include($cacheFile): [];
							if(!empty($cacheArr[$unikey]) && $cacheArr[$unikey] > $cacheBTime) continue;

							$vinYear = LibFc::VinYear(substr($rv['vin10_12'], 0, 1));
							$comWhere = sprintf(" and sma_gxb_code !='' and sma_vin1_8='%s' and sma_vin10_12='%s'", $rv['sma_vin1_8'], $rv['vin10_12']);
							$res = $this->get('stand_model_any', ['sma_vin, sma_vin13_17, sma_gxb_code'], $comWhere.sprintf(" and sma_vin13_17 >= '%s' order by sma_vin13_17 asc limit 1", $rv['vin13_17_min']), true);
							$startArr = $res['data'];
							while(!empty($startArr['sma_vin13_17']) && $startArr['sma_vin13_17'] < $rv['vin13_17_max'])
							{
								//和start的型号不同最小vin
								$res =  $this->get('stand_model_any', ['sma_vin, sma_vin13_17, sma_gxb_code'], $comWhere.sprintf(" and sma_gxb_code != '%s' and sma_vin13_17 > '%s' order by sma_vin13_17 asc limit 1", $startArr['sma_gxb_code'], $startArr['sma_vin13_17']), true);
								$nextArr = $res['data'];

								//和nextArr的型号不同最大vin
								$res =  $this->get('stand_model_any', ['sma_vin, sma_vin13_17, sma_gxb_code'], $comWhere.sprintf(" and sma_gxb_code != '%s' and sma_vin13_17 < '%s' order by sma_vin13_17 desc limit 1", $nextArr['sma_gxb_code'], $nextArr['sma_vin13_17']), true);
								$startArr = $res['data'];

								if($nextArr['sma_vin13_17'] != $startArr['sma_vin13_17'])
								{
									//查询总表查询这个区间的24小时前的车架号
									$vres =  $this->get('yp_vin_search', ['vs_vin as vin'], sprintf(" and vs_last_time < %d and vs_vin like '%s_%s%%' and vs_vin9 = vs_checkcode and right(vs_vin, 5) > '%s' and right(vs_vin, 5) < '%s' order by right(vs_vin, 5)", time()-3600*24, $rv['sma_vin1_8'], $rv['vin10_12'], $startArr['sma_vin13_17'], $nextArr['sma_vin13_17']));
									if(!empty($vres['data']))
									{
										$vinCount = count($vres['data']);
										$rate = 50;
										//根据数量决定采集的比例
										if($vinCount < 10) $rate = 3;
										else if($vinCount < 50) $rate = 5;
										else if($vinCount < 150) $rate = 10;
										else if($vinCount < 500) $rate = 20;
										//echo $rv['sma_vin1_8'],'_',$rv['vin10_12'],'%=>', $startArr['sma_vin13_17'],'=>',$nextArr['sma_vin13_17'],'=>',$rate,'<br>';
										foreach($vres['data'] as $xkk=>$xvv)
										{
											if( $xkk % $rate > 0) continue;
											$allJsVinArr[] = [
												'scl_vin'=>$xvv['vin'],	
												'scl_year'=>$vinYear,	
												'scl_reg_code'=>'ZDAPI',
												'scl_unikey'=>$unikey,
												'scl_scode'=>$site
											];
										}
									}
								}
								//交换开始结束
								$startArr = $nextArr;
								$nextArr = [];
							}
							$this->addVinToJsTable($site, $allJsVinArr);

							$cacheArr = file_exists($cacheFile)? include($cacheFile): [];
							$cacheArr[$unikey] = time();
							LibFc::ArraySave($cacheArr, $cacheFile);
						}
						
						$unikey = $wmi.$vn;
						$cacheArr = file_exists($cacheFile)? include($cacheFile): [];
						$cacheArr[$unikey] = time();
						LibFc::ArraySave($cacheArr, $cacheFile);

						LibFc::delFunLock($lockfile);
					}
				}
			}
			$this->set('stand_vin_zdapireg', ['vzr_lasttime'=>time()], sprintf(" and vzr_code='%s'", $site));
		}
		return LibFc::ReturnData(true);
	}


	//通过600w表采集泽达的车架号 ?site=lsg&type=has   ?site=lsg&type=jisuan
	public function catchZdvinByReg($site = '', $type = 'has')
	{
		if(empty($type)) $type = 'has';
		$cacheBTime = time()-3600*24*7;
		$res = $this->get('yp_vin_year', ['*'], ' order by rand()');
		$yearArr = array_column($res['data'], 'vin_10', 'vin_year');
		$where = " and vzr_status = 1";
		if(!empty($site)) $where .= sprintf(" and vzr_code in ('%s') order by vzr_id", implode("','", explode(',', $site)));
		$res = $this->get('stand_vin_zdapireg', ['*'], $where);
		$regArr = array_column($res['data'], null, 'vzr_code');
		foreach($regArr as $site=>$reg)
		{
			@mkdir(mvc::$cfg['LOGS'].'zdvin');
			$cacheFile = mvc::$cfg['LOGS'].'zdvin/'.$type.'_'.$site.'.php';

			if($site == 'yiwen') continue;
			if($site == 'date') continue;
			if(stripos($site, 'atmt') !== false) continue;
			
			//二、year>2006  &&  length<=5500  &&  gxb_count >= 2
			$reg['vzr_wmi'] = explode(',', $reg['vzr_wmi']);
			$byear = 2006;
			if($site == 'ford') $byear = 2017;
			foreach($yearArr as $y=>$vn)
			{
				if($y < $byear || ($reg['vzr_eyear'] > 0 && $y > $reg['vzr_eyear']) || $y > (date('Y')+1))
					continue;

				//根据不同的wmi指定特殊条件
				$othwhere = '';
				$where = $othwhere.sprintf(" and sma_vin1_3 in ('%s') and sma_vin10 ='%s' and sma_gxb_code != '' GROUP BY sma_vin1_8, vin10_12 HAVING COUNT(DISTINCT sma_gxb_code) > 1 ORDER BY RAND()", implode("','", $reg['vzr_wmi']), $vn);
				//vin18+vin10_12
				$table = 'stand_model_any LEFT JOIN stand_gxb_info ON sgi_gxb_code = sma_gxb_code AND sgi_vin1_8 = sma_vin1_8';
				$jsRes = $this->get($table, ['sma_vin1_8, sma_vin10_12 as vin10_12, MIN(sma_vin13_17) as vin13_17_min, MAX(sma_vin13_17) as vin13_17_max'], $where);
				foreach($jsRes['data'] as $rv)
				{
					$allJsVinArr = [];
					$unikey = $rv['sma_vin1_8'].'_'.$rv['vin10_12'];
					$cacheArr = file_exists($cacheFile)? include($cacheFile): [];
					if(!empty($cacheArr[$unikey]) && $cacheArr[$unikey] > $cacheBTime) continue;

					$vinYear = LibFc::VinYear(substr($rv['vin10_12'], 0, 1));
					$comWhere = sprintf(" and sma_gxb_code !='' and sma_vin1_8='%s' and sma_vin10_12='%s'", $rv['sma_vin1_8'], $rv['vin10_12']);
					$res = $this->get('stand_model_any', ['sma_vin, sma_vin13_17, sma_gxb_code'], $comWhere.sprintf(" and sma_vin13_17 >= '%s' order by sma_vin13_17 asc limit 1", $rv['vin13_17_min']), true);
					$startArr = $res['data'];
					while(!empty($startArr['sma_vin13_17']) && $startArr['sma_vin13_17'] < $rv['vin13_17_max'])
					{
						//和start的型号不同最小vin
						$res =  $this->get('stand_model_any', ['sma_vin, sma_vin13_17, sma_gxb_code'], $comWhere.sprintf(" and sma_gxb_code != '%s' and sma_vin13_17 > '%s' order by sma_vin13_17 asc limit 1", $startArr['sma_gxb_code'], $startArr['sma_vin13_17']), true);
						$nextArr = $res['data'];

						//和nextArr的型号不同最大vin
						$res =  $this->get('stand_model_any', ['sma_vin, sma_vin13_17, sma_gxb_code'], $comWhere.sprintf(" and sma_gxb_code != '%s' and sma_vin13_17 < '%s' order by sma_vin13_17 desc limit 1", $nextArr['sma_gxb_code'], $nextArr['sma_vin13_17']), true);
						$startArr = $res['data'];
						
						$abs = abs($nextArr['sma_vin13_17'] - $startArr['sma_vin13_17']);
						if($abs > 1)
						{
							$addVinArr = [];
							if($type == 'has')
							{
								//查询总表查询这个区间
								$vres =  $this->get('yp_vin_search', ['vs_vin as vin'], sprintf(" and vs_vin like '%s_%s%%' and vs_vin9 = vs_checkcode and right(vs_vin, 5) > '%s' and right(vs_vin, 5) < '%s' order by right(vs_vin, 5)", $rv['sma_vin1_8'], $rv['vin10_12'], $startArr['sma_vin13_17'], $nextArr['sma_vin13_17']));
								if(!empty($vres['data']))
									$addVinArr = array_column($vres['data'], null, 'vin');
							}
							else if(preg_match('/\d{5}/', $startArr['sma_vin13_17'], $match) && preg_match('/\d{5}/', $nextArr['sma_vin13_17'], $match) && $abs > 100)
							{//区间过大，直接算
								if($abs < 200) $jscount = 5;
								else if($abs < 500) $jscount = 10;
								else $jscount = 20;
								$jg = floor($abs/$jscount);
								$b = $startArr['sma_vin13_17'];
								$addVinArr = [];
								for($i = 1; $i < $jscount; $i++)
								{
									$tvin13_17 = str_pad($b+$i*$jg, 5, '0', STR_PAD_LEFT);
									$tempVin = $rv['sma_vin1_8'].'X'.$rv['vin10_12'].$tvin13_17;
									$vin9 =	LibFc::VinCheckCode($tempVin);
									$addVinArr[$rv['sma_vin1_8'].$vin9['real'].$rv['vin10_12'].$tvin13_17] = 1;
								}
							}
							if(!empty($addVinArr))
							{
								$res = $this->get('stand_catch_list', ['sce_vin'], sprintf(" and sce_vin in ('%s') and sce_reg_code='ZDAPI'", implode("','", array_keys($addVinArr))));
								foreach($res['data'] as $tvv)
								{
									unset($addVinArr[$tvv['sce_vin']]);
								}
								if(!empty($addVinArr))
								{
									$res = $this->get('stand_model_any', ['sma_vin'], sprintf(" and sma_vin in ('%s') and sma_from='ZDAPI'", implode("','", array_keys($addVinArr))));
									foreach($res['data'] as $tvv)
									{
										unset($addVinArr[$tvv['sma_vin']]);
									}
								}
								if(!empty($addVinArr))
								{
									$vins = array_keys($addVinArr);
									$this->catchZdvinJg($vins, $startArr, $nextArr);
								}
							}
						}
						//交换开始结束
						$startArr = $nextArr;
						$nextArr = [];
					}
					$cacheArr = file_exists($cacheFile)? include($cacheFile): [];
					$cacheArr[$unikey] = time();
					LibFc::ArraySave($cacheArr, $cacheFile);
				}
			}
		
			$this->set('stand_vin_zdapireg', ['vzr_lasttime'=>time()], sprintf(" and vzr_code='%s'", $site));
			LibFc::delFunLock($lockfile);
		}
		return LibFc::ReturnData(true);
	}


	private function catchZdvinJg($vinArr, $startArr, $nextArr, $haskey = null)
	{
		if($haskey === null)
		{
			$count = count($vinArr);
			$zjkey = (int) floor(count($vinArr)/2);
			$haskey = [$zjkey];
			for($i = 1; $i <= $zjkey; $i++)
			{
				if(($zjkey-$i) >= 0) $haskey[] = $zjkey-$i;
				if(($zjkey+$i) < $count) $haskey[] = $zjkey+$i;
			}
		}
		$vkey = array_shift($haskey);
		if(empty($vinArr[$vkey])) return [];
		$vin = $vinArr[$vkey];
		$res = $this->get('stand_model_any', ['sma_vin'], sprintf(" and sma_vin = '%s' and sma_from='ZDAPI'", $vin));
		if(!empty($res['data']))
			return $this->catchZdvinJg($vinArr, $startArr, $nextArr, $haskey);

		$zdres = $this->catchAnyVinfromZdApi([$vin]);
		if(!empty($zdres['data'][$vin]))
		{
			$zdArr = $zdres['data'][$vin];
			if($zdArr['viz_gxb_code'] == $startArr['sma_gxb_code'])
			{//和开始相同，取后面
				$startArr = [
					'sma_vin'=>$zdArr['viz_vin'],
					'sma_vin13_17'=>$zdArr['viz_vin13_17'],
					'sma_gxb_code'=>$zdArr['viz_gxb_code']
				];
				$tArr = [];
				$haskey = null;
				for($i == ($vkey+1); $i < count($vinArr); $i++)
				{
					$tArr[] = $vinArr[$i]; 
				}
				$vinArr = $tArr;
			}
			else if($zdArr['viz_gxb_code'] == $nextArr['sma_gxb_code'])
			{//和后面相同，取前面
				$nextArr = [
					'sma_vin'=>$zdArr['viz_vin'],
					'sma_vin13_17'=>$zdArr['viz_vin13_17'],
					'sma_gxb_code'=>$zdArr['viz_gxb_code']
				];
				$tArr = [];
				$haskey = null;
				for($i = 0; $i < $vkey; $i++)
				{
					$tArr[] = $vinArr[$i]; 
				}
				$vinArr = $tArr;
			}
		}
		else
		{
			$addtask = [
				'sce_reg_code'=>'ZDAPI',
				'sce_vin'=>$vin,
				'sce_status'=>-2,
				'sce_etime'=>time(),
				'sce_catch_count'=>1
			];
			$this->add('stand_catch_list', $addtask);
		}
		if(($haskey !== null && empty($haskey)) || empty($vinArr)) return [];
		return $this->catchZdvinJg($vinArr, $startArr, $nextArr, $haskey);
	}


	//通过600w表计算采集泽达的车架号
	public function addCatchJuhevinByReg()
	{
		$regArr = [
			'faw-vw'=>[
				'wmi'=>['LFV'],
				'vin10'=>['6','7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G']
			]
		];

		foreach($regArr as $site=>$reg)
		{
			$where = sprintf(" and sma_vin1_3 IN ('%s') AND sma_vin10 IN ('%s') GROUP BY sma_vin1_8, sma_vin10_12 HAVING COUNT(DISTINCT sma_gxb_code) > 1 order by sma_vin10 desc",
				implode("','", $reg['wmi']), implode("','", $reg['vin10']));
			$jsRes = $this->get('stand_model_any', ['sma_vin1_8, sma_vin10_12 as vin10_12, MIN(sma_vin13_17) as vin13_17_min, MAX(sma_vin13_17) as vin13_17_max'], $where);
			$yearCount = [];
			foreach($jsRes['data'] as $rv)
			{
				$allJsVinArr = [];
				$unikey = $rv['sma_vin1_8'].'_'.$rv['vin10_12'];
				$vinYear = LibFc::VinYear(substr($rv['vin10_12'], 0, 1));
				if(empty($yearCount[$vinYear])) $yearCount[$vinYear] = 0;
				if($yearCount[$vinYear] > 1000) continue;
				$comWhere = sprintf(" and sma_gxb_code !='' and sma_vin1_8='%s' and sma_vin10_12='%s'", $rv['sma_vin1_8'], $rv['vin10_12']);
				$res = $this->get('stand_model_any', ['sma_vin, sma_vin13_17, sma_gxb_code'], $comWhere.sprintf(" and sma_vin13_17 >= '%s' order by sma_vin13_17 asc limit 1", $rv['vin13_17_min']), true);
				$startArr = $res['data'];
				while(!empty($startArr['sma_vin13_17']) && $startArr['sma_vin13_17'] < $rv['vin13_17_max'])
				{
					if($yearCount[$vinYear] > 1000) break;
					//和start的型号不同最小vin
					$res =  $this->get('stand_model_any', ['sma_vin, sma_vin13_17, sma_gxb_code'], $comWhere.sprintf(" and sma_gxb_code != '%s' and sma_vin13_17 > '%s' order by sma_vin13_17 asc limit 1", $startArr['sma_gxb_code'], $startArr['sma_vin13_17']), true);
					$nextArr = $res['data'];

					//和nextArr的型号不同最大vin
					$res =  $this->get('stand_model_any', ['sma_vin, sma_vin13_17, sma_gxb_code'], $comWhere.sprintf(" and sma_gxb_code != '%s' and sma_vin13_17 < '%s' order by sma_vin13_17 desc limit 1", $nextArr['sma_gxb_code'], $nextArr['sma_vin13_17']), true);
					$startArr = $res['data'];
				
					if(!empty($startArr['sma_vin']) && !empty($nextArr['sma_vin']) && $startArr['sma_vin'] != $nextArr['sma_vin'])
					{
						$allJsVinArr[$startArr['sma_vin']] = [
							'scl_vin'=>$startArr['sma_vin'],	
							'scl_year'=>$vinYear,	
							'scl_reg_code'=>'JUHE',
							'scl_unikey'=>$unikey,
							'scl_scode'=>$site
						];
						$yearCount[$vinYear]++;

						$allJsVinArr[$nextArr['sma_vin']] = [
							'scl_vin'=>$nextArr['sma_vin'],	
							'scl_year'=>$vinYear,	
							'scl_reg_code'=>'JUHE',
							'scl_unikey'=>$unikey,
							'scl_scode'=>$site
						];
						$yearCount[$vinYear]++;
					}
					//交换开始结束
					$startArr = $nextArr;
					$nextArr = [];
				}
				if(!empty($allJsVinArr))
				{
					$allJsVinArr = array_values($allJsVinArr);
					$this->addAny('stand_catch_jsvin', array_keys($allJsVinArr[0]), array_values($allJsVinArr));
				}
			}
		}
		return LibFc::ReturnData(true);
	}

	/**
	  * @method 将某站点你的车架号入库（自动过滤已存在数据）
	  * @param  $regcode  string [必填] stand_scqd_reg的reg_code
	  * @param  $smaChk bool [必填] 是否检测在600万表里
	  * @param  $addVinArr array  [必填] 需要加入stand_catch_jsvin的数据 [
			['scl_vin'=>'', 'scl_year'=>....]
		]
	  * @author soul
	  * @copyright 2020/12/31
	  * @return array(3) { ["status"]=> bool(true) ["data"]=> 添加的行数 ["code"]=> int(0) } 
	  */
	public function addVinToJsTable($regcode, $allVinArr, $smaChk = true)
	{
		if(empty($allVinArr)) return LibFc::ReturnData(true);
		$addVinArr = [];
		$addCount = 0;
		$this->YpwDb->Begin();
		foreach($allVinArr as $yk=>$yv)
		{
			$addVinArr[$yv['scl_vin']] = $yv;
			if(count($addVinArr) == 200 || ($yk+1) == count($allVinArr))
			{
				$res = $this->get('stand_catch_jsvin', ['scl_vin'], sprintf(" and scl_vin in ('%s') and scl_reg_code='%s'", implode("','", array_keys($addVinArr)), $regcode));
				foreach($res['data'] as $tvv)
				{
					unset($addVinArr[$tvv['scl_vin']]);
				}

				if(!empty($addVinArr))
				{
					$res = $this->get('stand_catch_list', ['sce_vin'], sprintf(" and sce_vin in ('%s') and sce_reg_code='%s'", implode("','", array_keys($addVinArr)), $regcode));
					foreach($res['data'] as $tvv)
					{
						unset($addVinArr[$tvv['sce_vin']]);
					}
				}

				if(!empty($addVinArr) && $smaChk)
				{
					$res = $this->get('stand_model_any', ['sma_vin'], sprintf(" and sma_vin in ('%s') and sma_from != 'buy02'", implode("','", array_keys($addVinArr))));
					foreach($res['data'] as $tvv)
					{
						unset($addVinArr[$tvv['sma_vin']]);
					}
				}
				if(!empty($addVinArr))
				{
					$addVinArr = array_values($addVinArr);
					$addCount += count($addVinArr);
					$this->addAny('stand_catch_jsvin', array_keys($addVinArr[0]), $addVinArr);
				}
				$addVinArr = [];
			}
		}
		$this->YpwDb->End();
		return LibFc::ReturnData(true, $addCount);
	}


	//批量添加到任务，包含过滤功能
	public function addCatchList($site, $dataArr)
	{
		$addArr = [];
		$dataArr = array_column($dataArr, null, 'sce_vin');
		$count = count($dataArr);
		$YpwBase = new YpwBase();
		$addCount = 0;
		$YPCAR67 = new BaseDb(mvc::$cfg['DB']['YPCAR67']);
		$this->YpwDb->Begin();
		foreach($dataArr as $vin=>$v)
		{
			$count--;
			$v['sce_reg_code'] = $site;
			$addArr[$vin] = $v;
			if(count($addArr) == 200 || $count == 0)
			{
				$res = $YpwBase->get('stand_catch_list', ['sce_vin'], sprintf(" and sce_reg_code = '%s' and sce_vin in ('%s')", $site, implode("','", array_keys($addArr))));
				foreach($res['data'] as $hv){
					unset($addArr[$hv['sce_vin']]);
				}

				if(!empty($addArr)){
					$res = $this->get('stand_model_any', ['sma_vin'], sprintf(" and sma_vin in ('%s') and sma_from != 'buy02'", implode("','", array_keys($addArr))));
					foreach($res['data'] as $hv){
						unset($addArr[$hv['sma_vin']]);
					}
				}
				if(!empty($addArr) && $site == 'changan'){
					$res = $YPCAR67->get('temp_changan', ['cha_vin'], sprintf(" and cha_vin in ('%s') and lnk_extend_code != ''", implode("','", array_keys($addArr))));
					foreach($res['data'] as $hv){
						unset($addArr[$hv['cha_vin']]);
					}
				}

				if(!empty($addArr)){
					$addCount += count($addArr);
					$addArr = array_values($addArr);
					$YpwBase->addAny('stand_catch_list', array_keys($addArr[0]), $addArr);
				}
				$addArr = [];
			}
		}
		$this->YpwDb->End();
		return LibFc::ReturnData(true, $addCount);
	}


	//格式Partslink24的html并入库
	public function saveVinPartslink24($postArr)
	{
		$vin = LibFc::FormatVin($postArr['vin']);
		if(strlen($vin) != 17 || empty($postArr['html']))
			return LibFc::ReturnData(false, '获取VIN信息失败！');
		$html = $postArr['html'];
		$account = LibFc::Escape($postArr['account']);
		$YPCAR67 = new BaseDb(mvc::$cfg['DB']['YPCAR67']);
		
		$taskSet = ['vt_vin'=>$vin, 'vt_account'=>$account, 'vt_atime'=>time(), 'vt_html'=>$html];
		$taskSet['vt_post'] = $postArr;
		unset($taskSet['vt_post']['html']);
		$taskSet['vt_post'] = json_encode($taskSet['vt_post']);
		$YPCAR67->add('catch_vin_temp', $taskSet);
		$YPCAR67->set('catch_vin_task', ['cvt_status'=>3, 'cvt_etime'=>time()], sprintf(" and cvt_vin='%s' and cvt_status != 1", $vin));

		$LibHttp = new LibHttp();
		$url = 'http://crm.yiparts.com:3009/Admin/tools/partslink24Online.php?action=add';
		$saveres = $LibHttp->fetch($url, $postArr);
		$vmCodeArr = ['fawvw', 'audi'];
		if(stripos($html, $vin) && !empty($account) && in_array($postArr['cve_code'], $vmCodeArr))
		{
			//控制账号状态
			$ares = $YPCAR67->get('catch_vin_account', ['cac_status'], sprintf(" and cac_user='%s' limit 1", $account), true);
			if(!empty($ares['data']))
			{
				if(stripos($html, '发动机规格参数') && $ares['data']['cac_status'] != 2)
				{
					$YPCAR67->set('catch_vin_account', ['cac_status'=>2], sprintf(" and cac_user='%s'", $account));
				}
				else if(stripos($html, '发动机规格参数') === false && $ares['data']['cac_status'] == 2)
				{
					$YPCAR67->set('catch_vin_account', ['cac_status'=>3], sprintf(" and cac_user='%s'", $account));
				}
			}
		}
		return LibFc::ReturnData(true, $saveres);
	}


	//计算搜配的采集任务
	public function jsCatchSoupeiVin()
	{
		$regArr = [
			'changcheng'=>[
				'wmi'=>['LGW'],
				'vin10'=>['9', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K']
			],
			'saic-gm'=>[
				'wmi'=>['LSG'],
				'vin10'=>['6', '7', '8','9', 'A', 'B', 'C', 'D', 'E', 'F', 'G']
			]
		];

		foreach($regArr as $site=>$reg)
		{
			$where = sprintf(" and sma_vin1_3 IN ('%s') AND sma_vin10 IN ('%s') GROUP BY sma_vin1_8, sma_vin10_12 HAVING COUNT(DISTINCT sma_gxb_code) > 1 order by sma_vin10 desc",
				implode("','", $reg['wmi']), implode("','", $reg['vin10']));
			$jsRes = $this->get('stand_model_any', ['sma_vin1_8, sma_vin10_12'], $where);
			foreach($jsRes['data'] as $rv)
			{
				$unikey = $rv['sma_vin1_8'].$rv['sma_vin10_12'];
				$vinYear = LibFc::VinYear(substr($rv['sma_vin10_12'], 0, 1));
				$comWhere = sprintf(" and sma_vin1_8='%s' and sma_vin10_12='%s'", $rv['sma_vin1_8'], $rv['sma_vin10_12']);

				//取最小序列号的型号A
				$res = $this->get('stand_model_any', ['sma_vin13_17, sma_gxb_code'], $comWhere.' order by sma_vin13_17 limit 1', true);
				$beginCfg = $res['data'];
				
				while(!empty($beginCfg))
				{
					//下一个型号B不同的最小值V13-B
					$twhere = $comWhere.sprintf(" and sma_vin13_17 > '%s' and sma_gxb_code != '%s' order by sma_vin13_17 limit 1", $beginCfg['sma_vin13_17'], $beginCfg['sma_gxb_code']);
					$res = $this->get('stand_model_any', ['sma_vin13_17, sma_gxb_code'], $twhere, true);
					if(empty($res['data'])) break;
					$endCfg = $res['data'];
					
					//与型号B不同的最大值V13-A
					$twhere = $comWhere.sprintf(" and sma_vin13_17 < '%s' and sma_gxb_code != '%s' order by sma_vin13_17 desc limit 1", $endCfg['sma_vin13_17'], $endCfg['sma_gxb_code']);
					$res = $this->get('stand_model_any', ['sma_vin13_17, sma_gxb_code'], $twhere, true);
					if(empty($res['data'])) break;
					$beginCfg = $res['data'];
				
					//找 V13-A ~ V13-B 之前的车架号
					$addSql = sprintf("INSERT INTO stand_catch_list (sce_reg_code, sce_vin, sce_level) SELECT 'wdsp', vs_vin, vin_year FROM yp_vin_search
						left join yp_vin_year on vs_vin10 = vin_10
						WHERE vs_vin9 = vs_checkcode and vs_vin LIKE '%s_%s%%' AND RIGHT(vs_vin, 5) > %d AND RIGHT(vs_vin, 5) < %d and vs_ip != '127.0.0.1'
						AND vs_vin NOT IN (SELECT sma_vin FROM stand_model_any WHERE sma_vin1_8 = '%s' AND sma_vin10_12 ='%s' AND sma_vin13_17 > %d AND sma_vin13_17 < %d)
						AND vs_vin NOT IN (SELECT sce_vin FROM stand_catch_list WHERE sce_reg_code ='wdsp' AND sce_vin LIKE '%s_%s%%')
						", $rv['sma_vin1_8'], $rv['sma_vin10_12'], $beginCfg['sma_vin13_17'], $endCfg['sma_vin13_17'], $rv['sma_vin1_8'], $rv['sma_vin10_12'], $beginCfg['sma_vin13_17'], $endCfg['sma_vin13_17'],
						 $rv['sma_vin1_8'], $rv['sma_vin10_12']);
					$this->exeAnySql([$addSql]);

					//计算下一组，交换
					$beginCfg = $endCfg;
					$endCfg = [];
				}
			}
		}
		return LibFc::ReturnData(true);
	}


	/**
	  * @method 更新VIN规则的统计
	  * @author soul
	  * @copyright 2021/2/20
	  * @return 
			成功：['status'=>true, 'data'=>true|false]
			失败：['status'=>false, 'data'=>'错误原因']
	  */
	public function updateVinRegTj()
	{
		$res = $this->get('stand_model_any', ['sma_vin1_3 as wmi'], " group by sma_vin1_3");
		$wmiArr = array_column($res['data'], 'wmi');

		$res = $this->get('stand_model_reg', ['left(smr_vin1_8, 3) as wmi'], ' group by wmi');
		$wmiArr = array_merge($wmiArr, array_column($res['data'], 'wmi'));
		$wmiArr = array_unique($wmiArr);

		foreach($wmiArr as $wmi)
		{
			$this->YpwDb->Begin();

			//删除没有的
			$res = $this->get('stand_model_reg LEFT JOIN stand_model_any ON sma_vin1_8=smr_vin1_8 AND sma_vin10_12=smr_vin10_12 AND sma_gxb_code=smr_gxb_code', ['smr_id'], sprintf(" and smr_vin1_8 LIKE '%s%%' AND sma_gxb_code IS NULL", $wmi));
			if(!empty($res['data']))
			{
				$this->del('stand_model_reg', sprintf(" and smr_id in (%s)", implode(',', array_column($res['data'], 'smr_id'))));
			}

			$sqlArr = [
				//更新已有的
				sprintf("UPDATE stand_model_reg JOIN  (SELECT sma_gxb_code, sma_vin1_8, sma_vin10_12,COUNT(*) AS vin_count, 
			 MIN(CASE WHEN sma_year != '' THEN sma_year END) AS vin_time_min, MAX(sma_year) AS vin_time_max, MIN(sma_vin13_17) AS vin13_17_min, MAX(sma_vin13_17) AS vin13_17_max
			 FROM stand_model_any WHERE sma_vin1_3 = '%s' GROUP BY sma_vin1_8, sma_vin10_12, sma_gxb_code
			 ) AS sma ON sma_vin1_8=smr_vin1_8 AND sma_vin10_12=smr_vin10_12 AND sma_gxb_code=smr_gxb_code
			 SET  smr_vin_count = sma.vin_count,
			 smr_vin_time_min = sma.vin_time_min, 
			 smr_vin_time_max = sma.vin_time_max, 
			 smr_vin13_17_min = sma.vin13_17_min, 
			 smr_vin13_17_max= sma.vin13_17_max, 
			 smr_last_update=UNIX_TIMESTAMP() WHERE smr_vin1_8 LIKE '%s%%'", $wmi, $wmi),
				 //追加新的

			 sprintf("INSERT INTO stand_model_reg (smr_gxb_code, smr_vin1_8, smr_vin10_12, smr_vin_count, smr_vin_time_min, smr_vin_time_max, smr_vin13_17_min, smr_vin13_17_max, smr_add_user, smr_add_time, smr_last_update)
			 SELECT sma_gxb_code, sma_vin1_8, sma_vin10_12,COUNT(*) AS smr_vin_count, 
				MIN(CASE WHEN sma_year != '' THEN sma_year END) AS smr_vin_time_min, 
				MAX(sma_year) AS smr_vin_time_max,
				MIN(sma_vin13_17) AS smr_vin13_17_min,
				MAX(sma_vin13_17) AS smr_vin13_17_max,
				'系统' AS smr_add_user,
				UNIX_TIMESTAMP() AS smr_add_time,
				UNIX_TIMESTAMP() AS smr_last_update
				FROM stand_model_any LEFT JOIN stand_model_reg ON sma_vin1_8=smr_vin1_8 AND sma_vin10_12=smr_vin10_12 AND sma_gxb_code=smr_gxb_code 
				WHERE sma_vin1_3 = '%s' and sma_gxb_code != '' AND smr_gxb_code IS NULL GROUP BY sma_vin1_8, sma_vin10_12, sma_gxb_code		 
			 ", $wmi),
			];

			//更新
			$this->exeAnySql($sqlArr);

			$this->YpwDb->End();
		}
		
		$setArr = [
			'smr_status'=>1,
			'smr_check_user'=>'系统',
			'smr_check_time'=>time()
		];
		$this->set('stand_model_reg', $setArr, ' and smr_vin_count >= 20 and smr_status = 0');
		return LibFc::ReturnData(true);
	}
	


	/**
	  * @method 初始化600w表的统计
	  * @author soul
	  * @copyright 2021/5/28
	  * @return 
	  */
	public function resetStandVinTj()
	{
		$res = $this->get('stand_model_any', ['sma_gxb_code', 'sma_vin1_3'], " and sma_gxb_code != '' GROUP BY sma_gxb_code");
		$allGxbArr = array_column($res['data'], null, 'sma_gxb_code');	
		$this->YpwDb->Begin();

		$sqlArr = [
			"delete from stand_model_tj",
			"delete from stand_gxb_engine"
		];
		$this->exeAnySql($sqlArr);
		foreach($allGxbArr as $fgxb=>$fv)
		{
			$groupby = in_array(substr($fv['sma_vin1_3'], 0 , 1), ['L', 'H'])? ' GROUP BY sma_gxb_code, sma_vin1_8': ' GROUP BY sma_gxb_code, sma_vin1_8, sma_brand';
			$sqlArr = [
				//型号+v1_8
				sprintf("INSERT INTO stand_model_tj (smt_vin1_8, smt_gxb_code, smt_gxb_code_show, smt_vin10, smt_vin, smt_byear, smt_eyear, smt_vin_count, smt_brand, smt_engine, smt_cc, smt_kw, smt_passenger, smt_vtype, smt_tran, smt_gtype, smt_xuhang) 
				SELECT sma_vin1_8,  sma_gxb_code, sma_gxb_code_show, GROUP_CONCAT(DISTINCT sma_vin10), sma_vin, MIN(sma_vyear), MAX(sma_vyear), COUNT(*), sma_brand,
				GROUP_CONCAT(DISTINCT( CASE WHEN sma_engine != '' THEN sma_engine END)),
				GROUP_CONCAT(DISTINCT( CASE WHEN sma_cc != '' THEN sma_cc END)),
				GROUP_CONCAT(DISTINCT( CASE WHEN sma_kw != '' THEN sma_kw END)),
				GROUP_CONCAT(DISTINCT( CASE WHEN sma_passenger > 0 THEN sma_passenger END)),
				MAX(sma_vtype),
				GROUP_CONCAT(DISTINCT(CASE WHEN sma_tran != '' THEN sma_tran END)),
				MAX(sma_gtype),
				MAX(sma_xuhang)
				FROM stand_model_any
				WHERE sma_gxb_code = '%s' %s", $fgxb, $groupby),
				//型号+发动机
				sprintf("INSERT INTO stand_gxb_engine 
				SELECT sma_gxb_code, sma_engine, COUNT(*), sma_vin FROM stand_model_any WHERE sma_gxb_code = '%s' AND sma_engine != '' GROUP BY sma_gxb_code, sma_engine", $fgxb),
			];
			$this->exeAnySql($sqlArr);
		}
		$this->YpwDb->End();
		return LibFc::ReturnData(true);
	}


	/**
	  * @method 初始化本地需要的临时统计
	  * @author soul
	  * @copyright 2021/5/28
	  * @return 
	  */
	public function resetLocVinTj()
	{
		$res = $this->get('stand_model_tj', ['smt_vin1_8', 'SUM(smt_vin_count) count'], " GROUP BY smt_vin1_8");
		$vin8CountArr = array_column($res['data'], 'count', 'smt_vin1_8');

		$res = $this->get('stand_model_any', ['sma_vin1_8'], " GROUP BY sma_vin1_8");
		$vin8Arr = array_column($res['data'], 'sma_vin1_8');

		$this->YpwDb->Begin();
		$sqlArr = [
			"delete from tj_vii_vin11",
			"INSERT INTO tj_vii_vin11
			SELECT vii_vin1_8 AS vin1_8, LEFT(vii_vin10_12, 2) AS vin10_11, COUNT(DISTINCT vii_vin) AS img_count, SUM(CASE WHEN vii_status = 0 THEN 1 ELSE 0 END) img_nocount
			FROM stand_vin_imgs GROUP BY vii_vin1_8, vin10_11",
			"delete from tj_sma_vin11",
			"delete from tj_sma_vin12",
		];
		$this->exeAnySql($sqlArr);

		$tvinArr = [];
		$lastCount = 0;
		foreach($vin8Arr as $vk=>$vin8)
		{
			$lastCount += (int) $vin8CountArr[$vin8];
			$tvinArr[] = $vin8;
			if($lastCount > 100000 || count($tvinArr) == 20 || $vk+1 == count($vin8Arr))
			{
				$sqlArr = [];
				$sqlArr[] = sprintf("INSERT INTO tj_sma_vin11
				SELECT 
				sma_vin1_8,
				sma_vin10_11, 
				COUNT(DISTINCT sma_vin) AS sma_count, 
				COUNT(DISTINCT sma_gxb_code) AS gxb_count,
				GROUP_CONCAT(DISTINCT sma_gxb_code) AS gxbcodes,
				MIN(DISTINCT CASE WHEN sgi_length_min IS NULL OR sgi_length_min = 0 THEN 99999 ELSE sgi_length_min END ) AS length_min,
				MIN(DISTINCT CASE WHEN sma_length IS NULL OR sma_length = 0 THEN 99999 ELSE sma_length END ) AS length_min2
				FROM stand_model_any LEFT JOIN stand_gxb_info ON sgi_gxb_code = sma_gxb_code AND sgi_vin1_8 = sma_vin1_8
				WHERE sma_vin1_8 in ('%s') and sma_gxb_code !=''  GROUP BY sma_vin1_8, sma_vin10_11", implode("','", $tvinArr));

				$sqlArr[] = sprintf("INSERT INTO tj_sma_vin12
				SELECT 
				sma_vin1_8,
				sma_vin10_12, 
				sma_gxb_code,
				sma_gxb_code_show,
				COUNT(DISTINCT sma_vin) AS sma_count
				FROM stand_model_any WHERE sma_vin1_8 in ('%s') and sma_gxb_code !=''  GROUP BY sma_vin1_8, sma_vin10_12, sma_gxb_code", implode("','", $tvinArr));
				$this->exeAnySql($sqlArr);
				$tvinArr = [];
				$lastCount = 0;
			}
		}
		$this->YpwDb->End();
		return LibFc::ReturnData(true);
	}


	/**
	  * @method 获取600w车架号的型号
	  * @param  vinArr array  ['..',...]
	  * @author soul
	  * @copyright 2022/3/5
	  */
	public function getSmaGxb($vinArr, $fileds = ['sma_id', 'sma_vin'], $othwere = '')
	{
		$arr = [];
		$tvin = [];
		foreach($vinArr as $k=>$v)
		{
			$tvin[] = $v;
			if($k%500 === 499 || $k+1 == count($vinArr))
			{
				$res = $this->get('stand_model_any', $fileds, sprintf(" and sma_vin in ('%s')", implode("','", $tvin)).$othwere);
				foreach($res['data'] as $tv)
				{
					$arr[] = $tv;
				}
				$tvin = [];
			}
		}
		return LibFc::ReturnData(true, $arr);
	}

	/**
	  * @method 从燃油网各个渠道整合型号的基本信息  名称 续航 驱动 变速箱...
	  * @author soul
	  * @copyright 2022/3/23
	  */
	public function resetGxbBase()
	{
		$YPCAR67 = new BaseDb(mvc::$cfg['DB']['YPCAR67']);
		$arr = [];
		$fitfileds = ['gxb_rname','gxb_rtran','gxb_rxuhang','gxb_rdrive'];
		//中国新能源汽车目录(Gev)
		$res = $YPCAR67->get('model_chinacar.all_model_gev', ['upper(gal_format) gxb_code', 'gal_value gxb_code_show','gal_name gxb_rname', "group_concat(distinct gal_distance) gxb_rxuhang"], " and gal_format != '' group by gal_format");
		foreach($res['data'] as $v)
		{
			if(empty($arr[$v['gxb_code']])) 
			{
				$arr[$v['gxb_code']] = $v;
			}
			else
			{
				foreach($fitfileds as $ff)
				{
					if(empty($arr[$v['gxb_code']][$ff]) && !empty($v[$ff]))
						$arr[$v['gxb_code']][$ff] = $v[$ff];
				}
			}
		}
		//免征车辆购置税的新能源汽车车型目录
		$res = $YPCAR67->get('model_chinacar.all_new_energy', ['upper(nen_format) gxb_code', 'nen_model gxb_code_show','nen_name gxb_rname', "group_concat(distinct case when nen_endurance_1 != '' then nen_endurance_1 else nen_endurance_2 end) gxb_rxuhang"], " and nen_format != '' group by nen_format");
		foreach($res['data'] as $v)
		{
			if(empty($arr[$v['gxb_code']])) 
			{
				$arr[$v['gxb_code']] = $v;
			}
			else
			{
				foreach($fitfileds as $ff)
				{
					if(empty($arr[$v['gxb_code']][$ff]) && !empty($v[$ff]))
						$arr[$v['gxb_code']][$ff] = $v[$ff];
				}
			}
		}
		
		//中国汽车网
		$fileds = ['upper(clxh) gxb_code', 'clxh_display gxb_code_show', 'group_concat(distinct tymc) gxb_rname', 'group_concat(distinct bsqlx) gxb_rtran', 'group_concat(distinct qdxs) gxb_rdrive'];
		$res = $YPCAR67->get('model_chinacar.all_model', $fileds, " and clxh != '' group by clxh");
		foreach($res['data'] as $v)
		{
			if(empty($arr[$v['gxb_code']])) 
			{
				$arr[$v['gxb_code']] = $v;
			}
			else
			{
				foreach($fitfileds as $ff)
				{
					if(empty($arr[$v['gxb_code']][$ff]) && !empty($v[$ff]))
						$arr[$v['gxb_code']][$ff] = $v[$ff];
				}
			}
		}

		//工信部
		$res = $this->get('gxb_base', ['upper(gb_gxb_code) gxb_code', 'gb_gxb_code_show gxb_code_show'], ' group by gb_gxb_code');
		foreach($res['data'] as $v){
			if(empty($arr[$v['gxb_code']])) {
				$arr[$v['gxb_code']] = $v;
			}
		}

		$res = $this->get('gxb_base JOIN gxb_params ON gb_id = gp_gb_id', ['gb_gxb_code gxb_code, GROUP_CONCAT(DISTINCT gp_value) vals'], " and gp_gl_code = 'lts' group by gb_gxb_code");
		foreach($res['data'] as $v){
			$arr[$v['gxb_code']]['gxb_tyre'] = $v['vals'];
		}

		$res = $this->get('gxb_base JOIN gxb_params ON gb_id = gp_gb_id', ['gb_gxb_code gxb_code, GROUP_CONCAT(DISTINCT gp_value) vals'], " and gp_gl_code = 'qpck' group by gb_gxb_code");
		foreach($res['data'] as $v){
			$arr[$v['gxb_code']]['gxb_frontman'] = $v['vals'];
		}

		/*$res = $YPCAR67->get('model_jdcsww.data_model', ['upper(jml_model_format) gxb_code', 'jml_model gxb_code_show'], " and jml_model_format != '' group by jml_model_format");
		foreach($res['data'] as $v)
		{
			if(empty($arr[$v['gxb_code']])) 
			{
				$arr[$v['gxb_code']] = $v;
			}
		}

		$renameArr = [
			'轮胎数'=>'gxb_tyre',
			'驾驶室准乘人数'=>'gxb_frontman',
		];
		//轮胎数、前排
		$res = $YPCAR67->get('model_jdcsww.data_model join model_jdcsww.data_info ON jml_id = ino_jml_id', ['jml_model_format gxb_code', 'ino_text', 'group_concat(distinct ino_value) as vals'], " and ino_value != '' and ino_text IN ('轮胎数','驾驶室准乘人数') group by jml_model_format, ino_text");
		foreach($res['data'] as $v)
		{
			$filed = strtr($v['ino_text'], $renameArr);
			$arr[$v['gxb_code']][$filed] = $v['vals'];
		}*/
		
		$YpcBase = new YpcBase();
		$res = $YpcBase->get('yp_image_gxb', ["gxb_code, CONCAT('https://3thpics.paojd.cn/etk/', gxb_path, '/', gxb_name) AS gxb_img"], " group by gxb_code");
		foreach($res['data'] as $v)
		{
			$arr[$v['gxb_code']]['gxb_img'] = $v['gxb_img'];
		}
		
		$arr = array_values($arr);
		$this->YpwDb->Begin();
		$this->exeAnySql(["delete from stand_gxb_base"]);
		$addArr = [];
		foreach($arr as $k=>$v)
		{
			if(empty($v['gxb_code']) || strlen($v['gxb_code']) > 64) continue;

			if(!empty($v['gxb_rxuhang'])){
				$xhres = $this->formatXuhang([str_replace(',','/', $v['gxb_rxuhang'])]);
				if(!empty($xhres['data']['xuhang'])) $v['gxb_rxuhang'] = $xhres['data']['xuhang'];
			}
			$v['gxb_rtran'] = stripos($v['gxb_rtran'], '0,') === 0? substr($v['gxb_rtran'], 2): $v['gxb_rtran'];
			$drives = [];
			foreach(explode(',', $v['gxb_rdrive']) as $vv)
			{
				if(!empty($vv))
				{ 
					if(stripos($vv, '四轮') !== false){
						$drives[] = '四驱';
					}else if(stripos($vv, '全轮') !== false){
						$drives[] = '全轮';
					}else if(stripos($vv, '后轮') !== false){
						$drives[] = '后驱';
					}else if(stripos($vv, '前轮') !== false){
						$drives[] = '前驱';
					}else{
						$drives[] = strtr($vv, ['x'=>'×', 'X'=>'×']);
					}
				}
			}
			$addArr[] = [
				'sgb_gxb_code'=>$v['gxb_code'],
				'sgb_code_show'=>!empty($v['gxb_code_show'])? $v['gxb_code_show']: $v['gxb_code'],
				'sgb_rname'=>!empty($v['gxb_rname'])? $v['gxb_rname']: '',
				'sgb_rtran'=>!empty($v['gxb_rtran'])? $v['gxb_rtran']: '',
				'sgb_rdrive'=>implode(',', array_unique($drives)),
				'sgb_rxuhang'=>!empty($v['gxb_rxuhang'])? $v['gxb_rxuhang']: '',
				'sgb_tyre'=>!empty($v['gxb_tyre'])? $v['gxb_tyre']: '',
				'sgb_frontman'=>!empty($v['gxb_frontman'])? $v['gxb_frontman']: '',
				'sgb_img'=>!empty($v['gxb_img'])? $v['gxb_img']: '',
			];
			//replace(sgb_rxuhang,',', '/')
			if(count($addArr) == 1000 || $k+1 == count($arr))
			{
				$this->addAny('stand_gxb_base', array_keys($addArr[0]), $addArr);
				$addArr = [];
			}
		}
		$sqlArr = [
			"delete from stand_gxb_dipan",
			"INSERT INTO stand_gxb_dipan(sgd_gxb_code, sgd_gxb_code_show, sgd_dpgxb_code, sgd_dpgxb_code_show)
			SELECT gb_gxb_code, gb_gxb_code_show, gd_dpgxb_code, gd_dpgxb_code_show FROM gxb_base 
			JOIN gxb_dipan ON gb_id = gd_gb_id and gb_type='gxb' WHERE gb_gxb_code != gd_dpgxb_code GROUP BY gb_gxb_code, gd_dpgxb_code"
		];
		$this->exeAnySql($sqlArr);
		$this->YpwDb->End();
		return LibFc::ReturnData(true);
	}


	/**
	  * @method 填充某个工信部型号数据
	  * @param  $gxbShowCode  string [必填] 
	  * @param  $vin1_8  string [必填] 
	  * @author soul
	  * @copyright 
	  */
	public function initStandGxb($gxbShowCode, $vin1_8)
	{
		$filedArr = ["sma_brand", "sma_engine", "sma_cc", "sma_kw", "sma_length", "sma_width","sma_height", "sma_wheel", "sma_axle","sma_weight","sma_passenger","sma_vtype"];
		$res = $this->catchGxbcodeInfo($gxbShowCode, 1, $vin1_8);
		$arr = $res['data'];
		if(!empty($arr['merge']['sma_brand']))
		{
			$this->YpwDb->Begin();
			$mergeArr = $arr['merge'];
			foreach($filedArr as $filed)
			{
				if(empty($mergeArr[$filed])) continue;
				$where =  sprintf(" and sma_gxb_code='%s' and sma_vin1_8='%s'", LibFc::FormatNum($gxbShowCode), $vin1_8);
				$temp = explode(',', $mergeArr[$filed]);
				if(count($temp) == 1 && !empty($temp[0]))
				{
					//echo $gxbShowCode, '=>', $filed, '=>', $temp[0], '<br>';
					$temp[0] = $filed == 'sma_engine' && stripos($temp[0], '#') ? substr($temp[0], 0, stripos($temp[0], '#')): $temp[0];
					if(in_array($filed, ["sma_length", "sma_width","sma_height","sma_wheel", "sma_axle","sma_weight","sma_passenger"]))
					{
						$where .= sprintf(" and (%s = 0 or (%s !=%d and sma_from in ('catch', 'epc', 'buy01', 'buy02') ) )", $filed, $filed, $temp[0]);
					}
					else if(in_array($filed, ["sma_engine", "sma_cc","sma_kw"]))
					{
						$where .= sprintf(" and (%s = '' or (%s !='%s' and sma_from in ('catch', 'epc', 'buy01', 'buy02') ) )", $filed, $filed, LibFc::Escape($temp[0]));
					}
					else
					{
						$where .= sprintf(" and %s = ''", $filed);
					}
					if(in_array($filed, ["sma_axle"])) $temp[0] = (int) $temp[0];
					$this->set('stand_model_any', [$filed=>$temp[0]], $where);
				}
				else if(count($temp) > 1 && $filed == 'sma_engine')
				{
					//多个发动机的,确认功率排量
					$vres = $this->get('stand_model_any', ['distinct sma_engine as sma_engine'], sprintf(" and sma_gxb_code='%s' and sma_engine != '' and (sma_kw='' or sma_cc='')", LibFc::FormatNum($gxbShowCode)));
					foreach($vres['data'] as $ev)
					{
						$matchengs = [];
						$reArr = [' '=>'', '-'=>''];
						foreach($temp as $tempv)
						{
							$t = explode('#', $tempv);
							$ismatch = false;
							if(strtr($t[0], $reArr) == strtr($ev['sma_engine'], $reArr))
							{
								$ismatch = true;
							}
							else
							{//LA91D61D3H1HZG018 通过发动机号码查询只有一个电机 JAS70-D1-R/JAS70-D1-R    多个电机 IM171601/IM171301
								if(strlen($ev['sma_engine']) >= 12 && stripos($ev['sma_engine'], '/'))
								{
									$tengs = explode('/', $ev['sma_engine']);
									//前3是否一样
									if(substr($tengs[0], 0, 3) == substr($tengs[1], 0, 3) && strtr($t[0], $reArr) == strtr($tengs[0], $reArr))
									{
										$ismatch = true;
									}
								}
							}
							if($ismatch) $matchengs[$tempv] = $t;
						}
						if(empty($matchengs))
						{//发动机不匹配 
							$this->set('stand_model_any', ['sma_engine'=>'', 'sma_kw'=>'', 'sma_cc'=>''], $where.sprintf(" and sma_engine='%s' AND sma_from in ('buy01', 'buy02', 'ocr', 'manual')", LibFc::Escape($ev['sma_engine'])));
						}
						else if(count($matchengs) == 1 || (count($matchengs) == 2 && !empty($matchengs[$ev['sma_engine']])))
						{//只有一个匹配的 || 有两个但是其中一个没有功率排量
							unset($matchengs[$ev['sma_engine']]);
							foreach($matchengs as $t)
							{
								if(!empty($t[1])) $this->set('stand_model_any', ['sma_kw'=>$t[1]], $where.sprintf(" and sma_engine='%s' and sma_kw=''", LibFc::Escape($ev['sma_engine'])));
								if(!empty($t[2])) $this->set('stand_model_any', ['sma_cc'=>$t[2]], $where.sprintf(" and sma_engine='%s' and sma_cc=''", LibFc::Escape($ev['sma_engine'])));
								break;
							}
						}
						else
						{
							//LFCDKE5P0J1009101 多个功率的不填充
						}
					}
				}
			}
			$this->YpwDb->End();
		}
		return LibFc::ReturnData(true);
	}


	/**
	  * @method 更新VIN日期的计算规则  距离上次时间超过7天的
	  * @author soul
	  * @copyright 
	  */
	public function updateVinDateReg()
	{
		$cachetime = 7*3600*24;
		$res = $this->get('yp_allvin_date_reg', ['min(aldr_etime) as aldr_etime'], '', true);
		if(!empty($res['data']['aldr_etime']) && (time()-$res['data']['aldr_etime']) < $cachetime)
		{
			return LibFc::ReturnData(true);
		}

		$this->YpwDb->Begin();
		//查询需要处理的规则
		$this->del('yp_allvin_date_reg', ' and 1 = 1');
		$where = " and alb_vin1_3 like 'L%'  GROUP BY alb_vin1_3 HAVING COUNT(*) > 300";
		$regRes = $this->get('yp_allvin_base', ['alb_vin1_3, COUNT(*) as vin_count'], $where);
		foreach($regRes['data'] as $v)
		{
			$demoCount = $v['vin_count'];
			$nCount = ceil($demoCount*0.2);
			if($nCount > 10000)
			{
				$demoCount = 10000;
			}
			else if($nCount >= 5000)
			{
				$demoCount = $nCount;
			}
			$addArr = [
				'aldr_vin1_3'=>$v['alb_vin1_3'],
				'aldr_vin_count'=>$v['vin_count'],
				'aldr_demo_count'=>$demoCount,
			];
			$this->add('yp_allvin_date_reg', $addArr);
		}

		//抽样
		$where = sprintf(" and aldr_demo_time <= %d", strtotime('-7 day'));
		$res = $this->get('yp_allvin_date_reg', ['aldr_vin1_3, aldr_demo_count'], $where);
		$regArr = $res['data'];
		foreach($regArr as $rv)
		{
			$this->del('yp_allvin_date_regdemo', sprintf(" and vdr_vin1_3='%s'", $rv['aldr_vin1_3']));
			$where = sprintf(" and alb_vin1_3='%s' and alb_date != '' group by alb_vin order by rand() limit %d", $rv['aldr_vin1_3'], $rv['aldr_demo_count']);
			$res = $this->get('yp_allvin_base', ['alb_vin, alb_date'], $where);
			$addArr = [];
			foreach($res['data'] as $kk=>$vv)
			{
				$addArr[] = [
					'vdr_vin'=>$vv['alb_vin'],
					'vdr_vin1_3'=>substr($vv['alb_vin'], 0, 3),
					'vdr_vin1_8'=>substr($vv['alb_vin'], 0, 8),
					'vdr_vin10_11'=>substr($vv['alb_vin'], 9, 2),
					'vdr_vin12'=>substr($vv['alb_vin'], 11, 1),
					'vdr_vin13_17'=>substr($vv['alb_vin'], 12, 5),
					'vdr_date'=>$vv['alb_date'],
				];
				if(count($addArr) == 1000 || ($kk+1) == count($res['data']))
				{
					$this->addAny('yp_allvin_date_regdemo', array_keys($addArr[0]), $addArr);
					$addArr = [];
				}
			}
			$this->set('yp_allvin_date_reg', ['aldr_demo_time'=>time()], sprintf(" and aldr_vin1_3='%s'", $rv['aldr_vin1_3']));
		}
		
		//计算概率
		$where = sprintf(" and aldr_etime <= %d and aldr_demo_time > %d order by aldr_vin1_3", strtotime('-7 day'), strtotime('-10 day'));
		$res = $this->get('yp_allvin_date_reg', ['aldr_vin1_3'], $where);
		$regArr = $res['data'];
		foreach($regArr as $rv)
		{
			$filedArr = [
				'aldr_reg1_3_10_11'=>[
					'filed'=>['vdr_vin1_3', 'vdr_vin10_11', 'vdr_date'],
					'order'=>'order by vdr_vin1_3, vdr_vin10_11, vdr_vin12, vdr_vin13_17',
					'unireg'=>['vdr_vin1_3', 'vdr_vin10_11']
				],
				'aldr_reg1_3_10_12'=>[
					'filed'=>['vdr_vin1_3', 'vdr_vin10_11', 'vdr_vin12', 'vdr_date'],
					'order'=>'order by vdr_vin1_3, vdr_vin10_11, vdr_vin12, vdr_vin13_17',
					'unireg'=>['vdr_vin1_3', 'vdr_vin10_11', 'vdr_vin12']
				],
				'aldr_reg1_8_10_11'=>[
					'filed'=>['vdr_vin1_8', 'vdr_vin10_11', 'vdr_date'],
					'order'=>'order by vdr_vin1_8, vdr_vin10_11, vdr_vin12, vdr_vin13_17',
					'unireg'=>['vdr_vin1_8', 'vdr_vin10_11']
				],
				'aldr_reg1_8_10_12'=>[
					'filed'=>['vdr_vin1_8', 'vdr_vin10_11', 'vdr_vin12', 'vdr_date'],
					'order'=>'order by vdr_vin1_8, vdr_vin10_11, vdr_vin12, vdr_vin13_17',
					'unireg'=>['vdr_vin1_8', 'vdr_vin10_11', 'vdr_vin12']
				]
			];
			$setArr = [];
			$rateArr = [];
			foreach($filedArr as $filed=>$filedv)
			{
				$dateRes = $this->get('yp_allvin_date_regdemo', $filedv['filed'], sprintf(" and vdr_vin1_3 = '%s' %s", $rv['aldr_vin1_3'], $filedv['order']));
				$total = count($dateRes['data']);
				$okCount = 0;
				$last = null;
				foreach($dateRes['data'] as $fv)
				{
					$fv['vdr_date'] = str_replace('-', '', $fv['vdr_date']);
					$fv['vdr_ym'] = strlen($fv['vdr_date']) >= 6 ? substr($fv['vdr_date'], 0, 6): substr($fv['vdr_date'], 0, 4);
					$unival = '';
					foreach($filedv['unireg'] as $fvv)
					{
						$unival .= $fv[$fvv];
					}

					//第一个或者规则值发生变化
					if($last === null || $last['unireg'] != $unival)
					{
						$okCount++;
						$last = [
							'unireg'=>$unival,
							'date'=>$fv['vdr_ym']
						];
					}
					else if(
						(strlen($last['date']) == strlen($fv['vdr_ym']) && $fv['vdr_ym'] >= $last['date'])
						|| strlen($last['date']) == 4 && substr($fv['vdr_ym'], 0, 4) >= $last['date']
						|| strlen($fv['vdr_ym']) == 4 && $fv['vdr_ym'] >= substr($last['date'], 0, 4)
					)
					{
						$okCount++;
					}
					$last['date'] = $fv['vdr_ym'];
				}
				$setArr[$filed] = sprintf("%.2f", $okCount/$total*100);
				$rateArr[$filed] = $setArr[$filed];
			}
			
			$setArr['aldr_etime'] = time();
			arsort($rateArr);
			foreach($rateArr as $filed=>$frate)
			{
				if($frate < 80) unset($rateArr[$filed]);
			}
			$setArr['aldr_reg_use'] = implode(',', array_keys($rateArr));
			
			//没有规则的直接用 aldr_reg1_8_10_12
			if(empty($setArr['aldr_reg_use'])) $setArr['aldr_reg_use'] = 'aldr_reg1_8_10_12';
			$this->set('yp_allvin_date_reg', $setArr, sprintf(" and aldr_vin1_3='%s'", $rv['aldr_vin1_3']));
		}
		$this->YpwDb->End();
		return LibFc::ReturnData(true);
	}

	
	/**
	  * @method 检测车架号的时间是否在正常范围内
	  * @author soul
	  * @copyright 
	  */
	public function checkVinYear($vin, $ydate)
	{
		$arr = ['ok'=>1];
		//找相邻有日期的车架号校验年月是否在区间内
		$Ym = strlen($ydate) > 7? date('Ym', strtotime($ydate)): date('Ym', strtotime($ydate.'-01'));
		$YpwBase = new YpwBase();
		$vin13_17 = substr($vin, 12, 5);
		$twhere = sprintf(" and alb_date != '' and alb_vin1_3='%s' and alb_vin4_8='%s' and alb_vin10_11='%s' and alb_vin12='%s'", substr($vin, 0, 3), substr($vin, 3, 5), substr($vin, 9, 2), substr($vin, 11, 1));

		$res = $YpwBase->Get('yp_allvin_base', ['alb_vin, alb_date'], $twhere.sprintf(" and alb_vin13_17 <'%s' order by alb_vin13_17 desc limit 1", $vin13_17), true);
		if(!empty($res['data']))
		{//最小时间
			$arr['min'] = $res['data'];
			$tdate = $arr['min']['alb_date'];
			if(strlen($tdate) <= 7) $tdate .= '-01';
			$comYm = date('Ym', strtotime('-1 month', strtotime($tdate)));
			if($Ym < $comYm)
			{
				$arr['ok'] = 0;
				$ydate = '';
			}
		}
		if(!empty($ydate))
		{
			$res = $YpwBase->Get('yp_allvin_base', ['alb_vin, alb_date'], $twhere.sprintf(" and alb_vin13_17 >'%s' order by alb_vin13_17 asc limit 1", $vin13_17), true);
			if(!empty($res['data']))
			{//最大时间
				$arr['max'] = $res['data'];
				$tdate = $arr['max']['alb_date'];
				if(strlen($tdate) <= 7) $tdate .= '-01';
				$comYm = date('Ym', strtotime('+1 month', strtotime($tdate)));
				if($Ym > $comYm) 
				{
					$arr['ok'] = 0;
					$ydate = '';
				}
			}
		}
		return LibFc::ReturnData(true, $arr);
	}

	/**
	  * @method 格式化续航
	   * @param  $xhArr ['54.4千瓦时/431公里', '54.4千瓦时/445公里']
	  * @author soul
	  * @return
	  */
	public function formatXuhang($xhArr)
	{
		$arr = [];
		$arr['rl'] = [];
		$arr['lc'] = [];
		$xhArr = array_unique($xhArr);
		foreach($xhArr as $trow)
		{
			$reArr = ['km'=>'公里', 'kWh'=>'千瓦时'];
			$trow = strtr($trow, $reArr);
			$tt = explode('/', $trow);
			foreach($tt as $tkk=>$tvv)
			{
				$tvv = trim($tvv);
				if(stripos($tvv, '千瓦时') || stripos($tvv, 'Ah')){
					$arr['rl'][] = $tvv;
				}else if(stripos($tvv, '公里') || stripos($tvv, 'NEDC') || stripos($tvv, 'CLTC') || stripos($tvv, '工作') || preg_match('/^\d{2,}\.?\d*$/', $tvv, $match)){
					if(preg_match('/\d+\.?\d*/', $tvv, $match)){
						$lcnum = $match[0];
						if($lcnum < 20 || (count($tt) > 1 && $tkk === 0 && $lcnum < 50 && $tvv == $lcnum)) continue;
						$lcnum = (float) $lcnum;
						$lcoth = strtr($tvv, [$lcnum=>'','工况'=>'', '('=>'', '公里'=>'', ')'=>'']);
						if(empty($arr['lc'][$lcnum])) $arr['lc'][$lcnum] = [];
						if(!empty($lcoth)) $arr['lc'][$lcnum][] = $lcoth;
					}
				}else{
					//echo $tvv,'=>','无匹配<br>';
				}
			}
		}
		if(!empty($arr['lc']))
		{
			$xuhangArr = [];
			$arr['rl'] = array_unique($arr['rl']);
			if(count($arr['rl']) == 1) $xuhangArr[] = $arr['rl'][0];
			foreach($arr['lc'] as $lcnum=>$lcoth)
			{
				$xuhangArr[] = $lcnum.'公里'.(!empty($lcoth)? '('.implode(',', array_unique($lcoth)).')': ''); 
			}
			$arr['xuhang'] = implode('/', $xuhangArr);
		}
		return LibFc::ReturnData(true, $arr);
	}
	
	/**
	  * @method 格式化变速箱
	   * @param  $tranfull  自动/5+2(5个发动机档+2个电机档位)
	  * @author soul
	  * @return
	  */
	public function formatTran($tranfull)
	{
		$reArr = ['挡'=>'档','当'=>'档', '无级变速(CVT)'=>'CVT','十二'=>'12','十'=>'10','五'=>'5','六'=>'6','七'=>'7','八'=>'8','九'=>'9','十'=>'10'];
		$arr = ['tran'=>'', 'dws'=>'', 'hdfs'=>''];
		$tranfull = strtr($tranfull, $reArr);
		//自动/6,无极变速(CVT),无级变速(CVT),手动/5,手自一体/9,自动/5,无级变速(CVT)/无,手动/6,自动/7,自动/8,手自一体/6,自动/9,无级变速(CVT)/N/A,手自一体/7,自动/4,无级变速(CVT)级变速器,手自一体/8,自动,自动/1,自动/7个前进挡＋倒挡,手动/4,自动/无,无级变速(CVT)/,无级变速(CVT)/0,手自一体/5,自动/10,手自一体/10,无级变速(CVT)/7,手动/10,无级变速(CVT)/1,无级变速(CVT)/4,手自一体/4,无级变速(CVT)/不适用,无级变速(CVT)/6,无级变速(CVT)级变速,手自一体,自动/3,手动,手动/无,手自一体/7+倒档,手动/6+倒挡,风冷式,手动/5+1,无级变速(CVT)/\\,手动/前进挡5个倒档1个,手动/5个前进挡,1个倒档,手动/5档,自动/5+2(5个发动机档+2个电机档位),无级变速(CVT)/--,自动\\/9,无级变速(CVT)/8,自动/2,无级变速(CVT)极变速,无级变速(CVT)/无级变速器,无级变速(CVT)/无级变速,自动/ 8,无级变速(CVT)/5,无级变速(CVT)级变速器(模拟八档),5MT
		
		if(
			preg_match('/(\d{1,2})(AMT)/', $tranfull, $match)
			||preg_match('/(\d{1,2})(CVT)/', $tranfull, $match)
			||preg_match('/(\d{1,2})(AT)/', $tranfull, $match)
			||preg_match('/(\d{1,2})(MT)/', $tranfull, $match)
		)
		{
			if($match[1] >= 2)
			{
				$arr = ['tran'=>$match[0], 'dws'=>$match[1], 'hdfs'=>$match[2]];
				return LibFc::ReturnData(true, $arr);
			}
		}

		if(
			preg_match('/前进档(\d{1,2})个/', $tranfull, $match)
			|| preg_match('/(\d{1,2})个前进/', $tranfull, $match)
			|| preg_match('/(\d{1,2})档/', $tranfull, $match) 
			|| preg_match('/\/ *(\d{1,2})[\s个\+]/', $tranfull, $match)
			|| preg_match('/\/ *(\d{1,2})$/', $tranfull, $match)
			
		)
			$arr['dws'] = $match[1];

		if($arr['dws'] <= 2) $arr['dws'] = '';
	
		//转换
		if(stripos($tranfull, '手自一体') !== false || stripos($tranfull, 'AMT') !== false){
			$arr['hdfs'] = 'AMT';
		}else if(stripos($tranfull, 'CVT') !== false || stripos($tranfull, '无级变速') !== false){
			$arr['hdfs'] = 'CVT';
		}else if(stripos($tranfull, 'AT') !== false || stripos($tranfull, '自动') !== false){
			$arr['hdfs'] = 'AT';
		}else if(stripos($tranfull, 'MT') !== false || stripos($tranfull, '手动') !== false){
			$arr['hdfs'] = 'MT';
		}
		
		if(!empty($arr['hdfs'])){
			//已经格式化的
			if(preg_match('/(\d{1,2})'.$arr['hdfs'].'/', $tranfull, $match)){
				if($match[1] >= 2) $arr['dws'] = $match[1];
			}
			$arr['tran'] = $arr['dws'].$arr['hdfs'];
		}
		return LibFc::ReturnData(true, $arr);
	}

	/**
	  * @method 获取型号所有的发动机
	   * @param  $gxb  
	  * @author soul
	  * @return
	  */
	public function getGxbEngs($gxb)
	{
		$res = $this->get('gxb_base join gxb_engine on gb_id = ge_gb_id and gb_type="gxb"', ['ge_engine'], sprintf(" and gb_gxb_code='%s' group by ge_engine_format order by length(ge_engine_format) desc", LibFc::formatNum($gxb)));
		return LibFc::ReturnData(true, array_column($res['data'], 'ge_engine'));
	}



	public function addVinJiuCuo($vin, $keyword, $talkerId, $roomId = '', $imagedata = '', $postArr = [])
	{
		$arr = [];
		$roomId = $infoArr['roomId'];
		$userkey = $talkerId;
		if($roomId) $userkey .= '_'.$roomId;
		if(!is_array($postArr)) $postArr = [];
		if(strlen($imagedata) < 100) $imagedata = '';
		$jiucuo = [
			've_vin'=>$vin,
			've_notice'=>trim(strtr($keyword, [$vin=>''])),
			've_uid'=>8,
			've_userkey'=>$userkey,
			've_from'=>'ROBOT',
			've_byinfo'=>json_encode($postArr, JSON_PARTIAL_OUTPUT_ON_ERROR)
		];
		//第一次纠错直接取泽达
		$PjlModel = new PjlModel();
		$res = $PjlModel->addVinJiucuo($jiucuo, $imagedata);
		$jcres = $res['data'];
		if($jcres['check']){
			$arr = ['result'=>1, 'msg'=>'纠错已处理完成'];
		}else{
			//此车架号是否有图
			$res = $this->get('stand_vin_imgs', ['vii_id'], sprintf(" and vii_vin='%s' limit 1", $vin));
			$msg = empty($res['data'])? '您好，车架号【'.$vin.'】纠错反馈已收到，可提供车辆铭牌或者行驶证图。': '您好，车架号【'.$vin.'】纠错反馈已收到，工作人员正在快马加鞭处理中，谢谢您的反馈。';
			$arr = ['result'=>2, 'msg'=>$msg];
		}
		return LibFc::ReturnData(true, $arr);
	}
	
	/**
	  * @method 尝试纠正错误的VIN
	  * @param  $vin  string [必填] 车架号
	  * @author soul
	  * @return 
	  */
	public function getRealVin($vin)
	{
		$arr = [];
		$v18 = substr($vin, 0, 8);
		$v917 = substr($vin, 8, 9);
		$whereArr = [
			'v18'=>sprintf(" and left(smt_vin1_8, 1) in ('L', 'H') and smt_vin1_8 like '%s'", $v18),
			'v48'=>sprintf(" and left(smt_vin1_8, 1) in ('L', 'H') and smt_vin1_8 like '%%%s'", substr($vin, 3, 5)),
			'v37'=>sprintf(" and left(smt_vin1_8, 1) in ('L', 'H') and smt_vin1_8 like '%%%s%%'", substr($vin, 2, 5)),
			'v26'=>sprintf(" and left(smt_vin1_8, 1) in ('L', 'H') and smt_vin1_8 like '%s%%'", substr($vin, 1, 5)),
			'v15'=>sprintf(" and left(smt_vin1_8, 1) in ('L', 'H') and smt_vin1_8 like '%s%%'", substr($vin, 0, 5)),
		];
		$last = [];
		foreach($whereArr as $where){
			$res = $this->get('stand_model_tj', ['smt_vin1_8'], $where.' group by smt_vin1_8 order by sum(smt_vin_count) desc');
			if(empty($res['data'])) continue;
			foreach($res['data'] as $tv){
				$isvin = $tv['smt_vin1_8'].$v917;
				$check = LibFc::VinCheckCode($isvin);
				if($check['ok']){
					$diff = LibFc::diffByPos($v18, $tv['smt_vin1_8']);
					//超过两个字符不同有一定的错误率，只找一位的
					if(count($diff) < 2 && (empty($last) || count($diff) < count($last['diff']))){
						$last = ['newvin'=>$isvin, 'diff'=>$diff];
					}
				}
			}
			if($last) break;
		}
		$arr = $last;
		return LibFc::ReturnData(true, $arr);
	}
}