<?php
/**
  * @method 配件搜索
  * @author soul
  * @copyright 2017/9/22
  */
class B2cSearch extends B2cBase
{
	/**
	  * @method 增加查询记录
	  * @param  $dataArr [
		'ush_uid'=>'查询人',
		'ush_shop_id'=>'店铺ID',
		'ush_type'=>'vin|number|engine|model|item',
		'ush_word'=>'查询内容'
	  ]
	  * @author soul
	  * @copyright 2021/12/25
	  * @return 
	  */
	public function addSearchHistory($dataArr)
	{
		$ush_id = 0;
		if(!empty($dataArr['ush_uid']) && !empty($dataArr['ush_shop_id']) && !empty($dataArr['ush_word']))
		{
			$addArr = [
				'ush_uid'=>(int) $dataArr['ush_uid'],
				'ush_shop_id'=>(int) $dataArr['ush_shop_id'],
				'ush_type'=> $dataArr['ush_type'],
				'ush_word'=> LibFc::Escape($dataArr['ush_word']),
				'ush_etime'=>time()
			];
			
			$chk = sprintf(" and ush_uid=%d and ush_shop_id=%d and ush_type='%s' and ush_word='%s'", 
				$addArr['ush_uid'],$addArr['ush_shop_id'],$addArr['ush_type'],$addArr['ush_word']);
			$res = $this->get('us_search_history', ['ush_id'], $chk, true);
			$this->B2CDb->Begin();
			if(!empty($res['data']))
			{
				$ush_id = $res['data']['ush_id'];
				$this->set('us_search_history', ['ush_etime'=>time()], sprintf(" and ush_id=%d", $ush_id));
			}
			else
			{
				$res = $this->add('us_search_history', $addArr);
				$ush_id = $res['data'];
				$this->del('us_search_history', sprintf(" and ush_uid=%d and ush_etime < %d", $addArr['ush_uid'], strtotime('-6 month')));
			}
			$this->B2CDb->End();
		}
		return LibFc::ReturnData(true);
	}


	/**
	  * @method 配件搜索  条件：keyword关键字、mod3Id末级车型ID、partId末级配件分类、prbId配件品牌、minPrice maxPrice价格区间
	  * @param  $Params URL参数
	  * @author soul
	  * @copyright 2017/9/22
	  * @return 
			成功 ["status"=>true, "data"=> ] 
			失败 ["status"=>false, "data"=> 错误信息] 
	  */
	public function searchProduct($Params, $showConf = ['pro_show_b2c'=>1])
	{
		if(empty($Params['keyword']) && !empty($Params['word'])) $Params['keyword'] = $Params['word'];
		$returnArr = [
			'param'=>$Params,
			'proIds'=>[],
			'total'=>0,
			//此条件下配件的适用车型ID
			'mod3Ids'=>[],
			//此条件下配件的所有分类ID
			'partIds'=>[],
			//此条件下配件的配件品牌ID
			'prbIds'=>[],
			//表示是否已经有参数进入查询
			'searchFlag'=>false,
			'pal'=>[]
		];

		$showWhere = [];
		foreach($showConf as $k=>$v)
		{
			$showWhere[] = sprintf(" %s=%d", LibFc::Escape($k), $v);
		}
		$showWhere = empty($showWhere)? '': sprintf(" and (%s)", implode(',', $showWhere));

		$table = 'bc_product join sh_shop on pro_shop_id=shop_id and shop_istest =0 and shop_status = 1 and pro_status =1 '.$showWhere;
		$whereArr = [];

		$Params['mod3Id'] = (int) $Params['mod3Id'];

		if($Params['mod3Id'] > 0)
		{
			$table .= ' left join bc_product_model3_link on pro_id = pml3_pro_id';
			$whereArr['mod3'] = sprintf(" and pml3_mod3_id=%d", $Params['mod3Id']);
		}
		
		//配件分类
		$Params['partId'] = (int) $Params['partId'];

		if($Params['partId'] > 0)
		{
			$returnArr['partIds'][] = $Params['partId'];
			$whereArr['part'] = sprintf(" and pro_part_id=%d", $Params['partId']);

			//适用品牌
			$Params['prbId'] = (int) $Params['prbId'];
			if($Params['prbId'] > 0)
			{
				$returnArr['prbIds'][] = $Params['prbId'];
				$whereArr['proBrand'] = sprintf(" and pro_prb_id=%d", $Params['prbId']);
			}

			$table .= ' left join bc_product_param_string on pro_id = pps_pro_id';
			//配件分类参数查询
			$Params['palId'] = (int) $Params['palId'];
			$Params['palVal'] = isset($Params['palVal'])? trim($Params['palVal']): '';
			if($Params['palId'] > 0 && $Params['palVal'] != '')
			{
				$whereArr['pal'] = sprintf(" and pps_pal_id=%d and pps_value='%s'", $Params['palId'], LibFc::Escape($Params['palVal']));
			}
		}
		else
		{
			$Params['prbId'] = 0;
		}

		//配件关键字
		if($Params['keyword'] != '')
		{
			$keywordArr = LibFc::keyword($Params['keyword']);
			$B2cKeyword = new B2cKeyword();
			$res = $B2cKeyword->getKeywordKeyIds($keywordArr);
			if(!empty($res['data']))
			{
				$tempWhere = sprintf(" and (
					pro_id in (select prk_pro_id from bc_product_keyword where prk_key_id in (%s) group by prk_pro_id having count(*) = %d)
					or pro_name like '%%%s%%')", implode(',', $res['data']), count($res['data']), LibFc::Escape($Params['keyword']));

				//$tempWhere = sprintf(" and pro_id in (select prk_pro_id from bc_product_keyword where prk_key_id in (%s) group by prk_pro_id having count(*) = %d)", implode(',', $res['data']), count($res['data']));
			}
			else
			{
				$tempWhere = sprintf(" and pro_name like '%%%s%%'", LibFc::Escape($Params['keyword']));
			}
			$whereArr['word'] = $tempWhere;
		}

		if(!empty($Params['minPrice']) || !empty($Params['maxPrice']))
		{
			//价格区间
			$whereArr['price']= !empty($Params['minPrice']) ? sprintf(' and (case when pro_promotion_btime<=%d and pro_promotion_etime>=%d then pro_promotion_price else pro_sale_price end) >=%.2f',time(),time(),$Params['minPrice']) : '';
			$whereArr['price'] .= !empty($Params['maxPrice']) ? sprintf(' and (case when pro_promotion_btime<=%d and pro_promotion_etime>=%d then pro_promotion_price else pro_sale_price end) <=%.2f',time(),time(),$Params['maxPrice']) : '';
		}

		if($Params['partId'] > 0)
		{
			//配件品牌
			$temp = $whereArr;
			unset($temp['proBrand']);
			$temp[] = ' and pro_prb_id > 0';
			$res = $this->get($table, ['distinct pro_prb_id'], implode(' ', $temp));
			foreach($res['data'] as $v)
			{
				$returnArr['prbIds'][] = $v['pro_prb_id'];
			}

			$res = $this->get('bc_part_param_link join bc_param_label on pal_id=ppl_pal_id', ['ppl_pal_id', 'pal_name'], sprintf(" and ppl_part_id=%d order by ppl_seq limit 1", $Params['partId']), true);
			if(!empty($res['data']))
			{
				$palArr = $res['data'];
				$returnArr['pal'] = ['id'=>$palArr['ppl_pal_id'], 'name'=>$palArr['pal_name'], 'vals'=>[]];

				//配件公共参数
				$temp = $whereArr;
				unset($temp['pal']);
				$temp[] = ' and pps_pal_id = '.$palArr['ppl_pal_id'];
				$res = $this->get($table, ['distinct pps_value'], implode(' ', $temp));
				$returnArr['pal']['vals'] = array_column($res['data'], 'pps_value');
			}
		}

		//过滤车型备注的时间
		if(!empty($Params['mod3_id']) && $Params['vinyear']){
			$ignorePids = [];
			$tarr = explode('-', $Params['vinyear']);
			$ym = ['y'=>$tarr[0], 'ym'=>''];
			if($tarr[1]) $ym['ym'] = date('Ym', strtotime($tarr[0].'-'.$tarr[1].'-01'));
			$res = $this->get($table, ['pro_id, pml3_remark'], implode(' ', $whereArr).' and length(pml3_remark) > 7');
			foreach($res['data'] as $pv){
				$pv['pml3_remark'] = strtr($pv['pml3_remark'], ['-至今'=>'-'.date('Ym')]);
				if(preg_match_all('/(\d{6})-(\d{6})/', $pv['pml3_remark'], $match, PREG_SET_ORDER)){
					$isok = false;
					foreach($match as $mv){
						if(($ym['ym'] && $ym['ym'] >= $mv[1] && $ym['ym'] <= $mv[2]) || (empty($ym['ym']) && $ym['y'] >= substr($mv[1], 0, 4) && $ym['y'] <= substr($mv[2], 0, 4))){
							$isok = true;
							break;
						}
					}
					if(!$isok) $ignorePids[] = $pv['pro_id'];
				}
			}
			if($ignorePids) $whereArr['ignore'] = sprintf(" and pro_id not in (%s)", implode(',', $ignorePids));
		}
			
		//配件分类
		$temp = $whereArr;
		unset($temp['part']);
		$temp[] = ' and pro_part_id > 0';
		$res = $this->get($table, ['distinct pro_part_id'], implode(' ', $temp));
		foreach($res['data'] as $v)
		{
			$returnArr['partIds'][] = $v['pro_part_id'];
		}

		if(!empty($whereArr))
		{
			$returnArr['searchFlag'] = true;
			$res = $this->get($table, ['count(distinct(pro_id)) count'], implode(' ', $whereArr), true);
			$returnArr['total'] = $res['data']['count'];
			if($returnArr['total'] > 0)
			{
				//默认销量排序
				$res = $this->getSearchProductOrder($Params);
				$orderBy = $res['data'];
				$where = sprintf(" and pro_id in (select pro_id from %s where 1=1 %s group by pro_id) group by pro_id %s limit %d, %d", $table, implode(' ', $whereArr), $orderBy,  ($Params['page']-1)*$Params['perPage'], $Params['perPage']);
				$res = $this->get('bc_product join sh_shop on pro_shop_id=shop_id join bc_product_info on pri_pro_id=pro_id', ['pro_id'], $where);
				$returnArr['proIds'] = array_column($res['data'], 'pro_id');
			}
		}
		$returnArr['param'] = $Params;
		$returnArr['partIds'] = array_unique($returnArr['partIds']);
		$returnArr['prbIds'] = array_unique($returnArr['prbIds']);
		return LibFc::ReturnData(true, $returnArr); 
	}


	/**
	  * @method 号码搜索配件
	  * @param  $Params URL参数
	  * @author soul
	  * @copyright 2017/9/22
	  * @return 
			成功 ["status"=>true, "data"=> ] 
			失败 ["status"=>false, "data"=> 错误信息] 
	  */
	public function searchProductByNumber($Params, $showConf = ['pro_show_b2c'=>1])
	{
		$returnArr = [
			'param'=>$Params,
			'proIds'=>[],
			'total'=>0
		];
		$Params['formatNum'] = LibFc::FormatNum($Params['keyword']);
		if(strlen($Params['formatNum']) > 2)
		{
			$showWhere = [];
			foreach($showConf as $k=>$v)
			{
				$showWhere[] = sprintf(" %s=%d", LibFc::Escape($k), $v);
			}
			$showWhere = empty($showWhere)? '': sprintf(" and (%s)", implode(',', $showWhere));

			$where = sprintf(" and pro_status=1 %s and (num_format like '%s%%' or num_reformat like '%s%%')", $showWhere, $Params['formatNum'], strrev($Params['formatNum']));
		
			//价格范围
			$where .= !empty($Params['minPrice']) ? sprintf(' and (case when pro_promotion_btime<=%d and pro_promotion_etime>=%d then pro_promotion_price else pro_sale_price end) >=%.2f',time(),time(),$Params['minPrice']) : '';
			$where .= !empty($Params['maxPrice']) ? sprintf(' and (case when pro_promotion_btime<=%d and pro_promotion_etime>=%d then pro_promotion_price else pro_sale_price end) <=%.2f',time(),time(),$Params['maxPrice']) : '';
			
			$table = 'bc_number join bc_product on pro_id = num_pro_id join sh_shop on pro_shop_id=shop_id and shop_status = 1  and shop_istest =0';
			//销售中并且库存大于0
			$res = $this->get($table, ['count(distinct(pro_id)) count'], $where, true);
			$returnArr['total'] = $res['data']['count'];
			if($returnArr['total'] > 0)
			{
				//默认销量排序
				$res = $this->getSearchProductOrder($Params);
				$orderBy = $res['data'];
				$where = sprintf(" and pro_id in (select pro_id from %s where 1=1 %s group by pro_id) group by pro_id %s limit %d, %d", $table, $where, $orderBy,  ($Params['page']-1)*$Params['perPage'], $Params['perPage']);
				$res = $this->get('bc_product join sh_shop on pro_shop_id=shop_id join bc_product_info on pri_pro_id=pro_id', ['pro_id'], $where);
				$returnArr['proIds'] = array_column($res['data'], 'pro_id');
			}
		}
		return LibFc::ReturnData(true, $returnArr); 
	}
	
	
	/**
	  * @method 获取配件搜索的排序条件
	  * @param  $Params URL参数  new-desc | price-asc | price-desc
	  * @author soul
	  * @copyright 2017/9/22
	  * @return 
			成功 ["status"=>true, "data"=>'order by pro_sold_count desc'] 
			失败 ["status"=>false, "data"=> 错误信息] 
	  */
	private function getSearchProductOrder($Params)
	{
		$corder = $Params['corder'] == 'desc'? 'desc': 'asc';
		$orderBy = ' order by shop_money_bail desc, pro_promoted asc,pro_host asc,pro_sold_count desc, pri_code '.$corder;
		if(!empty($Params['orderSelf'])) $orderBy = $Params['orderSelf'];
		switch($Params['order'])
		{
			//新品
			case 'new-desc':
				$orderBy = ' order by pro_id desc';
			break;
			//价格从底到高
			case 'price-asc':
				$orderBy = sprintf(' order by (case when pro_promotion_btime<=%d and pro_promotion_etime>=%d then pro_promotion_price else pro_sale_price end) asc, pri_code %s',time(),time(), $corder);
			break;
			//价格从高到底
			case 'price-desc':
				$orderBy = sprintf(' order by (case when pro_promotion_btime<=%d and pro_promotion_etime>=%d then pro_promotion_price else pro_sale_price end) desc, pri_code %s',time(),time(), $corder);
			break;
			case 'sold-count':
				$orderBy = ' order by pro_sold_count desc, pri_code '.$corder;
			break;
			case 'code':
				$orderBy = ' order by pri_code '.$corder;
			break;
			case 'part_code':
				$orderBy = ' order by pt_seq, pas_seq, part_initial, pri_code '.$corder;
			break;
			case 'part_proname':
				$orderBy = " order by pt_seq, pas_seq, part_initial, pro_name";
			break;
			case 'sort_code':
				$orderBy = " order by GROUP_CONCAT(LPAD(sort_seq,5,'0') ORDER BY sort_seq SEPARATOR ''), pri_code ".$corder;
			break;
			case 'sort_proname':
				$orderBy = " order by GROUP_CONCAT(LPAD(sort_seq,5,'0') ORDER BY sort_seq SEPARATOR ''), pro_name";
			break;
			case 'sort_part_code':
				$orderBy = " order by GROUP_CONCAT(LPAD(sort_seq,5,'0') ORDER BY sort_seq SEPARATOR ''), pt_seq, pas_seq, part_initial, pri_code ".$corder;
			break;
			case 'sort_part_proname':
				$orderBy = " order by GROUP_CONCAT(LPAD(sort_seq,5,'0') ORDER BY sort_seq SEPARATOR ''), pt_seq, pas_seq, part_initial, pro_name";
			break;
			case 'pids': 
				$orderBy = sprintf(" order by FIELD(pro_id, %s)",implode(',', $Params['orderPids']));
			break;
		}
		return LibFc::ReturnData(true, $orderBy);
	}



	/**
	  * @method 店铺配件搜索  条件：keyword关键字、mod3Id末级车型ID、sortId店铺分类、minPrice maxPrice价格区间
	  * @param  $shopId 店铺ID
	  * @param  $Params URL参数
	  * @param  $perPage 每页显示多少条
	  * @author soul
	  * @copyright 2017/9/22
	  * @return 
			成功 ["status"=>true, "data"=> ] 
			失败 ["status"=>false, "data"=> 错误信息] 
	  */
	public function searchShopItem($shopId, $Params, $perPage = 20, $showConf = ['pro_show_b2c'=>1])
	{
		$shopId = (int) $shopId;
		if(empty($Params['keyword']) && !empty($Params['word'])) $Params['keyword'] = $Params['word'];
		$res = $this->get('sh_shop', ['shop_id, shop_smainnum, shop_srefnum, shop_sorder,shop_corder, shop_wordorder'], sprintf(" and shop_id=%d", $shopId), true);
		if(empty($res['data'])) return LibFc::ReturnData(false, '店铺不存在或者尚未开通！');
		$shopInfo = $res['data'];
		$Params['corder'] = $shopInfo['shop_corder'];
		$returnArr = [
			'param'=>$Params,
			'proIds'=>[],
			'total'=>0,
			//此条件下配件的适用车型ID
			'mod3Ids'=>[],
			//此条件下配件的所有店铺分类ID
			'sortIds'=>[],
			//表示是否已经有参数进入查询
			'searchFlag'=>false,
			'pal'=>[]
		];

		//查询历史
		if(!empty($Params['uid']) && !empty($Params['keyword']))
		{
			$historyArr = [
				'ush_uid'=>$Params['uid'],
				'ush_shop_id'=>$shopId,
				'ush_type'=>$Params['type'],
				'ush_word'=>$Params['keyword'],
			];
			$this->addSearchHistory($historyArr);
		}

		$typeArr = [$Params['type']];
		//搜索类型为所有，并且关键字不含有中文
		if($Params['type'] == 'all' && $Params['keyword'] != '' && empty($Params['mod3Id']) && !preg_match('/[\x7f-\xff]+/', $Params['keyword']))
		{
			$typeArr = ['number', $Params['type']];
		}
		$showWhere = [];
		foreach($showConf as $k=>$v)
		{
			$showWhere[] = sprintf(" %s=%d", LibFc::Escape($k), $v);
		}
		$showWhere = empty($showWhere)? '': sprintf(" and (%s)", implode(',', $showWhere));

		foreach($typeArr as $type)
		{
			$twhere = !empty(mvc::$cfg['PROALL'])? '' : 'and pro_status =1';
			$table = 'bc_product join sh_shop on pro_shop_id=shop_id and shop_status = 1 '.$twhere.' '.$showWhere.' and shop_id='.$shopId;
			$whereArr = [];

			//店铺分类
			$Params['sort_id'] = (int) $Params['sort_id'];
			if($Params['sort_id'] > 0)
			{
				$returnArr['sortIds'][] = $Params['sort_id'];
				$table .= ' join bc_product_sort on prs_pro_id = pro_id';
				$whereArr['sort'] = sprintf(" and prs_sort_id=%d", $Params['sort_id']);
			}

			//零件分类
			if(!empty($Params['spart_id']))
			{
				$t = explode('_', $Params['spart_id']);
				$whereArr['part'] = sprintf(" and pro_part_id = %d", $t[0]);
				if(!empty($t[1])) $whereArr['part'] .= sprintf(" and pro_pas_id = %d", $t[1]);
			}

			switch($type)
			{
				case 'number':
					$Params['formatNum'] = LibFc::FormatNum($Params['keyword']);
					if(strlen($Params['formatNum']) > 2)
					{
						$whereArr['num'] = $Params['numtype'] == 2? sprintf(" and num_format ='%s'", $Params['formatNum']) : sprintf(" and num_format like '%%%s%%'", $Params['formatNum']);
						$table .= ' join bc_number on pro_id = num_pro_id';
					}
					else
					{
						$whereArr['num'] = ' and 1=0';
					}
				break;
				case 'all':
				case 'item':
				case 'model':
					$Params['brandId'] = (int) $Params['brandId'];
					$Params['mod3Id'] = (int) $Params['mod3Id'];
					if($Params['mod3Id'] > 0 || !empty($Params['engine']))
					{
						$table .= ' join bc_product_model3_link on pro_id = pml3_pro_id';
						$whereArr['mod3'] = '';
						if($Params['mod3Id'] > 0)
						{
							$whereArr['mod3'] .= sprintf(" and pml3_mod3_id=%d", $Params['mod3Id']);
						}
						else if(!empty($Params['engine']))
						{
							$Ypc2Model = new Ypc2Model();
							$where = sprintf("  and mod3_engine ='%s'",  LibFc::Escape($Params['engine']));
							$res = $Ypc2Model->getModel(3, ['distinct mod3_id'], $where);
							$tm3Id = array_column($res['data'], 'mod3_id');
							$whereArr['mod3'] .= !empty($tm3Id)? sprintf(" and pml3_mod3_id in (%s)", implode(',', $tm3Id)): ' and 1=0';
						}
					}
					
					//店铺分类
					$Params['sortId'] = (int) $Params['sortId'];
					if($Params['sortId'] > 0)
					{
						$returnArr['sortIds'][] = $Params['sortId'];
						$table .= ' join bc_product_sort on prs_pro_id = pro_id';
						$whereArr['sort'] = sprintf(" and prs_sort_id=%d", $Params['sortId']);
					}
					else
					{
						$Params['sortId'] = 0;
					}

					//配件关键字
					if($Params['keyword'] != '')
					{
						$blparams = ['word'=>$Params['keyword'], 'shop_id'=>$shopId, 'count'=>10000];
						if(!empty($whereArr)){//能否限制少量产品
							$res = $this->get($table, ['distinct pro_id'], implode(' ', $whereArr));
							$blparams['pro_id'] = array_column($res['data'], 'pro_id');
						}
						$B2cElastic = new B2cElastic();
						$res = $B2cElastic->searchProId($blparams);
						if(!empty($res['data'])){
							$Params['orderPids'] = $res['data'];
							$tempWhere = sprintf(" and pro_id in (%s)", implode(',', $res['data']));
						}else{
							$tempWhere = sprintf(" and pro_name like '%%%s%%'", LibFc::Escape($Params['keyword']));
						}
						$whereArr['word'] = $tempWhere;
					}
				break;
				//购物车推荐
				case 'cart':
					if($Params['uid'] > 0)
					{
						$Params['uid'] = (int) $Params['uid'];
						
						$t = [];
						$res = $this->get("us_product_history join bc_product on pro_id=prh_pro_id", ['distinct pro_part_id'], sprintf(" and prh_uid=%d", $Params['uid']));
						if(!empty($res['data']))
						{
							$t[] = sprintf("pro_part_id in (%s)", implode(',', array_column($res['data'], 'pro_part_id')));
						}

						//购物车的车型ID
						$res = $this->get("us_product_history join bc_product_model3_link on pml3_pro_id=prh_pro_id", ['distinct pml3_mod3_id'], sprintf(" and prh_uid=%d", $Params['uid']));
						if(!empty($res['data']))
						{
							$table .= ' join bc_product_model3_link on pro_id = pml3_pro_id';
							$t[] = sprintf("pml3_mod3_id in (%s)", implode(',', array_column($res['data'], 'pml3_mod3_id')));
						}
						if(!empty($t))
						{
							$whereArr['cart'] = sprintf(" and (%s) and pro_id not in (select car_pro_id from us_cart where car_uid=%d)", implode(' or ', $t), $Params['uid']);
						}
					}
				break;
			}
			if(!empty($whereArr))
			{
				//过滤车型备注的时间
				if(!empty($Params['mod3_id']) && $Params['vinyear']){
					$ignorePids = [];
					$tarr = explode('-', $Params['vinyear']);
					$ym = ['y'=>$tarr[0], 'ym'=>''];
					if($tarr[1]) $ym['ym'] = date('Ym', strtotime($tarr[0].'-'.$tarr[1].'-01'));
					$res = $this->get($table, ['pro_id, pml3_remark'], implode(' ', $whereArr).' and length(pml3_remark) > 7');
					foreach($res['data'] as $pv){
						$pv['pml3_remark'] = strtr($pv['pml3_remark'], ['-至今'=>'-'.date('Ym')]);
						if(preg_match_all('/(\d{6})-(\d{6})/', $pv['pml3_remark'], $match, PREG_SET_ORDER)){
							$isok = false;
							foreach($match as $mv){
								if(($ym['ym'] && $ym['ym'] >= $mv[1] && $ym['ym'] <= $mv[2]) || (empty($ym['ym']) && $ym['y'] >= substr($mv[1], 0, 4) && $ym['y'] <= substr($mv[2], 0, 4))){
									$isok = true;
									break;
								}
							}
							if(!$isok) $ignorePids[] = $pv['pro_id'];
						}
					}
					if($ignorePids) $whereArr['ignore'] = sprintf(" and pro_id not in (%s)", implode(',', $ignorePids));
				}

				$res = $this->get($table, ['count(distinct(pro_id)) count'], implode(' ', $whereArr), true);
				if($res['data']['count'] > 0) 
				{
					$Params['type'] = $type;
					break;
				}
			}
		}
		
		//价格区间
		if(!empty($Params['minPrice']) || !empty($Params['maxPrice']))
		{
			$whereArr['price']= !empty($Params['minPrice']) ? sprintf(' and (case when pro_promotion_btime<=%d and pro_promotion_etime>=%d then pro_promotion_price else pro_sale_price end) >=%.2f',time(),time(),$Params['minPrice']) : '';
			$whereArr['price'] .= !empty($Params['maxPrice']) ? sprintf(' and (case when pro_promotion_btime<=%d and pro_promotion_etime>=%d then pro_promotion_price else pro_sale_price end) <=%.2f',time(),time(),$Params['maxPrice']) : '';
		}
		$Params['page'] = empty($Params['page'])? 1: (int)$Params['page'];
		$perPage = empty($perPage)? 20: (int) $perPage;
		$returnArr['searchFlag'] = true;
		$res = $this->get($table, ['count(distinct(pro_id)) count'], implode(' ', $whereArr), true);
		$returnArr['total'] = $res['data']['count'];
		if($returnArr['total'] > 0)
		{
			if(empty($Params['order'])) $Params['order'] = $Params['orderPids'] && $shopInfo['shop_wordorder']? 'pids': $shopInfo['shop_sorder'];
			$res = $this->getSearchProductOrder($Params);
			$orderBy = $res['data'];
			$where = sprintf(" and pro_id in (select pro_id from %s where 1=1 %s group by pro_id) group by pro_id %s limit %d, %d", $table, implode(' ', $whereArr), $orderBy, ($Params['page']-1)*$perPage, $perPage);
			$table = 'bc_product
				join sh_shop on pro_shop_id=shop_id
				join bc_product_info on pri_pro_id=pro_id
				join bc_part on pro_part_id = part_id 
				join bc_part_tree ON pt_part_id = part_id and pt_ismain=1
				left join bc_part_small on part_id = pas_part_id and pro_pas_id = pas_id';
			if(stripos($orderBy, 'sort_seq')) $table .= ' left join bc_product_sort on prs_pro_id = pro_id left join sh_sort on prs_sort_id = sort_id';
			$res = $this->get($table, ['pro_id'], $where);
			$returnArr['proIds'] = array_column($res['data'], 'pro_id');
		}
		$returnArr['param'] = $Params;
		return LibFc::ReturnData(true, $returnArr); 
	}



	/**
	  * @method 目录配件搜索  条件：keyword关键字、mod3Id末级车型ID、sortId店铺分类、minPrice maxPrice价格区间
	  * @param  $shopId 店铺ID
	  * @param  $Params URL参数
	  * @param  $perPage 每页显示多少条
	  * @author soul
	  * @copyright 2017/9/22
	  * @return 
			成功 ["status"=>true, "data"=> ] 
			失败 ["status"=>false, "data"=> 错误信息] 
	  */
	public function searchSuperItem($shopId, $Params, $perPage = 20)
	{
		$shopId = (int) $shopId;
		if(!empty($Params['number']))
		{
			$Params['keyword'] = $Params['number'];
			$Params['type'] = 'number';
		}
		$Params['type'] = empty($Params['type']) || $Params['type'] == 'search'? 'all': $Params['type'];
		if(empty($Params['keyword']) && !empty($Params['word'])) $Params['keyword'] = $Params['word'];
		$res = $this->get('sh_shop', ['shop_id, shop_smainnum, shop_srefnum, shop_sorder,shop_corder, shop_wordorder'], sprintf(" and shop_id=%d", $shopId), true);
		if(empty($res['data'])) return LibFc::ReturnData(false, '目录不存在或者尚未开通！');
		$shopInfo = $res['data'];
		$Params['corder'] = $shopInfo['shop_corder'];
		$returnArr = [
			'param'=>$Params,
			'proIds'=>[],
			'total'=>0,
			//此条件下配件的适用车型ID
			'mod3Ids'=>[],
			//此条件下配件的所有店铺分类ID
			'sortIds'=>[],
			'partIds'=>[],
			'prbIds'=>[],
			//表示是否已经有参数进入查询
			'searchFlag'=>false,
			'pal'=>[]
		];

		//查询历史
		if(!empty($Params['uid']) && !empty($Params['keyword']))
		{
			$historyArr = [
				'ush_uid'=>$Params['uid'],
				'ush_shop_id'=>$shopId,
				'ush_type'=>$Params['type'],
				'ush_word'=>$Params['keyword'],
			];
			$this->addSearchHistory($historyArr);
		}

		$typeArr = [$Params['type']];
		//搜索类型为所有，并且关键字不含有中文
		if($Params['type'] == 'all' && $Params['keyword'] != '' && empty($Params['mod3_id']) && !preg_match('/[\x7f-\xff]+/', $Params['keyword']))
		{
			$typeArr = ['number', $Params['type']];
		}
		if($Params['from'] && stripos($Params['from'],'PJL')!==false){
			$swhere = " and pro_show_pjl = 1";
		}else if($Params['from'] == 'robot'){
			$swhere = " and (pro_show_super = 1 or pro_show_pjl = 1)";
		}else{
			$swhere = " and pro_show_super = 1";
		}
		foreach($typeArr as $type)
		{
			$twhere = !empty(mvc::$cfg['PROALL'])? '' : 'and pro_status =1';
			$table = sprintf("bc_product join sh_super on pro_shop_id=ssu_shop_id and pro_status =1 %s and ssu_status = 1 and pro_shop_id=%d and ssu_btime <=%d and ssu_etime >= %d
			",$swhere, $shopId, time(), time());
			$whereArr = [];
			
			//店铺分类
			if(!empty($Params['sort_id'])){
				$tarr = [];
				foreach(explode(',', $Params['sort_id']) as $tv){
					if(!empty($tv)) $tarr[] = (int) $tv;
				}
				$tarr = array_unique($tarr);
				$returnArr['sortIds'] =  $tarr;
				$table .= ' join bc_product_sort on prs_pro_id = pro_id';
				$whereArr['sort'] =!empty($tarr)? sprintf(" and prs_sort_id in (%s)", implode(',', $tarr)): ' and 1=0';
			}

			if(!empty($Params['prb_id'])){
				$tarr = [];
				foreach(explode(',', $Params['prb_id']) as $tv){
					if(!empty($tv)) $tarr[] = (int) $tv;
				}
				$tarr = array_unique($tarr);
				$returnArr['prbIds'] = $tarr;
				$whereArr['pbrand'] = !empty($tarr)? sprintf(" and pro_prb_id in (%s)", implode(',', $tarr)): ' and 1=0';
			}

			if(!empty($Params['part_id'])){
				$tarr = [];
				foreach(explode(',', $Params['part_id']) as $tv){
					if(!empty($tv)) $tarr[] = (int) $tv;
				}
				$tarr = array_unique($tarr);
				$returnArr['partIds'] = $tarr;
				$whereArr['part'] = !empty($tarr)? sprintf(" and pro_part_id in (%s)", implode(',', $tarr)): ' and 1=0';
			}else if(!empty($Params['spart_id'])){
				$t = explode('_', $Params['spart_id']);
				$whereArr['part'] = sprintf(" and pro_part_id = %d", $t[0]);
				if(!empty($t[1])) $whereArr['part'] .= sprintf(" and pro_pas_id = %d", $t[1]);
			}

			switch($type)
			{
				case 'number':
					$re = ["、",",","，",";","；","\n","\t","\r"];
					$keyword = str_replace($re, ',', $Params['keyword']);
					$numwhere = [];
					foreach(explode(',', $keyword) as $tword){
						$tword = LibFc::FormatNum($tword);
						if(strlen($tword) > 2){
							$numwhere[] = $Params['numtype'] == 2? $tword: sprintf("num_format like '%%%s%%'", $tword);
						}
					}
					if(!empty($numwhere)){
						$whereArr['num'] = $Params['numtype'] == 2? sprintf(" and num_format in ('%s')", implode("','", $numwhere)) : sprintf(" and (%s)", implode(" or ", $numwhere));
						$table .= ' join bc_number on pro_id = num_pro_id';
					}else{
						$whereArr['num'] = ' and 1=0';
					}
				break;
				case 'all':
				case 'item':
				case 'model':
					$Ypc2Model = new Ypc2Model();
					$comWhere = '';
					if(!empty($Params['mod3_id']))
					{
						$tids = [];
						foreach(explode(',', $Params['mod3_id']) as $tid)
						{
							$tids[] = (int) $tid;
						}
						$tids = array_unique($tids);
						$table .= ' join bc_product_model3_link on pro_id = pml3_pro_id';
						$whereArr['mod3'] .= sprintf(" and pml3_mod3_id in (%s)", implode(',', $tids));
					}
					else
					{
						if(!empty($Params['brand_id'])) $comWhere .= sprintf(" and brand_id=%d", (int) $Params['brand_id']);
						if(!empty($Params['mod1_id'])) $comWhere .= sprintf(" and mod1_id=%d", (int) $Params['mod1_id']);
						if(!empty($Params['mod2_id'])) $comWhere .= sprintf(" and mod2_id=%d", (int) $Params['mod2_id']);
						if(!empty($Params['mod3_drive'])) $comWhere .= sprintf(" and mod3_drive='%s'",  LibFc::Escape($Params['mod3_drive']));
						if(!empty($Params['mod3_drive_short'])) $comWhere .= sprintf(" and mod3_drive_short='%s'",  LibFc::Escape($Params['mod3_drive_short']));
						if(!empty($Params['mod3_cc_name'])) $comWhere .= sprintf(" and mod3_cc_name='%s'",  LibFc::Escape($Params['mod3_cc_name']));
						if(!empty($Params['mod3_cc'])) $comWhere .= sprintf(" and mod3_cc='%s'",  LibFc::Escape($Params['mod3_cc']));
						if(!empty($Params['mod3_kw'])) $comWhere .= sprintf(" and mod3_kw='%s'",  LibFc::Escape($Params['mod3_kw']));
						if(!empty($Params['mod3_engine'])){
							$tvals = [];
							foreach(explode(',', $Params['mod3_engine']) as $tval){
								$tvals[] = LibFc::FormatNum($tval);
							}
							$tvals = array_unique($tvals);
							$comWhere .= sprintf(" and mod3_engine_format in ('%s')",  implode("','", $tvals));
						}
						if(!empty($Params['year'])) $comWhere .= sprintf(" and %d >= mod3_start_year  and (%d <= mod3_end_year or mod3_end_year=0) ", $Params['year'], $Params['year']);
						if(!empty($Params['cctran']))
						{
							$Params['cctran'] = base64_decode($Params['cctran']);
							$cc = explode('@', $Params['cctran']);
							$comWhere .= sprintf(" and mod3_cc_name = '%s' and (mod3_transmission ='%s' or mod3_transmission REGEXP '^[0-9]+%s$' or mod3_transmission like '电动车%s%%')", LibFc::Escape($cc[0]), LibFc::Escape($cc[1]), LibFc::Escape($cc[1]), LibFc::Escape($cc[1]));
						}
						if($comWhere != '')
						{
							$table .= ' join bc_product_model3_link on pro_id = pml3_pro_id';
							$res = $Ypc2Model->getModel(3, ['distinct mod3_id'], $comWhere);
							$tm3Id = array_column($res['data'], 'mod3_id');
							$whereArr['mod3'] .= !empty($tm3Id)? sprintf(" and pml3_mod3_id in (%s)", implode(',', $tm3Id)): ' and 1=0';
						}
					}
					//配件关键字
					if($Params['keyword'] != '')
					{	
						$blparams = ['word'=>$Params['keyword'], 'shop_id'=>$shopId, 'count'=>10000];
						if(!empty($whereArr)){//能否限制少量产品
							$res = $this->get($table, ['distinct pro_id'], implode(' ', $whereArr));
							$blparams['pro_id'] = array_column($res['data'], 'pro_id');
						}
						$B2cElastic = new B2cElastic();
						$res = $B2cElastic->searchProId($blparams);
						if(!empty($res['data'])){
							$Params['orderPids'] = $res['data'];
							$tempWhere = sprintf(" and pro_id in (%s)", implode(',', $res['data']));
						}else{
							$tempWhere = sprintf(" and pro_name like '%%%s%%'", LibFc::Escape($Params['keyword']));
						}
						$whereArr['word'] = $tempWhere;
					}
				break;
			}
			if(!empty($whereArr))
			{
				//过滤车型备注的时间
				if(!empty($Params['mod3_id']) && $Params['vinyear']){
					$ignorePids = [];
					$tarr = explode('-', $Params['vinyear']);
					$ym = ['y'=>$tarr[0], 'ym'=>''];
					if($tarr[1]) $ym['ym'] = date('Ym', strtotime($tarr[0].'-'.$tarr[1].'-01'));
					$res = $this->get($table, ['pro_id, pml3_remark'], implode(' ', $whereArr).' and length(pml3_remark) > 7');
					foreach($res['data'] as $pv){
						$pv['pml3_remark'] = strtr($pv['pml3_remark'], ['-至今'=>'-'.date('Ym')]);
						if(preg_match_all('/(\d{6})-(\d{6})/', $pv['pml3_remark'], $match, PREG_SET_ORDER)){
							$isok = false;
							foreach($match as $mv){
								if(($ym['ym'] && $ym['ym'] >= $mv[1] && $ym['ym'] <= $mv[2]) || (empty($ym['ym']) && $ym['y'] >= substr($mv[1], 0, 4) && $ym['y'] <= substr($mv[2], 0, 4))){
									$isok = true;
									break;
								}
							}
							if(!$isok) $ignorePids[] = $pv['pro_id'];
						}
					}
					if($ignorePids) $whereArr['ignore'] = sprintf(" and pro_id not in (%s)", implode(',', $ignorePids));
				}

				$res = $this->get($table, ['count(distinct(pro_id)) count'], implode(' ', $whereArr), true);
				if($res['data']['count'] > 0) 
				{
					$Params['type'] = $type;
					break;
				}
			}
		}
		
		
		
		$Params['page'] = empty($Params['page'])? 1: (int)$Params['page'];
		$perPage = empty($perPage)? 20: (int) $perPage;
		$returnArr['searchFlag'] = true;
		$res = $this->get($table, ['count(distinct(pro_id)) count'], implode(' ', $whereArr), true);
		$returnArr['total'] = $res['data']['count'];
		if($returnArr['total'] > 0)
		{
			if(empty($Params['order'])) $Params['order'] = $Params['orderPids'] && $shopInfo['shop_wordorder']? 'pids': $shopInfo['shop_sorder'];
			$res = $this->getSearchProductOrder($Params);
			$orderBy = $res['data'];
			$where = sprintf(" and pro_id in (select pro_id from %s where 1=1 %s group by pro_id) group by pro_id %s limit %d, %d", $table, implode(' ', $whereArr), $orderBy, ($Params['page']-1)*$perPage, $perPage);
			$table = 'bc_product
				join sh_shop on pro_shop_id=shop_id
				join bc_product_info on pri_pro_id=pro_id
				join bc_part on pro_part_id = part_id 
				join bc_part_tree ON pt_part_id = part_id and pt_ismain=1
				left join bc_part_small on part_id = pas_part_id and pro_pas_id = pas_id';
			if(stripos($orderBy, 'sort_seq')) $table .= ' left join bc_product_sort on prs_pro_id = pro_id left join sh_sort on prs_sort_id = sort_id';
			$res = $this->get($table, ['pro_id'], $where);
			$returnArr['proIds'] = array_column($res['data'], 'pro_id');
		}
		$returnArr['param'] = $Params;
		return LibFc::ReturnData(true, $returnArr); 
	}


	/**
	  * @method 店铺配件搜索  条件：keyword关键字、mod3Id末级车型ID、sortId店铺分类、minPrice maxPrice价格区间
	  * @param  $shopId 店铺ID
	  * @param  $Params URL参数
	  * @param  $perPage 每页显示多少条
	  * @author soul
	  * @copyright 2017/9/22
	  * @return 
			成功 ["status"=>true, "data"=> ] 
			失败 ["status"=>false, "data"=> 错误信息] 
	  */
	public function searchGzhItem($shopId, $Params, $perPage = 20)
	{
		$shopId = (int) $shopId;
		if(!empty($Params['number']))
		{
			$Params['keyword'] = $Params['number'];
			$Params['type'] = 'number';
		}
		$res = $this->get('sh_shop', ['shop_id, shop_smainnum, shop_srefnum, shop_sorder,shop_corder, shop_wordorder'], sprintf(" and shop_id=%d", $shopId), true);
		if(empty($res['data'])) return LibFc::ReturnData(false, '目录不存在或者尚未开通！');
		$shopInfo = $res['data'];
		$Params['corder'] = $shopInfo['shop_corder'];
		$returnArr = [
			'param'=>$Params,
			'proIds'=>[],
			'total'=>0,
			//此条件下配件的适用车型ID
			'mod3Ids'=>[],
			//此条件下配件的所有店铺分类ID
			'sortIds'=>[],
			//表示是否已经有参数进入查询
			'searchFlag'=>false,
			'pal'=>[]
		];

		//查询历史
		if(!empty($Params['uid']) && !empty($Params['keyword']))
		{
			$historyArr = [
				'ush_uid'=>$Params['uid'],
				'ush_shop_id'=>$shopId,
				'ush_type'=>$Params['type'],
				'ush_word'=>$Params['keyword'],
			];
			$this->addSearchHistory($historyArr);
		}

		$typeArr = [$Params['type']];
		//搜索类型为所有，并且关键字不含有中文
		if($Params['type'] == 'all' && $Params['keyword'] != '' && empty($Params['mod3_id']) && !preg_match('/[\x7f-\xff]+/', $Params['keyword']))
		{
			$typeArr = ['number', $Params['type']];
		}
		$showWhere = ' and pro_show_app = 1';

		foreach($typeArr as $type)
		{
			$twhere = !empty(mvc::$cfg['PROALL'])? '' : 'and pro_status =1';
			$table = 'bc_product join sh_shop on pro_shop_id=shop_id and shop_status = 1 '.$twhere.$showWhere.' and shop_id='.$shopId;
			$whereArr = [];

			//店铺分类
			if(!empty($Params['sort_id'])){
				$tarr = [];
				foreach(explode(',', $Params['sort_id']) as $tv){
					if(!empty($tv)) $tarr[] = (int) $tv;
				}
				$tarr = array_unique($tarr);
				$returnArr['sortIds'] =  $tarr;
				$table .= ' join bc_product_sort on prs_pro_id = pro_id';
				$whereArr['sort'] =!empty($tarr)? sprintf(" and prs_sort_id in (%s)", implode(',', $tarr)): ' and 1=0';
			}

			if(!empty($Params['prb_id'])){
				$tarr = [];
				foreach(explode(',', $Params['prb_id']) as $tv){
					if(!empty($tv)) $tarr[] = (int) $tv;
				}
				$tarr = array_unique($tarr);
				$returnArr['prbIds'] = $tarr;
				$whereArr['pbrand'] = !empty($tarr)? sprintf(" and pro_prb_id in (%s)", implode(',', $tarr)): ' and 1=0';
			}

			if(!empty($Params['part_id'])){
				$tarr = [];
				foreach(explode(',', $Params['part_id']) as $tv){
					if(!empty($tv)) $tarr[] = (int) $tv;
				}
				$tarr = array_unique($tarr);
				$returnArr['partIds'] = $tarr;
				$whereArr['part'] = !empty($tarr)? sprintf(" and pro_part_id in (%s)", implode(',', $tarr)): ' and 1=0';
			}else if(!empty($Params['spart_id'])){
				$t = explode('_', $Params['spart_id']);
				$whereArr['part'] = sprintf(" and pro_part_id = %d", $t[0]);
				if(!empty($t[1])) $whereArr['part'] .= sprintf(" and pro_pas_id = %d", $t[1]);
			}

			switch($type)
			{
				case 'number':
					$re = ["、",",","，",";","；","\n","\t","\r"];
					$keyword = str_replace($re, ',', $Params['keyword']);
					$numwhere = [];
					foreach(explode(',', $keyword) as $tword){
						$tword = LibFc::FormatNum($tword);
						if(strlen($tword) > 2){
							$numwhere[] = $Params['numtype'] == 2? $tword: sprintf("num_format like '%%%s%%'", $tword);
						}
					}
					if(!empty($numwhere)){
						$whereArr['num'] = $Params['numtype'] == 2? sprintf(" and num_format in ('%s')", implode("','", $numwhere)) : sprintf(" and (%s)", implode(" or ", $numwhere));
						$table .= ' join bc_number on pro_id = num_pro_id';
					}else{
						$whereArr['num'] = ' and 1=0';
					}
				break;
				case 'all':
				case 'item':
				case 'model':
					$Params['brand_id'] = (int) $Params['brand_id'];
					if(!empty($Params['mod3_id']) || !empty($Params['mod3_engine']))
					{
						$table .= ' join bc_product_model3_link on pro_id = pml3_pro_id';
						$whereArr['mod3'] = '';
						if(!empty($Params['mod3_id']))
						{
							$tids = [];
							foreach(explode(',', $Params['mod3_id']) as $tid)
							{
								$tids[] = (int) $tid;
							}
							$tids = array_unique($tids);
							$whereArr['mod3'] .= sprintf(" and pml3_mod3_id in (%s)", implode(',', $tids));
						}
						else if(!empty($Params['mod3_engine']))
						{
							$Ypc2Model = new Ypc2Model();
							$where = sprintf("  and mod3_engine ='%s'",  LibFc::Escape($Params['mod3_engine']));
							$res = $Ypc2Model->getModel(3, ['distinct mod3_id'], $where);
							$tm3Id = array_column($res['data'], 'mod3_id');
							$whereArr['mod3'] .= !empty($tm3Id)? sprintf(" and pml3_mod3_id in (%s)", implode(',', $tm3Id)): ' and 1=0';
						}
					}

					//配件关键字
					if($Params['keyword'] != '')
					{
						$blparams = ['word'=>$Params['keyword'], 'shop_id'=>$shopId, 'count'=>10000];
						if(!empty($whereArr)){//能否限制少量产品
							$res = $this->get($table, ['distinct pro_id'], implode(' ', $whereArr));
							$blparams['pro_id'] = array_column($res['data'], 'pro_id');
						}
						$B2cElastic = new B2cElastic();
						$res = $B2cElastic->searchProId($blparams);
						if(!empty($res['data'])){
							$Params['orderPids'] = $res['data'];
							$tempWhere = sprintf(" and pro_id in (%s)", implode(',', $res['data']));
						}else{
							$tempWhere = sprintf(" and pro_name like '%%%s%%'", LibFc::Escape($Params['keyword']));
						}
						$whereArr['word'] = $tempWhere;
					}
				break;
				//购物车推荐
				case 'cart':
					if($Params['uid'] > 0)
					{
						$Params['uid'] = (int) $Params['uid'];
						
						$t = [];
						$res = $this->get("us_product_history join bc_product on pro_id=prh_pro_id", ['distinct pro_part_id'], sprintf(" and prh_uid=%d", $Params['uid']));
						if(!empty($res['data']))
						{
							$t[] = sprintf("pro_part_id in (%s)", implode(',', array_column($res['data'], 'pro_part_id')));
						}

						//购物车的车型ID
						$res = $this->get("us_product_history join bc_product_model3_link on pml3_pro_id=prh_pro_id", ['distinct pml3_mod3_id'], sprintf(" and prh_uid=%d", $Params['uid']));
						if(!empty($res['data']))
						{
							$table .= ' join bc_product_model3_link on pro_id = pml3_pro_id';
							$t[] = sprintf("pml3_mod3_id in (%s)", implode(',', array_column($res['data'], 'pml3_mod3_id')));
						}
						if(!empty($t))
						{
							$whereArr['cart'] = sprintf(" and (%s) and pro_id not in (select car_pro_id from us_cart where car_uid=%d)", implode(' or ', $t), $Params['uid']);
						}
					}
				break;
			}
			if(!empty($whereArr))
			{
				//过滤车型备注的时间
				if(!empty($Params['mod3_id']) && $Params['vinyear']){
					$ignorePids = [];
					$tarr = explode('-', $Params['vinyear']);
					$ym = ['y'=>$tarr[0], 'ym'=>''];
					if($tarr[1]) $ym['ym'] = date('Ym', strtotime($tarr[0].'-'.$tarr[1].'-01'));
					$res = $this->get($table, ['pro_id, pml3_remark'], implode(' ', $whereArr).' and length(pml3_remark) > 7');
					foreach($res['data'] as $pv){
						$pv['pml3_remark'] = strtr($pv['pml3_remark'], ['-至今'=>'-'.date('Ym')]);
						if(preg_match_all('/(\d{6})-(\d{6})/', $pv['pml3_remark'], $match, PREG_SET_ORDER)){
							$isok = false;
							foreach($match as $mv){
								if(($ym['ym'] && $ym['ym'] >= $mv[1] && $ym['ym'] <= $mv[2]) || (empty($ym['ym']) && $ym['y'] >= substr($mv[1], 0, 4) && $ym['y'] <= substr($mv[2], 0, 4))){
									$isok = true;
									break;
								}
							}
							if(!$isok) $ignorePids[] = $pv['pro_id'];
						}
					}
					if($ignorePids) $whereArr['ignore'] = sprintf(" and pro_id not in (%s)", implode(',', $ignorePids));
				}
				$res = $this->get($table, ['count(distinct(pro_id)) count'], implode(' ', $whereArr), true);
				if($res['data']['count'] > 0) 
				{
					$Params['type'] = $type;
					break;
				}
			}
		}
		
		//价格区间
		if(!empty($Params['minPrice']) || !empty($Params['maxPrice']))
		{
			$whereArr['price']= !empty($Params['minPrice']) ? sprintf(' and (case when pro_promotion_btime<=%d and pro_promotion_etime>=%d then pro_promotion_price else pro_sale_price end) >=%.2f',time(),time(),$Params['minPrice']) : '';
			$whereArr['price'] .= !empty($Params['maxPrice']) ? sprintf(' and (case when pro_promotion_btime<=%d and pro_promotion_etime>=%d then pro_promotion_price else pro_sale_price end) <=%.2f',time(),time(),$Params['maxPrice']) : '';
		}
		$Params['page'] = empty($Params['page'])? 1: (int)$Params['page'];
		$perPage = empty($perPage)? 20: (int) $perPage;
		$returnArr['searchFlag'] = true;
		$res = $this->get($table, ['count(distinct(pro_id)) count'], implode(' ', $whereArr), true);
		$returnArr['total'] = $res['data']['count'];
		if($returnArr['total'] > 0)
		{
			if(empty($Params['order'])) $Params['order'] = $Params['orderPids'] && $shopInfo['shop_wordorder']? 'pids': $shopInfo['shop_sorder'];
			$res = $this->getSearchProductOrder($Params);
			$orderBy = $res['data'];
			$where = sprintf(" and pro_id in (select pro_id from %s where 1=1 %s group by pro_id) group by pro_id %s limit %d, %d", $table, implode(' ', $whereArr), $orderBy, ($Params['page']-1)*$perPage, $perPage);
			$table = 'bc_product
				join sh_shop on pro_shop_id=shop_id
				join bc_product_info on pri_pro_id=pro_id
				join bc_part on pro_part_id = part_id 
				join bc_part_tree ON pt_part_id = part_id and pt_ismain=1
				left join bc_part_small on part_id = pas_part_id and pro_pas_id = pas_id';
			if(stripos($orderBy, 'sort_seq')) $table .= ' left join bc_product_sort on prs_pro_id = pro_id left join sh_sort on prs_sort_id = sort_id';
			$res = $this->get($table, ['pro_id'], $where);
			$returnArr['proIds'] = array_column($res['data'], 'pro_id');
		}
		$returnArr['param'] = $Params;
		return LibFc::ReturnData(true, $returnArr); 
	}


	/**
	  * @method 对外接口 目录配件搜索  条件：keyword关键字、mod3Id末级车型ID
	  * @param  $shopId 店铺ID
	  * @param  $Params URL参数
	  * @param  $perPage 每页显示多少条
	  * @author soul
	  * @copyright 2017/9/22
	  * @return 
			成功 ["status"=>true, "data"=> ] 
			失败 ["status"=>false, "data"=> 错误信息] 
	  */
	public function searchApiItem($shopId, $Params, $perPage = 20)
	{
		$shopId = (int) $shopId;
		$res = $this->get('sh_shop', ['shop_id, shop_sorder, shop_corder, shop_wordorder'], sprintf(" and shop_id=%d and shop_status = 1", $shopId), true);
		if(empty($res['data'])) return LibFc::ReturnData(false, '目录不存在或者尚未开通！');
		$shopInfo = $res['data'];
		$Params['corder'] = $shopInfo['shop_corder'];
		$returnArr = [
			'param'=>$Params,
			'proIds'=>[],
			'total'=>0,
			//此条件下配件的适用车型ID
			'mod3Ids'=>[],
			//此条件下配件的所有店铺分类ID
			'sortIds'=>[],
			'partIds'=>[],
			//表示是否已经有参数进入查询
			'searchFlag'=>false,
			'pal'=>[]
		];

		$whereArr = ['com'=>sprintf(' and pro_shop_id=%d and pro_status =1', $shopId)];
		$table = 'bc_product';
		//号码查询
		if(!empty($Params['number']))
		{
			$re = ["、",",","，",";","；","\n","\t","\r"];
			$keyword = str_replace($re, ',', $Params['number']);
			$numwhere = [];
			foreach(explode(',', $keyword) as $tword){
				$tword = LibFc::FormatNum($tword);
				if(strlen($tword) > 2){
					$numwhere[] = $Params['numtype'] == 2? $tword: sprintf("num_format like '%%%s%%'", $tword);
				}
			}
			if(!empty($numwhere)){
				$whereArr['num'] = $Params['numtype'] == 2? sprintf(" and num_format in ('%s')", implode("','", $numwhere)) : sprintf(" and (%s)", implode(" or ", $numwhere));
				$table .= ' join bc_number on pro_id = num_pro_id';
			}else{
				$whereArr['com'] = '';
			}
		}
		else if(!empty($Params['mod3_id']))
		{//车型搜索
			$Ypc2Model = new Ypc2Model();
			$tids = [];
			foreach(explode(',', $Params['mod3_id']) as $tid)
			{
				$tids[] = (int) $tid;
			}
			$tids = array_unique($tids);
			$table .= ' join bc_product_model3_link on pro_id = pml3_pro_id';
			$whereArr['mod3'] .= sprintf(" and pml3_mod3_id in (%s)", implode(',', $tids));
		}
		else
		{
			$whereArr['com'] = '';
		}
		if(!empty($whereArr['com']))
		{
			//配件关键字
			if($Params['keyword'] != '')
			{
				$blparams = ['word'=>$Params['keyword'], 'shop_id'=>$shopId, 'count'=>10000];
				if(!empty($whereArr)){//能否限制少量产品
					$res = $this->get($table, ['distinct pro_id'], implode(' ', $whereArr));
					$blparams['pro_id'] = array_column($res['data'], 'pro_id');
				}
				$B2cElastic = new B2cElastic();
				$res = $B2cElastic->searchProId($blparams);
				if(!empty($res['data'])){
					$Params['orderPids'] = $res['data'];
					$tempWhere = sprintf(" and pro_id in (%s)", implode(',', $res['data']));
				}else{
					$tempWhere = sprintf(" and pro_name like '%%%s%%'", LibFc::Escape($Params['keyword']));
				}
				$whereArr['word'] = $tempWhere;
			}

			//店铺分类
			$Params['sort_id'] = (int) $Params['sort_id'];
			if($Params['sort_id'] > 0)
			{
				$returnArr['sortIds'][] = $Params['sort_id'];
				$table .= ' join bc_product_sort on prs_pro_id = pro_id';
				$whereArr['sort'] = sprintf(" and prs_sort_id=%d", $Params['sort_id']);
			}

			if(!empty($Params['part_id']))
			{
				$tarr = [];
				foreach(explode(',', $Params['part_id']) as $tv)
				{
					if(!empty($tv)) $tarr[] = (int) $tv;
				}
				$tarr = array_unique($tarr);
				$returnArr['partIds'] = $tarr;
				if(!empty($tarr)) 
					$whereArr['part'] = sprintf(" and pro_part_id in (%s)", implode(',', $tarr));
			}
			else if(!empty($Params['spart_id']))
			{
				$t = explode('_', $Params['spart_id']);
				$whereArr['part'] = sprintf(" and pro_part_id = %d", $t[0]);
				if(!empty($t[1])) $whereArr['part'] .= sprintf(" and pro_pas_id = %d", $t[1]);
			}

			//过滤车型备注的时间
			if(!empty($Params['mod3_id']) && $Params['vinyear']){
				$ignorePids = [];
				$tarr = explode('-', $Params['vinyear']);
				$ym = ['y'=>$tarr[0], 'ym'=>''];
				if($tarr[1]) $ym['ym'] = date('Ym', strtotime($tarr[0].'-'.$tarr[1].'-01'));
				$res = $this->get($table, ['pro_id, pml3_remark'], implode(' ', $whereArr).' and length(pml3_remark) > 7');
				foreach($res['data'] as $pv){
					$pv['pml3_remark'] = strtr($pv['pml3_remark'], ['-至今'=>'-'.date('Ym')]);
					if(preg_match_all('/(\d{6})-(\d{6})/', $pv['pml3_remark'], $match, PREG_SET_ORDER)){
						$isok = false;
						foreach($match as $mv){
							if(($ym['ym'] && $ym['ym'] >= $mv[1] && $ym['ym'] <= $mv[2]) || (empty($ym['ym']) && $ym['y'] >= substr($mv[1], 0, 4) && $ym['y'] <= substr($mv[2], 0, 4))){
								$isok = true;
								break;
							}
						}
						if(!$isok) $ignorePids[] = $pv['pro_id'];
					}
				}
				if($ignorePids) $whereArr['ignore'] = sprintf(" and pro_id not in (%s)", implode(',', $ignorePids));
			}

			$Params['page'] = empty($Params['page'])? 1: (int)$Params['page'];
			$perPage = empty($perPage)? 20: (int) $perPage;
			$returnArr['searchFlag'] = true;
			$res = $this->get($table, ['count(distinct(pro_id)) count'], implode(' ', $whereArr), true);
			$returnArr['total'] = $res['data']['count'];
			if($returnArr['total'] > 0)
			{
				if(empty($Params['order'])) $Params['order'] = $Params['orderPids'] && $shopInfo['shop_wordorder']? 'pids': $shopInfo['shop_sorder'];
				$res = $this->getSearchProductOrder($Params);
				$orderBy = $res['data'];
				$where = sprintf(" and pro_id in (select pro_id from %s where 1=1 %s group by pro_id) group by pro_id %s limit %d, %d", $table, implode(' ', $whereArr), $orderBy, ($Params['page']-1)*$perPage, $perPage);
				$table = 'bc_product
					join sh_shop on pro_shop_id=shop_id
					join bc_product_info on pri_pro_id=pro_id
					join bc_part on pro_part_id = part_id 
					join bc_part_tree ON pt_part_id = part_id and pt_ismain=1
					left join bc_part_small on part_id = pas_part_id and pro_pas_id = pas_id';
				if(stripos($orderBy, 'sort_seq')) $table .= ' left join bc_product_sort on prs_pro_id = pro_id left join sh_sort on prs_sort_id = sort_id';
				$res = $this->get($table, ['pro_id'], $where);
				$returnArr['proIds'] = array_column($res['data'], 'pro_id');
			}
		}
		$returnArr['param'] = $Params;
		return LibFc::ReturnData(true, $returnArr); 
	}



	/**
	  * @method 获取公众号或者目录的分类
	  * @param  $shopid              int [必填] 店铺ID
	  * @param  $Params   [
			mod3_id              string [选填] 车型品牌ID
			word              string [选填] 关键字
			engine              string [选填] 发动机编码
			number              string [选填] 号码
	  ]
	  * @author soul
	  * @copyright 2020/7/27
	  * @return 
	  shopid=350955&mod3_id=14486
	  {"status":true,"data":{"spart":[{"spart_id":"4012_0","spart_name":"\u63a7\u5236\u81c2"},{"spart_id":"4935_0","spart_name":"\u7403\u5934"}],"sort":[{"sort_id":"7391","sort_name":"\u7403\u5934"},{"sort_id":"7392","sort_name":"\u524d\u5e73\u8861\u6746\u7403\u5934"},{"sort_id":"7393","sort_name":"\u6a2a\u62c9\u6746\u5916\u7403\u5934"},{"sort_id":"7394","sort_name":"\u6a2a\u62c9\u6746\u5185\u7403\u5934"},{"sort_id":"7396","sort_name":"\u540e\u5e73\u8861\u6746\u7403\u5934"},{"sort_id":"7398","sort_name":"\u63a7\u5236\u81c2"},{"sort_id":"7400","sort_name":"\u4e0b\u6446\u81c2"}]},"code":0}
	  */
	public function getSearchParts($shopId, $Params)
	{
		$shopId = (int) $shopId;
		if(!empty($Params['number']))
		{
			$Params['keyword'] = $Params['number'];
			$Params['type'] = 'number';
		}
		$Params['type'] = empty($Params['type']) || $Params['type'] == 'search'? 'all': $Params['type'];
		$typeArr = [$Params['type']];
		//搜索类型为所有，并且关键字不含有中文
		if($Params['type'] == 'all' && $Params['keyword'] != '' && empty($Params['mod3_id']) && !preg_match('/[\x7f-\xff]+/', $Params['keyword']))
		{
			$typeArr = ['number', $Params['type']];
		}
		
		$arr = [
			'spart'=>[],	
			'sort'=>[],	
			'part'=>[],	
			'type'=>'param'
		];
		$spartIdArr = [];
		foreach($typeArr as $type)
		{
			$twhere = !empty(mvc::$cfg['PROALL'])? '' : 'and pro_status =1';
			$table = 'bc_product join sh_shop on pro_shop_id=shop_id and shop_status = 1 '.$twhere.' and shop_id='.$shopId;
			$whereArr = [];
			switch($type)
			{
				case 'number':
					$re = ["、",",","，",";","；","\n","\t","\r"];
					$keyword = str_replace($re, ',', $Params['keyword']);
					$numwhere = [];
					foreach(explode(',', $keyword) as $tword){
						$tword = LibFc::FormatNum($tword);
						if(strlen($tword) > 2){
							$numwhere[] = $Params['numtype'] == 2? $tword: sprintf("num_format like '%%%s%%'", $tword);
						}
					}
					if(!empty($numwhere)){
						$whereArr['num'] = $Params['numtype'] == 2? sprintf(" and num_format in ('%s')", implode("','", $numwhere)) : sprintf(" and (%s)", implode(" or ", $numwhere));
						$table .= ' join bc_number on pro_id = num_pro_id';
					}else{
						$whereArr['num'] = ' and 1=0';
					}
				break;
				case 'all':
				case 'item':
				case 'model':
					$Ypc2Model = new Ypc2Model();
					$comWhere = '';
					if(!empty($Params['mod3_id']))
					{
						$table .= ' join bc_product_model3_link on pro_id = pml3_pro_id';
						$whereArr['mod3'] .= sprintf(" and pml3_mod3_id =%d", (int) $Params['mod3_id']);
					}
					else
					{
						if(!empty($Params['brand_id'])) $comWhere .= sprintf(" and brand_id=%d", (int) $Params['brand_id']);
						if(!empty($Params['mod1_id'])) $comWhere .= sprintf(" and mod1_id=%d", (int) $Params['mod1_id']);
						if(!empty($Params['mod2_id'])) $comWhere .= sprintf(" and mod2_id=%d", (int) $Params['mod2_id']);
						if(!empty($Params['mod3_drive'])) $comWhere .= sprintf(" and mod3_drive='%s'",  LibFc::Escape($Params['mod3_drive']));
						if(!empty($Params['mod3_drive_short'])) $comWhere .= sprintf(" and mod3_drive_short='%s'",  LibFc::Escape($Params['mod3_drive_short']));
						if(!empty($Params['mod3_cc_name'])) $comWhere .= sprintf(" and mod3_cc_name='%s'",  LibFc::Escape($Params['mod3_cc_name']));
						if(!empty($Params['mod3_cc'])) $comWhere .= sprintf(" and mod3_cc='%s'",  LibFc::Escape($Params['mod3_cc']));
						if(!empty($Params['mod3_kw'])) $comWhere .= sprintf(" and mod3_kw='%s'",  LibFc::Escape($Params['mod3_kw']));
						if(!empty($Params['mod3_engine'])) $comWhere .= sprintf(" and mod3_engine='%s'",  LibFc::Escape($Params['mod3_engine']));
						if(!empty($Params['year'])) $comWhere .= sprintf(" and %d >= mod3_start_year  and (%d <= mod3_end_year or mod3_end_year=0) ", $Params['year'], $Params['year']);
						if(!empty($Params['cctran']))
						{
							$Params['cctran'] = base64_decode($Params['cctran']);
							$cc = explode('@', $Params['cctran']);
							$comWhere .= sprintf(" and mod3_cc_name = '%s' and (mod3_transmission ='%s' or mod3_transmission REGEXP '^[0-9]+%s$' or mod3_transmission like '电动车%s%%')", LibFc::Escape($cc[0]), LibFc::Escape($cc[1]), LibFc::Escape($cc[1]), LibFc::Escape($cc[1]));
						}
						if($comWhere != '')
						{
							$table .= ' join bc_product_model3_link on pro_id = pml3_pro_id';
							$res = $Ypc2Model->getModel(3, ['distinct mod3_id'], $comWhere);
							$tm3Id = array_column($res['data'], 'mod3_id');
							$whereArr['mod3'] .= !empty($tm3Id)? sprintf(" and pml3_mod3_id in (%s)", implode(',', $tm3Id)): ' and 1=0';
						}
					}

					//配件关键字
					if($Params['keyword'] != '')
					{
						$blparams = ['word'=>$Params['keyword'], 'shop_id'=>$shopId, 'count'=>10000];
						if(!empty($whereArr)){//能否限制少量产品
							$res = $this->get($table, ['distinct pro_id'], implode(' ', $whereArr));
							$blparams['pro_id'] = array_column($res['data'], 'pro_id');
						}
						$B2cElastic = new B2cElastic();
						$res = $B2cElastic->searchProId($blparams);
						if(!empty($res['data'])){
							$Params['orderPids'] = $res['data'];
							$tempWhere = sprintf(" and pro_id in (%s)", implode(',', $res['data']));
						}else{
							$tempWhere = sprintf(" and pro_name like '%%%s%%'", LibFc::Escape($Params['keyword']));
						}
						$whereArr['word'] = $tempWhere;
					}
				break;
			}

			//过滤车型备注的时间
			if(!empty($Params['mod3_id']) && $Params['vinyear']){
				$ignorePids = [];
				$tarr = explode('-', $Params['vinyear']);
				$ym = ['y'=>$tarr[0], 'ym'=>''];
				if($tarr[1]) $ym['ym'] = date('Ym', strtotime($tarr[0].'-'.$tarr[1].'-01'));
				$res = $this->get($table, ['pro_id, pml3_remark'], implode(' ', $whereArr).' and length(pml3_remark) > 7');
				foreach($res['data'] as $pv){
					$pv['pml3_remark'] = strtr($pv['pml3_remark'], ['-至今'=>'-'.date('Ym')]);
					if(preg_match_all('/(\d{6})-(\d{6})/', $pv['pml3_remark'], $match, PREG_SET_ORDER)){
						$isok = false;
						foreach($match as $mv){
							if(($ym['ym'] && $ym['ym'] >= $mv[1] && $ym['ym'] <= $mv[2]) || (empty($ym['ym']) && $ym['y'] >= substr($mv[1], 0, 4) && $ym['y'] <= substr($mv[2], 0, 4))){
								$isok = true;
								break;
							}
						}
						if(!$isok) $ignorePids[] = $pv['pro_id'];
					}
				}
				if($ignorePids) $whereArr['ignore'] = sprintf(" and pro_id not in (%s)", implode(',', $ignorePids));
			}

			$table .= ' join bc_part on pro_part_id = part_id 
			join bc_part_tree ON pt_part_id = part_id and pt_ismain=1
			left join bc_part_small on part_id = pas_part_id and pro_pas_id = pas_id';
			$res = $this->get($table, ["part_id, concat(pro_part_id, '_', pro_pas_id) as spart_id, case when pas_name is null then part_name else pas_name end as spart_name"], implode(' ', $whereArr).' group by pro_part_id, pro_pas_id order by pt_seq, part_initial, pas_seq');
			if(!empty($res['data'])) 
			{
				$arr['spart'] = $res['data'];
				//是否有店铺分类
				$table .= ' join bc_product_sort on prs_pro_id = pro_id join sh_sort on prs_sort_id = sort_id';
				$res = $this->get($table, ['sort_id, sort_name'], implode(' ', $whereArr).' group by sort_id order by sort_seq, sort_name');
				$arr['sort'] = $res['data'];
				break;
			}
			if(!empty($whereArr)) $arr['type'] = 'all';
		}
		if(!empty($arr['spart']))
		{
			$partIdArr = array_column($arr['spart'], 'part_id');
			$where =  sprintf(" and pt_ismain = 1 and pt_part_id in (%s) order by pt_seq, part_initial", implode(',', $partIdArr));
			$pres = $this->get('bc_part JOIN bc_part_tree ON part_id = pt_part_id', ['part_id, part_name, part_is_end, pt_path'], $where);
			$plinkArr = [];
			foreach($pres['data'] as $v)
			{
				$t = explode(',', $v['pt_path']);
				if(empty($t[1])) continue;
				$p = $t[1];
				unset($v['pt_path']);
				$plinkArr[$p][$v['part_id']] = $v;
			}

			//找出顶级分类
			$tres = $this->get('bc_part JOIN bc_part_tree ON part_id = pt_part_id', ['part_id, part_name, part_is_end'], sprintf(" and part_id in (%s) and pt_ismain = 1 and pt_parent_part_id = 0 order by pt_seq, part_initial", implode(',', array_keys($plinkArr))));
			foreach($tres['data'] as $v)
			{
				$v['sons'] = [];
				$arr['part'][$v['part_id']] = $v;
			}

			foreach($arr['part'] as $ppid=>$pv)
			{
				if(empty($plinkArr[$ppid]))
				{
					unset($arr['part'][$ppid]);
					continue;
				}
				$pv['sons'] = array_values($plinkArr[$ppid]);
				$arr['part'][$ppid] = $pv;
			}
			$arr['part'] = array_values($arr['part']);
		}
		if(!empty($arr['sort']))
		{
			$sortIdArr = array_column($arr['sort'], 'sort_id');
			$where =  sprintf(" and sort_shop_id = %d and sot_sort_id in (%s) and sot_psort_id>0 order by sort_seq",$shopId, implode(',', $sortIdArr));
			$pres = $this->get('sh_sort JOIN sh_sort_tree ON sort_id = sot_sort_id', ['sort_id, sort_name, sot_psort_id'], $where);
			//找出顶级分类
			if($pres['data'])
			{
				$sortIdArr = array_merge($sortIdArr, array_column($pres['data'], 'sot_psort_id'));
				$tres = $this->get('sh_sort JOIN sh_sort_tree ON sort_id = sot_sort_id', ['sort_id, sort_name,sot_psort_id'], sprintf(" and sort_id in (%s) order by sot_psort_id,sort_seq", implode(',', $sortIdArr)));
				$sortArr = [];
				foreach($tres['data'] as $v)
				{
					$temp = [
						'sort_id' => $v['sort_id'],
						'sort_name' => $v['sort_name'],
					];
					if ($v['sot_psort_id'] == 0) {
						$sortArr[$v['sort_id']] = $temp;
					} else {
						$sortArr[$v['sot_psort_id']]['sons'][] = $temp;
					}
				}	
				$arr['sort'] = array_values($sortArr);
			}
		}
		return LibFc::ReturnData(true, $arr); 
	}


	/**
	  * @method 发动机查询
	  * @http	get
	  * @param  shopid             string [必填] 店铺ID
	  * @param  word                string|array [必填] 关键字 至少2个字符  CAL
	  * @param  type                string [选填] 简版目录:super|联动版公众号:gzh
	  * @param  limit               int [选填] 取多少条，默认全部
	  * @param  engtype             int [选填] 1模糊查  2精准查 默认1
	  * @author soul
	  * @copyright 2019/7/22
	  * @return {"status":true,"data":[{"brand_name":"奥迪","engine":"CALA","fuel":"汽油","kw":"195","cc":"3197"},{"brand_name":"奥迪","engine":"CALB","fuel":"汽油","kw":"199","cc":"3197"}],"code":0}
	  */
	public function searchEngine($shopid, $word, $type = 'super', $limit = null, $engtype = 1)
	{
		$arr = [];
		if(is_array($word)){
			$where = sprintf(" and mod3_engine_format in ('%s')", implode("','", $word));
		}else{
			$word = LibFc::FormatNum($word);
			if(strlen($word) < 2 || !in_array($type, ['gzh', 'super', 'superpjl'])) return LibFc::ReturnData(true, $arr);
			$where = $engtype == 2? sprintf(" and mod3_engine_format ='%s'", $word) : sprintf(" and mod3_engine_format like '%%%s%%'", $word);
		}
		$Ypc2Model = new Ypc2Model();
		$res = $Ypc2Model->get('bc_model3', ['distinct mod3_id'], $where);
		if(!empty($res['data']))
		{
			$where = sprintf(" and pml3_mod3_id in(%s)", implode(',', array_column($res['data'], 'mod3_id')));
			if($type == 'gzh')
			{
				$table = sprintf("bc_product 
				join sh_shop_app on pro_shop_id=aps_shop_id and pro_status = 1 and pro_show_app = 1 and aps_status = 1  and pro_shop_id=%d and aps_btime <=%d and aps_etime >= %d
				join bc_product_model3_link on pml3_pro_id=pro_id ", $shopid, time(), time());
			}
			else
			{
				$table = sprintf("bc_product 
				join sh_super on pro_shop_id=ssu_shop_id and pro_status = 1 and pro_show_super = 1 and ssu_status = 1  and pro_shop_id=%d and ssu_btime <=%d and ssu_etime >= %d
				join bc_product_model3_link on pml3_pro_id=pro_id ", $shopid, time(), time());
			}
			
			$res = $this->get($table, ['distinct pml3_mod3_id'], $where);
			if(!empty($res['data']))
			{
				$where = sprintf(" and mod3_id in(%s) group by brand_name, mod3_engine,mod3_kw,mod3_cc order by max(brand_initial), mod3_engine", implode(',', array_column($res['data'], 'pml3_mod3_id')));
				if(!empty($limit) && $limit > 0) $where .= sprintf(" limit %d", $limit);
				$res = $Ypc2Model->getModel(3, ['brand_id', 'brand_name', 'mod3_engine', 'mod3_fuel', 'mod3_kw','mod3_cc'], $where);
				$arr = $res['data'];
			}
		}
		return LibFc::ReturnData(true, $arr);
	}
}