There are questions remain, We'll search for the answers together. But one thing we known for sure,the future is not set!

【原创文章】同步ecshop与ectouchQQ登陆并显示用户QQ昵称和头像

ectouch 百蔬君 6714℃ 已收录 1评论

在昨天的文章《追查Ectouch QQ登录每次用户名都不同的原因和解决办法》中详细追踪了ectouch第三方qq登陆的问题及解决方案。修正了ectouch user_id输入错误的问题之后,在之后的使用中是没问题的,可以在touch_user_info表和users表中联合查询。但是在这里我们可以更进一步来改进他,及实现网站qq登陆和手机qq登陆的统一,也就是我在《追查》一文中提到的第二套方案,让从网站和手机登录的qq用户使用同一个账户,并个性化qq登陆用户资料。同时也是对QQ登录每次用户名都不同的一个彻底解决方案,即取消get_one_user的联合查询。

继续来看mobile\include\apps\default\controller\UserController.class.php中登陆成功后的这段public function third_login代码

if ($_SESSION['access_token']) {
$res = new $type($info, $_SESSION['access_token']);
$openid = $res->get_openid();
// 获取用户信息
$userinfo = $res->get_user_info($openid);
// 处理数据
$userinfo['aite_id'] = $type . '_' . $openid; // 添加登录标示
$_SESSION['aite_id'] = $userinfo['aite_id'];//获取qq的aite_id值
if ($userinfo['user_name'] = model('Users')->get_one_user($userinfo['aite_id'])) {//
// 已有记录
self::$user->set_session($userinfo['user_name']);
self::$user->set_cookie($userinfo['user_name']);
model('Users')->update_user_info();
model('Users')->recalculate_price();
$jump_url = empty($this->back_act) ? url('index') : $this->back_act;
$this->redirect($jump_url);
}
if (empty($userinfo['user_name'])) $userinfo['user_name'] =substr($openid, -6);
if(self::$user->check_user($userinfo['user_name'])) {
$userinfo['user_name'] = $userinfo['user_name'].rand(1000, 9999); // 重名处理
}
$userinfo['email'] = empty($userinfo['email']) ? substr($openid, -6) . '@' . get_top_domain() : $userinfo['email'];
// 插入数据库
model('Users')->third_reg($userinfo);
self::$user->set_session($userinfo['user_name']);
self::$user->set_cookie($userinfo['user_name']);
model('Users')->update_user_info();
model('Users')->recalculate_price();
$jump_url = empty($this->back_act) ? url('index') : $this->back_act;
$this->redirect($jump_url);
}

$userinfo['aite_id'] = $type . '_' . $openid; // 添加登录标示这里可以看到,以aite_id作为用户是否已经存在的依据是ok的,因为$openid是qq号与网站对应的唯一值,那么是否是同一个qq用户就以ecshop的users表中的aite_id为准来作为用户的唯一标识,这样可以使得从网站及手机登录的qq用户拥有中一个aite_id值,而不用相互隔开,实现两端登陆同步。

另外作为$userinfo[‘user_name’]来说,我觉得这样的设计不合理,为什么我每次的用户只能是数据库中已经存在的从前的用户名,网站显示我当前的昵称不是更好吗?我本来就是qq登陆嘛。

我们一步一步来改进它,首先获取qq的昵称,并赋值给$userinfo[‘user_name’],将$userinfo['user_name']=$userinfo['nickname'];//获取qq昵称放在放在if判断前面。在这里get_one_user函数就必须修改了,即从ecshop的users查询,这也是迫不得已的选择,因为users表中已经存在很多从网站登录的qq用户了。写到这里我突然想到一个修改上一个错误的方案,就是当用qq用户登录的时候,在users中查询到aite_id值,这时候在touch_user_info中以aite_id为关联字段,来修改他的user_id,这样只要以前的客户再次登陆就可以修复这个user_id的错误。不管怎样,get_one_user函数必须要修改为从users查询。

function get_one_user($aite_id) {
$sql = 'SELECT user_name FROM ' . $this->pre . 'users WHERE aite_id = "' . $aite_id . '" ';
$res = $this->row($sql);
return $res['user_name'];
}

去掉了touch_user_info的联合查询,这样只要从网站qq登陆过就可以读取了,但是之前在手机端登陆过的就没有什么办法了。这样就将电脑QQ第三方登录与手机QQ第三方登录统一了起来。

好了,思路来了,下面要实现另外一个问题,如果将从手机登录的QQ用户的aite_id写入users表呢?aite_id都要写入了,那么把其他的参数也一起写入users,比如性别啊,头像地址啊,让我们的QQ登陆用户更加个性化!!

首先将QQ的json数组的值传给session,在$userinfo['aite_id'] = $type . '_' . $openid; // 添加登录标示下面添加。

                    $userinfo['aite_id'] = $type . '_' . $openid; // 添加登录标示
                    $_SESSION['aite_id'] = $userinfo['aite_id'];//获取qq的aite_id值
                    $userinfo['user_name']=$userinfo['nickname'];//获取qq昵称
                    $_SESSION['figureurl_qq_2']=(string)$userinfo['figureurl_qq_2']; //获取qq头像
                    $_SESSION['gender']=(string)$userinfo['gender'];   //获取性别   

再下面的$userinfo[‘user_name’] =substr($openid, -6);要做一个判断,即if (empty($userinfo['user_name'])) $userinfo['user_name'] =substr($openid, -6);

邮箱名称也要变变,由于qq的第三方登录没有开放邮箱和qq号码数据,所以这里必须自己生成。昵称一般都是中文,其实这里是个鸡肋,没有邮箱不行,他是ecshop登陆的一种方式,如果有呢,实际意义不大,但是邮箱名不能是中文,所以这里要修改。

$userinfo['email'] = empty($userinfo['email']) ? $userinfo['user_name'] . '@' . get_top_domain() : $userinfo['email'];

修改为

$userinfo['email'] = empty($userinfo['email']) ? substr($openid, -6) . '@' . get_top_domain() : $userinfo['email'];

邮箱名以openid的末尾6位标识,这是是无奈之举,没有一个更好的办法,如果QQ API开放QQ邮箱就好了。

再往下看,

                    model('Users')->third_reg($userinfo);
                    self::$user->set_session($userinfo['user_name']);
                    self::$user->set_cookie($userinfo['user_name']);
                    model('Users')->update_user_info();
                    model('Users')->recalculate_price();

third_reg第三方登录之后有一个update_user_info(),我们就在这里更新我们获取的数据,这个函数位于mobile\include\apps\default\model\UsersModel.class.php,修改这个函数之前还需要做一件事情,因为users默认表中没有存放缩微图的字段,需要自己添加一个,这个进入phpmyadmin自己操作就好了,非常简单。或者进ecshop后台添加,类似这样的语句alter table users ADD thumb var(200) not null;,有了thumb字段之后就可以存放数据了。

下面来修改update_user_info函数。
首先修改查询会员信息的sql语句

$sql = 'SELECT u.user_money,u.email, u.aite_id,u.sex,u.thumb, u.pay_points, u.user_rank, u.rank_points, ' .
' IFNULL(b.type_money, 0) AS user_bonus, u.last_login, u.last_ip' .
' FROM ' . $this->pre . 'users AS u ' .
' LEFT JOIN ' . $this->pre . 'user_bonus AS ub' .
' ON ub.user_id = u.user_id AND ub.used_time = 0 ' .
' LEFT JOIN ' . $this->pre . '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]'";

添加了u.aite_id,u.sex,u.thumb,在这个sql语句前面初始化几个变量

        $aite_id='';
         $sex='';
         $thumb='';

将读出来的数据付给这几个变量,便于比较以前的数据是否和现在的数据是否有变动。

if ($row = $this->row($sql)) {
            /* 更新SESSION */
            $_SESSION['last_time'] = $row['last_login'];
            $_SESSION['last_ip'] = $row['last_ip'];
            $_SESSION['login_fail'] = 0;
            $_SESSION['email'] = $row['email'];
            $aite_id=$row['aite_id'];
            $sex=$row['sex'];
            $thumb=$row['thumb'];

现在来改造最后的执行更新的sql语句了。我们要根据不同的情况来构造不同的语句。

/* 更新登录时间,登录次数及登录ip */
$sql = "UPDATE " . $this->pre . "users SET" .
" visit_count = visit_count + 1, " .
" last_ip = '" . real_ip() . "'," ;
if (!empty($_SESSION['gender']) && $sex != $_SESSION['gender']){
$gender_var=1;
if ($_SESSION['gender']!='男') $gender_var=0;
$sql =$sql." sex = '" . $gender_var . "',";
}
if (!empty($_SESSION['figureurl_qq_2']) && $thumb != $_SESSION['figureurl_qq_2']){
$sql =$sql." thumb = '" . $_SESSION['figureurl_qq_2'] . "'";
}
if (!empty($_SESSION['aite_id']) && $aite_id != $_SESSION['aite_id']){
$sql =$sql." aite_id = '" . $_SESSION['aite_id'] . "'" ;
}
$sql =$sql." last_login = '" . gmtime() . "'" .
" WHERE user_id = '" . $_SESSION['user_id'] . "'";
$this->query($sql);

这个语句就是比较当前的aite_id,gender和thumb是否和之前一样,如果不同就更新。这样就将QQ登陆用户的最新数据同步到users了。好了,有了数据之后,在哪里显示出来呢。

查询用户资料的函数是 get_user_default,他位于mobile\include\base\model\ClipsBaseModel.class.php文件中,在sql语句中增加thumb的字段就好了。之后在mobile\themes\default\user.dwt显示头像的位置调用。最终效果如下。

Snap1

 

调用qq头像,显示qq用户昵称,比原来的随机数字用户名和默认灰色头像好看多了吧。

转载请注明:百蔬君 » 【原创文章】同步ecshop与ectouchQQ登陆并显示用户QQ昵称和头像

喜欢 (3)or分享 (0)
发表我的评论
取消评论

请证明您不是机器人(^v^):

表情
(1)个小伙伴在吐槽
  1. 没看懂,能不能把改动的四个文件源码发我研究一下,2501804535@qq.com;
    匿名2019-04-06 18:31 回复