首页、列表页、搜索页等部位商品价格都能显示准确的价格;
获取会员组价格区间,(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);}
就是这么简单。
下载类文件
版权属于:大卫科技Blog
本文链接:https://www.iyuu.cn/archives/18/
转载时须注明出处