<?php
/**
  * @method 智配产品操作
  * @author soul
  * @copyright 2016/3/31
  */
class B2cZhipei extends B2cBase
{
	public $ZpBase = null;
	public $YpcBase=null;
	public $mod2JsonCache = [];

	public function __construct()
	{
		parent::__construct();
		$this->ZpBase = new BaseDb(mvc::$cfg['DB']['ZHIPEIC']);
		$this->YpcBase = new YpcBase();
	}


	//比较参数匹配值
	private function comparePara($arr, $proPara, $filedname)
	{
		//通过名称比较数据
		foreach($arr as $k=>$v)
		{
			foreach(explode(',', $v[$filedname]) as $tname)
			{
				$unistr = strtoupper($tname);
				if(!empty($proPara[$unistr]))
				{
					$v['val'] = implode(',', $proPara[$unistr]);
					unset($proPara[$unistr]);
					break;
				}
			}
			if(!empty($v['val']))
			{
				$arr[$k] = $v;
			}
			else
			{
				unset($arr[$k]);
			}
		}
		return ['match'=>$arr, 'not'=>$proPara];
	}

	/**
	 * @method  从智配数据更新到跑街
	 * @param $shopId int 商家店铺ID
	 * @param $zpShop string 智配用户名
	 * @param $zpActArr array 操作   ['item', 'addmodel', 'resetmodel']
	 * @author	soul
	 * @copyright 2020/5/21
	 */
	public function importZhipeiItem($shopId, $zpShop, $zpActArr = [])
	{
		set_time_limit(0);
		ini_set('memory_limit', '2048M');
		$zpShop = LibFc::Escape($zpShop);
		$shopId = (int) $shopId;
		if($shopId  < 1) return LibFc::ReturnData(false, '店铺不存在！');
		if(empty($zpShop) || !is_array($zpActArr)) return LibFc::ReturnData(false, 'importZhipeiItem 参数不正确！');
		$logfile = mvc::$cfg['PATH_CACHE'].'ZHIPEI_'.date('Y-m-d').'.log';
			
		//检查店铺是否存在
		$res = $this->get('sh_shop', ['shop_status'], sprintf(" and shop_id=%d", $shopId), true);
		if(empty($res['data'])) return LibFc::ReturnData(false, '店铺不存在');

		$res = $this->ZpBase->get('auto_product', ['pro_user'], sprintf(" and pro_user = '%s'", $zpShop), true);
		if(empty($res['data'])) return LibFc::ReturnData(false,  $zpShop.'无产品数据！');
	
		$B2cBrand = new B2cBrand();
		$B2cProduct = new B2cProduct();
		$B2cShopSort = new B2cShopSort();

		$errorArr = [];
		//检测数据

		$needSetPidArr = [];
		foreach($zpActArr as $zpAct=>$zpActVal)
		{
			if(empty($zpActVal)) continue;
			switch($zpAct)
			{
				//产品更新
				case 'item':
					$res = $this->ZpBase->get('auto_product', ['*'], sprintf(" and pro_user = '%s' order by pro_id", $zpShop));
					$zpItemArr = array_column($res['data'], null, 'pro_id');
					if(empty($zpItemArr)) return LibFc::ReturnData(false,  '产品数量为空，更新失败');
					$impProArr = [];

					//打星的号码
					$xnumIdArr = [];

					//配件品牌
					$res = $B2cBrand->addShopBrand($shopId, $zpShop);
					$prb_id = (int) $res['data'];

					//产品名称对应的零件关系
					$proNameToPart = [];
					foreach(array_unique(array_column($zpItemArr, 'pro_name')) as $proName)
					{
						$proName = trim($proName);
						if($proName == '') continue;
						$res = $B2cProduct->checkPart($proName,true);
						$proNameToPart[strtoupper($proName)] = $res['data'];
					}

					//默认运费模板
					$res = $this->get('sh_freight_tpl',['frt_id'],sprintf(" and frt_shop_id=%d order by frt_default desc", $shopId), true);
					$frt_id = (int) $res['data']['frt_id'];

					//零件对应的参数
					$partParam = [];
					$res = $this->get('bc_part_param_link JOIN bc_param_label ON pal_id = ppl_pal_id', ['ppl_part_id as part_id, pal_id, pal_name, ppl_toname_zhipei as ppl_toname'], sprintf(" and ppl_part_id in (%s)", implode(',', array_unique(array_column($proNameToPart, 'part')))));
					foreach($res['data'] as $tv)
					{
						$partParam[$tv['part_id']][$tv['pal_id']] = $tv;
					}

					foreach($zpItemArr as $zpid=>$zpro)
					{
						$numseq = 0;
						$tempArr = [];
						$zpro['pro_oems'] = json_decode($zpro['pro_oems'], true);
						$zpro['pro_image'] = json_decode($zpro['pro_image'], true);
						$zpro['pro_param'] = json_decode($zpro['pro_param'], true);
						
						$tempArr['base']['pro_dfrom'] = 'ZHIPEI';
						$tempArr['base']['pro_dfrom_id'] = $zpid;
						$tempArr['base']['pro_prb_id'] = $prb_id;
						$tempArr['base']['pro_name'] = $zpro['pro_name'];
						//自编号
						$tempArr['info']['pri_code'] = $zpro['pro_format'];
						
						//通过名称确定分类
						if(!empty($proNameToPart[strtoupper(trim($zpro['pro_name']))])) 
						{
							$temp = $proNameToPart[strtoupper(trim($zpro['pro_name']))];
							$tempArr['base']['pro_part_id'] = $temp['part'];
							$tempArr['base']['pro_pas_id'] = $temp['pas_id'];
							$tempArr['base']['pro_part_path'] = $temp['part_path'];
							$tempArr['part_name'] = $temp['part_name'];
						}
						else
						{
							$errorArr[] = json_encode($zpro).'分类无法确定';
							continue;
						}
						
						//处理号码
						if(!empty($zpActArr['num']))
						{
							//其他OE
							$othnums = $zpro['pro_alias'].','.$zpro['pro_unmanaged'];
							$othnums = strtr($othnums, ['；'=>',',';'=>',', '，'=>',']);
							foreach(array_unique(explode(',', $othnums)) as $nv)
							{
								if(!empty($nv)) $tempArr['nums'][--$numseq] = ['num_factory'=>'OE', 'num_display'=>$nv];
							}

							foreach($zpro['pro_oems'] as $nid=>$nv)
							{
								$fac = 'OE';
								if(stripos($nv, '****'))
								{
									$xnumIdArr[] = (int) $nid;
								}
								if(trim($nv) != '')
								{
									$tempArr['nums'][--$numseq] = ['num_factory'=>$fac, 'num_display'=>$nv, 'oemid'=>$nid];
								}
							}
						}

						
						//参数
						if(!empty($zpActArr['para']))
						{
							$proPara = [];
							foreach($zpro['pro_param'] as $tk=>$tv)
							{
								$proPara[strtoupper($tk)][] = $tv;
							}
							$partPara = !empty($partParam[$tempArr['base']['pro_part_id']])? $partParam[$tempArr['base']['pro_part_id']]: [];
							$matchPara = $this->comparePara($partPara, $proPara, 'ppl_toname');
							
							//零件参数
							foreach($matchPara['match'] as $tv)
							{
								$tempArr['param'][$tv['pal_id']] = $tv['val'];
							}

							//未匹配的转到自定义参数
							foreach($matchPara['not'] as $tk=>$tv)
							{
								$tempArr['pro_param'][] = [$tk, implode(',', $tv)];
							}
						}
						
						//图片
						if(!empty($zpActArr['img']))
						{
							$tempArr['upimgs'] = [];
							foreach($zpro['pro_image'] as $imgurl)
							{
								//["//part-item-images.zhipeicloud.com/partitem/002/932/932.jpg?x-oss-process=image/resize,m_mfit,h_800,w_800"]
								$imgDir = '';
								if(preg_match('/(oss-[0-9a-zA-Z\-\_]+)\.aliyuncs\.com(\/partitem\/[0-9a-zA-Z\-\_\/\.]+)\?/', $imgurl, $match)){
									$imgDir = mvc::$cfg['ZHIPEI']['picture'].$match[1].$match[2];
								}else if(preg_match('/zhipeicloud\.com\/[0-9a-zA-Z\/]{5,}\.jpg/', $imgurl, $match)){
									$imgDir = mvc::$cfg['ZHIPEI']['picture'].$match[0];
								}
								if(!$imgDir) {
									//$errorArr[] = $imgurl.'分析路径失败';
								}else if(file_exists($imgDir)){
									$tempArr['upimgs'][] = $imgDir;
								}else{
									//$errorArr[] = $imgDir.'图片不存在';
								}
							}
						}
						$impProArr[] = $tempArr;
					}
					
					//处理打星的号码
					$xnumIdArr = array_unique($xnumIdArr);
					$xnumArr = [];
					if(!empty($xnumIdArr))
					{
						$res = $this->YpcBase->get('yp_model3_zhipei_oem', ['oem_id', 'oem_text'], sprintf(" and oem_id in (%s)", implode(',', $xnumIdArr)));
						$xnumArr = array_column($res['data'], 'oem_text', 'oem_id');
					}
				
					foreach($impProArr as $pk=>$pv)
					{
						//处理号码 处理打星的号码
						if(!empty($zpActArr['num']) && !empty($pv['nums']))
						{
							foreach($pv['nums'] as $nk=>$nv)
							{
								if(!empty($xnumArr[$nv['oemid']])) $nv['num_display'] = $xnumArr[$nv['oemid']];
								unset($nv['oemid']);
								if(stripos($nv['num_display'], '****')) 
								{
									unset($pv['nums'][$nk]);
								}
								else
								{
									$pv['nums'][$nk] = $nv;
								}
							}
						}
						
						//确定产品ID 优先来源ID
						$res = $this->get('bc_product', ['pro_id'], sprintf(" and pro_dfrom='%s' and pro_dfrom_id=%d and pro_shop_id=%d", $pv['base']['pro_dfrom'], $pv['base']['pro_dfrom_id'], $shopId), true);
						if(!empty($res['data'])){
							$pv['base']['pro_id'] = $res['data']['pro_id'];
						}else{//自编号
							$res = $this->get('bc_product join bc_product_info on pri_pro_id=pro_id', ['pro_id'], sprintf(" and pri_code='%s' and pro_shop_id=%d", LibFc::Escape($pv['info']['pri_code']), $shopId), true);
							if(!empty($res['data'])){
								$pv['base']['pro_id'] = $res['data']['pro_id'];
							}else{
								$res = $this->get('bc_number join bc_product on num_pro_id=pro_id and num_self=1', ['num_pro_id'], sprintf(" and num_format='%s' and pro_shop_id=%d", LibFc::FormatNum($pv['info']['pri_code']), $shopId), true);
								if(!empty($res['data'])){
									$pv['base']['pro_id'] = $res['data']['num_pro_id'];
								}
							}
						}

						if(empty($pv['base']['pro_id'])){
							if(empty($pv['base']['pro_part_id']))
							{
								$tempErr[] = '配件分类不存在。';
							}
							$pv['shop_sort'] = [$pv['part_name']];
							$pv['info']['pri_publish_time'] = 0;
							$pv['info']['pri_frt_id'] = $frt_id;
							$pv['base']['pro_status'] = !empty($zpActArr['pro_status']) ? 1: 0;
							$pv['base']['pro_shop_id'] = $shopId;
						}
						$impProArr[$pk] = $pv;
					}
					//数据分析有误
					if(!empty($errorArr))
					{
						return LibFc::ReturnData(true, ['imp'=>false, 'chkerr'=>$errorArr]);
					}

					//产品入库
					foreach($impProArr as $pk=>$pv)
					{
						$this->B2CDb->Begin();
						//店铺分类
						if(!empty($pv['shop_sort']))
						{
							$res = $B2cShopSort->getAddShopSortId($shopId, $pv['shop_sort']);
							$pv['shopSort'] = array_values($res['data']);
						}
						$pv['hasimg'] = 0;
						if(empty($pv['base']['pro_id']))
						{
							$res = $B2cProduct->addProduct($pv,$shopId);
							$pv['base']['pro_id'] = $res['data'];
							$pv['type'] = 'new';
							$needSetPidArr[] = $pv['base']['pro_id'];
						}
						else if($zpActArr['item'] != 'onlynew')
						{
							//追加号码，查询已有号码
							if(!empty($pv['nums']) && $zpActArr['num'] == 'onlyadd')
							{
								$res = $this->get('bc_number', ['*'], sprintf(" and num_pro_id=%d and num_self = 0", $pv['base']['pro_id']));
								foreach($res['data'] as $tv)
								{
									$pv['nums'][$tv['num_id']] = $tv;
								}
							}

							//编辑情况下不改变原有分类
							unset($pv['base']['pro_name']);
							unset($pv['base']['pro_part_id']);
							unset($pv['base']['pro_pas_id']);
							unset($pv['base']['pro_part_path']);
							unset($pv['shopSort']);
							

							//仅处理无参数产品
							if(!empty($zpActArr['para']) && $zpActArr['para'] == 'nopara')
							{
								$res = $this->get('bc_product_param_float', ['*'], sprintf(" and ppf_pro_id=%d", $pv['base']['pro_id']));
								if(!empty($res['data']))
								{
									unset($pv['param']);
									unset($pv['pro_param']);
								}
								else
								{
									$res = $this->get('bc_product_param_string', ['*'], sprintf(" and pps_pro_id=%d", $pv['base']['pro_id']));
									if(!empty($res['data']))
									{
										unset($pv['param']);
										unset($pv['pro_param']);
									}
								}
							}
							$needSetPidArr[] = $pv['base']['pro_id'];
							$B2cProduct->setProduct($shopId, $pv['base']['pro_id'], $pv);
							$pv['type'] = 'has';
							
							if(!empty($zpActArr['img']) && $zpActArr['img'] == 'noimg')
							{
								//查看产品是否有图片
								$res = $this->get('bc_product_pic', ['pp_spi_id'], sprintf(" and pp_pro_id=%d", $pv['base']['pro_id']));
								if(!empty($res['data'])) $pv['hasimg'] = 1;
							}
						}
						if(in_array($pv['base']['pro_id'], $needSetPidArr)){
							if(!empty($pv['pro_param']))
								$B2cProduct->setBatchParam($pv['base']['pro_id'], $shopId, $pv['pro_param']);
							
							//图片上传 无图产品或者强制替换图片的
							if(!empty($zpActArr['img']) && !empty($pv['upimgs']) && (in_array('resetimg', $zpActArr) || !$pv['hasimg']))
							{
								$spiIdArr = [];
								$pv['upimgs'] = array_unique($pv['upimgs']);
								foreach ($pv['upimgs'] as $img) 
								{
									$res = $B2cProduct->batchUploadImg($img, $shopId, false);
									if($res['status'] && !empty($res['data'])) 
										$spiIdArr[] = $res['data']['spi_id'];
								}
								if(!empty($spiIdArr)) $B2cProduct->setProductPic($shopId, $pv['base']['pro_id'], $spiIdArr);
							}
						}
						$impProArr[$pk] = $pv;
						$this->B2CDb->End();
					}
					
				break;
				//车型处理
				case 'model':
					$ypToZpIdArr = [];

					//确定产品ID
					$res = $this->get('bc_product', ['pro_id,pro_dfrom_id'], sprintf(" and pro_dfrom='ZHIPEI' and pro_shop_id=%d", $shopId));
					$hasLinkId = array_column($res['data'], 'pro_id', 'pro_dfrom_id');
					
					$res = $this->get('bc_product join bc_product_info on pri_pro_id=pro_id', ['pro_id, pri_code'], sprintf(" and pro_shop_id=%d", $shopId));
					$hasLinkCode = array_column($res['data'], 'pro_id', 'pri_code');

					$res = $this->get('bc_number join bc_product on num_pro_id=pro_id and num_self=1', ['num_pro_id pro_id, num_format'], sprintf(" and pro_shop_id=%d", $shopId));
					$hasLinkCode2 = array_column($res['data'], 'pro_id', 'num_format');

					//通过自编号确认产品ID对应关系
					$where = sprintf(" and pro_user = '%s' and pro_format != ''", $zpShop);
					if($zpActArr['modelitem'] == 'nomodel'){
						$where .= sprintf(" and pro_id in (select distinct mod_pro_id from auto_product_model WHERE mod_pro_user = '%s' 
						and ((mod_auo_sub_id = 0 and mod_zp_mod2_ids = '') OR mod_match_yp->'$.ok' IS NULL or mod_match_yp->'$.ok'='[]'))", $zpShop);
					}else if($zpActArr['modelitem'] == 'nolinkmod2'){
						$where .= sprintf(" and pro_id in (select distinct mod_pro_id from auto_product_model WHERE mod_pro_user = '%s' and mod_auo_sub_id = 0 and mod_zp_mod2_ids = '')", $zpShop);
					}
					$res = $this->ZpBase->get('auto_product', ['pro_id, pro_format'], $where);
					foreach($res['data'] as $tv){
						$ypProId = 0;
						if($hasLinkId[$tv['pro_id']]){
							$ypProId = $hasLinkId[$tv['pro_id']];
						}else if($hasLinkCode[$tv['pro_format']]){
							$ypProId = $hasLinkCode[$tv['pro_format']];
						}else{
							$format = LibFc::FormatNum($tv['pro_format']);
							if($hasLinkCode2[$format]){
								$ypProId = $hasLinkCode2[$format];
							}
						}
						//仅处理刚才新增的
						if($zpActArr['item'] == 'onlynew' && !in_array($ypProId, $needSetPidArr)) continue;
						$ypToZpIdArr[$ypProId] = $tv['pro_id'];
					}
					$LibLog = new LibLog();
					$total = count($ypToZpIdArr);
					$runcount = 0;
					$LibLog->write('SHOP:'.$shopId.'=>count:'.$total.'=> MODEL begin=>'.json_encode($ypToZpIdArr), $logfile);
					foreach($ypToZpIdArr as $ypProId=>$zpProId){
						$res = $this->matchItemModel($zpProId);
						$runcount++;
						$LibLog->write('SHOP:'.$shopId.'=>YP:'.$ypProId.'=>ZP:'.$zpProId.'=> MODEL '.round($runcount/$total, 2), $logfile);
						if(!empty($res['data'])){
							$newModArr = [];
							foreach($res['data'] as $tkk=>$tvv){
								$newModArr[$tkk] = ['pml3_mod3_id'=>$tkk, 'pml3_remark'=>implode('; ',$tvv)];
							}
							//追加模式
							if($zpActVal == 'onlyadd'){
								$tres = $this->get('bc_product_model3_link', ['pml3_mod3_id', 'pml3_remark'], sprintf(" and pml3_pro_id =%d and pml3_mod3_id not in (%s)", $ypProId, implode(',', array_keys($newModArr))));
								foreach($tres['data'] as $tvv){
									$newModArr[$tvv['pml3_mod3_id']] = $tvv;
								}
							}
							$B2cProduct->setProductModel($ypProId, $newModArr, 'ZHIPEI');
						}
					}
					$LibLog->write('SHOP:'.$shopId.'=>count:'.count($ypToZpIdArr).'=> MODEL End', $logfile);
				break;
			}
		}
		return LibFc::ReturnData(true, ['imp'=>true, 'chkerr'=>$errorArr]);
	}

	//智配和宜配的驻车转换
	private function formatParkingBrake($str)
	{
		$arr = [];
		if(stripos($str, '手刹') !== false || stripos($str, '机械驻车') !== false || stripos($str, '脚刹') !== false) $arr[] = '手刹';
		if(stripos($str, '电子') !== false) $arr[] = '电子驻车';
		return implode('/', $arr);
	}

	//智配和宜配的变速箱转换
	private function formatTransmission($str)
	{
		$arr = ['dw'=>'', 'type'=>''];
		//档位
		$dangWei = '';
		if(preg_match('/^(\d+)(.*)/', $str, $match))
		{
			$str = $match[2];
			$arr['dw'] = $match[1].'档';
		}
		//顺序不能随便
		$replaceArr = [				
			'A/MT'=>'手自一体',
			'AMT'=>'手自一体',
			'DCT'=>'双离合',
			'单速'=>'单速',
			'三离合'=>'三离合',
			'ASG'=>'序列',
			'AT'=>'自动',
			'MT'=>'手动',
			'E-CVT'=>'E-CVT',
			'CVT'=>'CVT',
			'固定齿比'=>'单速',
		];
		foreach($replaceArr as $kt=>$vt)
		{
			if(stripos($str, $kt) !== false || stripos($str, $vt) !== false)
			{
				$str = $vt;
				break;
			}
		}
		$arr['type'] = $str;
		return $arr['dw'].$arr['type'];
	}


	/**
	 * @method  智配产品ID对应的宜配车型
	 * @param $zpProId int 智配产品ID
	 * @author	soul
	 * @copyright 2020/5/21
	 */
	public function matchItemModel($zpProId)
	{
		$okArr = [];
		//将model_json的数据转换到mod_zp_mod2_ids
		$zpres = $this->ZpBase->get('auto_product_model', ['mod_apmid, model_json'], sprintf(" and mod_pro_id='%s' and mod_auo_sub_id=0 and model_json like '%%autoValue%%'", $zpProId));
		foreach($zpres['data'] as $v){
			$this->formatModByJson($v);
		}

		$linkModArr = [];

		//有车型ID部分
		$filed = ['mod_apmid, make_name zp_brand, model_id zp_mod2id, model_name zp_mod2, mod_auo_sub_id zp_mod3id, sub_name zp_mod3, mod_auo_param zp_param'];
		$zpres = $this->ZpBase->get('auto_product_model JOIN data_model ON sub_id = mod_auo_sub_id', $filed, sprintf(" and mod_pro_id='%s' and mod_auo_sub_id > 0", $zpProId));
		foreach($zpres['data'] as $v){
			$linkModArr[] = $v;
		}

		if(empty($linkModArr)){
			//无车型ID部分
			$filed = ['mod_apmid, make_name zp_brand, model_id zp_mod2id, model_name zp_mod2, mod_auo_sub_id zp_mod3id, mod_zp_ccname zp_mod3, mod_auo_param zp_param'];
			$zpres = $this->ZpBase->get('auto_product_model JOIN (SELECT make_id, make_name,brand_id,brand_name,series_id,series_name,model_id,model_name FROM `data_model` GROUP BY model_id) mod2 on FIND_IN_SET(model_id, mod_zp_mod2_ids)', $filed, sprintf(" and mod_pro_id='%s' and mod_auo_sub_id = 0", $zpProId));
			foreach($zpres['data'] as $v){
				$linkModArr[] = $v;
			}
		}
		
		if(empty($linkModArr)) return LibFc::ReturnData(true, $okArr);
		//智配产品对应的车型  50041419  同一个车型id 有多条记录
		
		$zpItemModArr = [];
		foreach($linkModArr as $v)
		{
			$unikey = $v['zp_mod2id'].'@'.$v['zp_mod3id'];
			$paras = json_decode($v['zp_param'], true);
			$v['zp_param'] = [];
			foreach($paras as $tv)
			{
				//刹车类型：小卡钳，时间：201401-至今   ["时间：201207-，发动机型号：10UF01 5G02，驱动方式：前置前驱，变速箱型号：6速手自一体，年款：2015"]
				//["发动机型号：DAM15DL，时间：201401-至今", "发动机型号：BJ415A，时间：201401-至今"]
				//[{"oemId": 321312, "partsName": "分离轴承", "autoParamString": "发动机型号：G4KD，时间：201009-201710"}]
				$tempArr = [];
				if(is_array($tv)) $tv = $tv['autoParamString'];
				foreach(explode('，', $tv) as $tvv)
				{
					$temp = explode('：', $tvv);
					if(count($temp) == 2)
					{
						if($temp[0] == '时间'){
							$t = explode('-', $temp[1]);
							if(empty($t[1]) || $t[1] == '至今') $t[1] = '300012';
							$t[2] = $temp[1];
							$temp[1] = $t;
						}
						if($temp[0] == '变速箱型号') $temp[1] = $this->formatTransmission($temp[1]);
						if($temp[0] == '驻车制动类型') $temp[1] = $this->formatParkingBrake($temp[1]);
						$tempArr[$temp[0]] = $temp[1];
					}
				}
				if(!empty($tempArr)) $v['zp_param'][] = $tempArr;
			}
			$zpItemModArr[$unikey][] = $v;
		}

		//寻找智配车型ID对应的宜配车型ID
		$mergeArr = [];
		$m3idsTj = [];
		foreach($zpItemModArr as $unikey=>$iParam)
		{
			foreach($iParam as $zpMod)
			{
				$modArr = []; $hasArr = []; $tm3ids = [];
				//if($zpMod['zp_mod3id'] != 59726) continue;
				//直接绑定车型的zp_mod33_link
				if(!empty($zpMod['zp_mod3id'])){
					$table = 'yp_model3 m3 
					JOIN zp_mod33_link ON zml3_yp_mod3_id = m3_id';
					$res = $this->YpcBase->get($table, ['m3_id, 1 isbind, zml3_zp_mod3_id zvm_mod3_id'], sprintf(" and zml3_zp_mod3_id =%d group by m3_id", $zpMod['zp_mod3id']));
					if($res['data']){
						foreach($res['data'] as $tv){
							$tm3ids[] = $tv['m3_id'];
							$hasArr[$tv['m3_id']] = $tv;
						}
					}
				}
				
				//通过绑定的车代+排量 反查 zp_mod32_link
				if(!empty($zpMod['zp_mod2id'])){
					$zpccname = $zpMod['zp_mod3']; $zpcc = 0;
					if(preg_match('/(\d+(.\d+)?)[TLD]+/', $zpccname, $match)){
						$zpcc = $match[1]*1000;
						$zpccname = $match[0];
					}
					$table = 'yp_model3 m3 
					JOIN zp_mod32_link ON yp_mod3_id = m3_id
					JOIN '.mvc::$cfg['DB']['ZHIPEIC']['db_name'].'.data_model ON model_id = zp_mod2_id';
					if(!empty($tm3ids)){//如果已经有绑定，再通过车代找未绑定的部分
						$where = sprintf(" and zp_mod2_id=%d and m3_id not in (select zml3_yp_mod3_id from zp_mod33_link) group by m3_id", $zpMod['zp_mod2id']);
					}else{
						$where = sprintf(" and zp_mod2_id=%d group by m3_id", $zpMod['zp_mod2id']);
					}
					$res = $this->YpcBase->get($table, ['m3_id, sub_id zvm_mod3_id, 0 isbind, m3_cc, m3_cc_name'], $where);
					if($res['data']){
						$tmods = $res['data'];
						//排量完整匹配
						$issame = false;
						foreach($tmods as $tv){
							if($zpccname == $tv['m3_cc_name']){
								$tm3ids[] = $tv['m3_id'];
								$hasArr[$tv['m3_id']] = $tv;
								$issame = true;
							}
						}
						if(!$issame || empty($tm3ids)){//排量名有差异
							foreach($tmods as $tv){
								if(stripos($zpccname, $tv['m3_cc_name']) === 0 || $zpcc == $tv['m3_cc'] || (!empty($zpcc) && abs($zpcc - $tv['m3_cc']) < 49)){
									$tm3ids[] = $tv['m3_id'];
									$hasArr[$tv['m3_id']] = $tv;
								}
							}
						}
					}
				}

				if(empty($tm3ids)){
					$mres = $zpMod;
					$mres['error'] = '无法对应车型';
					$this->ZpBase->set('auto_product_model', ['mod_match_yp'=>json_encode($mres), 'mod_match_time'=>time()], sprintf(" and mod_apmid=%d", $zpMod['mod_apmid']));
					continue;
				}
				//格式化YP车型信息
				$res = $this->getFormatMod3($tm3ids);
				$modArr = $res['data'];
				foreach($modArr as $k=>$v){
					if(!empty($hasArr[$k])) $v = array_merge($v, $hasArr[$k]);
					$modArr[$k] = $v;
				}
				$res = $this->filterMod($zpMod, $modArr);
				$this->ZpBase->set('auto_product_model', ['mod_match_yp'=>json_encode($res['data']), 'mod_match_time'=>time()], sprintf(" and mod_apmid=%d", $zpMod['mod_apmid']));
				foreach($res['data']['ok'] as $m3id=>$ipvps){
					foreach($ipvps as $ipvp){
						$mergeArr[$m3id][] = $ipvp;
						$m3idsTj[$m3id]['count']++;
						if($ipvp['needtime']) $m3idsTj[$m3id]['needtime']++;
					}
				}
			}
		}

		//以车型ID合并备注
		$comFileds = ['发动机型号', '驱动方式', '驻车制动类型', '变速箱型号', '工信部型号', '时间'];
		foreach($mergeArr as $m3id=>$ipvps){
			$rows = [];
			foreach($ipvps as $ipvp){
				$tone = [];
				foreach($ipvp as $filed=>$fvv){
					if(in_array($filed, $comFileds) || in_array($filed, ['年款','年款版本', 'needtime'])) continue;
					if(!empty($ipvp['时间'])) $fvv .= '('.$ipvp['时间'][2].')';
					$tone[$filed] = $fvv;
				}
				if(empty($tone) && $m3idsTj[$m3id] && $ipvp['时间']) $tone['时间'] = $ipvp['时间'][2];
				if($tone) $rows[] = implode(',', $tone);
			}
			$okArr[$m3id] = array_unique($rows);
		}
		return LibFc::ReturnData(true, $okArr);
	}


	/**
	 * @method  auto_product_model从json中初始化智配的车代ID和车型参数
	 * @param $dv ['mod_apmid'=>'', 'model_json'=>'[{"0": {"autoId": 5660, "autoValue": "铃木", "autoHierarchyId": 1}, "1": {"autoId": 5687, "autoValue": "长安铃木", "autoHierarchyId": 2}, "autoParameterTypeName": "品牌"}, {"autoId": 5691, "autoValue": "羚羊(200007-201512)", "autoHierarchyId": 3, "autoParameterTypeName": "车系"}, {"autoParameterTypeName": "车组"}, {"autoParameterId": 1298, "autoParameterValue": "1.3L", "autoParameterTypeName": "排量"}, {"autoParameterId": 32198, "autoParameterValue": "G13B", "autoParameterTypeName": "发动机型号"}, {"autoParameterId": 11673, "autoParameterValue": "67", "autoParameterTypeName": "发动机功率"}, {"autoParameterId": 199, "autoParameterValue": "5速手动", "autoParameterTypeName": "变速器"}, {"autoParameterId": 25, "autoParameterValue": "三厢车", "autoParameterTypeName": "车身形式"}, {"autoParameterId": 78, "autoParameterValue": "前置前驱", "autoParameterTypeName": "驱动形式"}, {"autoParameterId": 1, "autoParameterValue": "汽油车", "autoParameterTypeName": "能源类型"}, {"autoParameterId": 328, "autoParameterValue": "2011", "autoParameterTypeName": "年款"}, {"autoParameterId": 892, "autoParameterValue": "国四", "autoParameterTypeName": "排放标准"}]']  
	 * @author	soul
	 * @copyright 2020/5/21
	 */
	public function formatModByJson($dv)
	{
		$tarr = json_decode($dv['model_json'], true);
		$tm = [];
		$tfArr = ['排量'=>'cc','发动机型号'=>'engine','发动机功率'=>'kw','变速器'=>'tran','驱动形式'=>'drive','开始年月'=>'sbym','结束年月'=>'seym','工信部型号'=>'gxbs','备注'=>'remark','能源类型'=>'fuel','年款'=>'nk'];
		$zpModOth = [
			'zmo_brand'=>'',	
			'zmo_make'=>'',	
			'zmo_mod1'=>'',	
			'zmo_mod2'=>'',	
		];
		foreach($tarr as $vv)
		{
			switch($vv['autoParameterTypeName'])
			{
				case '品牌':
					$tm['brand'] = $vv[0]['autoValue'];
					$zpModOth['zmo_brand'] = $vv[0]['autoValue'];
					$zpModOth['zmo_brand_id'] = $vv[0]['autoId'];
					if(!empty($vv[1]))
					{
						$tm['make'] = $vv[1]['autoValue'];
						$zpModOth['zmo_make'] = $vv[1]['autoValue'];
						$zpModOth['zmo_make_id'] = $vv[1]['autoId'];
					}
				break;
				case '车系':
					$tm['mod1'] = $vv['autoValue'];
					$zpModOth['zmo_mod1_id'] = $vv['autoId'];
					$zpModOth['zmo_mod1'] = $vv['autoValue'];
				break;
				case '车组': 
					if(!empty(!empty($vv[1]['autoValue'])))
					{
						$tname = $vv[1]['autoValue'];
						$it = stripos($tname, '(');
						$tname =$it ? substr($tname, 0, $it+1).$vv[0]['autoValue'].' '.substr($tname, $it+1): $tname.'('.$vv[0]['autoValue'].')';
						$tm['mod2'] = $tname;
						$zpModOth['zmo_mod2_id'] = $vv[1]['autoId'];
						$zpModOth['zmo_mod2'] = $tname;
					}
					else if(!empty(!empty($vv[0]['autoValue'])))
					{
						$tm['mod2'] = $vv[0]['autoValue'];
						$zpModOth['zmo_mod2_id'] = $vv[0]['autoId'];
						$zpModOth['zmo_mod2'] = $vv[0]['autoValue'];
					}
				break;
				default:
					if(!empty($vv['autoParameterValue']) && !empty($tfArr[$vv['autoParameterTypeName']]))
						$tm[$tfArr[$vv['autoParameterTypeName']]] = $vv['autoParameterValue'];
				break;
			}
		}
		if(stripos($tm['fuel'], '电动车') !== false && empty($tm['cc'])) $tm['cc'] = '电动车';

		//唯一键
		$unikeys = [$zpModOth['zmo_brand'],$zpModOth['zmo_make'],$zpModOth['zmo_mod1'],$zpModOth['zmo_mod2']];
		$unikey = md5(implode('@', $unikeys));
		$zpModOth['zmo_unikey'] = $unikey;
		
		if(!empty($this->mod2JsonCache[$unikey]['zp_mod2_ids'])){
			$zpModOth = $this->mod2JsonCache[$unikey];//已经匹配过
		}else{
			$res = $this->ZpBase->get('zp_model_othmod2', ['*'], sprintf(" and zmo_unikey='%s'", $zpModOth['zmo_unikey']), true);
			if(!empty($res['data'])){
				$zpModOth = $res['data'];
				$res = $this->ZpBase->get('zp_model_othmod2_link join data_model on model_id = zmol_zp_mod2_id', ['distinct model_id'], sprintf(" and zmol_zmo_id=%d", $zpModOth['zmo_id']));
				$zpModOth['zp_mod2_ids'] = implode(',', array_column($res['data'], 'model_id'));
			}else{
				$res = $this->ZpBase->add('zp_model_othmod2', $zpModOth);
				$zpModOth['zmo_id'] = $res['data'];
			}
		}

		//提取时间
		$tm['mod1'] = preg_replace('/(\d{6}-)\)/', '$1至今)', $tm['mod1']); //朗逸 三厢(184 201501-)
		$tm['mod2'] = preg_replace('/(\d{6}-)\)/', '$1至今)', $tm['mod2']); //朗逸 三厢(184 201501-)
		$tm['mod1'] = preg_replace('/(\d{6}-)$/', '$1至今)', $tm['mod1']); //182(201203-
		$tm['mod2'] = preg_replace('/(\d{6}-)$/', '$1至今)', $tm['mod2']); //182(201203-
		if(preg_match('/\d{6}-((\d{6})|(至今))/', trim($tm['mod1'].' '.$tm['mod2']), $match)){
			$tm['mod_ym'] = $match[0];
			$tm['mod_y'] = preg_replace('/(\d{4})(\d{2})/', '${1}', $tm['mod_ym']);
			$tm['mod1'] = str_replace($tm['mod_ym'], $tm['mod_y'], $tm['mod1']);
			if(!empty($tm['mod2'])) $tm['mod2'] = str_replace($tm['mod_ym'], $tm['mod_y'], $tm['mod2']);
		}

		//提取产品适配属性 
		$setArr = ['mod_zp_mod2_ids'=>'', 'mod_auo_param'=>'[]', 'mod_match_yp'=>'[]', 'mod_match_time'=>0,
			'mod_zp_ccname'=>$tm['cc'],
			'model_auto_brand'=>$zpModOth['zmo_brand'].($zpModOth['zmo_make'] == $zpModOth['zmo_brand']? '': ' '.$zpModOth['zmo_make']),
			'model_auto_series'=>$zpModOth['zmo_mod1'],
			'model_auto_model'=>$tm['cc'],
		];
		$param = [];
		if(!empty($tm['sbym'])){
			$param[] = '时间：'.$tm['sbym'].'-'.(empty($tm['seym'])? $tm['seym']: '至今');
		}else if($tm['mod_ym']) {
			$param[] = '时间：'.$tm['mod_ym'];
		}
		$pfArr = ['engine'=>'发动机型号', 'drive'=>'驱动方式','tran'=>'变速箱型号','gxbs'=>'工信部型号','remark'=>'备注','nk'=>'年款'];
		foreach($pfArr as $pk=>$pv)
		{
			if(!empty($tm[$pk])) $param[] = $pv.'：'.$tm[$pk];
		}
		$setArr['mod_auo_param'] = json_encode([implode('，', $param)], JSON_UNESCAPED_UNICODE);
		if(!empty($zpModOth['zp_mod2_ids'])){
			$setArr['mod_zp_mod2_ids'] = $zpModOth['zp_mod2_ids'];
		}else if(isset($this->mod2JsonCache[$unikey])){//缓存
			$zpModOth = $this->mod2JsonCache[$unikey];
			if(!empty($zpModOth['zp_mod2_ids'])) $setArr['mod_zp_mod2_ids'] = $zpModOth['zp_mod2_ids'];
		}else{
			//-----可能的生产商-----
			$tm['brandwhere'] = []; $tm['ccwhere'] = []; $tm['modwhere'] = [];
			$tm['brands'] = [$tm['brand']];
			if($tm['brand'] == '东风') $tm['brands'][] = '东风汽车';
			if($tm['brand'] == '比速') $tm['brands'][] = '比速汽车';
			if($tm['brand'] == '飞碟') $tm['brands'][] = '永源/飞碟';
			if($tm['brand'] == '唐骏') $tm['brands'][] = '唐骏欧铃';
			if($tm['brand'] == '上汽大通MAXUS') $tm['brands'][] = '上汽MAXUS';
			if(stripos($tm['make'], '进口') !== false){
				$tm['brandwhere'][] = sprintf(" and make_name in ('%s') and brand_name like '%%进口%%'", implode("','", $tm['brands']));
			}else if(!empty($tm['make'])){
				$tm['brandwhere'][] = sprintf(" and make_name in ('%s') and brand_name ='%s'", implode("','", $tm['brands']), $tm['make']);
				$tm['brandwhere'][] = sprintf(" and make_name = '%s'", $tm['make']);
			}
			$tm['brandwhere'][] = sprintf(" and make_name in ('%s')", implode("','", $tm['brands']));
			
			//-----可能的车代-----
			if(stripos($tm['mod2'], $tm['mod1']) === 0){
				$tm['mod2_name'] = $tm['mod2']; //A5 Coupe quattro(8T3 200706-201707)
			}else{
				$tm['mod2_name'] = $tm['mod1'];
				if(!empty($tm['mod2'])) {
					$tm['mod2_name'] .= '('.str_replace('(', ' ', $tm['mod2']).')';
				}
			}
			$tm['mod2_name'] = strtr($tm['mod2_name'], ['(0-0)'=>'',' 0-0)'=>'', '))'=>')', ')('=>' ']);
			$tm['mod2_names'] = [$tm['mod2_name']];
			if(!empty($tm['mod_y'])) $tm['mod2_names'][] = strtr(str_replace($tm['mod_y'], '', $tm['mod2_name']), ['()'=>'', ' )'=>')']);
			if($tm['mod2_name'] == '域虎') $tm['mod2_names'][] = '域虎(2011-2018)';
			if(in_array($tm['make'], ['进口宝马']) 
				|| in_array($tm['mod1'], ['1系','2系','3系','3系GT','4系','5系','5系GT','6系','6系GT','7系','8系','M2系','M3系','M4系','M5系','X3','X4','X6','AMG C级','C级','E级','S级','SL级','SLK级', 'SLC级', '唯雅诺','奔驰S级','奔驰C级','奔驰E级','奔驰CLS级','奔驰ML级','S级 迈巴赫'])
				|| (stripos($tm['make'], '进口') !== false && stripos($tm['mod1'], '系'))
				|| (stripos($tm['make'], '进口') !== false && stripos($tm['mod1'], '级'))
			) 
				$tm['mod2_names'][] = $tm['mod2'];
			
			$tm['mod_names'] = [];
			$tm['mod2_names'] = array_unique($tm['mod2_names']);
			foreach($tm['mod2_names'] as $tk=>$tv)
			{
				$tnames = [$tv];
				if(stripos($tv, '思威CR-V') === 0) $tnames[] = str_replace('思威CR-V', 'CR-V思威', $tv);
				if(stripos($tv, '福运S系/小福星S系') === 0) $tnames[] = str_replace('福运S系/小福星S系', '福运S系/福星S系', $tv);
				if(stripos($tv, '新豹二代') === 0) $tnames[] = str_replace('新豹二代', '新豹2', $tv);
				if(stripos($tv, '新豹三代') === 0) $tnames[] = str_replace('新豹二代', '新豹3', $tv);
				if(stripos($tv, '瑞纳 三厢(HC') === 0) $tnames[] = str_replace('瑞纳 三厢(HC', '瑞纳(HC', $tv);
				if(stripos($tv, '飞度 两厢') === 0) $tnames[] = str_replace('飞度 两厢', '飞度', $tv);
				if(stripos($tv, '朗逸 三厢') === 0) $tnames[] = str_replace('朗逸 三厢', '朗逸', $tv);
				if(stripos($tv, '炫威XR-V') === 0) $tnames[] = str_replace('炫威XR-V', 'XR-V炫威', $tv);
				if(stripos($tv, '英朗XT') === 0) $tnames[] = str_replace('英朗XT', '英朗 XT', $tv);
				if(stripos($tv, '英朗GT') === 0) $tnames[] = str_replace('英朗GT', '英朗 GT', $tv);
				if(stripos($tv, '悦动(ELANTRA)') === 0) $tnames[] = str_replace('悦动(ELANTRA)', '悦动 ELANTRA', $tv);
				if(stripos($tv, '桑塔纳 三厢(B2') === 0) $tnames[] = str_replace('桑塔纳 三厢(B2', '桑塔纳(B2', $tv);
				if(stripos($tv, '新桑塔纳/浩纳') === 0) $tnames[] = str_replace('新桑塔纳/浩纳', '新桑塔纳/浩纳 两厢', $tv);
				if(stripos($tv, '金刚 三厢') === 0) $tnames[] = str_replace('金刚 三厢', '金刚', $tv);
				if(stripos($tv, '一代') !== false) $tnames[] = str_replace('一代', '1代', $tv);
				if(stripos($tv, '二代') !== false) $tnames[] = str_replace('二代', '2代', $tv);
				if(stripos($tv, '三代') !== false) $tnames[] = str_replace('三代', '3代', $tv);
				if(stripos($tv, '四代') !== false) $tnames[] = str_replace('四代', '4代', $tv);
				if(stripos($tv, '五代') !== false) $tnames[] = str_replace('五代', '5代', $tv);
				if(stripos($tv, '六代') !== false) $tnames[] = str_replace('六代', '6代', $tv);
				if(stripos($tv, '七代') !== false) $tnames[] = str_replace('七代', '7代', $tv);
				if(stripos($tv, '八代') !== false) $tnames[] = str_replace('八代', '8代', $tv);
				if(stripos($tv, '九代') !== false) $tnames[] = str_replace('九代', '9代', $tv);
				if(stripos($tv, '十代') !== false) $tnames[] = str_replace('十代', '10代', $tv);
				if(stripos($tv, '凯越 新款(') === 0) $tnames[] = str_replace('凯越 新款(', '凯越(新款 ', $tv);
				if(stripos($tv, '凯越 老款(') === 0) $tnames[] = str_replace('凯越 老款(', '凯越(老款 ', $tv);
				if(stripos($tv, '圣达菲 新款') === 0) $tnames[] = str_replace('圣达菲 新款', '圣达菲新款', $tv);
				if(stripos($tv, '新桑塔纳/浩纳') === 0) $tnames[] = str_replace('新桑塔纳/浩纳', '新桑塔纳/浩纳 两厢', $tv);
				if(stripos($tv, 'MINI ') === 0) $tnames[] = str_replace('MINI ', '', $tv);
				if(stripos($tv, '-至今)')) $tnames[] = str_replace('-至今)', '-)', $tv);
				if($tm['brand'] == '东风风光' && stripos($tv, '风光') === false) $tnames[] = '风光'.$tv;
				if($tm['brand'] == '东风风行' && stripos($tv, '风行') === false) $tnames[] = '风行'.$tv;
				if($tm['make'] == '广汽三菱' && $tv == '帕杰罗(V73)') $tnames[] = '帕杰罗V73';
				if($tv == '爱唯欧 两厢') $tnames[] = '爱唯欧(两厢)';
				if($tv == '爱唯欧 三厢') $tnames[] = '爱唯欧(三厢)';
				if($tv == '五菱宏光V') $tnames[] = '五菱荣光V/五菱宏光V';
				if($tv == 'CX30 两厢(CX30)') $tnames[] = 'CX30 两厢';
				if($tv == 'CX30 三厢(CX30)') $tnames[] = 'CX30 三厢';
				if($tv == '理念S1') $tnames[] = 'S1';
				if($tv == '致尚XT(第一代 2013-2016)') $tnames[] = '致尚XT(2013-2016)';
				if(stripos($tm['make'], '进口') !== false) $tnames[] = $tv.'(进口)';
				$tm['mod_names'][$tv] = $tnames;
			}
			
			$ignoreReg = '[\(\) \\-\/]';
			foreach($tm['mod_names'] as $tncs){
				$tnames = [];
				foreach($tncs as $tnc){
					$tnames[] = preg_replace('/'.$ignoreReg.'/', '', $tnc);
				}
				$tm['modwhere'][] = [
					'names'=>$tncs,
					'where'=>sprintf(" and REGEXP_REPLACE(model_name, '%s', '') in ('%s')", $ignoreReg, implode("','", $tnames))
				];
			}
			
			foreach($tm['mod_names'] as $tncs){
				$twhere = [];
				foreach($tncs as $tnc){
					$twhere[] = sprintf(" REGEXP_REPLACE(model_name, '%s', '') like '%s%%'", $ignoreReg, preg_replace('/'.$ignoreReg.'/', '', $tnc));
					if(substr($tnc, -1) == ')' && !preg_match('/\d{4}/', $tnc, $match)){
						$twhere[] = sprintf(" REGEXP_REPLACE(model_name, '%s', '') like '%s%%'", $ignoreReg, preg_replace('/'.$ignoreReg.'/', '', substr($tnc, 0, -1)));
					}
					if(preg_match('/ ?\d{4}-(\d{4}|至今|)/', $tnc, $match)){
						$tname = str_replace($match[0], '%', $tnc);
						$twhere[] = sprintf(" REGEXP_REPLACE(model_name, '%s', '') like '%s%%'", $ignoreReg, preg_replace('/'.$ignoreReg.'/', '', $tname));
					}
					//博越 2016-(2015-至今) => 博越(2015-至今)
					if(preg_match('/( ?\d{4}-[(\d{4})|(至今)]?)\(\d{4}\-/', $tnc, $match)){
						$tname = str_replace($match[1], '%', $tnc);
						$twhere[] = sprintf(" REGEXP_REPLACE(model_name, '%s', '') like '%s%%'", $ignoreReg, preg_replace('/'.$ignoreReg.'/', '', $tname));
					}
				}
				$twhere = array_unique($twhere);
				$tm['modwhere'][] = [
					'names'=>$tncs,
					'where'=>sprintf(" and (%s)", implode(' or ', $twhere))
				];
			}

			$tm['wheres'] = [];
			foreach($tm['brandwhere'] as $bwhere)
			{
				foreach($tm['modwhere'] as $modw)
				{
					$where = $bwhere.$modw['where'].' group by model_id';
					$tm['wheres'][] = $where;
					$res = $this->ZpBase->get('data_model', ['*'], $where);
					$likeArr = $res['data'];
					if(count($likeArr) == 1)
					{
						$tm['match'] = $likeArr[0];
						$zpModOth['zp_mod2_ids'] = $tm['match']['model_id'];
						$tset = ['zmo_status'=>1, 'zmo_etime'=>time()];
						$this->ZpBase->set('zp_model_othmod2', $tset, sprintf(" and zmo_unikey='%s'", $zpModOth['zmo_unikey']));
						$this->ZpBase->replace('zp_model_othmod2_link', ['zmol_zmo_id'=>$zpModOth['zmo_id'], 'zmol_zp_mod2_id'=>$zpModOth['zp_mod2_ids']]);
						break;
					}
					else if(count($likeArr) > 1)
					{
						foreach($likeArr as $ltk=>$ltv)
						{	
							$mname = preg_replace('/\d{4}-\d{4}/', '%', $ltv['model_name']);
							$mname = preg_replace('/\d{4}-至今/', '%', $mname);
							$mname = strtr($mname, ['()'=>'']);
							if(in_array($mname, $modw['names']))
							{
								$tm['match'] = $ltv;
								$zpModOth['zp_mod2_ids'] = $tm['match']['model_id'];
								$tset = ['zmo_status'=>1, 'zmo_etime'=>time()];
								$this->ZpBase->set('zp_model_othmod2', $tset, sprintf(" and zmo_unikey='%s'", $zpModOth['zmo_unikey']));
								$this->ZpBase->replace('zp_model_othmod2_link', ['zmol_zmo_id'=>$zpModOth['zmo_id'], 'zmol_zp_mod2_id'=>$zpModOth['zp_mod2_ids']]);
								break;
							}
						}
						if(!empty($zpModOth['zp_mod2_ids'])) break;
					}
				}
				if(!empty($zpModOth['zp_mod2_ids'])) break;
			}
			
			$this->mod2JsonCache[$unikey] = $zpModOth;
			if(!empty($zpModOth['zp_mod2_ids'])){
				$setArr['mod_zp_mod2_ids'] = $zpModOth['zp_mod2_ids'];
			}else{
				//var_dump($tm, $zpModOth, $dv, $setArr); exit;
			}
		}
		$this->ZpBase->set('auto_product_model', $setArr, sprintf(" and mod_apmid=%d", $dv['mod_apmid']));
		return LibFc::ReturnData(true, $setArr);
	}

	
	/**
	 * @method  auto_product_model从json中初始化智配的车代ID和车型参数
	 * @param $dv ['mod_apmid'=>'', 'model_json'=>'[{"0": {"autoId": 5660, "autoValue": "铃木", "autoHierarchyId": 1}, "1": {"autoId": 5687, "autoValue": "长安铃木", "autoHierarchyId": 2}, "autoParameterTypeName": "品牌"}, {"autoId": 5691, "autoValue": "羚羊(200007-201512)", "autoHierarchyId": 3, "autoParameterTypeName": "车系"}, {"autoParameterTypeName": "车组"}, {"autoParameterId": 1298, "autoParameterValue": "1.3L", "autoParameterTypeName": "排量"}, {"autoParameterId": 32198, "autoParameterValue": "G13B", "autoParameterTypeName": "发动机型号"}, {"autoParameterId": 11673, "autoParameterValue": "67", "autoParameterTypeName": "发动机功率"}, {"autoParameterId": 199, "autoParameterValue": "5速手动", "autoParameterTypeName": "变速器"}, {"autoParameterId": 25, "autoParameterValue": "三厢车", "autoParameterTypeName": "车身形式"}, {"autoParameterId": 78, "autoParameterValue": "前置前驱", "autoParameterTypeName": "驱动形式"}, {"autoParameterId": 1, "autoParameterValue": "汽油车", "autoParameterTypeName": "能源类型"}, {"autoParameterId": 328, "autoParameterValue": "2011", "autoParameterTypeName": "年款"}, {"autoParameterId": 892, "autoParameterValue": "国四", "autoParameterTypeName": "排放标准"}]']  
	 * @author	soul
	 * @copyright 2020/5/21
	 */
	public function formatModByJsonLast($dv)
	{
		$tarr = json_decode($dv['model_json'], true);
		$tm = [];
		$tfArr = ['排量'=>'cc','发动机型号'=>'engine','发动机功率'=>'kw','变速器'=>'tran','驱动形式'=>'drive','开始年月'=>'sbym','结束年月'=>'seym','工信部型号'=>'gxbs','备注'=>'remark','能源类型'=>'fuel','年款'=>'nk'];
		$zpModOth = [
			'zmo_brand'=>'',	
			'zmo_make'=>'',	
			'zmo_mod1'=>'',	
			'zmo_mod2'=>'',	
			'zmo_mod3'=>'',	
		];
		foreach($tarr as $vv)
		{
			switch($vv['autoParameterTypeName'])
			{
				case '品牌':
					$tm['brand'] = $vv[0]['autoValue'];
					$zpModOth['zmo_brand'] = $vv[0]['autoValue'];
					$zpModOth['zmo_brand_id'] = $vv[0]['autoId'];
					if(!empty($vv[1]))
					{
						$tm['make'] = $vv[1]['autoValue'];
						$zpModOth['zmo_make'] = $vv[1]['autoValue'];
						$zpModOth['zmo_make_id'] = $vv[1]['autoId'];
					}
				break;
				case '车系':
					$tm['mod1'] = $vv['autoValue'];
					$zpModOth['zmo_mod1_id'] = $vv['autoId'];
					$zpModOth['zmo_mod1'] = $vv['autoValue'];
				break;
				case '车组': 
					if(!empty(!empty($vv[1]['autoValue'])))
					{
						$tname = $vv[1]['autoValue'];
						$it = stripos($tname, '(');
						$tname =$it ? substr($tname, 0, $it+1).$vv[0]['autoValue'].' '.substr($tname, $it+1): $tname.'('.$vv[0]['autoValue'].')';
						$tm['mod2'] = $tname;
						$zpModOth['zmo_mod2_id'] = $vv[1]['autoId'];
						$zpModOth['zmo_mod2'] = $tname;
					}
					else if(!empty(!empty($vv[0]['autoValue'])))
					{
						$tm['mod2'] = $vv[0]['autoValue'];
						$zpModOth['zmo_mod2_id'] = $vv[0]['autoId'];
						$zpModOth['zmo_mod2'] = $vv[0]['autoValue'];
					}
				break;
				default:
					if(!empty($vv['autoParameterValue']) && !empty($tfArr[$vv['autoParameterTypeName']]))
						$tm[$tfArr[$vv['autoParameterTypeName']]] = $vv['autoParameterValue'];
				break;
			}
		}
		if(stripos($tm['fuel'], '电动车') !== false && empty($tm['cc'])) $tm['cc'] = '电动车';
		$zpModOth['zmo_mod3'] = $tm['cc'];
		//唯一键
		$unikeys = [$zpModOth['zmo_brand'],$zpModOth['zmo_make'],$zpModOth['zmo_mod1'],$zpModOth['zmo_mod2'],$zpModOth['zmo_mod3']];
		$unikey = md5(implode('@', $unikeys));
		$zpModOth['zmo_unikey'] = $unikey;
		$zpModOth['zmo_eng'] = $tm['engine']? : '';
		$zpModOth['zmo_kw'] = $tm['kw']? : '';
		
		if(!empty($this->mod2JsonCache[$unikey]['zmo_zvm_mod3_id'])){
			$zpModOth = $this->mod2JsonCache[$unikey];//已经匹配过
		}else{
			$res = $this->ZpBase->get('zp_model_oth', ['*'], sprintf(" and zmo_unikey='%s'", $zpModOth['zmo_unikey']), true);
			if(!empty($res['data'])){
				$zpModOth = $res['data'];
			}else{
				$this->ZpBase->add('zp_model_oth', $zpModOth);
			}
		}

		//提取时间
		$tm['mod1'] = preg_replace('/(\d{6}-)\)/', '$1至今)', $tm['mod1']); //朗逸 三厢(184 201501-)
		$tm['mod2'] = preg_replace('/(\d{6}-)\)/', '$1至今)', $tm['mod2']); //朗逸 三厢(184 201501-)
		$tm['mod1'] = preg_replace('/(\d{6}-)$/', '$1至今)', $tm['mod1']); //182(201203-
		$tm['mod2'] = preg_replace('/(\d{6}-)$/', '$1至今)', $tm['mod2']); //182(201203-
		if(preg_match('/\d{6}-((\d{6})|(至今))/', trim($tm['mod1'].' '.$tm['mod2']), $match)){
			$tm['mod_ym'] = $match[0];
			$tm['mod_y'] = preg_replace('/(\d{4})(\d{2})/', '${1}', $tm['mod_ym']);
			$tm['mod1'] = str_replace($tm['mod_ym'], $tm['mod_y'], $tm['mod1']);
			if(!empty($tm['mod2'])) $tm['mod2'] = str_replace($tm['mod_ym'], $tm['mod_y'], $tm['mod2']);
		}

		//提取产品适配属性 
		$setArr = ['mod_auo_sub_id'=>0, 'mod_auo_param'=>'[]', 'mod_match_yp'=>'[]', 'mod_match_time'=>0];
		$param = [];
		if(!empty($tm['sbym'])){
			$param[] = '时间：'.$tm['sbym'].'-'.(empty($tm['seym'])? $tm['seym']: '至今');
		}else if($tm['mod_ym']) {
			$param[] = '时间：'.$tm['mod_ym'];
		}
		$pfArr = ['engine'=>'发动机型号', 'drive'=>'驱动方式','tran'=>'变速箱型号','gxbs'=>'工信部型号','remark'=>'备注','nk'=>'年款'];
		foreach($pfArr as $pk=>$pv)
		{
			if(!empty($tm[$pk])) $param[] = $pv.'：'.$tm[$pk];
		}
		$setArr['mod_auo_param'] = json_encode([implode('，', $param)], JSON_UNESCAPED_UNICODE);

		if(!empty($zpModOth['zmo_zvm_mod3_id'])){
			$setArr['mod_auo_sub_id'] = $zpModOth['zmo_zvm_mod3_id'];
		}else if(isset($this->mod2JsonCache[$unikey])){//缓存
			$zpModOth = $this->mod2JsonCache[$unikey];
			if(!empty($zpModOth['zmo_zvm_mod3_id'])) $setArr['mod_auo_sub_id'] = $zpModOth['zmo_zvm_mod3_id'];
		}else{
			//-----可能的生产商-----
			$tm['brandwhere'] = []; $tm['ccwhere'] = []; $tm['modwhere'] = [];
			$tm['brands'] = [$tm['brand']];
			if($tm['brand'] == '东风') $tm['brands'][] = '东风汽车';
			if($tm['brand'] == '比速') $tm['brands'][] = '比速汽车';
			if($tm['brand'] == '飞碟') $tm['brands'][] = '永源/飞碟';
			if($tm['brand'] == '唐骏') $tm['brands'][] = '唐骏欧铃';
			if($tm['brand'] == '上汽大通MAXUS') $tm['brands'][] = '上汽MAXUS';
			if(stripos($tm['make'], '进口') !== false){
				$tm['brandwhere'][] = sprintf(" and make_name in ('%s') and brand_name like '%%进口%%'", implode("','", $tm['brands']));
			}else if(!empty($tm['make'])){
				$tm['brandwhere'][] = sprintf(" and make_name in ('%s') and brand_name ='%s'", implode("','", $tm['brands']), $tm['make']);
				$tm['brandwhere'][] = sprintf(" and make_name = '%s'", $tm['make']);
			}
			$tm['brandwhere'][] = sprintf(" and make_name in ('%s')", implode("','", $tm['brands']));
			
			//-----可能的排量-----
			$tm['cc_names'] = [$tm['cc']];
			if(!empty($tm['fuel']) && stripos($tm['fuel'], '汽油') === false) $tm['cc_names'][] = trim($tm['cc'].'-'.strtr($tm['fuel'], ['车'=>'']), '-');
			if($tm['fuel'] == '两用燃料') $tm['cc_names'][] = trim($tm['cc'].'-天然气', '-');
			
			foreach($tm['cc_names'] as $tnc){
				$tm['ccwhere'][] = sprintf(" and sub_name='%s'", $tnc);
			}
			foreach($tm['cc_names'] as $tnc){
				if(stripos($tnc, '-') === false) $tm['ccwhere'][] = sprintf(" and sub_name like '%s(%%'", $tnc);
				if(stripos($tnc, '燃料电池') !== false) $tm['ccwhere'][] = sprintf(" and sub_name like '%%%s%%'", $tnc);
			}

			//-----可能的车代-----
			if(stripos($tm['mod2'], $tm['mod1']) === 0){
				$tm['mod2_name'] = $tm['mod2']; //A5 Coupe quattro(8T3 200706-201707)
			}else{
				$tm['mod2_name'] = $tm['mod1'];
				if(!empty($tm['mod2'])) {
					$tm['mod2_name'] .= '('.str_replace('(', ' ', $tm['mod2']).')';
				}
			}
			$tm['mod2_name'] = strtr($tm['mod2_name'], ['(0-0)'=>'',' 0-0)'=>'', '))'=>')', ')('=>' ']);
			$tm['mod2_names'] = [$tm['mod2_name']];
			if(!empty($tm['mod_y'])) $tm['mod2_names'][] = strtr(str_replace($tm['mod_y'], '', $tm['mod2_name']), ['()'=>'', ' )'=>')']);
			if($tm['mod2_name'] == '域虎') $tm['mod2_names'][] = '域虎(2011-2018)';
			if(in_array($tm['make'], ['进口宝马']) 
				|| in_array($tm['mod1'], ['1系','2系','3系','3系GT','4系','5系','5系GT','6系','6系GT','7系','8系','M2系','M3系','M4系','M5系','X3','X4','X6','AMG C级','C级','E级','S级','SL级','SLK级', 'SLC级', '唯雅诺','奔驰S级','奔驰C级','奔驰E级','奔驰CLS级','奔驰ML级','S级 迈巴赫'])
				|| (stripos($tm['make'], '进口') !== false && stripos($tm['mod1'], '系'))
				|| (stripos($tm['make'], '进口') !== false && stripos($tm['mod1'], '级'))
			) 
				$tm['mod2_names'][] = $tm['mod2'];
			
			$tm['mod_names'] = [];
			$tm['mod2_names'] = array_unique($tm['mod2_names']);
			foreach($tm['mod2_names'] as $tk=>$tv)
			{
				$tnames = [$tv];
				if(stripos($tv, '思威CR-V') === 0) $tnames[] = str_replace('思威CR-V', 'CR-V思威', $tv);
				if(stripos($tv, '福运S系/小福星S系') === 0) $tnames[] = str_replace('福运S系/小福星S系', '福运S系/福星S系', $tv);
				if(stripos($tv, '新豹二代') === 0) $tnames[] = str_replace('新豹二代', '新豹2', $tv);
				if(stripos($tv, '新豹三代') === 0) $tnames[] = str_replace('新豹二代', '新豹3', $tv);
				if(stripos($tv, '瑞纳 三厢(HC') === 0) $tnames[] = str_replace('瑞纳 三厢(HC', '瑞纳(HC', $tv);
				if(stripos($tv, '飞度 两厢') === 0) $tnames[] = str_replace('飞度 两厢', '飞度', $tv);
				if(stripos($tv, '朗逸 三厢') === 0) $tnames[] = str_replace('朗逸 三厢', '朗逸', $tv);
				if(stripos($tv, '炫威XR-V') === 0) $tnames[] = str_replace('炫威XR-V', 'XR-V炫威', $tv);
				if(stripos($tv, '英朗XT') === 0) $tnames[] = str_replace('英朗XT', '英朗 XT', $tv);
				if(stripos($tv, '英朗GT') === 0) $tnames[] = str_replace('英朗GT', '英朗 GT', $tv);
				if(stripos($tv, '悦动(ELANTRA)') === 0) $tnames[] = str_replace('悦动(ELANTRA)', '悦动 ELANTRA', $tv);
				if(stripos($tv, '桑塔纳 三厢(B2') === 0) $tnames[] = str_replace('桑塔纳 三厢(B2', '桑塔纳(B2', $tv);
				if(stripos($tv, '新桑塔纳/浩纳') === 0) $tnames[] = str_replace('新桑塔纳/浩纳', '新桑塔纳/浩纳 两厢', $tv);
				if(stripos($tv, '金刚 三厢') === 0) $tnames[] = str_replace('金刚 三厢', '金刚', $tv);
				if(stripos($tv, '一代') !== false) $tnames[] = str_replace('一代', '1代', $tv);
				if(stripos($tv, '二代') !== false) $tnames[] = str_replace('二代', '2代', $tv);
				if(stripos($tv, '三代') !== false) $tnames[] = str_replace('三代', '3代', $tv);
				if(stripos($tv, '四代') !== false) $tnames[] = str_replace('四代', '4代', $tv);
				if(stripos($tv, '五代') !== false) $tnames[] = str_replace('五代', '5代', $tv);
				if(stripos($tv, '六代') !== false) $tnames[] = str_replace('六代', '6代', $tv);
				if(stripos($tv, '七代') !== false) $tnames[] = str_replace('七代', '7代', $tv);
				if(stripos($tv, '八代') !== false) $tnames[] = str_replace('八代', '8代', $tv);
				if(stripos($tv, '九代') !== false) $tnames[] = str_replace('九代', '9代', $tv);
				if(stripos($tv, '十代') !== false) $tnames[] = str_replace('十代', '10代', $tv);
				if(stripos($tv, '凯越 新款(') === 0) $tnames[] = str_replace('凯越 新款(', '凯越(新款 ', $tv);
				if(stripos($tv, '凯越 老款(') === 0) $tnames[] = str_replace('凯越 老款(', '凯越(老款 ', $tv);
				if(stripos($tv, '圣达菲 新款') === 0) $tnames[] = str_replace('圣达菲 新款', '圣达菲新款', $tv);
				if(stripos($tv, '新桑塔纳/浩纳') === 0) $tnames[] = str_replace('新桑塔纳/浩纳', '新桑塔纳/浩纳 两厢', $tv);
				if(stripos($tv, 'MINI ') === 0) $tnames[] = str_replace('MINI ', '', $tv);
				if(stripos($tv, '-至今)')) $tnames[] = str_replace('-至今)', '-)', $tv);
				if($tm['brand'] == '东风风光' && stripos($tv, '风光') === false) $tnames[] = '风光'.$tv;
				if($tm['brand'] == '东风风行' && stripos($tv, '风行') === false) $tnames[] = '风行'.$tv;
				if($tm['make'] == '广汽三菱' && $tv == '帕杰罗(V73)') $tnames[] = '帕杰罗V73';
				if($tv == '爱唯欧 两厢') $tnames[] = '爱唯欧(两厢)';
				if($tv == '爱唯欧 三厢') $tnames[] = '爱唯欧(三厢)';
				if($tv == '五菱宏光V') $tnames[] = '五菱荣光V/五菱宏光V';
				if($tv == 'CX30 两厢(CX30)') $tnames[] = 'CX30 两厢';
				if($tv == 'CX30 三厢(CX30)') $tnames[] = 'CX30 三厢';
				if($tv == '理念S1') $tnames[] = 'S1';
				if($tv == '致尚XT(第一代 2013-2016)') $tnames[] = '致尚XT(2013-2016)';
				if(stripos($tm['make'], '进口') !== false) $tnames[] = $tv.'(进口)';
				$tm['mod_names'][$tv] = $tnames;
			}
			
			$ignoreReg = '[\(\) \\-\/]';
			foreach($tm['mod_names'] as $tncs){
				$tnames = [];
				foreach($tncs as $tnc){
					$tnames[] = preg_replace('/'.$ignoreReg.'/', '', $tnc);
				}
				$tm['modwhere'][] = [
					'names'=>$tncs,
					'where'=>sprintf(" and REGEXP_REPLACE(model_name, '%s', '') in ('%s')", $ignoreReg, implode("','", $tnames))
				];
			}
			
			foreach($tm['mod_names'] as $tncs){
				$twhere = [];
				foreach($tncs as $tnc){
					$twhere[] = sprintf(" REGEXP_REPLACE(model_name, '%s', '') like '%s%%'", $ignoreReg, preg_replace('/'.$ignoreReg.'/', '', $tnc));
					if(substr($tnc, -1) == ')' && !preg_match('/\d{4}/', $tnc, $match)){
						$twhere[] = sprintf(" REGEXP_REPLACE(model_name, '%s', '') like '%s%%'", $ignoreReg, preg_replace('/'.$ignoreReg.'/', '', substr($tnc, 0, -1)));
					}
					if(preg_match('/ ?\d{4}-(\d{4}|至今|)/', $tnc, $match)){
						$tname = str_replace($match[0], '%', $tnc);
						$twhere[] = sprintf(" REGEXP_REPLACE(model_name, '%s', '') like '%s%%'", $ignoreReg, preg_replace('/'.$ignoreReg.'/', '', $tname));
					}
					//博越 2016-(2015-至今) => 博越(2015-至今)
					if(preg_match('/( ?\d{4}-[(\d{4})|(至今)]?)\(\d{4}\-/', $tnc, $match)){
						$tname = str_replace($match[1], '%', $tnc);
						$twhere[] = sprintf(" REGEXP_REPLACE(model_name, '%s', '') like '%s%%'", $ignoreReg, preg_replace('/'.$ignoreReg.'/', '', $tname));
					}
				}
				$twhere = array_unique($twhere);
				$tm['modwhere'][] = [
					'names'=>$tncs,
					'where'=>sprintf(" and (%s)", implode(' or ', $twhere))
				];
			}

			$tm['wheres'] = [];
			foreach($tm['brandwhere'] as $bwhere)
			{
				foreach($tm['ccwhere'] as $ccwhere)
				{
					foreach($tm['modwhere'] as $modw)
					{
						$where = $bwhere.$ccwhere.$modw['where'].' group by sub_id';
						$tm['wheres'][] = $where;
						$res = $this->ZpBase->get('data_model', ['*'], $where);
						$likeArr = $res['data'];
						if(count($likeArr) == 1)
						{
							$tm['match'] = $likeArr[0];
							$zpModOth['zmo_zvm_mod3_id'] = $tm['match']['sub_id'];
							$tset = ['zmo_status'=>1, 'zmo_zvm_mod3_id'=>$zpModOth['zmo_zvm_mod3_id'], 'zmo_etime'=>time()];
							$this->ZpBase->set('zp_model_oth', $tset, sprintf(" and zmo_unikey='%s'", $zpModOth['zmo_unikey']));
							break;
						}
						else if(count($likeArr) > 1)
						{
							foreach($likeArr as $ltk=>$ltv)
							{	
								$mname = preg_replace('/\d{4}-\d{4}/', '%', $ltv['model_name']);
								$mname = preg_replace('/\d{4}-至今/', '%', $mname);
								$mname = strtr($mname, ['()'=>'']);
								if(in_array($mname, $modw['names']))
								{
									$tm['match'] = $ltv;
									$zpModOth['zmo_zvm_mod3_id'] = $tm['match']['sub_id'];
									$tset = ['zmo_status'=>1, 'zmo_zvm_mod3_id'=>$zpModOth['zmo_zvm_mod3_id'], 'zmo_etime'=>time()];
									$this->ZpBase->set('zp_model_oth', $tset, sprintf(" and zmo_unikey='%s'", $zpModOth['zmo_unikey']));
									break;
								}
							}
							if(!empty($zpModOth['zmo_zvm_mod3_id'])) break;
						}
					}
					if(!empty($zpModOth['zmo_zvm_mod3_id'])) break;
				}
				if(!empty($zpModOth['zmo_zvm_mod3_id'])) break;
			}
			
			$this->mod2JsonCache[$unikey] = $zpModOth;
			if(!empty($zpModOth['zmo_zvm_mod3_id'])){
				$setArr['mod_auo_sub_id'] = $zpModOth['zmo_zvm_mod3_id'];
			}else{
				//var_dump($tm, $zpModOth, $dv, $setArr); exit;
			}
		}
		$this->ZpBase->set('auto_product_model', $setArr, sprintf(" and mod_apmid=%d", $dv['mod_apmid']));
		return LibFc::ReturnData(true, $setArr);
	}

	//过滤车型
	private function filterMod($zpMod, $modArr)
	{
		$matchArr = ['ok'=>[], 'error'=>[]];
		if(empty($zpMod['zp_param'])){
			foreach($modArr as $m3id=>$mod){
				$matchArr['ok'][$m3id] = [[]];
			}
			return LibFc::ReturnData(true, $matchArr);
		}
		$comFileds = ['发动机型号', '电动机名称', '驱动方式', '驻车制动类型', '变速箱型号', '工信部型号', '时间'];
		$merge = [];
		//["发动机型号：CPJ，时间：201205-201412", "发动机型号：CFN，时间：201205-至今"]  ["发动机型号：DAM15DL，时间：201401-至今", "发动机型号：BJ415A，时间：201401-至今"]
		foreach($zpMod['zp_param'] as $ipvp){
			$unikey = '';
			foreach($comFileds as $filed){
				if(empty($ipvp[$filed])) continue;
				$unikey .= $filed;
			}
			$merge[$unikey][] = $ipvp; 
		}
			
		foreach($modArr as $m3id=>$mod){
			$errArr = [];
			foreach($merge as $unikey=>$ipvps){
				foreach($ipvps as $ipvp){
					$terrArr = [];
					$tokArr = [];
					$ipvp['needtime'] = 0; //需要备注时间的车型
					foreach($comFileds as $filed)
					{
						if(empty($ipvp[$filed])) continue;
						$fvv = $ipvp[$filed];
						switch($filed)
						{
							case '时间':
								if(
									((!empty($mod['mod3_ym_s']) && $fvv[0] <= $mod['mod3_ym_s']) || (empty($mod['mod3_ym_s']) && substr($fvv[0], 0, 4) <= $mod['mod3_y_s'])) &&
									((!empty($mod['mod3_ym_e']) && $fvv[1] >= $mod['mod3_ym_e']) || (empty($mod['mod3_ym_e']) && substr($fvv[1], 0, 4) >= $mod['mod3_y_e']))
								){
									$tokArr[] = $filed;
								}else if(
									(
										(!empty($mod['mod3_ym_s']) && $mod['mod3_ym_s'] <= $fvv[1]) || (!empty($mod['mod3_y_s']) && $mod['mod3_y_s'] <= substr($fvv[1], 0, 4))
									) &&
									(
										(!empty($mod['mod3_ym_e']) && $mod['mod3_ym_e'] >= $fvv[0]) || (!empty($mod['mod3_y_e']) && $mod['mod3_y_e'] >= substr($fvv[0], 0, 4))
									)
								) {////$start1 <= $end2 && $end1 >= $start2 时间有交集、将时间放入到车型备注里
									$tokArr[] = $filed;
									$ipvp['needtime'] = 1;
								}else{
									$errtxt = $filed.'：'.$fvv[2].'=>'.($mod['mod3_ym_s']? : $mod['mod3_y_s']).'-'.($mod['mod3_ym_e']? : $mod['mod3_y_e']).'不符';
									$terrArr[] = strtr($errtxt, ['300012'=>'至今']);
								}
							break;
							case '发动机型号':
							case '电动机名称':
								$format = LibFc::FormatNum($fvv);
								if(
									(!empty($mod['mod3_engine_format']) && 
										($format == $mod['mod3_engine_format'] || 'M'.$format == $mod['mod3_engine_format'] || $format == 'M'.$mod['mod3_engine_format'] || 'OM'.$format == $mod['mod3_engine_format'] || $format == 'OM'.$mod['mod3_engine_format'])
									) ||
									(strlen($mod['mod3_engine']) > 2 && stripos($fvv, $mod['mod3_engine']) === 0) ||
									(strlen($fvv) > 2 && stripos($mod['mod3_engine'], $fvv) === 0) ||
									($fvv == '2H0' && $mod['mod3_engine'] == '2HO') ||
									strlen($fvv) === 1
								){//1GR=>1GR-FE
									$tokArr[] = $filed;
								}else{
									$terrArr[] = $filed.'：'.$fvv.'=>'.$mod['mod3_engine_format'].'不符';
								}
							break;
							case '驱动方式':
								if(!empty($mod['mod3_drive']) && (stripos($fvv, $mod['mod3_drive']) !== false || stripos($mod['mod3_drive'], $fvv) !== false)){
									$tokArr[] = $filed;
								}else{
									$terrArr[] = $filed.'：'.$fvv.'=>'.$mod['mod3_drive'].'不符';
								}
							break;
							case '驻车制动类型':
								if(!empty($mod['parking_brake']) && (stripos($fvv, $mod['parking_brake']) !== false || stripos($mod['parking_brake'], $fvv) !== false)){
									$tokArr[] = $filed;
								}else{
									$terrArr[] = $filed.'：'.$fvv.'=>'.$mod['parking_brake'].'不符';
								}
							break;
							case '变速箱型号':
								if(!empty($mod['transmission']) && (
									(stripos($fvv, $mod['transmission']) !== false || stripos($mod['transmission'], $fvv) !== false) ||
									$fvv == strtr($mod['transmission'], ['手自一体'=>'自动', 'CVT'=>'自动'])
								)){
									$tokArr[] = $filed;
								}else{
									$terrArr[] = $filed.'：'.$fvv.'=>'.$mod['transmission'].'不符';
								}
							break;
							case '工信部型号':
								$format = LibFc::FormatNum($fvv);
								$res = $this->YpcBase->get('yp_model3_gxb_num', ['mg_code'], sprintf(" and mg_m3_id=%d", $m3id));
								$gxbs = array_column($res['data'], 'mg_code');
								if(!empty($format) && in_array($format, $gxbs)){
									$tokArr[] = $filed;
								}else{
									$terrArr[] = $filed.'：'.$fvv.'=>'.implode(',', $gxbs).'不符';
								}
							break;
						}
					}
					if(empty($terrArr)){//$m3id 匹配成功
						$matchArr['ok'][$m3id][] = $ipvp;
						break;
					}else{
						$matchArr['error'][$m3id][] = implode(',', $terrArr);
					}
				}
			}
		}

		foreach($matchArr['ok'] as $m3id=>$ipvps){
			if(isset($matchArr['error'][$m3id])) unset($matchArr['error'][$m3id]);
		}
		foreach($matchArr['error'] as $m3id=>$errs){
			$matchArr['error'][$m3id] = array_unique($errs);
		}
		return LibFc::ReturnData(true, $matchArr);
	}

	//获取车型ID
	private function getFormatMod3($m3idArr)
	{
		$arr = [];
		if(!empty($m3idArr))
		{
			$m3idArr = array_unique($m3idArr);
			$ComModel = new ComModel();
			$filed = ['mod3_id, mod3_start_year, mod3_start_month, mod3_end_year, mod3_end_month, mod3_engine, mod3_engine_format, mod3_cc, mod3_transmission,mod3_drive,mod3_drive_short, mod3_parking_brake'];
			$mres = $ComModel->get('bc_model3', $filed, sprintf(" and mod3_id in (%s)", implode(',', $m3idArr)));
			foreach($mres['data'] as $v)
			{
				//年份转换
				if(empty($v['mod3_start_year'])){
					$v['mod3_y_s'] = '1949';
					$v['mod3_ym_s'] = '194901';
				}else{
					$v['mod3_y_s'] = $v['mod3_start_year'];
					if(!empty($v['mod3_start_month'])) $v['mod3_ym_s'] = $v['mod3_y_s'].$v['mod3_start_month'];
				}
				
				if(empty($v['mod3_end_year'])){
					$v['mod3_y_e'] = '3000';
					$v['mod3_ym_e'] = '300012';
				}else{
					$v['mod3_y_e'] = $v['mod3_end_year'];
					if(!empty($v['mod3_end_month'])) $v['mod3_ym_e'] = $v['mod3_y_e'].$v['mod3_end_month'];
				}
				unset($v['mod3_start_year']);unset($v['mod3_start_month']);unset($v['mod3_end_year']);unset($v['mod3_end_month']);
				$v['parking_brake'] = $this->formatParkingBrake($v['mod3_parking_brake']);
				$v['transmission'] = $this->formatTransmission($v['mod3_transmission']);
				$arr[$v['mod3_id']] = $v;
			}
		}
		return LibFc::ReturnData(true, $arr);
	}
}