<?php
class vinImgAction extends baseAction
{
	public function test()
	{
		$Params = mvc::$URL_PARAMS;
		$YpwVinImg = new YpwVinImg();
		/*$res = $YpwVinImg->getImgOcrSma($Params['vin'], 3);
		var_dump($res);*/

		$YpwBase = new YpwBase();
		$YpwVin = new YpwVin();
		$OthVinImg = new OthVinImg();
		$OthVinImg->debug = true;

		$res = $YpwVin->getRealVin($Params['vin']);
		echo '<hr>VIN纠正<br>';
		print_r($res['data']);

		$res = $YpwVinImg->get('stand_vin_imgs', ['*'], sprintf(" and vii_vin='%s'", $Params['vin']), true);
		$res = $YpwVinImg->ocrViiImg($res['data']);
		echo '<hr>图片OCR<br>';
		print_r($res['data']);

		//saic-gm ftm
		$res = $YpwBase->get('stand_ocrimg_reg', ['*'], " and reg_status = 1 and reg_code = 'saic-gm'");
		$reg = $res['data'][0];
		$twhere = " and vii_vin = '".$Params['vin']."'";
		$viires = $YpwBase->get('stand_vin_imgs left join stand_model_any ON sma_vin = vii_vin', ['*'], $twhere, true);
		
		echo '<hr>图片类型:'.$viires['data']['vii_imgtype'], '<br>';
		
		echo '<hr>ENG6<br>';
		$res = $OthVinImg->matchEng6($viires['data']['vii_vin'], $viires['data']['vii_imgtype'], $viires['data']['vii_imgocr'], $viires['data']['vii_year']);
		print_r($res['data']);

		$btime = microtime(true);
		//$matchres = $OthVinImg->sma($viires['data'], $reg,5, true);
		$matchres = $OthVinImg->sma($viires['data'], $reg, 0, true);
		$matchres = $matchres['data'];
		echo '<hr>sma=>', ceil((microtime(true) - $btime)*1000), 'ms<br>';
		print_r($matchres);

		$res = $OthVinImg->matchBatteryByTxt($viires['data']['vii_imgocr']);
		echo '<hr>电池<br>';
		print_r($res['data']);
		

		$btime = microtime(true);
		$matchres = $OthVinImg->smaNoGxb($viires['data']['vii_vin'], $viires['data']['vii_imgocr']);
		echo '<hr>smaNoGxb=>', ceil((microtime(true) - $btime)*1000), 'ms<br>';
		print_r($matchres);
		
		$res = $YpwVinImg->get('stand_vin_imgs', ['vii_id, vii_vin, vii_imgocr, vii_year'], sprintf(" and vii_vin='%s'", $Params['vin']), true);
		$res = $YpwVinImg->ocrVinDate($res['data']);
		echo '<hr>制造日期<br>';
		print_r($res['data']);

		$res = $YpwVinImg->get('stand_vin_imgs', ['vii_id, vii_vin, vii_imgocr, vii_year'], sprintf(" and vii_vin='%s'", $Params['vin']), true);
		$res = $YpwVinImg->ocrVinEpcCode($res['data'], []);
		echo '<hr>原厂代码<br>';
		print_r($res['data']);

		$res = $OthVinImg->matchAnyByVinGxbTxt($viires['data']['vii_vin'], $viires['data']['sma_gxb_code'], $viires['data']['vii_imgocr']);
		echo '<hr>型号&ocr提取其他属性<br>';
		print_r($res['data']);
		
		$res = $OthVinImg->smaByBatteryTxt($viires['data']['vii_vin'], $viires['data']['vii_imgocr']);
		echo '<hr>电池型号<br>';
		print_r($res['data']);
	}


	public function TestBatteryTxt()
	{
		$Params = mvc::$URL_PARAMS;
		$YpwVinImg = new YpwVinImg();
		$YpwBase = new YpwBase();
		$OthVinImg = new OthVinImg();
		$OthVinImg->debug = true;
		$twhere = " and vii_vin = '".$Params['vin']."'";
		$viires = $YpwBase->get('stand_vin_imgs left join stand_model_any ON sma_vin = vii_vin', ['*'], $twhere, true);
		$res = $OthVinImg->smaByBatteryTxt($viires['data']['vii_vin'], $viires['data']['vii_imgocr']);
		echo '<hr>电池型号<br>';
		print_r($res['data']);

	}

	/** 
	  * @method 识别VIN图片内容 可指定wmi?wmi=LSG  ?all=1表示永久执行  php index.php vinImg onlyOcr type=retask all=1   
	  * @author soul
	  * @copyright 2022/1/21
	  * @return 
	  */
	public function onlyOcr()
	{
		set_time_limit(0);
		$Params = mvc::$URL_PARAMS;
		$YpwVinImg = new YpwVinImg();
		$per = 100;
		while(1){
			$twhere = "";
			$cfg = ['rotate'=>[0], 'timeout'=>10];
			if($Params['type'] == 'reocr'){
				$twhere .= " AND vii_ocrstatus = -1";
			}else{
				$twhere .= sprintf(" and vii_ocrstatus = 0 and (
					vii_status in (0,-3) 
					or (vii_vin1_3 NOT LIKE 'L%%' AND vii_vin1_3 NOT LIKE 'H%%') 
				) and vii_atime > %d", strtotime('-15 day'));
			}
			if(!empty($Params['wmi'])) $twhere .= sprintf(" and vii_vin1_3 = '%s'", strtoupper($Params['wmi']));
			$table = "(
			SELECT vii_id, vii_status, vii_vin, vii_imghost, vii_img, vii_imgtype FROM stand_vin_imgs 
			WHERE 1 ".$twhere." LIMIT ".($per*10)."
			) AS t";
			$viires = $YpwVinImg->get($table, ['*'], sprintf(" ORDER BY RAND () LIMIT %d", $per));
			foreach($viires['data'] as $v){
				//echo mvc::$URL_METHOD.':'.$v['vii_vin']." begin\n";
				$ores = $YpwVinImg->ocrViiImg($v, $cfg);
				echo mvc::$URL_METHOD.':'.$v['vii_vin'].'=>'.strlen($ores['data']['vii_imgocr'])."\n";
			}
			if($Params['all']){
				if(count($viires['data']) < $per){
					echo mvc::$URL_METHOD." sleep 60s\n";
					sleep(60);
				}
			}else{
				break;
			}
		}
		echo 'ok';
	}


	//图片类型 php index.php vinImg initImgType
	function initImgType()
	{
		set_time_limit(0);
		$Params = mvc::$URL_PARAMS;
		$YpwVinImg = new YpwVinImg();
		$MainOcr = new MainOcr();
		$LibHttp = new LibHttp();
		$run = 0;
		while(1){
			$per = 100;
			try {
				$run++;
				$table = "(
				SELECT vii_id, vii_status, vii_imghost, vii_vin, vii_img FROM stand_vin_imgs 
				WHERE vii_imgtype = -5 order by vii_id desc LIMIT ".($per*10)."
				) AS t";
				$viires = $YpwVinImg->get($table, ['*'], sprintf(" ORDER BY RAND () LIMIT %d", $per));
				echo $run."轮".count($viires['data'])."\n";
				foreach($viires['data'] as $v){
					$imgurl = mvc::$cfg['urls']['vinimg_'.$v['vii_imghost']].$v['vii_img'];
					$image = $LibHttp->fetch($imgurl);
					$imgdata = base64_encode($image);
					$res = $MainOcr->vinCls($imgdata);
					$imgcls = $res['data'];
					$imgtype = 0;
					if(in_array($imgcls, ['xsz','hgz', 'djzs'])){
						$imgtype = 1;
					}else if($imgcls == 'mp'){
						$imgtype = 2;
					}
					$set = ['vii_imgtype'=>$imgtype];
					$YpwVinImg->set('stand_vin_imgs', $set, sprintf(" and vii_id=%d", $v['vii_id']));
					echo $v['vii_img'].'=>'.$imgtype."\n";
				}
				if(count($viires['data']) < $per) break;
			}catch (Exception $e) {
				sleep(300);
				echo "错误: " . $e->getMessage();
			}
		}
		echo 'ok';
	}

	
	//裁剪图片 php index.php vinImg cropLocalImage bid=0 eid=30000000 php index.php vinImg cropLocalImage bid=30000000 eid=60000000  php index.php vinImg cropLocalImage bid=100000000 eid=110000000  php index.php vinImg cropLocalImage bid=90000000
	function cropLocalImage()
	{
		set_time_limit(0);
		$Params = mvc::$URL_PARAMS;
		$YpwVinImg = new YpwVinImg();
		$MainOcr = new MainOcr();
		$orgdir = 'F:\vinimg/';
		$twhere = " and vii_imghost = 2 and vii_crop = 0 and vii_imgtype in (1,2)";
		if(isset($Params['eid'])) $twhere .= sprintf(" and vii_id <= %d", $Params['eid']);
		if(isset($Params['bid'])){
			$res = $YpwVinImg->get('stand_vin_imgs', ['min(vii_id) vii_id'], $twhere.sprintf(" and vii_id >= %d", $Params['bid']), true);
			$twhere .= sprintf(" and vii_id >= %d", $res['data']['vii_id']);
		}
		echo $twhere;
		$nofileStop = 0;
		$run = 0;
		while(1){
			$per = 500;
			try {
				$run++;
				$viires = $YpwVinImg->get('stand_vin_imgs', ['vii_id, vii_status, vii_vin, vii_img'], $twhere.' limit '.$per);
				echo $run."轮".count($viires['data'])."\n";
				foreach($viires['data'] as $v){
					$orgFile = $orgdir.$v['vii_img'];
					$fileok = true;
					if(!file_exists($orgFile)){
						$fileok = false;
					}else if(filesize($orgFile) < 512){
						$fileok = false;
					}
					if(!$fileok){
						$nofileStop++;
						echo $orgFile."\n";
						//if($nofileStop > 1000) die('文件不存在超过'.$nofileStop);
						$YpwVinImg->set('stand_vin_imgs', ['vii_crop'=>-1], sprintf(" and vii_id=%d", $v['vii_id']));
						continue;
					}
					$nofileStop = 0;
					$toFile = $orgFile;
					$imgdata = base64_encode(file_get_contents($orgFile));
					$res = $MainOcr->getVinInfoArea($imgdata);
					$detres = $res['data'];
					$crop = 0;
					if($detres['pos']){
						if($detres['match'] >= 0.7){
							$res = LibFc::cropImage($imgdata, $detres['pos'], 'base64', 'blob');
							if($res['status'] && !empty($res['data'])){
								if(file_put_contents($toFile, $res['data'])){
									$crop = 1; //裁剪失败
								}else{
									$crop = -1; //裁剪失败
								}
							}else{
								$crop = -1; //裁剪失败
							}
						}else{
							$crop = -3;//准确率过低
						}
					}else{
						$crop = -2;//检测不到
					}
					$set = ['vii_crop'=>$crop];
					if($crop == 1 && in_array($v['vii_status'], [0,-3])){//待处理的重新识别
						$set['vii_ocrstatus'] = -1;
						$set['vii_smastatus'] = 'ocr';
					}
					$YpwVinImg->set('stand_vin_imgs', $set, sprintf(" and vii_id=%d", $v['vii_id']));
					echo $orgFile.'=>'.$crop."\n";
				}
				if(count($viires['data']) < $per) break;
			}catch (Exception $e) {
				sleep(300);
				echo "错误: " . $e->getMessage();
			}
		}
		echo 'ok';
	}


	//检测新规则和老规则的匹配概率
	public function checkSmaRate()
	{
		set_time_limit(0);
		$Params = mvc::$URL_PARAMS;
		$YpwVin = new YpwVin();
		$YpwBase = new YpwBase();
		$OthVinImg = new OthVinImg();
		//是否指定某个站点
		$where = " and reg_status = 1";
		if(!empty($Params['site'])) 
			$where .= sprintf(" and reg_code in ('%s')", implode("','", explode(",", LibFc::Escape($Params['site']))));
		$rres = $YpwBase->get('stand_ocrimg_reg', ['*'], $where.' limit 10');
		$regArr = [];
		foreach($rres['data'] as $reg)
		{
			//自动计算wmi
			if($reg['reg_code'] == 'auto')
			{
				$res = $YpwBase->get('stand_ocrimg_reg', ['GROUP_CONCAT(reg_wmi) reg_wmi'], " and reg_code != 'auto'", true);
				$twmiArr = explode(',', $res['data']['reg_wmi']);
				
				$table ="(SELECT smt_vin1_8, SUM(smt_vin_count) smt_vin_count FROM stand_model_tj WHERE smt_vin1_8 LIKE 'L%' GROUP BY smt_vin1_8 HAVING SUM(smt_vin_count) > 200) AS a";
				$res = $YpwBase->get($table, ['LEFT(smt_vin1_8, 3) wmi'], " GROUP BY wmi HAVING SUM(smt_vin_count) > 10000");
				$newwmis = array_diff(array_column($res['data'], 'wmi'), $twmiArr);
				sort($newwmis);
				$newwmis = implode(',', $newwmis);
				if($newwmis != $reg['reg_wmi'])
				{
					$YpwBase->set('stand_ocrimg_reg', ['reg_wmi'=>$newwmis], " and reg_code='auto'");
					$reg['reg_wmi'] = $newwmis;
				}
			}
			if($reg['reg_code'] == 'jiukou_auto')
			{
				$res = $YpwBase->get('stand_ocrimg_reg', ['GROUP_CONCAT(reg_wmi) reg_wmi'], " and reg_code != 'jiukou_auto'", true);
				$twmiArr = explode(',', $res['data']['reg_wmi']);
				
				$table ="(SELECT smt_vin1_8, SUM(smt_vin_count) smt_vin_count FROM stand_model_tj WHERE smt_vin1_8 NOT LIKE 'L%' and  smt_vin1_8 NOT LIKE 'H%' GROUP BY smt_vin1_8 HAVING SUM(smt_vin_count) > 5) AS a";
				$res = $YpwBase->get($table, ['LEFT(smt_vin1_8, 3) wmi'], " GROUP BY wmi HAVING SUM(smt_vin_count) > 100");
				$newwmis = array_diff(array_column($res['data'], 'wmi'), $twmiArr);
				sort($newwmis);
				$newwmis = implode(',', $newwmis);
				if($newwmis != $reg['reg_wmi'])
				{
					$YpwBase->set('stand_ocrimg_reg', ['reg_wmi'=>$newwmis], " and reg_code='jiukou_auto'");
					$reg['reg_wmi'] = $newwmis;
				}
			}
			if(empty($reg['reg_wmi'])) continue;
			$reg['reg_wmi'] = explode(',', $reg['reg_wmi']);
			$regArr[$reg['reg_code']] = $reg;
		}

		foreach($regArr as $site=>$reg)
		{
			$per = 100;
			$viitable = sprintf("(select vii_id,vii_vin,vii_imgocr,vii_imgtype,sma_gxb_code from stand_model_any join stand_vin_imgs on vii_vin = sma_vin where sma_vin1_3 in ('%s') and sma_from = 'ocr' limit %d) as a", implode("','", $reg['reg_wmi']), $per*10);
			$viires = $YpwBase->get($viitable, ['*'], sprintf(" order by rand() limit %d", $per));
			if(empty($viires['data'])) break;
			$ok = 0;
			foreach($viires['data'] as $viiArr)
			{
				$vin = $viiArr['vii_vin'];
				if(!empty($hasArr[$vin])) continue;
				$matchres = $OthVinImg->sma($viiArr, $reg);
				$matchres = $matchres['data'];
				if(!empty($matchres['sma']))
				{//入库
					$newgxb = LibFc::FormatNum($matchres['sma']['sma_gxb_code_show']);
					if($newgxb == $viiArr['sma_gxb_code'])
					{
						$ok++;
						continue;
					}
					else
					{
						echo $vin, '=>', $viiArr['sma_gxb_code'], '=>', $newgxb, '<hr>';
					}
				}
				else
				{
					echo $vin, '=>', $viiArr['sma_gxb_code'], '=>', $matchres['error'], '<hr>';
				}
			}
			echo $site, '=>', sprintf("%d%%", $ok/$per*100), '<hr>';
		}
		echo 'ok';
	
	}

	/**
	  * @method 从VIN图片内容匹配型号
	  * @author soul
	  * @copyright 2022/1/21
	  * @return 
	  */
	public function sma()
	{
		set_time_limit(0);
		$Params = mvc::$URL_PARAMS;
		$YpwVin = new YpwVin();
		$YpwBase = new YpwBase();
		$OthVinImg = new OthVinImg();
		while(1){
			//是否指定某个站点
			$where = " and reg_status = 1 and reg_todb=1";
			if(!empty($Params['site'])) 
				$where .= sprintf(" and reg_code in ('%s')", implode("','", explode(",", LibFc::Escape($Params['site']))));
			$rres = $YpwBase->get('stand_ocrimg_reg', ['*'], $where.' order by rand()');
			$regArr = array_column($rres['data'], null, 'reg_code');
			$hasArr = [];
			foreach($regArr as $site=>$reg)
			{
				//自动计算wmi  直接锁1小时，不要delFunLock
				if($reg['reg_code'] == 'auto' && LibFc::hasFunLock(mvc::$URL_METHOD.'_autowmi', 3600*24)){
					$res = $YpwBase->get('stand_ocrimg_reg', ['GROUP_CONCAT(reg_wmi) reg_wmi'], " and reg_code != 'auto'", true);
					$hasWmiArr = explode(',', $res['data']['reg_wmi']);
					$newwmis = [];
					$cres = $YpwBase->get('stand_model_tj', ['LEFT(smt_vin1_8, 3) wmi, SUM(smt_vin_count) vin_count'], " and (smt_vin1_8 LIKE 'L%' OR smt_vin1_8 LIKE 'H%') GROUP BY wmi HAVING SUM(smt_vin_count) >= 10");
					foreach($cres['data'] as $tv)
					{
						if(in_array($tv['wmi'], $hasWmiArr)) continue;
						if($tv['vin_count'] > 4000){
							$newwmis[] = $tv['wmi'];
						}else if($tv['vin_count'] >= 10){
							//样本是否有泽达或者人工
							$res = $YpwBase->get('stand_model_any', ['count(*) vin_count'], sprintf(" and sma_vin1_3='%s' and sma_from in ('manual', 'ZDAPI')", $tv['wmi']), true);
							if($res['data']['vin_count'] > 10)
							{
								$newwmis[] = $tv['wmi'];
							}
						}
					}
					sort($newwmis);
					$newwmis = implode(',', $newwmis);
					if($newwmis != $reg['reg_wmi'])
					{
						$YpwBase->set('stand_ocrimg_reg', ['reg_wmi'=>$newwmis], " and reg_code='auto'");
						$reg['reg_wmi'] = $newwmis;
					}
				}
				if(empty($reg['reg_wmi'])) continue;
				if(empty($reg['reg_max_year'])) $reg['reg_max_year'] = date('Y')+1;
				$reg['reg_wmi'] = explode(',', $reg['reg_wmi']);
				
				echo $reg['reg_remark']."=>开始\n";
				foreach($reg['reg_wmi'] as $twmi)
				{
					$twhere = sprintf(" and vii_vin1_3 ='%s' and vii_imgtype in (1,2) and (
						vii_status in (0,-3,-5) OR
						(vii_status = 1 AND vii_vin IN (SELECT sma_vin FROM stand_model_any WHERE sma_vin1_3 ='%s' AND sma_from ='buy02'))
					)
					and vii_smastatus='sma' and vii_year >=%d and vii_year<=%d order by vii_id desc limit %d", 
						$twmi, $twmi, $reg['reg_min_year'], $reg['reg_max_year'], $reg['reg_per']);
					$viires = $YpwBase->get('stand_vin_imgs', ['vii_id,vii_status,vii_vin1_8,vii_year,vii_vin,vii_imgocr,vii_imgtype'], $twhere);
					if(empty($viires['data'])) continue;
					foreach($viires['data'] as $viiArr)
					{
						$vin = $viiArr['vii_vin'];
						if(!empty($hasArr[$vin])) continue;
					
						$matchres = $OthVinImg->sma($viiArr, $reg);
						$matchres = $matchres['data'];
						echo mvc::$URL_METHOD.':'.$vin."=>".($matchres['sma']['sma_gxb_code']??$matchres['status'])."\n";

						//检测
						$chkres = $YpwVin->get('stand_model_any LEFT JOIN stand_vin_zdapi ON sma_vin = viz_vin', ['sma_id, sma_from, viz_id'], sprintf(" and sma_vin='%s'", $vin), true);
						$chkres = $chkres['data'];
						$YpwVin->YpwDb->Begin();
						$set = [];
						if(!empty($matchres['sma']))
						{//入库
							$addArr = $matchres['sma'];
							$addFlag = true;
							if($viiArr['vii_year'] >= date('Y'))
							{//新的包含型号，给人工处理
								$gxbres = $YpwBase->get("gxb_base JOIN gxb_params ON gp_gb_id=gb_id AND gp_gl_code='vin18' and gb_type='gxb'", ['distinct gb_gxb_code'], sprintf(" and gb_gxb_code LIKE '%s_%%' AND gp_value = '%s'", $addArr['sma_gxb_code'], $viiArr['vii_vin1_8']));
								if(!empty($gxbres['data']))
								{
									$addFlag = false;
									//泽达没有，并且来源为ocr的直接删除
									if(!empty($chkres['sma_id']) && empty($chkres['viz_id']) && $chkres['sma_from'] == 'ocr')
										$YpwBase->del('stand_model_any', sprintf(" and sma_vin='%s' and sma_from='ocr'", $vin));

									$set = [
										'vii_smastatus'=>'anygxb',
										'vii_smaerr'=>'新VIN型号包含:'.implode(',', array_column($gxbres['data'], 'gb_gxb_code')),
										'vii_smatime'=>time(),
										'vii_istask'=>1
									];
									$YpwBase->set('stand_vin_imgs', $set, sprintf(" and vii_id=%d", $viiArr['vii_id']));
								}
							}
							if($addFlag)
							{
								//泽达没有，并且来源为ocr的替换
								if(!empty($chkres['sma_id']) && empty($chkres['viz_id']) && $chkres['sma_from'] == 'ocr')
								{
									$addres = $YpwVin->addAnySma([$addArr], true);
								}
								else
								{
									$addres = $YpwVin->addAnySma([$addArr], false);
								}
								$hasArr = array_merge($addres['data'], $hasArr);
							}
						}else{
							//匹配不到，泽达没有，并且来源为ocr的直接删除
							if(!empty($chkres['sma_id']) && empty($chkres['viz_id']) && $chkres['sma_from'] == 'ocr'){
								$YpwBase->del('stand_model_any', sprintf(" and sma_vin='%s' and sma_from='ocr'", $vin));
							}
							
							//错误处理
							$set = [
								'vii_smastatus'=>$matchres['status'],
								'vii_smaerr'=>strlen($matchres['error']) > 255? substr($matchres['error'], 0, 255): $matchres['error'],
								'vii_smatime'=>time()
							];
							if(in_array($matchres['status'], ['vin_max','vin_min','anygxb','task'])) $set['vii_istask'] = 1;
							if($matchres['imgType'] && $matchres['imgType'] == -1)
								$set['vii_status'] = -1;
							if($viiArr['vii_status'] == -5) $set['vii_status'] = 0;
							$YpwBase->set('stand_vin_imgs', $set, sprintf(" and vii_id=%d", $viiArr['vii_id']));
						}
						$YpwVin->YpwDb->End();
					}
				}
			}
			if($Params['all']){
				echo mvc::$URL_METHOD." sleep 60s\n";
				sleep(60);
			}else{
				break;
			}
		}
		echo 'ok';
	}


	/**
	  * @method 将未处理或者大概率错的WMI图重新识别
	  * @author soul
	  * @copyright 2022/1/21
	  * @return 
	  */
	public function addReOcrVin()
	{
		$MainOcr = new MainOcr();
		$YpwBase = new YpwBase();
		$res = $YpwBase->get('stand_model_any', ['sma_vin1_3 wmi'], " and sma_vin1_3 LIKE 'L%' group by sma_vin1_3");
		$okwmi = array_column($res['data'], 'wmi');

		$rewmiRes = $YpwBase->get('stand_vin_imgs', ['vii_vin1_3 wmi'], " and vii_vin1_3 LIKE 'L%' AND vii_status = 1 group by vii_vin1_3");
		$okwmi = array_merge($okwmi, array_column($res['data'], 'wmi'));
		$okwmi = array_unique($okwmi);
		
		$rewmiRes = $YpwBase->get('stand_vin_imgs', ['vii_vin1_3 wmi'], " and vii_vin1_3 LIKE 'L%' AND vii_status = 0 group by vii_vin1_3");
		$reWmiArr = [];
		foreach($rewmiRes['data'] as $v)
		{
			if(!in_array($v['wmi'], $okwmi))
			{
				$reWmiArr[] = $v['wmi'];
			}
		}

		if(!empty($reWmiArr))
		{
			$addSql = [];
			$addSql[] = sprintf("INSERT INTO stand_vin_imgs_revin (vir_vii_id, vir_oldvin)
			SELECT vii_id, vii_vin FROM stand_vin_imgs WHERE vii_vin1_3 IN ('%s') AND vii_id NOT IN (SELECT vir_vii_id FROM stand_vin_imgs_revin)", implode("','", $reWmiArr));

			/*$addSql[] = "INSERT INTO stand_vin_imgs_revin (vir_vii_id, vir_oldvin) SELECT vii_id, vii_vin FROM stand_vin_imgs WHERE vii_status =0 
			AND vii_vin1_8 NOT IN (SELECT smt_vin1_8 FROM stand_model_tj)
			AND vii_id NOT IN (SELECT vir_vii_id FROM stand_vin_imgs_revin)";*/
			$YpwBase->exeAnySql($addSql);
		}
		echo 'ok';
	}


	/**
	  * @method 识别图片中的发动机号码并加入清单任务
	  * @author soul
	  * @copyright 2022/3/5
	  * @return 
	  */
	public function ocrEng6()
	{
		set_time_limit(0);
		//if(!LibFc::hasFunLock(mvc::$URL_METHOD, 3600)) return true;
		$YpwBase = new YpwBase();
		$OthVinImg = new OthVinImg();
		//所有状态 and vii_status = 0
		$comWhere = ' AND vii_ocreng6 = 0 AND vii_year >= 2017';
		$cfgArr = [
			['type'=>2, 'where'=>$comWhere.sprintf(" and vii_atime > %d AND vii_imgtype = 1 ", strtotime('-14 day'))],
			['type'=>1, 'where'=>$comWhere.sprintf(" and vii_atime > %d AND vii_vin1_3 in ('WP0', 'WP1') and vii_imgtype != -5", strtotime('-14 day'))],
			['type'=>1, 'where'=>$comWhere.sprintf(" AND vii_vin1_3 in ('WP0', 'WP1') AND vii_status != 1 and vii_imgtype != -5")],
		];
		foreach($cfgArr as $cfg){
			//$cfg['where'] = " and vii_vin = 'LGAX3A137S8016332'";
			$rewmiRes = $YpwBase->get('stand_vin_imgs', ['vii_id, vii_vin, vii_imgocr, vii_imgtype, vii_year'], $cfg['where']);
			foreach($rewmiRes['data'] as $v)
			{
				$vin = $v['vii_vin'];
				$eng6flag = -1;
				$res = $OthVinImg->matchEng6($vin, $cfg['type'], $v['vii_imgocr'], $v['vii_year']);
				$eng6s = $res['data']['eng6s'];
				if(!empty($eng6s)){
					$eng6flag = 1;
					$eng6s = array_values(array_unique($eng6s));
					$twhere = sprintf(" and sce_reg_code= 'engine6' and sce_vin='%s' and sce_engine6 in ('%s')", $vin, implode("','", $eng6s));
					$res = $YpwBase->get('stand_catch_list', ['sce_engine6'], $twhere);
					$hasArr = array_column($res['data'], 'sce_engine6');
					foreach($eng6s as $tk=>$eng6)
					{
						if(strlen($eng6) > 5 && !in_array($eng6, $hasArr))
						{
							$addArr = [
								'sce_reg_code'=>'engine6',
								'sce_vin'=>$vin,
								'sce_level'=>3000-$tk,
								'sce_engine6'=>$eng6,
							];
							$YpwBase->add('stand_catch_list', $addArr);
						}
					}
				}
				$YpwBase->set('stand_vin_imgs', ['vii_ocreng6'=>$eng6flag], ' and vii_id='.$v['vii_id']);
			}
		}
		LibFc::delFunLock(mvc::$URL_METHOD);
		echo 'ok';
	}


	//计算vin图库中1_12最小最大的VIN任务
	public function initVinMinMaxTask()
	{
		if(!LibFc::hasFunLock(mvc::$URL_METHOD, 3600)) return true;
		$smaMinCount = 30;//ocr 最低样本量
		$YpwVin = new YpwVin();
		$res = $YpwVin->get('stand_vin_imgs_task', ['vta_wmi'], ' and vta_js = 1');
		$wmiArr = array_column($res['data'], 'vta_wmi');

		$v8res = $YpwVin->get('stand_model_tj', ['smt_vin1_8'], " and (smt_vin1_8 like 'L%' OR smt_vin1_8 not like 'H%') group by smt_vin1_8");
		foreach($v8res['data'] as $v8v)
		{
			$vin8 = $v8v['smt_vin1_8'];
			$smares = $YpwVin->get('stand_model_any', ['sma_vin1_8 vin1_8, sma_vin10_12 vin10_12, MIN(sma_vin13_17) vin13_17_min, MAX(sma_vin13_17) vin13_17_max, count(*) vin_count'], sprintf(" and sma_vin1_8='%s' and vii_year >= 2010 GROUP BY sma_vin1_8, sma_vin10_12", $vin8));
			foreach($smares['data'] as $sv)
			{
				$comwhere = sprintf(" and vii_vin1_8='%s' and vii_vin10_12='%s'", $sv['vin1_8'], $sv['vin10_12']);
				//比现在最小值还小的图
				$vres = $YpwVin->get('stand_vin_imgs', ['vii_id, vii_vin, vii_status, vii_istask'], $comwhere.sprintf(" and vii_vin13_17 < '%s' order by vii_vin13_17 asc", $sv['vin13_17_min']));
				foreach($vres['data'] as $vmv)
				{
					//图片已处理或者已标记为待处理任务
					if($vmv['vii_status'] == 1 || ($vmv['vii_status'] == 0 && $vmv['vii_istask'] == 1)) break;
					$setArr = ['vii_istask'=>1];
					//重置状态
					if(in_array($vmv['vii_status'], [-2,-3,-5]))
					{
						$setArr['vii_status'] = 0;
						$setArr['vii_check_uid'] = 0;
						$setArr['vii_check_time'] = 0;
					} 
					$YpwVin->set('stand_vin_imgs', $setArr, sprintf(" and vii_vin='%s' and vii_status IN (0,-2,-3,-5)", $vmv['vii_vin'])); //存在多图
					break;
				}
				if(in_array(substr($sv['vin1_8'], 0, 3), $wmiArr) && in_array(substr($sv['vin1_8'], 0, 1), ['L', 'H']) && $sv['vin_count'] < $smaMinCount)
				{//ocr样本量不足，增加任务
					$maxTask = 1;
					$vres = $YpwVin->get('stand_vin_imgs', ['count(*) s0_count'], $comwhere.' and vii_status = 0 and vii_istask = 1', true);
					if($vres['data']['s0_count'] < $maxTask)
					{
						$taskCount = $maxTask - $vres['data']['s0_count'];
						$res = $YpwVin->get('stand_vin_imgs', ['vii_id'], $comwhere.' and vii_status != 1 and vii_istask = 0');
						if(!empty($res['data']))
						{
							$setArr = ['vii_istask'=>2, 'vii_status'=>0, 'vii_check_uid'=>0, 'vii_check_time'=>0];
							$YpwVin->set('stand_vin_imgs', $setArr, sprintf(" and vii_status IN (0,-2,-3,-5) and vii_id in (%s)", implode(',', array_column($res['data'], 'vii_id'))));
						}
					}
				}
			}
		}
		$sqlArr = [
			//重置任务
			"UPDATE stand_vin_imgs SET vii_smastatus='sma', vii_smatime=0, vii_smaerr='' WHERE vii_status IN (0,-2,-3,-5) AND vii_smastatus IN ('vin_count', 'vin_min', 'vin_max') AND vii_smatime < (UNIX_TIMESTAMP(NOW()) - 3600*24*3)",
			//将任务加入泽达任务
			//"INSERT INTO stand_catch_list (sce_reg_code, sce_vin, sce_level) SELECT 'ZDAPI', vii_vin, vii_year FROM stand_vin_imgs WHERE vii_status != 1 and vii_istask = 1 AND vii_year <= 2020 AND vii_vin NOT IN (SELECT sce_vin FROM stand_catch_list WHERE sce_reg_code = 'ZDAPI') GROUP BY vii_vin",
		];
		$YpwVin->exeAnySql($sqlArr, false);
		LibFc::delFunLock(mvc::$URL_METHOD);
		echo 'ok';
	}


	/**
	  * @method VIN图重新识别VIN 处理 stand_vin_imgs 不符合的删除
	  * @author soul
	  * @copyright 2022/1/21
	  * @return 
	  */
	public function reOcrVinAll()
	{
		if(date('H') <= 21 && date('H') >= 7 ) exit('高峰期禁止运行');
		set_time_limit(0);
		$Params = mvc::$URL_PARAMS;
		$MainOcr = new MainOcr();
		$YpwBase = new YpwBase();
		$LibHttp = new LibHttp();
		$table = "(SELECT vii_id, vii_vin, vii_status, vii_imghost, vii_img FROM stand_vin_imgs 
			WHERE vii_vinocr = '' AND vii_status = 0 order by vii_id desc LIMIT 1000
		) AS t";
		$viiRes = $YpwBase->get($table, ['*'], " ORDER BY RAND () LIMIT 300");
		foreach($viiRes['data'] as $v)
		{
			$v['vii_img'] = mvc::$cfg['urls']['vinimg_'.$v['vii_imghost']].$v['vii_img'];
			$image = $LibHttp->fetch($v['vii_img']);
			$imageData = base64_encode($image);
			$res = $MainOcr->vin($imageData, ['site'=>'yt', 'issmall'=>1]);
			if($res['status']){
				$newVin = LibFc::FormatVin($res['data']);
				$setVii = ['vii_vinocr'=>'yt'];
				if(strlen($newVin) == 17){
					$newVinYear = LibFc::VinYear($newVin);
					if($newVin != $v['vii_vin']) $setVii['vii_status'] = -1;
				}else{
					$setVii['vii_status'] = -1;
				}
				$YpwBase->set('stand_vin_imgs', $setVii, sprintf(' and vii_id=%d and vii_status < 1',$v['vii_id']));
			}
		}
		echo 'ok';
	}

	/**
	  * @method vin图是否为多型号
	  * @author soul
	  * @copyright 2022/5/12
	  * @return 
	  */
	public function chkVinAnyGxb()
	{
		/*/$YpwBase = new YpwBase();
		$YpcVin = new YpcVin();
		$per = 1000;
		$table = "(SELECT vii_id, vii_vin FROM stand_vin_imgs WHERE vii_id > 30357941 AND vii_id < 34838588 and vii_anygxb = 0 and vii_status IN (0,-3) AND (vii_vin LIKE 'L%' OR vii_vin LIKE 'H%') LIMIT ".($per*50).") AS t";
		$vires = $YpwBase->get($table, ['*'], " ORDER BY RAND () LIMIT ".$per);
		foreach($vires['data'] as $iv)
		{
			$res = $YpcVin->getAnyXinanglinVin($iv['vii_vin'], false);
			$gxbCount = count(array_unique(array_column($res['data'], 'sma_gxb_code')));
			$vii_anygxb = $gxbCount > 1? 1: -1;
			$YpwBase->set('stand_vin_imgs', ['vii_anygxb'=>$vii_anygxb],sprintf(' and vii_id=%d',$iv['vii_id']));
		}
		echo 'ok';*/
	}
	

	public function formatSmaNotSameGxbCode()
	{
		if(!LibFc::hasFunLock(mvc::$URL_METHOD, 3600)) return true;
		$YpwBase = new YpwBase();
		$wres = $YpwBase->get('stand_model_any', ['sma_gxb_code_show', 'GROUP_CONCAT(DISTINCT sma_gxb_code) gxbs'], " and sma_from = 'ocr' AND REPLACE(REPLACE(REPLACE(REPLACE(sma_gxb_code_show,'-', ''), '(', ''), ')', ''), '.', '') != sma_gxb_code group by sma_gxb_code_show");
		foreach($wres['data'] as $iv)
		{
			$set = [
				'sma_gxb_code'=>LibFc::FormatNum($iv['sma_gxb_code_show']),
				'sma_etime'=>time()
			];
			$set['sma_gtype'] = LibFc::getGxbCarType($set['sma_gxb_code']);
			foreach(explode(',', $iv['gxbs']) as $ogxb)
			{
				if($ogxb != $set['sma_gxb_code'])
				{
					$YpwBase->set('stand_model_any', $set, sprintf(" and sma_from = 'ocr' and sma_gxb_code = '%s' and sma_gxb_code_show='%s'", $ogxb, LibFc::Escape($iv['sma_gxb_code_show'])));
				}
			}
		}
		LibFc::delFunLock(mvc::$URL_METHOD);
		echo 'ok';
	}



	/**
	  * @method 从VIN图片内容匹配发动机功率
	  * @author soul
	  * @copyright 2022/1/21
	  * @return 
	  */
	public function engineKw()
	{
		set_time_limit(0);
		$Params = mvc::$URL_PARAMS;
		$YpwVin = new YpwVin();
		$YpwBase = new YpwBase();
		$OthVinImg = new OthVinImg();
		$OthVinImg->debug = true;
		$per = 20;
		$twhere = sprintf(" and ckw_from = 'ocr' and ckw_ed_kw = 0 and ckw_jgl_kw = 0 AND ckw_ocr_res != 'ok' AND ckw_etime<=%d", strtotime('-7 day'));
		//$twhere = " and ckw_gxb_format = 'BJ6400L3R4CNG'";
		$viitable = sprintf("(select * from stand_gxbengine_kw where 1 %s limit %d) as a", $twhere, $per*50);
		$kwres = $YpwBase->get($viitable, ['*'], sprintf(" order by rand() limit %d", $per));
		foreach($kwres['data'] as $v)
		{
			$matchres = $OthVinImg->engineKw($v['ckw_gxb_format'], $v['ckw_engine'], $v);
			$matchres = $matchres['data'];
			//var_dump($matchres);echo '<hr>';exit;
			$setArr = [
				'ckw_ed_kw'=>$matchres['ckw_ed_kw'],
				'ckw_jgl_kw'=>$matchres['ckw_jgl_kw'],
				'ckw_uid'=>8,
				'ckw_etime'=>time(),
				'ckw_from'=>'ocr',
				'ckw_ocr_res'=>$matchres['msg'],
				'ckw_match'=>json_encode($matchres['match']),
			];
			$YpwBase->set('stand_gxbengine_kw', $setArr, sprintf(" and ckw_from = 'ocr' and ckw_id=%d", $v['ckw_id']));
		}
		echo 'ok';
	}

	/**
	  * @method 计算需处理的多型号图
	  * @author soul
	  * @copyright 2022/9/8
	  * @return 
	  */
	public function jsTask()
	{
		if(!LibFc::hasFunLock(mvc::$URL_METHOD, 1000)) return true;
		$cacheBTime = time()-3600*24*7;
		$cacheFile = mvc::$cfg['LOGS'].'cache_jsTask.php';
		$YpwBase = new YpwBase();
		$taskres = $YpwBase->get('tj_sma_vin12 join yp_vin_year on left(sma_vin10_12, 1) = vin_10', ['sma_vin1_8, sma_vin10_12'], " and vin_year >= 2008 and left(sma_vin1_8, 3) in (select vta_wmi from stand_vin_imgs_task where vta_js = 1) group by sma_vin1_8, sma_vin10_12 having count(distinct sma_gxb_code) > 1 order by rand() limit 1000");
		foreach($taskres['data'] as $reg)
		{
			$where = sprintf(" and sma_vin1_8='%s' and sma_vin10_12='%s'", $reg['sma_vin1_8'], $reg['sma_vin10_12']);
			$jsRes = $YpwBase->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);
			foreach($jsRes['data'] as $rv)
			{
				$allJsVinArr = [];
				$unikey = $rv['sma_vin1_8'].'_'.$rv['vin10_12'];
				$cacheArr = file_exists($cacheFile)? include($cacheFile): [];
				if(!empty($cacheArr[$unikey]) && (time() - strtotime($cacheArr[$unikey])) > $cacheBTime) continue;
			
				$setSqlArr = [
					sprintf("update stand_vin_imgs set vii_anygxb = 0 where vii_status=0 and vii_vin1_8='%s' and vii_vin10_12='%s' and vii_anygxb=1", $rv['sma_vin1_8'], $rv['vin10_12'])
				];
				
				$comWhere = sprintf(" and sma_gxb_code !='' and sma_vin1_8='%s' and sma_vin10_12='%s'", $rv['sma_vin1_8'], $rv['vin10_12']);
				$res = $YpwBase->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 =  $YpwBase->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 =  $YpwBase->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)
					{
						$setSqlArr[] = sprintf("update stand_vin_imgs set vii_anygxb=1, vii_istask =1 where vii_status=0 and vii_vin1_8='%s' and vii_vin10_12='%s' and vii_vin13_17 > '%s' and vii_vin13_17 < '%s'", $rv['sma_vin1_8'], $rv['vin10_12'], $startArr['sma_vin13_17'], $nextArr['sma_vin13_17']);
					}
					//交换开始结束
					$startArr = $nextArr;
					$nextArr = [];
				}
				$YpwBase->exeAnySql($setSqlArr);
				$cacheArr = file_exists($cacheFile)? include($cacheFile): [];
				$cacheArr[$unikey] = date('Y-m-d H:i:s');
				LibFc::ArraySave($cacheArr, $cacheFile);
			}
		}
		LibFc::delFunLock(mvc::$URL_METHOD);
		echo 'ok';
	}
	
	//检测车架号错误的图片
	function chkErrVinImg()
	{
		if(date('H') > 8 || date('H') < 18) exit('not time');
		$MainOcr = new MainOcr();
		$LibHttp = new LibHttp();
		$table = "(
		SELECT vii_id, vii_status, vii_vin, vii_imghost, vii_img FROM stand_vin_imgs join stand_vin_imgs_revin on vii_id = vir_vii_id
		WHERE vii_status = 0 and vir_status = 0 LIMIT 10000
		) AS t";
		$YpwBase = new YpwBase();
		$viires = $YpwBase->get($table, ['*'], " ORDER BY RAND () LIMIT 100");
		foreach($viires['data'] as $v){
			$vin = $v['vii_vin'];
			$imgurl = mvc::$cfg['urls']['vinimg_'.$v['vii_imghost']].$v['vii_img'];
			$image = $LibHttp->fetch($imgurl);
			$imgdata = base64_encode($image);
			if(strlen($imgdata) < 1024) continue;
			$res = $MainOcr->vin($imgdata, ['site'=>'yt', 'nocoll'=>true]);
			if(!empty($res['data']) && $res['data'] != $vin){
				$YpwBase->set('stand_vin_imgs', ['vii_status'=>-1], sprintf(" and vii_id=%d and vii_status != 1", $v['vii_id']));
			}else if($res['data'] == $vin){
				$YpwBase->set('stand_vin_imgs', ['vii_vinocr'=>'yt'], sprintf(" and vii_id=%d", $v['vii_id']));
			}
			$YpwBase->del('stand_vin_imgs_revin', sprintf(" and vir_vii_id=%d", $v['vii_id']));
		}
		echo 'ok';
	}
	
	//同一个车架号只保留识别内容最长的图片
	function delVinAnyImg()
	{
		$YpwBase = new YpwBase();
		$res = $YpwBase->get('stand_vin_imgs', ['vii_vin1_3, vii_year'], " GROUP BY vii_vin1_3, vii_year");
		$vyearArr = $res['data'];
		shuffle($vyearArr);
		foreach($vyearArr as $v){
			$year = $v['vii_year'];
			$wmi = $v['vii_vin1_3'];
			$res = $YpwBase->get('stand_vin_imgs', ['vii_vin'], sprintf(" and vii_vin1_3='%s' and vii_year=%d GROUP BY vii_vin HAVING COUNT(*) > 1", $wmi, $year, $wmi, $year));
			$vinAnyArr = array_column($res['data'], 'vii_vin');
			foreach($vinAnyArr as $vin){
				$res = $YpwBase->get('stand_vin_imgs', ['vii_id', 'vii_status', 'length(vii_imgocr) strlen'], sprintf(" and vii_vin='%s' order by length(vii_imgocr) desc", $vin));
				$need = [];
				//优先取已经处理的
				foreach($res['data'] as $tk=>$tv){
					if($tv['vii_status'] == 1){
						$need = $tv;
						break;
					}
				}
				//留第一条
				if(!$need) $need = $res['data'][0];
				if($need['vii_id']) 
					$YpwBase->set('stand_vin_imgs', ['vii_status'=>-4], sprintf(" and vii_id !=%d and vii_vin='%s'", $need['vii_id'], $vin));
			}	
		}
		echo 'ok';
	}

	//处理历史
	function initOldWeight()
	{
		$per = 200;
		$YpwBase = new YpwBase();
		$OthVinImg = new OthVinImg();
		$YpwVinImg = new YpwVinImg();
		while(1){
			$table = "(
				SELECT vii_id, vii_vin, vii_imgocr, sma_gxb_code FROM zz_temp_weight
				JOIN `stand_vin_imgs` ON a = vii_id
				JOIN `stand_model_any` ON sma_vin = vii_vin 
				WHERE b = 0 AND sma_weight = 0 LIMIT ".($per*100).") t";
			$lres = $YpwBase->get($table, ['*'], "  ORDER BY RAND() LIMIT ".$per);
			foreach($lres['data'] as $v){
				if(strlen($v['vii_imgocr']) < 10){
					$res = $YpwVinImg->get('stand_vin_imgs', ['*'], sprintf(" and vii_id=%d", $v['vii_id']), true);
					$cfg = ['rotate'=>[0], 'timeout'=>10];
					$res = $YpwVinImg->ocrViiImg($res['data'], $cfg);
					if($res['data']['vii_imgocr']) $v['vii_imgocr'] = $res['data']['vii_imgocr'];
				}
				$res = $OthVinImg->matchAnyByVinGxbTxt($v['vii_vin'], $v['sma_gxb_code'], $v['vii_imgocr']);
				echo $v['vii_vin'].'=>'.$res['data']['sma_weight']."\n";
				$set = ['b'=>-1];
				if($res['data']['sma_weight']){
					$YpwBase->set('stand_model_any', ['sma_weight'=>$res['data']['sma_weight'], 'sma_etime'=>time()], sprintf(" and sma_vin='%s' and sma_weight=0", $v['vii_vin']));
					$YpwBase->set('zz_temp_weight', ['b'=>1, 'd'=>$res['data']['sma_weight']], sprintf(" and a=%d", $v['vii_id']));
				}else{
					$YpwBase->set('zz_temp_weight', ['b'=>-1], sprintf(" and a=%d", $v['vii_id']));
				}
			}
			if(count($lres['data']) < $per) break;
		}
		echo 'ok';
	}

	//ocr提取制造日期
	function matchVinDate()
	{
		if(!LibFc::hasFunLock(mvc::$URL_METHOD, 3600)) return true;
		$YpwVinImg = new YpwVinImg();
		$sqlArr = [
		"DELETE FROM `stand_vin_imgs_ocrdate` WHERE NOT EXISTS (SELECT 1 FROM stand_vin_imgs WHERE vii_id = vir_vii_id) AND vir_status = 0",	
		"INSERT INTO stand_vin_imgs_ocrdate (vir_vii_id) SELECT vii_id FROM stand_vin_imgs
		WHERE vii_imgtype = 2 AND vii_year >= 2005 AND LEFT(vii_vin,1) NOT IN ('L','H') AND NOT EXISTS (SELECT 1 FROM yp_allvin_base  WHERE alb_vin = vii_vin AND LEFT(alb_vin1_3,1) NOT IN ('L','H')) AND vii_id NOT IN (SELECT vir_vii_id FROM stand_vin_imgs_ocrdate)  AND LENGTH(vii_imgocr) > 30"
		];
		$YpwVinImg->exeAnySql($sqlArr);
		$whereArr = [
			" and vir_status = 0",	
			sprintf(" and vir_status = 1 and vir_etime < %d",strtotime("-7 days")),
		];
		$per = 1000;
		foreach($whereArr as $where){
			//$where = ' AND vii_vin="JTJZA11A4B2403338" ';
			while(1){
				$rewmiRes = $YpwVinImg->get('stand_vin_imgs_ocrdate join stand_vin_imgs on vir_vii_id = vii_id', ['vii_id, vii_vin, vii_imgocr, vii_year'], $where.' limit '.$per);
				foreach($rewmiRes['data'] as $v){
					$vin = $v['vii_vin'];
					$res = $YpwVinImg->ocrVinDate($v);
					$dArr = $res['data'];
					if($dArr['okdate']){
						$res = $YpwVinImg->get('yp_allvin_base', ['alb_date'], sprintf(" and alb_vin ='%s'", $vin));
						if(empty($res['data'])){
							$addDate = [
								'alb_vin'=>$vin,
								'alb_vin1_3'=>substr($vin, 0, 3),
								'alb_vin4_8'=>substr($vin, 3, 5),
								'alb_vin10_11'=>substr($vin, 9, 2),
								'alb_vin12'=>substr($vin, 11, 1),
								'alb_vin13_17'=>substr($vin, 12, 5),
								'alb_date'=>$dArr['okdate'],
								'alb_from'=>'ocr',
							];
							$YpwVinImg->add('yp_allvin_base', $addDate);
						}
						$set = ['vir_status'=>2, 'vir_date'=>$dArr['okdate'], 'vir_etime'=>time()];
						$YpwVinImg->set('stand_vin_imgs_ocrdate', $set, sprintf(" and vir_vii_id=%d", $v['vii_id']));
					}else if($dArr['matches']){
						$set = ['vir_status'=>1, 'vir_date'=>implode(',', $dArr['matches']), 'vir_etime'=>time()];
						$YpwVinImg->set('stand_vin_imgs_ocrdate', $set, sprintf(" and vir_vii_id=%d", $v['vii_id']));
					}else{
						$set = ['vir_status'=>-1, 'vir_date'=>'', 'vir_etime'=>time()];
						$YpwVinImg->set('stand_vin_imgs_ocrdate', $set, sprintf(" and vir_vii_id=%d", $v['vii_id']));
					}
					echo mvc::$URL_METHOD.':'.$vin.'=>'.$set['vir_date']."\n";
				}
				if(count($rewmiRes['data']) < $per) break;
			}
		}
		LibFc::delFunLock(mvc::$URL_METHOD);
		echo 'ok';
	}


	//ocr二次任务 vinImg/reTask?type=epccode vinImg/reTask?type=sma_weight vinImg/reTask?type=sma_passenger  vinImg/reTask?type=battery vinImg/reTask?type=errvin
	function reTask()
	{
		$Params = mvc::$URL_PARAMS;
		if(empty($Params['type'])) exit('?type=xxxx');
		$acttype = $Params['type'];
		if(!LibFc::hasFunLock(mvc::$URL_METHOD.$acttype, 600)) return true;
		$YpwVinImg = new YpwVinImg();
		$Ypc67Base = new BaseDb(mvc::$cfg['DB']['YPCAR67']);
		$YpwVin = new YpwVin();
		$YpcVin = new YpcVin();
		$LibHttp = new LibHttp();
		$OthVinImg = new OthVinImg();
		$now = time();
		$fillsmaFields = ['passenger'=>'sma_passenger', 'weight'=>'sma_weight'];
		if($acttype == 'epccode'){
			echo "加入任务列表\n";
			$v18CodesAll = [];
			$table = 'yp_model3 
			JOIN yp_model2 ON m3_m2_id = m2_id 
			JOIN yp_model1 ON m2_m1_id = m1_id
			JOIN yp_vin_model3_link ON vm3_m3_id = m3_id
			JOIN yp_vin ON vin_id = vm3_vin_id
			JOIN yp_model3_etk_code ON mec_m3_id = m3_id';
			$res = $Ypc67Base->get($table, ['vin_full v18, mec_code ecode'], " and vin_vin3 IN ('LFM','LVG') AND mec_code LIKE '%-%' GROUP BY vin_full, mec_code");
			foreach($res['data'] as $v){
				$v18CodesAll[$v['v18']][] = $v['ecode'];
			}

			$table = 'yp_model3 
			JOIN yp_model2 ON m3_m2_id = m2_id 
			JOIN yp_model1 ON m2_m1_id = m1_id
			JOIN yp_vin_model3_link ON vm3_m3_id = m3_id
			JOIN yp_vin ON vin_id = vm3_vin_id
			JOIN yp_model3_modcode ON mem_m3_id = m3_id';
			$res = $Ypc67Base->get($table, ['vin_full v18, mem_code ecode'], " and vin_vin3 IN ('LFM','LVG') AND mem_code LIKE '%-%' GROUP BY vin_full, mem_code");
			foreach($res['data'] as $v){
				$v['ecode'] = explode('@', $v['ecode']);
				if(!is_array($v18CodesAll[$v['v18']]) || !in_array($v['ecode'][0], $v18CodesAll[$v['v18']])) $v18CodesAll[$v['v18']][] = $v['ecode'][0];
			}

			$res = $YpwVinImg->get('stand_vin_epccode', ['left(vie_vin, 8) v18', 'vie_unicode ecode'], ' GROUP BY v18, ecode');
			foreach($res['data'] as $v){
				if(!is_array($v18CodesAll[$v['v18']]) || !in_array($v['ecode'], $v18CodesAll[$v['v18']])) $v18CodesAll[$v['v18']][] = $v['ecode'];
			}
			
			$ckey = 'reTask_'.$acttype.'_addtask';
			$res = $YpwVinImg->getKeyVal($ckey);
			if(empty($res['data']) || ($now - (int) $res['data']) > 3600){
				$sqlArr = [
					"DELETE FROM stand_vin_imgs_retask where vir_type='epccode' and NOT EXISTS (SELECT 1 FROM stand_vin_imgs WHERE vir_type='epccode' and vii_id = vir_vii_id AND vii_year >= 2020 AND vii_vin1_3 IN ('LFM','LVG')) AND vir_status = 0",
					"UPDATE stand_vin_imgs_retask JOIN stand_vin_epccode ON vir_vin = vie_vin SET vir_status = 2 WHERE vir_type='epccode' and vir_status != 2",
					"INSERT INTO stand_vin_imgs_retask (vir_type, vir_vii_id, vir_vin) SELECT 'epccode', vii_id, vii_vin FROM stand_vin_imgs
					WHERE vii_imgtype = 2 AND vii_year >= 2020 AND vii_vin1_3 IN ('LFM','LVG') AND vii_id NOT IN (SELECT vir_vii_id FROM stand_vin_imgs_retask where vir_type='epccode') AND vii_vin NOT IN (SELECT vie_vin FROM stand_vin_epccode)"
				];
				$YpwVinImg->exeAnySql($sqlArr);
				$YpwVinImg->setKeyVal($ckey, $now);
			}
		}else if(stripos($acttype, 'sma_') === 0){
			foreach($fillsmaFields as $gField=>$sField){
				if($sField != $acttype) continue;
				echo $gField."加入任务列表\n";
				//多值型号缓存
				$ckey = 'gxb_anycache_'.$gField;
				$res = $YpwVinImg->getKeyVal($ckey);
				if(empty($res['data']) || ($now - (int) $res['data']) > 3600*24){
					$sqlArr = [
						sprintf("DELETE FROM gxb_anycache where ga_type='%s'", $gField),
						sprintf("INSERT INTO gxb_anycache(ga_type, ga_gxb_code) SELECT '%s', gb_gxb_code FROM gxb_base JOIN gxb_params ON gb_id = gp_gb_id AND gp_gl_code='%s'
						WHERE gb_gtype != 1 GROUP BY gb_gxb_code HAVING COUNT(DISTINCT gp_value) > 1", $gField, $gField)
					];
					$YpwVinImg->exeAnySql($sqlArr);
					$YpwVinImg->setKeyVal($ckey, $now);
				}
				//加入任务
				$ckey = 'fill_'.$acttype;
				$run = 0;
				while(1){
					$res = $YpwVinImg->getKeyVal($ckey);
					if(empty($res['data'])){
						$lastTime = 0;
						$nextTime = 1546272000;
					}else{
						$lastTime = (int) $res['data'];
						$nextTime = $lastTime+3600*24*7;
					}
					if($nextTime > $now) $nextTime = $now;
					$sql = sprintf("INSERT INTO stand_vin_imgs_retask (vir_type, vir_vii_id, vir_vin) 
					SELECT '%s', vii_id, vii_vin FROM stand_model_any JOIN stand_vin_imgs ON sma_vin = vii_vin
					JOIN gxb_anycache ON sma_gxb_code = ga_gxb_code and ga_type='%s'
					WHERE %s = 0 and sma_etime>=%d and sma_etime <=%d AND NOT EXISTS (SELECT 1 FROM stand_vin_imgs_retask WHERE vir_vii_id = vii_id AND vir_type = '%s')", $acttype, $gField, $sField, $lastTime, $nextTime, $acttype);
					echo $sql."\n";
					$YpwVinImg->exeAnySql([$sql]);
					$YpwVinImg->setKeyVal($ckey, $nextTime);
					$run++;
					if($nextTime >= $now || $run > 10) break;
				}
			}
		}else if($acttype == 'battery'){
			$ckey = 'reTask_'.$acttype.'_addtask';
			$res = $YpwVinImg->getKeyVal($ckey);
			if(empty($res['data']) || ($now - (int) $res['data']) > 3600){
				$sqlArr = [
					"INSERT INTO stand_vin_imgs_retask (vir_type, vir_vii_id, vir_vin) 
					SELECT 'battery', vii_id, vii_vin FROM stand_vin_imgs
					WHERE vii_imgtype = 2 AND vii_imgocr LIKE '%容量%' AND vii_id NOT IN (SELECT vir_vii_id FROM stand_vin_imgs_retask WHERE vir_type='battery')"
				];
				$YpwVinImg->exeAnySql($sqlArr);
				$YpwVinImg->setKeyVal($ckey, $now);
			}
		}else if($acttype == 'errvin'){
			$ckey = 'reTask_'.$acttype.'_addtask';
			$res = $YpwVinImg->getKeyVal($ckey);
			if(empty($res['data']) || ($now - (int) $res['data']) > 3600){
				$sqlArr = [
					"INSERT INTO stand_vin_imgs_retask (vir_type, vir_vii_id, vir_vin) 
					SELECT 'errvin', vii_id, vii_vin FROM stand_vin_imgs
					WHERE vii_status = 0 AND vii_vin1_8 NOT IN (SELECT DISTINCT smt_vin1_8 FROM stand_model_tj) AND vii_id NOT IN (SELECT vir_vii_id FROM stand_vin_imgs_retask WHERE vir_type='errvin')"
				];
				$YpwVinImg->exeAnySql($sqlArr);
				$YpwVinImg->setKeyVal($ckey, $now);
			}
		}else{
			exit($acttype.'不存在');
		}

		$YpwVinImg->exeAnySql(["UPDATE stand_vin_imgs SET vii_ocrstatus=-1 WHERE vii_ocrstatus=0 AND vii_id IN (SELECT vir_vii_id FROM stand_vin_imgs_retask WHERE vir_status = 0 and vir_type='{$acttype}')"]);
		
		//运行任务
		if($acttype == 'errvin'){
			$whereArr = [
				sprintf(" and vir_type='%s' and vir_status = 0", $acttype)
			];
		}else{
			$whereArr = [
				sprintf(" and vir_type='%s' and vii_ocrstatus > 0 AND LENGTH(vii_imgocr) > 2 and vir_status = 0", $acttype),	
				sprintf(" and vir_type='%s' and vii_ocrstatus > 0 AND LENGTH(vii_imgocr) > 2 and vir_status = 1 and vir_etime < %d", $acttype, strtotime("-7 days"))
			];
		}
		$per = 10000;
		foreach($whereArr as $where){
			echo $where."\n";
			while(1){
				if($acttype == 'epccode'){
					$rewmiRes = $YpwVinImg->get('stand_vin_imgs_retask t join stand_vin_imgs on vir_vii_id = vii_id', ['vir_id, vii_id, vii_vin, vii_imghost, vii_img, vii_imgocr, vir_reocr, vii_year'], $where.' order by vii_id desc limit '.$per);
				}else if(stripos($acttype, 'sma_') === 0){
					$rewmiRes = $YpwVinImg->get('stand_vin_imgs_retask t join stand_vin_imgs on vir_vii_id = vii_id JOIN stand_model_any sma on sma_vin = vii_vin', ['vir_id, vii_id, vii_vin, vii_imghost, vii_img, vii_imgocr, vir_reocr, vii_year, sma.*'], $where.' limit '.$per);
				}else if($acttype == 'battery'){
					$rewmiRes = $YpwVinImg->get('stand_vin_imgs_retask t join stand_vin_imgs on vir_vii_id = vii_id', ['vir_id, vii_vin, vii_imgocr'], $where.' limit '.$per);
				}else if($acttype == 'errvin'){
					$rewmiRes = $YpwVinImg->get('stand_vin_imgs_retask t join stand_vin_imgs on vir_vii_id = vii_id', ['vir_id, vii_vin, vii_id'], $where.' limit '.$per);
				}
				foreach($rewmiRes['data'] as $v){
					$vin = $v['vii_vin'];
					$v18 = substr($vin, 0, 8);
					$set = [];
					if($acttype == 'epccode'){
						//丰田提取EPC原厂代码
						$epcCodes = isset($v18CodesAll[$v18])? $v18CodesAll[$v18]: [];
						$res = $YpwVinImg->ocrVinEpcCode($v, $epcCodes);
						
						$dArr = $res['data'];
						if(!$dArr['ok']){
							if(empty($v['vir_reocr'])){
								$imgurl = mvc::$cfg['urls']['vinimg_'.$v['vii_imghost']].$v['vii_img'];
								$res = $YpwVinImg->reocrByUrl($imgurl);
								$ocrtxt = $res['data'];
								$set['vir_reocr'] = $ocrtxt;
								$tv = $v; $tv['vii_imgocr'] = $ocrtxt;
								$res = $YpwVinImg->ocrVinEpcCode($tv, $epcCodes);
								if($res['data']['ok'] || $res['data']['matches']) $dArr = $res['data'];
							}else{
								$tv = $v; $tv['vii_imgocr'] = $tv['vir_reocr'];
								$res = $YpwVinImg->ocrVinEpcCode($tv, $epcCodes);
								if($res['data']['ok'] || $res['data']['matches']) $dArr = $res['data'];
							}
						}
						
						if($dArr['ok']){//匹配正确，入库
							$set['vir_status'] = 2;
							$set['vir_data'] = ['unicode'=>$dArr['ok']];
							$res = $YpwVinImg->get('stand_vin_epccode', ['vie_vin'], sprintf(" and vie_vin = '%s'", $vin), true);
							if(empty($res['data'])){
								$add = [
									'vie_vin'=>$vin,
									'vie_unicode'=>$dArr['ok'],
									'vie_from'=>'ocr',
									'vie_etime'=>time()
								];
								$YpwVinImg->add('stand_vin_epccode', $add);
							}
						}else if($v['matches']){
							$set['vir_status'] = 1;
							$set['vir_data'] = ['unicode'=>$dArr['matches']];
						}else{
							$set['vir_status'] = -1;
							$set['vir_data'] = [];
						}
						
					}else if(stripos($acttype, 'sma_') === 0){
						//整备质量 座位数...
						$res = $OthVinImg->matchAnyByVinGxbTxt($vin, $v['sma_gxb_code'], $v['vii_imgocr'], [$acttype]);
						$dArr = $res['data'];
						if($dArr[$acttype]){
							$smaSet = [$acttype=>$dArr[$acttype]];
							$set['vir_status'] = 2;
							$set['vir_data'] = $dArr;
							$YpwVinImg->set('stand_model_any', $smaSet, sprintf(" and sma_vin='%s'", $vin));
						}else{
							$set['vir_status'] = -1;
							$set['vir_data'] = [];
						}
					}else if($acttype == 'battery'){
						$res = $OthVinImg->matchBatteryByTxt($v['vii_imgocr']);
						$dArr = $res['data'];
						if($dArr){
							$set['vir_status'] = 2;
							$set['vir_data'] = $dArr;
						}else{
							$set['vir_status'] = -1;
							$set['vir_data'] = [];
						}
					}else if($acttype == 'errvin'){
						$res = $YpwVin->getRealVin($v['vii_vin']);
						$dArr = $res['data'];
						if($dArr['newvin']){
							$rvin = $dArr['newvin'];
							$csetArr = [
								'vii_status'=>0,
								'vii_vin'=>$rvin,
								'vii_vin1_3'=>substr($rvin, 0, 3),
								'vii_vin1_8'=>substr($rvin, 0, 8),
								'vii_vin10_12'=>substr($rvin, 9, 3),
								'vii_vin13_17'=>substr($rvin, 12, 5),
								'vii_year'=>LibFc::VinYear(substr($rvin, 9, 1)),	
							];
							$YpwVin->set('stand_vin_imgs', $csetArr, sprintf(" and vii_id=%d and vii_status != 1", $v['vii_id']));
							$set['vir_status'] = 2;
							$set['vir_data'] = $dArr;
						}else{
							$set['vir_status'] = -1;
							$set['vir_data'] = [];
						}
					}
					if($set){
						echo mvc::$URL_METHOD.'_'.$acttype.':'.$vin.'=>'.$set['vir_status']."\n";
						if(isset($set['vir_data']) && is_array($set['vir_data'])) $set['vir_data'] = json_encode($set['vir_data'], JSON_UNESCAPED_UNICODE);
						$set['vir_etime'] = time();
						$YpwVinImg->set('stand_vin_imgs_retask', $set, sprintf(" and vir_id=%d", $v['vir_id']));
					}
				}
				if(count($rewmiRes['data']) < $per){
					break;
				}
			}
		}
		LibFc::delFunLock(mvc::$URL_METHOD.$acttype);
		echo 'ok';
	}
	

	//初始化型号与电池的规则
	function initGxbBatteryReg()
	{
		if(!LibFc::hasFunLock(mvc::$URL_METHOD.$acttype, 3600)) return true;
		$YpwVin = new YpwVin();
		$LibYpApi = new LibYpApi();
		
		//把所有涉及的型号入任务库 (JSON_UNQUOTE(vir_data->'$.capacity') IS NOT NULL OR JSON_UNQUOTE(vir_data->'$.voltage') IS NOT NULL) AND 
		$sqlArr = [
			"DELETE FROM stand_gxb_battery WHERE (sgby_vin1_8, sgby_gxb_code, sgby_engine) NOT IN (
			SELECT sma_vin1_8, sma_gxb_code, sma_engine FROM stand_vin_imgs_retask t 
			JOIN stand_vin_imgs ON vir_vii_id = vii_id AND vir_status = 2 AND vir_type = 'battery'
			JOIN stand_model_any sma ON sma_vin = vii_vin
			GROUP BY sma_vin1_8, sma_gxb_code, sma_engine)",
			"UPDATE stand_gxb_battery JOIN (
			SELECT sma_vin1_8, sma_gxb_code, sma_engine, COUNT(*) vin_count FROM stand_vin_imgs_retask t 
			JOIN stand_vin_imgs ON vir_vii_id = vii_id AND vir_status = 2 AND vir_type = 'battery'
			JOIN stand_model_any sma ON sma_vin = vii_vin
			GROUP BY sma_vin1_8, sma_gxb_code, sma_engine
			) t ON sgby_vin1_8 = sma_vin1_8 AND sgby_gxb_code = sma_gxb_code AND sma_engine = sgby_engine
			SET sgby_vin_count = vin_count",
			"INSERT INTO `stand_gxb_battery`(sgby_vin1_8, sgby_gxb_code, sgby_gxb_code_show, sgby_engine, sgby_vin, sgby_vin_count, sgby_uid, sgby_etime)
			SELECT sma_vin1_8, sma_gxb_code, max(sma_gxb_code_show), sma_engine, sma_vin, count(*), 8, ".time()." FROM stand_vin_imgs_retask t 
			JOIN stand_vin_imgs ON vir_vii_id = vii_id AND vir_status = 2 AND vir_type = 'battery'
			JOIN stand_model_any sma ON sma_vin = vii_vin
			WHERE sma_gxb_code != '' and sma_engine != '' and (sma_vin1_8, sma_gxb_code, sma_engine) NOT IN (SELECT sgby_vin1_8, sgby_gxb_code, sgby_engine FROM stand_gxb_battery)
			GROUP BY sma_vin1_8, sma_gxb_code, sma_engine"];
		$YpwVin->exeAnySql($sqlArr);

		$YpwVin->set('stand_gxb_battery', ['sgbt_status'=>0], " and sgbt_status = 1 and sgby_uid in (0,8) and (sgby_engine_b = '' or sgby_capacity = 0 or sgby_voltage = 0)");

		//逐个型号初始化
		$where = sprintf(" and sgbt_status = 0 and sgby_uid in (0, 8) group by sgby_vin1_8, sgby_gxb_code, sgby_engine");
		//$where = sprintf(" and sgby_gxb_code = 'AHC6450BEVD1G' group by sgby_vin1_8, sgby_gxb_code, sgby_engine");
		$sres = $YpwVin->get('stand_gxb_battery', ['sgby_vin1_8, sgby_gxb_code, sgby_gxb_code_show, sgby_engine, sgby_vin_count, count(*) reg_count'], $where);
		foreach($sres['data'] as $v){
			//确认容量和电压  vir_status = 2 AND
			$comwhere = sprintf(" and sma_vin1_8='%s' AND sma_gxb_code='%s' AND sma_engine='%s'", $v['sgby_vin1_8'], $v['sgby_gxb_code'], $v['sgby_engine']);
			$table = "stand_vin_imgs_retask
			JOIN stand_vin_imgs ON vir_vii_id = vii_id AND vir_type = 'battery'
			JOIN stand_model_any sma ON sma_vin = vii_vin";
			$res = $YpwVin->get($table, ["JSON_UNQUOTE(vir_data->'$.capacity') capacity, JSON_UNQUOTE(vir_data->'$.voltage') voltage, COUNT(*) vin_count, sma_vin"], $comwhere." AND JSON_UNQUOTE(vir_data->'$.capacity') IS NOT NULL AND JSON_UNQUOTE(vir_data->'$.voltage') IS NOT NULL GROUP BY capacity, voltage HAVING COUNT(*) > 10 ORDER BY COUNT(*) DESC");
			if(empty($res['data'])) continue;
			$total = [];
			$top = [];
			foreach($res['data'] as $kk=>$vv){
				//仅保留数字
				$vv['onlynum'] = strtr($vv['capacity'].'@'.$vv['voltage'], ['.'=>'']);
				$total[$vv['onlynum']] += $vv['vin_count']; 
				$total['all'] += $vv['vin_count'];
				if($kk == 0) $top = $vv;
			}
			$top['numcount'] = $total[$top['onlynum']];
			$top['rate'] = $total[$top['onlynum']] / $total['all'];
			if(	   ($top['numcount'] >= 30 && $top['numcount'] < 50 &&  $top['rate'] >= 0.98) 
				|| ($top['numcount'] >= 50 && $top['numcount'] < 100 &&  $top['rate'] >= 0.95) 
				|| ($top['numcount'] >= 100 && $top['numcount'] < 150 &&  $top['rate'] >= 0.9) 
				|| ($top['numcount'] >= 150 && $top['numcount'] < 300 &&  $top['rate'] >= 0.85) 
				|| ($top['numcount'] >= 300 && $top['numcount'] < 1000 &&  $top['rate'] >= 0.8) 
				|| ($top['numcount'] >= 1000 &&  $top['rate'] > 0.7)
			){
				$res = $YpwVin->get('stand_gxb_battery', ['*'], sprintf(" and sgby_vin1_8='%s' AND sgby_gxb_code='%s' AND sgby_engine='%s' and ((sgby_capacity=0 and sgby_voltage=0) or (sgby_capacity='%s' and sgby_voltage='%s'))", $v['sgby_vin1_8'], $v['sgby_gxb_code'], $v['sgby_engine'], $top['capacity'], $top['voltage']), true);
				$oldArr = $res['data']? $res['data']: [];
				$set = [];
				if(!$oldArr || $oldArr['sgby_capacity'] != $top['capacity']){
					$set = [
						'sgby_capacity'=>$top['capacity'],	
						'sgby_voltage'=>$top['voltage'],	
						'sgby_vin'=>$top['sma_vin']
					];
				}

				if(!$oldArr || empty($oldArr['sgby_engine_b'])){
					//尝试通过清单找驱动电机
					$h = date('H');
					if($h >= 7 && $h < 20){
						$twhere = $comwhere.sprintf(" AND JSON_UNQUOTE(vir_data->'$.capacity')='%s' AND JSON_UNQUOTE(vir_data->'$.voltage') = '%s' AND LENGTH(sma_engine6) > 5 order by rand() LIMIT 50", $set['sgby_capacity'], $set['sgby_voltage']);
						$res = $YpwVin->get($table, ["sma_vin vin", "sma_engine6 engine6"], $twhere);
						foreach($res['data'] as $vvv){
							$txtRes = $LibYpApi->Get('vin/catchVinQingdan', $vvv, [], true);
							if($txtRes['status'] && is_array($txtRes['data'])){
								if($txtRes['data']['engine_b']){
									$set['sgby_vin'] = $vvv['vin'];
									$set['sgby_engine_b'] = $txtRes['data']['engine_b'];
								}
								break;
							}
						}
					}
					if(empty($set['sgby_engine_b'])){
						$twhere = $comwhere.sprintf(" AND JSON_UNQUOTE(vir_data->'$.capacity')='%s' AND JSON_UNQUOTE(vir_data->'$.voltage') = '%s' AND JSON_UNQUOTE(vir_data->'$.engine_b') IS NOT NULL GROUP BY engine_b HAVING COUNT(*) > 10 ORDER BY COUNT(*) DESC", $set['sgby_capacity'], $set['sgby_voltage']);
						$res = $YpwVin->get($table, ["JSON_UNQUOTE(vir_data->'$.engine_b') engine_b, COUNT(*) vin_count"], $twhere);
						$totaleb = 0;
						$topeb = $res['data'][0];
						foreach($res['data'] as $kk=>$vv){
							$totaleb += $vv['vin_count'];
						}
						if(($topeb['vin_count'] > 50 && $topeb['vin_count']/$totaleb >= 0.95) || ($topeb['vin_count'] > 100 && $topeb['vin_count']/$totaleb > 0.75)){
							$set['sgby_engine_b'] = $topeb['engine_b'];
						}
					}
				}
				if($set){
					$set['sgby_uid'] = 8;
					$set['sgby_etime'] = time();
					if($set['sgby_engine_b'] && $set['sgby_capacity'] && $set['sgby_voltage']) $set['sgbt_status'] = 1;
					if($oldArr['sgby_id']){
						$YpwVin->set('stand_gxb_battery', $set, sprintf(' and sgby_id=%d', $oldArr['sgby_id']));
					}else{
						/*$set['sgby_vin1_8'] = $v['sgby_vin1_8'];
						$set['sgby_gxb_code'] = $v['sgby_gxb_code'];
						$set['sgby_gxb_code_show'] = $v['sgby_gxb_code_show'];
						$set['sgby_engine'] = $v['sgby_engine'];
						$set['sgby_vin_count'] = $v['sgby_vin_count'];
						$YpwVin->add('stand_gxb_battery', $set);*/
					}
					echo $v['sgby_vin1_8'].'=>'.$v['sgby_gxb_code'].'=>'.$v['sgby_engine']."=>set\n";
				}else{
					echo $v['sgby_vin1_8'].'=>'.$v['sgby_gxb_code'].'=>'.$v['sgby_engine']."=>noset\n";
				}
			}
		}
		
		//单个高概率
		foreach(['sgby_capacity'=>'capacity', 'sgby_voltage'=>'voltage', 'sgby_engine_b'=>'engine_b'] as $kf=>$kv){
			$where = sprintf(" and %s = ''", $kf);
			//$where .= " and sgby_gxb_code='FZ6470BEVC10N'";
			$sres = $YpwVin->get('stand_gxb_battery', ['sgby_id, sgby_vin1_8, sgby_gxb_code, sgby_engine'], $where);
			foreach($sres['data'] as $v){
				$comwhere = sprintf(" and sma_vin1_8='%s' AND sma_gxb_code='%s' AND sma_engine='%s'", $v['sgby_vin1_8'], $v['sgby_gxb_code'], $v['sgby_engine']);
				$table = "stand_vin_imgs_retask
				JOIN stand_vin_imgs ON vir_vii_id = vii_id AND vir_type = 'battery'
				JOIN stand_model_any sma ON sma_vin = vii_vin";
				$res = $YpwVin->get($table, ["JSON_UNQUOTE(vir_data->'$.".$kv."') val, COUNT(*) vin_count"], $comwhere." AND JSON_UNQUOTE(vir_data->'$.".$kv."') IS NOT NULL GROUP BY val HAVING COUNT(*) > 2 ORDER BY COUNT(*) DESC");
				if(empty($res['data'])) continue;
				$total = [];
				$top = [];
				foreach($res['data'] as $kk=>$vv){
					$vv['onlynum'] = in_array($kv, ['capacity', 'voltage']) ? strtr($vv['val'], ['.'=>'']): $vv['val'];
					$total[$vv['onlynum']] += $vv['vin_count']; 
					$total['all'] += $vv['vin_count'];
					if($kk == 0) $top = $vv;
				}
				$top['numcount'] = $total[$top['onlynum']];
				$top['rate'] = $total[$top['onlynum']] / $total['all'];
				if(($top['numcount'] >= 30 && $top['numcount'] < 50 &&  $top['rate'] >= 0.98) || ($top['numcount'] >= 50 &&  $top['rate'] >= 0.95) || ($top['numcount'] >= 100 &&  $top['rate'] >= 0.9)){
					$YpwVin->set('stand_gxb_battery', [$kf=>$top['val']], sprintf(' and sgby_id=%d', $v['sgby_id']));
				}
			}
		}

		$YpwVin->set('stand_gxb_battery', ['sgbt_status'=>1], " and sgbt_status = 0 and sgby_engine_b != '' and sgby_capacity != 0 and sgby_voltage != 0");
		LibFc::delFunLock(mvc::$URL_METHOD.$acttype);
		echo 'ok';
	}

	//OCR型号识别错误位的统计
	public function buildOcrErrReg()
	{
		$Params = mvc::$URL_PARAMS;
		$YpwVin = new YpwVin();
		//仅记录无的缓存
		$cacheFile = mvc::$cfg['LOGS'].'cache_buildOcrErrReg.php';
		$cacheArr = file_exists($cacheFile)? include($cacheFile): [];
		$cachetime = 3600*24*7;
		if($Params['gxb']){
			$where = sprintf(" and length(smt_gxb_code) >= 5 and smt_gxb_code ='%s' group by smt_gxb_code", LibFc::FormatNum($Params['gxb']));
		}else{
			//AND EXISTS ( SELECT 1 FROM gxb_base WHERE gb_gxb_code = smt_gxb_code)
			$where = sprintf(" and length(smt_gxb_code) >= 5 AND NOT EXISTS (SELECT 1 FROM stand_gxb_ocrerrbit WHERE sge_gxb_code = smt_gxb_code AND sge_etime > %d) group by smt_gxb_code", time() - $cachetime);
		}
		$res = $YpwVin->get('stand_model_tj', ['smt_gxb_code, smt_gxb_code_show'], $where);
		$gxbArr = array_column($res['data'], 'smt_gxb_code_show', 'smt_gxb_code');
		unset($res);
		$i = 0;
		foreach($gxbArr as $gxb=>$sgxb){
			$i++;
			if(preg_match('/^[0-9]+CC$/', $gxb)) continue; //历史无用数据 型号为排量 2987CC 2199CC
			if($cacheArr[$gxb] && (time() - $cacheArr[$gxb]) > $cachetime) continue;
			$cacheArr[$gxb] = time();
			$regMatch = [];
			$len = strlen($sgxb);
			$gxbchars = 'A-Za-z0-9';
			if(stripos($sgxb, ' ')) $gxbchars .= ' ';
			if(stripos($sgxb, '-')) $gxbchars .= '\\-';
			if(stripos($sgxb, '.')) $gxbchars .= '\.';
			
			$where = sprintf(" and sma_gxb_code='%s' and vii_imgocr NOT LIKE '%%%s%%' and vii_imgocr REGEXP '(^|[^A-Za-z0-9])[A-Za-z0-9]{2}[%s]{%d}([^A-Za-z0-9]|$)'", $gxb, $gxb, $gxbchars, $len-2);
			if($gxb != $sgxb) $where .= sprintf(" and vii_imgocr NOT LIKE '%%%s%%'", $sgxb);
			$vres = $YpwVin->get('stand_vin_imgs JOIN stand_model_any ON sma_vin=vii_vin', ['vii_vin, vii_imgocr'], $where);
			if(empty($vres['data'])){
				LibFc::ArraySave($cacheArr, $cacheFile);
				continue;
			}
			
			// 开始比较
			$mreg = '/(?:^|[^A-Za-z0-9])([A-Za-z0-9]{2}['.$gxbchars.']{'.($len-2).'})(?:[^A-Za-z0-9]|$)/is';
			foreach($vres['data'] as $tv){
				if(preg_match_all($mreg, $tv['vii_imgocr'], $matches)){
					foreach($matches[1] as $tgxb){
						$tgxb = strtoupper($tgxb);
						$diff = LibFc::diffByPos(strtoupper($sgxb), $tgxb);
						//超过两个不一样的跳过
						if(count($diff) > 2) continue;
						//识别的型号是否在库里
						$res = $YpwVin->get('stand_model_tj', ['smt_gxb_code'], sprintf(" and smt_gxb_code ='%s' limit 1", LibFc::FormatNum($tgxb)), true);
						if($res['data']) continue;
						foreach($diff as $dk=>$dv){
							$dkey = $dk.':'.$dv['a'].':'.$dv['b'];
							if(empty($regMatch['diff'][$dkey])){
								$regMatch['diff'][$dkey] = ['count'=>1, 'vin'=>$tv['vii_vin']];
							}else{
								$regMatch['diff'][$dkey]['count']++;
							}
						}
						break;
					}
				}
			}
			if(empty($regMatch['diff'])){
				$YpwVin->del('stand_gxb_ocrerrbit', sprintf(" and sge_gxb_code='%s'", $gxb));
			}else{
				//倒序
				uasort($regMatch['diff'], function ($a, $b) {
					return $b['count'] <=> $a['count'];
				});
				$reBits = [];
				foreach($regMatch['diff'] as $dkey=>$rv){
					$tvals = explode(':', $dkey);
					if(empty($reBits[$tvals[0]])){
						$reBits[$tvals[0]] = [$tvals[0], $tvals[1], $tvals[2]];
					}else{
						$reBits[$tvals[0]][2] .= $tvals[2];
					}
				}
				$reBits = array_values($reBits);
				$add = [
					'sge_gxb_code'=>$gxb,	
					'sge_rebits'=>json_encode($reBits),	//注意数字键
					'sge_tj'=>json_encode($regMatch['diff']),	
					'sge_etime'=>time()	
				];
				$YpwVin->replace('stand_gxb_ocrerrbit', $add);
			}
			echo $i.'=>'.$gxb.'=>'.$add['sge_rebits']."\n";
		}
		echo 'ok';
	}

	public function initClsTrain()
	{
		$YpwVin = new YpwVin();
		$tjres = $YpwVin->get('stand_vin_imgs', ['vii_vin1_3, vii_year, COUNT(*) vin_cout'], " and vii_imgtype in (0,1,2) GROUP BY vii_vin1_3, vii_year HAVING COUNT(*) > 200 ORDER BY vin_cout DESC");
		$file = mvc::$cfg['LOGS'].'vincls_train_data.txt';
		@unlink($file);
		$handle = fopen($file, 'a');
		$clsArr = ['0'=>'oth','1'=>'xsz','2'=>'mp'];
		foreach($tjres['data'] as $v){
			$count = $v['vin_cout'];
			if($count > 100000){
				$count = ceil($count*0.01);
			}else if($count > 50000){
				$count = ceil($count*0.02);
			}else if($count > 10000){
				$count = ceil($count*0.03);
			}else if($count > 1000){
				$count = ceil($count*0.1);
			}else if($count > 1000){
				$count = ceil($count*0.15);
			}else{
				$count = ceil($count*0.2);
			}
			$msg = '';
			$res = $YpwVin->get('stand_vin_imgs', ['vii_imghost, vii_img, vii_imgtype'], sprintf(" and vii_vin1_3='%s' and vii_year=%d and vii_imgtype in (0,1,2) order by rand() limit %d", $v['vii_vin1_3'], $v['vii_year'], $count));
			foreach($res['data'] as $vv){
				$imgurl = mvc::$cfg['urls']['vinimg_'.$vv['vii_imghost']].$vv['vii_img'];
				//$msg .= $imgurl.'  '.$clsArr[$vv['vii_imgtype']]."\n";
				$msg .= $imgurl."\n";
			}
			fwrite($handle, $msg);
		}
		fclose($handle);
		echo 'ok';
	}
}