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);}
就是这么简单。

1543732895313558.png

下载类文件

最后修改:2019 年 08 月 06 日 01 : 09 PM
如果觉得我的文章对你有用,请随意赞赏

发表评论