iwebshop商城封装类完善全站会员价格显示

首页、列表页、搜索页等部位商品价格都能显示准确的价格;

获取会员组价格区间,(1)手动定义商品价格; (2)商品自动折扣或货品自动折扣;

第一次运行开销:2次数据库查询、60+60+20次左右循环(以20个商品,每个商品3个货品为例)

因为第一次查询后,会按会员组设置缓存(默认缓存7200秒,自己可以按需要更改),所以性能很高。

实现思路:

数组合并规则:NO1.货品价覆盖商品价,NO2会员价再次覆盖商品价或追加(覆盖方式修改模板地方很少,追加方式很优秀,但修改模板地方较多)

废话不多,上代码:

class groupPrice
{
	//用户ID
	public $user_id = 0;

	//用户组ID
	public $group_id = '';

	//用户组折扣
	public $group_discount = '';

	/**
	 * 构造函数
	 */
	public function __construct($user_id = 0)
	{
		if($user_id)
		{
			$this->user_id = $user_id;
		}
		else
		{
			$userCheckRights = IWeb::$app->getController()->user;
			$this->user_id = ( isset($userCheckRights['user_id']) && $userCheckRights['user_id'] ) ? $userCheckRights['user_id'] : 0;
		}

		//获取用户组ID及组的折扣率
		if($this->user_id)
		{
			$groupObj = new IModel('member as m , user_group as g');
			$groupRow = $groupObj->getObj('m.user_id = '.$this->user_id.' and m.group_id = g.id','g.*');
			if($groupRow)
			{
				$this->group_id       = $groupRow['id'];
				$this->group_discount = $groupRow['discount'] * 0.01;
			}
		}
	}
	/**
	 * 获取会员组价格区间,(1)手动定义商品价格; (2)商品自动折扣
	 * @param  $items   array 商品数组
	 * @return float 价格区间
	 * 开销:2次数据库查询、60+60+20次左右循环(以20个商品,每个商品3个货品为例)
	 * 优化:加缓存
	 */
	public function find($items){
		if(!$this->group_id)
		{
			return $items;
		}
		if(!$items){
			return;
		}
		$ids = array();
		$ids = array_column($items, 'id');	//取所有商品ID
		$where = self::joinStr($ids);		//拼接商品ID
		//file_put_contents('./where'.date('Ymd').'.txt',date('Ymd H:i:s').$where."\r\n",FILE_APPEND);

		//按会员组设置缓存 md5($where.$this->group_id);
		$cacheKey = md5($where.'group_id'.$this->group_id);
		$cacheObj = new ICache();
		$cacheDATA= $cacheObj->get($cacheKey);	//取缓存数据
		if($cacheDATA){
			return $cacheDATA;	//有缓存,返回数据
		}

		//查询会员组价格设定
		$groupPriceDB = new IModel('group_price');
		$groupPriceRow= $groupPriceDB->query('goods_id '.$where.' and group_id = '.$this->group_id,['goods_id','price']);
		if($groupPriceRow){
			$groupPriceRow=array_unique($groupPriceRow,SORT_REGULAR); //去重
			//按商品goods_id合并用户组价格数组
			$result = array();
			foreach ($groupPriceRow as $val) {
				if(!isset($result[$val['goods_id']]['group_price'])) {
					$result[$val['goods_id']]['id']=$val['goods_id'];
					$result[$val['goods_id']]['group_price'] = array();
				}
				array_push($result[$val['goods_id']]['group_price'],$val['price']);
			}
			//$groupPriceRow = array_values($result);
			$groupPriceRow = $result;
			//MY_fun::p($groupPriceRow);			//会员价数组
			$mark_G = true;		//标记有会员价
		}else{
			$mark_G = false;
		}

		//查询货品默认价格
		$tb_product   = new IModel('products');
		$product_info = $tb_product->query('goods_id '.$where,['goods_id','sell_price']);
		if($product_info){
			$product_info = array_unique($product_info,SORT_REGULAR); //去重
			//按商品goods_id合并货品价格数组
			$result = array();
			foreach ($product_info as $val) {
				if(!isset($result[$val['goods_id']]['sell_price'])) {
					$result[$val['goods_id']]['id']=$val['goods_id'];
					$result[$val['goods_id']]['sell_price'] = array();
				}
				array_push($result[$val['goods_id']]['sell_price'],$val['sell_price']);
			}
			//$product_info = array_values($result);
			$product_info = $result;
			//MY_fun::p($product_info);			//货品价数组
			$mark_P = true;		//标记有货品价
		}else{
			$mark_P = false;
		}

		//数组合并规则:NO1.货品价覆盖商品价,NO2会员价再次覆盖商品价或追加
		//【核心算法 开始】
		foreach($items as $key=>$vo){
			$mark = 1;	//【1 NO货品价,NO会员价】、【2 YES货品价,NO会员价】、【3 NO货品价,YES会员价】、【4 YES货品价,YES会员价】
			#NO1.货品价覆盖商品价
			if(isset($product_info[$vo['id']]) && $mark_P){
				$mark = 2;
				$items[$key]['sell_price'] = $product_info[$vo['id']]['sell_price'];
			}
			#NO2会员组价格再次覆盖商品价sell_price(无需改模板),或追加(需改模板)
			if(isset($groupPriceRow[$vo['id']]) && $mark_G){
				$mark += 2;
				$items[$key]['sell_price'] = $groupPriceRow[$vo['id']]['group_price'];
			}
			switch($mark){
				case 1:		//【1 NO货品价,NO会员价】
					$items[$key]['sell_price'] = self::priceFormat($items[$key]['sell_price'] * $this->group_discount);
					break;
				case 2:		//【2 YES货品价,NO会员价】
					$minPrice = min($items[$key]['sell_price']);
					$minPrice = self::priceFormat($minPrice * $this->group_discount);
					if(count($items[$key]['sell_price']) > 1){
						$maxPrice = max($items[$key]['sell_price']);
						$maxPrice = self::priceFormat($maxPrice * $this->group_discount);
						$items[$key]['sell_price'] = join('-',array($minPrice,$maxPrice));
					}else{
						$items[$key]['sell_price'] = $minPrice;
					}
					break;
				case 3:		//【3 NO货品价,YES会员价】
				case 4:		//【4 YES货品价,YES会员价】
					$minPrice = min($items[$key]['sell_price']);
					$minPrice = floatval($minPrice);
					if(count($items[$key]['sell_price']) > 1){
						$maxPrice = max($items[$key]['sell_price']);
						$maxPrice = floatval($maxPrice);
						$items[$key]['sell_price'] = join('-',array($minPrice,$maxPrice));
					}else{
						$items[$key]['sell_price'] = $minPrice;
					}
					break;
			}
		}
		$cacheObj->set($cacheKey,$items,7200);	//设置缓存
		//【核心算法 结束】
		//MY_fun::p($items);
		return $items;
	}
	//字符串拼接
	public function joinStr($id)
	{
		if(is_array($id))
		{
			sort($id);	//升序排序
			$where = "in (".join(',',$id).")";
		}
		else
		{
			$where = '= '.$id;
		}
		return $where;
	}
	/**
	 * 商品价格格式化
	 * @param $price float 商品价
	 * @return float 格式化后的价格
	 */
	public static function priceFormat($price)
	{
		return floatval(round($price,2));
	}
}

使用方法:

大卫博客

//模板中
//第一步:
{set:$groupPriceObj = new groupPrice();}

//第二步
$groupPriceInfo=$groupPriceObj->find($item);

//例如:热销单品的会员价显示
原来的
{set:$resultData =Api::run('getCommendHot',8);}
改为
{set:$resultData =Api::run('getCommendHot',8);$resultData=$groupPriceObj->find($resultData);}
就是这么简单。

类文件下载:

groupPrice.rar

大卫博客
请先登录后发表评论
  • 最新评论
  • 总共0条评论