在ecshop源码折扣计算中的代码在lib_main.php
的update_user_info()函数中
$sql = 'SELECT u.user_money,u.email, u.pay_points, u.user_rank, u.rank_points, '.
' IFNULL(b.type_money, 0) AS user_bonus, u.last_login, u.last_ip'.
' FROM ' .$GLOBALS['ecs']->table('users'). ' AS u ' .
' LEFT JOIN ' .$GLOBALS['ecs']->table('user_bonus'). ' AS ub'.
' ON ub.user_id = u.user_id AND ub.used_time = 0 ' .
' LEFT JOIN ' .$GLOBALS['ecs']->table('bonus_type'). ' AS b'.
" ON b.type_id = ub.bonus_type_id AND b.use_start_date <= '$time' AND b.use_end_date >= '$time' ".
" WHERE u.user_id = '$_SESSION[user_id]'";
if ($row = $GLOBALS['db']->getRow($sql))
{
/* 更新SESSION */
$_SESSION['last_time'] = $row['last_login'];
$_SESSION['last_ip'] = $row['last_ip'];
$_SESSION['login_fail'] = 0;
$_SESSION['email'] = $row['email'];
/*判断是否是特殊等级,可能后台把特殊会员组更改普通会员组*/
if($row['user_rank'] >0)
{
$sql="SELECT special_rank from ".$GLOBALS['ecs']->table('user_rank')."where rank_id='$row[user_rank]'";
if($GLOBALS['db']->getOne($sql)==='0' || $GLOBALS['db']->getOne($sql)===null)
{
$sql="update ".$GLOBALS['ecs']->table('users')."set user_rank='0' where user_id='$_SESSION[user_id]'";
$GLOBALS['db']->query($sql);
$row['user_rank']=0;
}
}
/* 取得用户等级和折扣 */
if ($row['user_rank'] == 0)
{
// 非特殊等级,根据等级积分计算用户等级(注意:不包括特殊等级)
$sql = 'SELECT rank_id, discount FROM ' . $GLOBALS['ecs']->table('user_rank') . " WHERE special_rank = '0' AND min_points <= " . intval($row['rank_points']) . ' AND max_points > ' . intval($row['rank_points']);
if ($row = $GLOBALS['db']->getRow($sql))
{
$_SESSION['user_rank'] = $row['rank_id'];
$_SESSION['discount'] = $row['discount'] / 100.00;
}
else
{
$_SESSION['user_rank'] = 0;
$_SESSION['discount'] = 1;
}
}
else
{
// 特殊等级
$sql = 'SELECT rank_id, discount FROM ' . $GLOBALS['ecs']->table('user_rank') . " WHERE rank_id = '$row[user_rank]'";
if ($row = $GLOBALS['db']->getRow($sql))
{
$_SESSION['user_rank'] = $row['rank_id'];
$_SESSION['discount'] = $row['discount'] / 100.00;
}
else
{
$_SESSION['user_rank'] = 0;
$_SESSION['discount'] = 1;
}
}
}
在看分析前必须理解三个概念,
user_rank不一定是最终计算折扣的等级
user_rank>0时,系统就认为该会员属于特殊会员组
special_rank=0时,系统就认为该等级属于特殊会员组
根据这段代码分析,
一、ecshop 先按照user_id取出数据,根据用户数据的user_rank是否>0来判断该用户以前是否是特殊会员组。
但是又有2种情况发生,
1,当后台把user_rank所在的等级由原来的特殊会员组改为非特殊会员组时
2,管理员把user_rank所在的等级删除了
所以在代码中针对这两种情况代码执行
$sql="update ".$GLOBALS['ecs']->table('users')."set user_rank='0' where user_id='$_SESSION[user_id]'";
$GLOBALS['db']->query($sql);
$row['user_rank']=0;
也就是把user_rank重置为0,也就是当前用户已经还原成为了非特殊会员组
二、用户在此根据user_rank==0来判断该会员现在是否属于特殊会员组 =0则属于非特殊会员组
当user_rank==0 时 根据 rank_points来进行计算,,最终得到折扣。但是sql中添加了special_rank = '0'的条件,
根据这个分析,ecshop 的等级积分可能会存在重叠的情况,但是推荐会员等级列表中非特殊会员组最好永远只有1组而且积分连续而且不重叠
这样才会每次按积分查询时都会满足唯一一个非特殊等级组,才符合实际情况。
user_rank>0时根据user_rank 来进行计算,最终得到折扣。此时此等级的积分基本无效,所以建议把积分上下限都设为很大很大如(100000000)
这样当错误的操作或无意中取消为非会员组时,才不会影响到程序
针对如果积分范围不属于某个非特殊会员组,和特殊会员组不存在的2种情况,ecshop也进行了
$_SESSION['user_rank'] = 0;
$_SESSION['discount'] = 1;
的操作