<?php
/**
  * @method 配件搜索
  * @author soul
  * @copyright 2017/9/22
  */
class B2cSearch extends B2cBase
{
	/**
	  * @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])
	{
		$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['keyword'] != '' && $Params['partId'] < 1)
		{
			$keywordArr = LibFc::keyword($Params['keyword']);
			$B2cPart = new B2cPart();
			$res = $B2cPart->getPartNameKeywordCache();
			$PartNameKeyArr = $res['data'];
			$TempArr = $keywordArr;
			$MatchArr = array();
			foreach($TempArr as $KK=>$VV)
			{
				$MatchPart = LibFc::keyArrExists($TempArr, $PartNameKeyArr);
				if(!empty($MatchPart['value']))
				{
					$Key = is_array($MatchPart['value']) ? implode('_', $MatchPart['value']): $MatchPart['value'];
					$MatchArr[$Key] = $MatchPart;
				}
				unset($TempArr[$KK]);
			}
			if(count($MatchArr) == 1)
			{
				$MatchArr = array_shift($MatchArr);
				$Params['partId'] = is_array($MatchArr['value']) ? (int) array_pop($MatchArr['value']): (int) $MatchArr['value'];
				foreach($MatchArr['keys'] as $V)
				{
					$Params['keyword'] = str_ireplace($V, '', $Params['keyword']);
				}
			}
		}*/

		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)", implode(',', $res['data']), count($res['data']));
				/*$wordArr = $res['data'];
				$tempWhere = ' and 1=0';
				for($i = count($wordArr); $i > 0; $i--)
				{
					//关键字组合有数据
					$res = $this->get('bc_product_keyword', ['count(*) count'], sprintf(" and prk_key_id in (%s) group by prk_pro_id HAVING count(*) = %d", implode(',', $wordArr), $i), true);
					if(!empty($res['data']))
					{
						
						echo $tempWhere;
						break;
					}
				}*/
			}
			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) %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 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, 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 店铺搜索
	  * @param  $Params URL参数
	  * @author soul
	  * @copyright 2017/9/22
	  * @return 
			成功 ["status"=>true, "data"=> ] 
			失败 ["status"=>false, "data"=> 错误信息] 
	  */
	public function searchShop($Params)
	{
		$returnArr = [
			'param'=>$Params,
			'shopIds'=>[],
			'total'=>0,
			//地区选择ID
			'pctIds'=>[]
		];

		//关键字搜索
		$where = ' and shop_status = 1';

		// 省份
		if(!empty($Params['pctIds']))
		{
			$pctIdArr = array_filter(explode(',', $Params['pctIds']),'LibFc::Int');
			if(!empty($pctIdArr))
			{
				$pctWhere = sprintf(" and instr( concat(',', shop_pct_ids, ',') , ',%s,')>0", implode(',', $pctIdArr));
				$where .=$pctWhere;	
			}
		}

		//排序
		$orderBy = '';
		$orderByProCount = '';
		switch($Params['order'])
		{
			// 销量
			case 'sold': 
				$orderBy = ' order by shop_sold_count desc, sum(pro_status) desc';
			break;
			//描述评分
			case 'describe': 
				$orderBy = ' order by shop_describe_score desc, sum(pro_status) desc';
			break;
			// 默认
			default:
				$orderBy = ' order by shop_sold_count desc, sum(pro_status) desc';
			break;
		}

		

		if($Params['keyword'] != '')
		{
			//有关键字的查询
			// $table = 'sh_shop_keyword join sh_shop on shop_id = shk_shop_id and shop_status = 1';
			$keywordArr = LibFc::keyword($Params['keyword']);
			$B2cKeyword = new B2cKeyword();
			$res = $B2cKeyword->getKeywordKeyIds($keywordArr);
			$wordArr = $res['data'];

			if(!empty($wordArr))
			{
				// print_r($wordArr);
				//模糊查询
				$moWhere = sprintf(" or (shop_name like '%%%s%%' or shop_id in (select shop_id from sh_shop left join us_user_base on shop_uid=ub_uid where ub_username like '%%%s%%'".$pctWhere.") and shop_status = 1)",LibFc::Escape($Params['keyword']),LibFc::Escape($Params['keyword']));
				
				for($i = count($wordArr); $i > 0; $i--)
				{
					$noPctWhere = sprintf(" and shop_id in (
						select shk_shop_id from sh_shop_keyword join sh_shop on shop_id = shk_shop_id where shk_key_id in (%s) %s group by shk_shop_id having count(*) = %d
					) %s", implode(',', $wordArr), $where, $i,$moWhere);

					$where.= sprintf(" and shop_istest!=1 and shop_show_b2c = 1 and (shop_id in (
						select shk_shop_id from sh_shop_keyword join sh_shop on shop_id = shk_shop_id where shk_key_id in (%s) %s group by shk_shop_id having count(*) = %d
					) %s)", implode(',', $wordArr), $where.$pctWhere, $i,$moWhere);
					// echo $where;

					$res = $this->get('sh_shop', ['count(*) count'], $where, true);
					if(!empty($res['data'])) break;
				}
				// 总数 
				$returnArr['total'] = $res['data']['count'];
			}
			else
			{
				$where .= sprintf(" and shop_istest!=1 and shop_show_b2c = 1 and (shop_name like '%%%s%%' or shop_id in (select shop_id from sh_shop left join us_user_base on shop_uid=ub_uid where ub_username like '%%%s%%'))",LibFc::Escape($Params['keyword']),LibFc::Escape($Params['keyword']));
				//无关键字的查询
				$res = $this->get('sh_shop left join us_user_base on shop_uid=ub_uid', ['count(*) count'], $where, true);
				// 总数
				$returnArr['total'] = $res['data']['count'];
			}
		}
		else
		{
			//无关键字的查询
			$where .= ' and shop_istest!=1 and shop_show_b2c = 1';
			$res = $this->get('sh_shop', ['count(*) count'], $where, true);
			$returnArr['total'] = $res['data']['count'];
		}

		// 分页
		if($returnArr['total'] > 0)
		{
			$where .= sprintf(" group by shop_id %s limit %d,%d", $orderBy, ($Params['page']-1)*$Params['perPage'], $Params['perPage']);
			$res = $this->get('sh_shop left join bc_product on shop_id = pro_shop_id', ['shop_id'], $where);
			$returnArr['shopIds'] = array_column($res['data'], 'shop_id');

			// 省份
			$res = $this->getFieldUniVal('sh_shop', 'shop_pct_ids', $noPctWhere);
			foreach($res['data'] as $v)
			{
				$returnArr['pctIds'] = array_merge($returnArr['pctIds'], explode(',', $v));
			}
			sort($returnArr['pctIds']);
		}
		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 searchShopItem($shopId, $Params, $perPage = 20, $showConf = ['pro_show_b2c'=>1])
	{
		$shopId = (int) $shopId;
		$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'],
			];
			$LibYpApi = new LibYpApi();
			$LibYpApi->get('super/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 = [];
			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['brandId'] = (int) $Params['brandId'];
					$Params['mod1Id'] = (int) $Params['mod1Id'];
					$Params['mod2Id'] = (int) $Params['mod2Id'];
					$Params['mod3Id'] = empty($Params['mod3Id'])? (int) $Params['mod3_id']: (int) $Params['mod3Id'];
					$whereArr['mod3'] = '';
					
					//车型属性条件过滤
					$tw ='';

					if(!empty($Params['brand_id'])) $tw .= sprintf(" and brand_id=%d", (int) $Params['brand_id']);
					if(!empty($Params['mod1_id'])) $tw .= sprintf(" and mod1_id=%d", (int) $Params['mod1_id']);
					if(!empty($Params['mod2_id'])) $tw .= sprintf(" and mod2_id=%d", (int) $Params['mod2_id']);
					if(!empty($Params['mod3_drive'])) $tw .= sprintf(" and mod3_drive='%s'",  LibFc::Escape($Params['mod3_drive']));
					if(!empty($Params['mod3_drive_short'])) $tw .= sprintf(" and mod3_drive_short='%s'",  LibFc::Escape($Params['mod3_drive_short']));
					if(!empty($Params['mod3_cc_name'])) $tw .= sprintf(" and mod3_cc_name='%s'",  LibFc::Escape($Params['mod3_cc_name']));
					if(!empty($Params['mod3_cc'])) $tw .= sprintf(" and mod3_cc='%s'",  LibFc::Escape($Params['mod3_cc']));
					if(!empty($Params['mod3_kw'])) $tw .= sprintf(" and mod3_kw='%s'",  LibFc::Escape($Params['mod3_kw']));
					if(!empty($Params['mod3_engine'])) $tw .= sprintf(" and mod3_engine='%s'",  LibFc::Escape($Params['mod3_engine']));
					if(!empty($Params['year'])) $tw .= 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']);
						$tw .= 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(!empty($Params['engine'])) $tw .=  sprintf(" and mod3_engine ='%s'", LibFc::Escape($Params['engine']));
					if(isset($Params['cc']) && $Params['cc'] !== '')  $tw .=  sprintf(" and mod3_cc =%d", $Params['cc']);
					$ComModel = new ComModel();
					if($tw != '')
					{
						if(!empty($Params['brandId'])) $tw .= sprintf(" and mod3_brand_id=%d", $Params['brandId']);
						if(!empty($Params['mod1Id'])) $tw .= sprintf(" and mod3_mod1_id=%d", $Params['mod1Id']);
						$res = $ComModel->getModel(3, ['distinct mod3_id'], $tw);
						$tm3Id = array_column($res['data'], 'mod3_id');
						$whereArr['mod3'] .= !empty($tm3Id)? sprintf(" and pml3_mod3_id in (%s)", implode(',', $tm3Id)): ' and 1=0';
					}
			
					if(!empty($Params['mod3Id']))
						$whereArr['mod3'] .= sprintf(" and pml3_mod3_id=%d", $Params['mod3Id']);

					if(!empty($Params['mod3Id']) || !empty($whereArr['mod3']))
						$table .= ' join bc_product_model3_link on pro_id = pml3_pro_id';

					if(!empty($Params['mod1Id']))
					{
						$table .= ' join bc_product_model1_link on pro_id = pml1_pro_id';
						$whereArr['mod3'] .= sprintf(" and pml1_mod1_id=%d", $Params['mod1Id']);
					}
					if(!empty($Params['mod2Id']))
					{
						$table .= ' join bc_product_model2_link on pro_id = pml2_pro_id';
						$whereArr['mod3'] .= sprintf(" and pml2_mod2_id=%d", $Params['mod2Id']);
					}
				
					
					//店铺分类
					$Params['sortId'] = (int) $Params['sortId'];
					if($Params['sortId'] > 0)
					{
						$returnArr['sortIds'][] = $Params['sortId'];
						//是否有子类
						$res = $this->get('sh_sort_tree', ['sot_sort_id'], sprintf(" and sot_psort_id=%d", $Params['sortId']));
						foreach($res['data'] as $sv)
						{
							if(!in_array($sv['sot_sort_id'], $returnArr['sortIds'])) $returnArr['sortIds'][] = $sv['sot_sort_id'];
						}

						$table .= ' join bc_product_sort on prs_pro_id = pro_id';
						$whereArr['sort'] = sprintf(" and prs_sort_id in (%s)", implode(',', $returnArr['sortIds']));
					}
					else
					{
						$Params['sortId'] = 0;
					}

					//配件关键字
					if($Params['keyword'] != '')
					{
						//通过适用车型查找
						$wordMod3IdArr = [];
						if(empty($whereArr['mod3']))
						{
							$modelWordWhere = '';
							//提取年份
							if(preg_match('/20\d{2}/', $Params['keyword'], $match))
							{
								if($match[0] <= date('Y')+1)
								{
									$Params['keyword'] = str_replace($match[0], '', $Params['keyword']);
									$modelWordWhere .= sprintf(" and mod3_start_year <=%d and (mod3_end_year >= %d or mod3_end_year=0) ", $match[0], $match[0]);
								}
							}
							$wordArr = LibFc::keyword($Params['keyword']);
							$res = $ComModel->get('yp_model_word', ['mw_id'], sprintf(" and mw_word in ('%s')", implode("','", $wordArr)));
							if(!empty($res['data']))
							{
								$wordIdArr = array_column($res['data'], 'mw_id');
								for($i = count($wordIdArr); $i > 0; $i--)
								{
									$mtable = 'yp_model_word_link join bc_model3 on mwl_mod3_id = mod3_id';
									$res = $ComModel->get($mtable, ['mwl_mod3_id'], $modelWordWhere.sprintf(" and mwl_mw_id in (%s) group by mwl_mod3_id having count(*) = %d limit 1000", implode(',', $wordIdArr), $i));
									if(!empty($res['data']))
									{
										$wordMod3IdArr = array_column($res['data'], 'mwl_mod3_id');
										break;
									}
								}
							}
						}
						if(!empty($wordMod3IdArr))
						{
							$whereArr['mod3'] = sprintf(" and pml3_mod3_id in (%s)", implode(',', $wordMod3IdArr));
							$table .= ' join bc_product_model3_link on pro_id = pml3_pro_id';
						}

						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'] = implode(',', array_column($res['data'], 'pro_id'));
							}
							$LibYpApi = new LibYpApi();
							$res = $LibYpApi->Get('b2c/searchByEs', [], $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;
			}
			foreach($whereArr as $wk=>$wv)
			{
				if(empty($wv)) unset($whereArr[$wk]);
			}
			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;
		$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'],
			];
			$LibYpApi = new LibYpApi();
			$LibYpApi->get('super/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']];
		}


		foreach($typeArr as $type)
		{
			$twhere = !empty(mvc::$cfg['PROALL'])? '' : 'and pro_status =1';
			$table = sprintf("bc_product");
			$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':
					$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 ComModel();
					$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';
						}
					}
				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;
				}
			}
		}
		$whereArr['ww'] = sprintf(" and pro_status = 1 and pro_shop_id in(%s)",$shopId);
		//var_dump($whereArr);exit();
		$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'] = $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); 
	}

}