微信扫码登陆绑定账号功能

1、前台链接进入微信官方的授权接口,当点击链接时,则根据url中的appid自动生成公司微信二维码

<a href="https://open.weixin.qq.com/connect/qrconnect?appid=(微信官方提供的appid)&redirect_uri=http%3A%2F%2F(项目域名地址)%2F(项目模块名)%2F(模块控制器名)%2F(模块方法名)&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect"><span class="fgt pull-right"><img src="__PUBLIC__/web/images/wx.png">微信登录</span></a>

2、先定义好微信授权接口类,以便下面授权时调用

class WeAuth
{
    protected $appId = "公司微信的appid";
    protected $appSecret = "企业微信号的密钥";

    function __construct()
    {
       // parent::__construct(false);

        if(config('weixin.openAppId'))
        {
            $this->appId = config('weixin.openAppId');
        }

        if(config('weixin.openAppSecret'))
        {
            $this->appSecret = config('weixin.openAppSecret');
        }
    }

    /**
     * 开始授权
     * @return mixed
     */
    public function doAuth()
    {
        //如果扫码页面的url路径中有code码,则授权完成进入回调函数
        if (isset($_REQUEST['code'])) {
            return $this->getUserInfo();
        }
        else {
        //获取请求页面时通信协议的名称和版本。例如,“HTTP/1.0”。
        $protocal = $_SERVER['SERVER_PROTOCOL'];
        //当前请求头中 Host: 项的内容,如果存在的话。
        $http_host = $_SERVER['HTTP_HOST'];
        //判断是http请求还是https请求
        if ($protocal['5'] == 's') {
            $protocal = 'https://';
        }
        else {
            $protocal = 'http://';
        }
        $origin_url = $protocal . $http_host;
        // $origin_url = str_replace("www.", "", $origin_url);
        //进入获取用户信息授权路径
        $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $this->appId . "&redirect_uri=" . urlencode($origin_url) . $_SERVER['REQUEST_URI'] . "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
        header("Location:" . $url);
        exit();
        }
    }

    /**
     * 授权完成之后的回调,获取微信信息
     * @return mixed
     */
    public function getUserInfo()
    {
        $code = $_REQUEST['code'];
        $state = $_REQUEST['state'];
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" . $this->appId . "&secret=" . $this->appSecret . "&code=" . $code . "&grant_type=authorization_code";
        $json = file_get_contents($url);
        $base_info = json_decode($json);
        $access_token = $base_info->access_token;
        $openid = $base_info->openid;
        $url = "https://api.weixin.qq.com/sns/userinfo?access_token=" . $access_token . "&openid=" . $openid . "&lang=zh_CN";
        $json = file_get_contents($url);
        $wechat_user_info = json_decode($json,true);
        header('Content-type: text/html;charset=utf-8');
        return $wechat_user_info;
    }

}

3、当扫描二维码后,进入指定的页面和函数中,判断如果是登陆状态则跳转首页如果不是则进入微信授权去登陆。如果授权成功,则进入登陆判断。如果有该微信的信息则登陆,没有则进入绑定微信页面

protected $userId;
public function index()
{
    $userId = session("userId");
    if (!$userId) {
        //实例化授权接口类
        $auth = new WeAuth();
        //调用微信授权函数
        $wechatInfo = $auth->doAuth();
        // print_r($wechatInfo);exit();
        //判断授权是否成功
        if($wechatInfo && isset($wechatInfo['unionid']) && !empty($wechatInfo['unionid']))
        {
            //获取到用户的微信id,查找数据库内是否有该微信id
            //如果没有,则跳转微信账号绑定项目账号功能,如果已经存在,则直接登录
            $unionId = $wechatInfo['unionid'];
            $msg = findById("user",array('a.unionId'=>$unionId),"a.*");
            if(empty($msg["data"])||$msg['code']==0){
                //未绑定账号,跳转到绑定账号页面,并将查到的微信用户信息发送到wxbind方法体内
                return view('web@/index/wxbind',array('data'=>$wechatInfo));
                //$this->redirect(url('/web/Index/wxbind',array('data'=>$wechatInfo)));
            }else {
                //限制异常状态的账号登录
                $user = $msg["data"];
                $userState = $user["status"];
                if ($userState == '1012002'){
                    echo '<script language="javascript">alert("微信登录失败:用户状态异常。");</script>';
                    $this->redirect(url('/web/Index/index'));
                }
                if ($userState == '1012005') {
                    echo '<script language="javascript">alert("微信登录失败:当前账户已被冻结,请联系管理员。");</script>';
                    $this->redirect(url('/web/Index/index'));
                }
                //将数据写入session
                session('user', $user);
                session('userId', $user["id"]);
                //登录成功跳转到首页
                $this->redirect(url('/web/Index/index'));
            }
        }else{
            echo '<script language="javascript">alert("微信登录失败:获取微信信息失败。");</script>';
            $this->redirect(url('/web/Index/index'));
        }
    } else {
        $this->redirect(url('/web/Index/index'));
    }

}

4、绑定微信功能的页面,并展示微信用户信息

//微信登录, 已有平台账号页面
function wxbind(){
    //将授权获得的微信用户信息赋值$data,并发送给前台
   $data = input('request.');
    if(empty($data)){
        $data = array();
    }
    return view("",array('data'=>$data));
}

5、wxbind的前台页面

<div class="col-lg-12 col-md-12 col-sm-12">
    <div class="col-md-12 col-sm-12">
        <div class="col-md-12 col-sm-12">
            <h3 class="welcome">
                <img src="{$data.headimgurl|default='__PUBLIC__/web/images/tx.jpg'}">Hi,{$data.nickname|default=''},欢迎登录平台
            </h3>
        </div>
        <div class="col-md-3 col-sm-12"></div>
        <div class="col-md-6 col-sm-12 choosewxbt">
            <div class="col-md-6 col-sm-12 wxbtnow" style="padding:0;" ><p>已有平台账号</p></div>
            <div class="col-md-6 col-sm-12" style="padding:0;" id="notyet"><p>没有平台账号</p></div>
        </div>
        <div class="col-md-3 col-sm-12"></div>
        <div class="col-md-12 col-sm-12"><p class="sm">绑定账号后,可实现一键登录哦</p></div>
    </div>
    <div class="col-lg-4 col-md-4 col-sm-12"></div>
    <div class="col-md-4 col-sm-12 biaodan wxlogin">
        <div class="col-md-12 col-sm-12">
            <div class="form-group">
                <form action="" method="post" id="wxform">
                <input type="text" name="phone" id="phone" class="form-control" placeholder="登录用户名">
                <input type="password" name="password" id="password" style="margin-bottom: 14px;;"  class="form-control" placeholder="密码">

                <input type="hidden" name="unionid" id="unionid" value="{$data.unionid|default=''}">  <!--微信返回的unionid-->
                <input type="hidden" name="headimgurl" id="headimgurl" value="{$data.headimgurl|default=''}"> <!---微信返回的用户头像地址-->
                <input type="hidden" name="nickname" id="nickname" value="{$data.nickname|default=''}">   <!--微信返回的用户昵称-->
                <button type="button" class="btn btn-block btn-outline btn-warning" id="submit">立即绑定</button>

                </form>

            </div>
            <div class="hr-line-dashed"></div>
        </div>
    </div>
    <div class="col-lg-4 col-md-4 col-sm-12"></div>
</div>

6、前台发送数据的Js

$("#submit").click(function () {

   // var isPhone = /^([0-9]{3,4}-)?[0-9]{7,8}$/;
  //  var isMob=/^((\+?86)|(\(\+86\)))?(13[012356789][0-9]{8}|15[012356789][0-9]{8}|18[012356789][0-9]{8}|147[0-9]{8}|1349[0-9]{7})$/;
    var phone_str=$("#phone").val();
    phone_str = $.trim(phone_str);
    if(phone_str==""){
        toastr.error('登录用户名必填');
        return;
    }
    /*else if(!(isPhone.test(phone_str)||isMob.test(phone_str))){
        alert('手机号码格式错误');
        return;
    }*/
    var password = $('#password').val();
    password = $.trim(password);
    if(password ==''){
        toastr.error('密码必填');
        return ;
    }
    var unionid = $("#unionid").val();//微信的id
    var nickname = $("#nickname").val();//微信名
    var url = "{:url('/web/Index/dobind')}";
    $.post(url, {'mobile':phone_str,'password':password,'unionid':unionid,'nickname':nickname}, function (data) {
        if(data.code ==1){
            toastr.success('绑定成功');
            setTimeout('go()',1000);

        }else {
            toastr.error(data.msg);
        }
    });
});

7、绑定微信的方法体

//已有账号,绑定操作
function dobind(){
    $postData = input('request.',null,'trim');
    try{
        if(empty($postData['mobile'])){
            return array('code'=>'0','msg'=>'登录用户名不能为空','data'=>'');
        }
        if(empty($postData['password'])){
            return array('code'=>'0','msg'=>'密码不能为空','data'=>'');
        }
        $map = array(
            'name'=>$postData['mobile'],
        );
        $msg = findById("user", $map, "a.*");
        //如果没有查询到数据,或返回值为0,则返回错误
        if (empty($msg["data"]) || $msg['code'] == 0) {
            return array('code'=>'0','msg'=>'该用户不存在,无法绑定。','data'=>'');
        }else{
            $user = $msg["data"];
            //判断查出的用户密码与绑定账号页面输入的密码是否一致,密码一致则允许绑定
            if ($user["password"] !== md5($postData['password'])){
                return array('code' => '0', 'msg' => '密码错误,请重新输入。', 'data' => '');
            }
            //限制账号异常的用户进行登录
            $userState = $user["status"];
            if ($userState == '1012002') {
                return array('code' => '0', 'msg' => '用户状态异常,不能绑定', 'data' => '');
            }
            if ($userState == '1012005') {
                return array('code' => '0', 'msg' => '当前账户已被冻结,无法绑定', 'data' => '');
            }
            //传入的微信id
            $data = array(
                'unionId'=>$postData['unionid'],
            );
            //传入的微信名
            $data['wx_name'] = $postData['nickname'];
            if(empty($user['realname'])){
                $data['realname'] = $postData['nickname'];
            }
            #todo 微信头像暂时还没处理
            //根据传入的手机号将该用户的id和扫码的微信绑定
            $res = saveDataByCon('user',$data,array('name'=>$postData['mobile']));
            //如果保存成功则进行登录
            if($res['code']==1){
                //保存成功后,缓存数据,相当于直接登录了
                //获取logo并缓存
                $logo = '/img/111.jpg';
                //获取孵化器的名字 并缓存
                if(strpos(','.$user["roleIds"].',',',1,')!==false && !empty($user["etprsIqbtId"])){
                    //孵化器企业管理员,应该读取孵化器企业的名字
                    $name = getField('etprsIqbt',array('id'=>$user['etprsIqbtId']),'name');

                }elseif(!empty($user['iqbtId'])){
                    $name = getField('incubator',array('id'=>$user['iqbtId']),'name');
                    if(!empty($user['logo'])){
                        $logo = getField('sysFile',array('id'=>$user['logo']),'savePath');
                    }
                }else{
                    $name = "海创汇云平台";
                }
                session('sysName',$name);
                session('logo',$logo);
                session('user', $user);
                session('userId', $user["id"]);
                if($user["userCate"]=="1011002"){
                    session('etprsId', $user["etprsId"]);
                }
                session('iqbtId', $user["iqbtId"]);
                session("etprsIqbtId",$user["etprsIqbtId"]);
                return $res;
            }
        }

    }catch (\Exception $e) {
        //绑定失败则记录事务
        c_Log($e);
        return array("code" => 0, "msg" =>'绑定失败','data'=>'');
    }
}

8、如果平台账号也没有,则注册账号并绑定微信号,注册成功后写入session登陆,并跳转到首页

//微信登录  没有平台账号情况的页面
    function wxempty($unionid='',$nickname='',$headimgurl=''){
        $data = array(
            'unionid'=>$unionid,
            'nickname'=>$nickname,
            'headimgurl'=>$headimgurl,
        );
        return view('',array('data'=>$data));
    }

9、前台发送注册信息的html

//展示信息
<h3 class="welcome">
    <img src="{$data.headimgurl|default='__PUBLIC__/web/images/tx.jpg'}">Hi,{$data.nickname|default=''},欢迎登录海创汇云平台
</h3>
//表单
<form action="" method="post" id="rgst">
<input type="text" class="form-control" name="mobile" id="mobile" placeholder="联系电话(登录名必填)" onfocus="this.placeholder=''" onblur="this.placeholder='联系电话(登录名必填)'">
<input type="text" class="form-control" name="realname" id="realname" placeholder="姓名" onfocus="this.placeholder=''" onblur="this.placeholder='姓名'">
<p class="col-lg-12 col-md-12 col-sm-12 find find1">
    <input type="text" class="form-control pull-left" id="verify"  name="verify" placeholder="短信验证码" onfocus="this.placeholder=''" onblur="this.placeholder='短信验证码'">
    <button type="button" class="btn btn-block btn-outline btn-default pull-right a" id="sms">点击获取</button>
</p>
<input style="margin-bottom:14px;" type="password" name="password" id="password" class="form-control" placeholder="密码(6-20位字母、数字、符号组合)" onfocus="this.placeholder=''" onblur="this.placeholder='密码(6-20位字母、数字、符号组合)'">
<input style="margin-bottom:14px;" type="password"  name="cfmpassword" id="cfmpassword" class="form-control" placeholder="确认密码" onfocus="this.placeholder=''" onblur="this.placeholder='确认密码'">
<input type="hidden" name="unionid" id="unionid" value="{$data.unionid|default=''}">  <!--微信返回的unionid-->
<input type="hidden" name="headimgurl" id="headimgurl" value="{$data.headimgurl|default=''}"> <!---微信返回的用户头像地址-->
<input type="hidden" name="nickname" id="nickname" value="{$data.nickname|default=''}">   <!--微信返回的用户昵称-->

</form>
<button type="button" id="btnrgst" class="btn btn-block btn-outline btn-warning">完成</button>

10、没有账号需要注册时发送的ajax

$("#btnrgst").click(function () {

    var isPhone = /^([0-9]{3,4}-)?[0-9]{7,8}$/;
    var isMob=/^((\+?86)|(\(\+86\)))?(13[012356789][0-9]{8}|17[012356789][0-9]{8}|15[012356789][0-9]{8}|18[012356789][0-9]{8}|147[0-9]{8}|1349[0-9]{7})$/;
    var phone_str=$("#mobile").val();
    phone_str = $.trim(phone_str);
    var realname = $.trim($("#realname").val());
    var password = $.trim($("#password").val());
    var cfmpassword = $.trim($("#cfmpassword").val());
    if(phone_str==""){
        toastr.error('电话号码不能为空');
        return false;
    }else if(!(isPhone.test(phone_str)||isMob.test(phone_str))){
        toastr.error('电话号码格式不正确');
        return false;
    }
    if(realname==""){
        toastr.error('姓名不能为空');
        return ;
    }
    var verify = $.trim($("#verify").val());
    if(verify==''){
        toastr('短信验证码不能为空');
        return false;
    }

    if(password==""){
        toastr.error('密码不能为空');
        return;
    }
    if(password!=cfmpassword){
        toastr.error('两次密码不一致,请重新输入');
        return;
    }
    var regExp=/^(?![\d]+$)(?![a-zA-Z]+$)(?![^\da-zA-Z]+$).{6,20}$/;
    if(!regExp.test(password)){
        toastr.error('密码必须为6-20位字母、数字或符号组合');
        return;
    }
    var form = $("#rgst");
    var url = "{:url('/web/Index/dobindempty')}";
    var data=form.serialize();
    $.post(url, data, function (data) {
        if (data.code == 1) {
            toastr.success('注册成功,请登录');
            setTimeout('go()',1000);
        } else {
            toastr.error(data.msg);
        }
    });

});

11、没有注册过时,扫码后进入注册的函数,并将微信号的信息一同保存在数据中

//微信登录,没有注册的,绑定首次注册的用户
function dobindempty(){
    $postData = input('request.',null,'trim');
    //加校验
    $role = [
        'mobile|联系电话'=>'require',
        'realname|姓名'=>'require',
        'verify|短信验证码'=>'require',
        'password|密码'=>'require',
        'cfmpassword|确认密码'=>'require|confirm:password',
    ];
    $err = [
        'mobile'=>'联系电话不能为空',
        'realname'=>'姓名不能为空',
        'verify'=>'短信验证码必填',
        'password'=>'密码必填',
        'cfmpassword'=>'确认密码必填且必须和密码一致',
    ];
    $validate = new Validate($role,$err);
    if(! $validate->check($postData)){
        return array('code'=>'0','msg'=>$validate->getError(),'data'=>'');
    }

    try {
        $username = $postData['mobile'];
        $umsg = findById("user", array("name" => $username), "id");
        if (!empty($umsg["data"])) {
            return array("code" => 0, "msg" => "绑定失败,该手机号已注册");
        }
        //验证手机短信验证码
        $verify =$postData['verify'];
        $res = verifySmsCode($username, $verify, 600);
        //验证失败
        if ($res['code'] == '0') {
            return array('code' => '0', 'msg' => $res['msg'], 'data' => '');
        }

        $etprs["addtime"] = time();
        //开启事物
        Db::startTrans();
        $msg = saveData("enterprise", $etprs, "企业注册");
        if ($msg["code"] === '1') {
            $etprsId = $msg["data"];
            $user["name"] = $username;
            $user["realname"] = $postData['realname'];
            $user["registerTime"] = date("Y-m-d H:i", time());
            $user["addtime"] = time();
            $user["mobile"] = $username;
            $user["password"] = md5($postData['password']);
            $user["userCate"] = "1011002";
            $user["status"] = "1012003";      //这个状态有待进一步讨论
            $user["etprsId"] = $etprsId;
            $user["etprsIqbtId"] = 1;
            $user["roleIds"] = "2";//角色:企业
            $user['realname'] = $postData['nickname'];
            $user['unionId'] = $postData['unionid'];
            $user['wx_name'] = $postData['nickname'];
            #todo  企业还有一些状态为加上  比如,没有对应的孵化器
            $vld = $this->validate($user, 'User.register');
            if ($vld === true) {
                $msg2 = saveData("user", $user, "企业用户注册");
                if ($msg2["code"] =='0') {
                    throw new \think\Exception("绑定失败,用户信息保存失败 " . $msg2["msg"]);
                }else{
                    //保存成功后,缓存数据,相当于直接登录了
                    //获取logo并缓存
                    session('user', $user);
                    session('userId', $msg2['data']);
                    session('etprsId', $etprsId);
                    session('iqbtId', '0');
                    session("etprsIqbtId",'1');
                }
            } else {
                throw new \think\Exception("用户信息校验失败" . $vld);
            }
        } else {
            throw new \think\Exception("绑定失败,企业信息保存失败" . $msg["msg"]);
        }

        Db::commit();
        return array("code" => 1, "msg" => "注册成功",'data'=>'');
    } catch (\Exception $e) {
        //记录事务
        c_Log($e);
        // 回滚事务
        Db::rollback();
        return array("code" => 0, "msg" =>'注册失败','data'=>'');
    }
}

Complete!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,095评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,654评论 18 139
  • 正在读研的吉米申请了学校的一个助管岗位,主要任务是给常常到外地出差的老师报账和打印文件。这是个不错的选择——一来每...
    阿超双螺旋阅读 551评论 2 0
  • 跌跌撞撞的路上,我们一直都在努力,爱的终点是婚姻,也更应该是幸福。 每当宝贝睡去的时候,我都习惯的等老公回家,时间...
    5号陶子阅读 980评论 2 2
  • 学生A出生在一个贫困的农村家庭,母亲患有精神病,父亲退残走路不便,一家人主要靠捡破烂维持生计。他常常衣衫褴褛,蓬头...
    梨蕊阅读 799评论 0 3