thinkadmin实现微信服务号登录注册,包括省市县三级联动

本文介绍如何使用thinkadmin框架结合微信服务号实现用户登录注册功能,包括省市县三级联动。文章提供相关控制器代码如getUserMassage,以及注册界面enroll.html的示例。个人中心界面index.html尚在开发中,当前仅用于测试。作者建议读者熟悉thinkadmin框架并参考其官方文档进行配置和开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PS:本篇文章使用了thinkadmin框架,thinkadmin框架是建立在thinkphp的基础上的,更多thinkadmin的详情请自行前往搜索了解;
注:本篇文章中所要的数据库,以及注册界面图片等,在后续我会上传资源,大家自行下载了结即可;

控制器: getUserMassage
代码如下:

<?php

namespace app\Permissions\controller;

use app\wechat\service\WechatService;
use think\admin\Controller;
use think\facade\Db;
use think\facade\Request;

/**
 * curl访问
 */
class getUserMassage extends Controller
{
    public function curlRequest($url)
    {
        $action = curl_init();
        curl_setopt($action, CURLOPT_URL, $url);
        curl_setopt($action, CURLOPT_HEADER, 0);
        curl_setopt($action, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($action, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($action, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($action, CURLOPT_CONNECTTIMEOUT, 60);
        $result = curl_exec($action);
        curl_close($action);
        return $result;
    }

    /**
     * 用于获取用户登录的最基本数据
     * @return void
     * @throws \think\admin\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getUserOpenid()
    {
        $getConfig = WechatService::getConfig();  //获取到微信公众号的相关配置
        $appid = $getConfig['appid'];  //从获取到的数组中获取到微信服务号的appid与secret
        $secret = $getConfig['appsecret'];
        $code = Request::get('code'); //接收到用户授权登录发送过来的code

        //使用curl访问微信提供的url地址,包括appid与secret与code三个参数
        $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $appid . '&secret=' . $secret . '&code=' . $code . '&grant_type=authorization_code';
        $resultData = $this->curlRequest($url);  //此处微信返回的数据中心包括openid与access_token与refresh_token与刷新时间等,详情请看微信开放文档公众号授权的详细描述
        $arrayData = json_decode($resultData, true); //将返回的数据由json转换为数组
        $openid = $arrayData['openid'];  //从数组中获取到openid

        $userData = Db::table('user_basic_information')->where('openid', '=', $openid)->find(); //根据用户的openid在数据库用户数据表查询用户的相关数据
        if ($userData == null) {  //如果在数据库中没有检索到用户的数据,则进行用户注册
            $access_token = $arrayData['access_token'];  //从上方获取的数组中获取到access_token,此处的token是专用于获取用户数据的token与普通调用接口的token不同
            $getUserDataUrl = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $access_token . '&openid=' . $openid . '&lang=zh_CN';  //根据上方的access_token与openid访问微信提供的url拉取用户数据
            $getResult = $this->curlRequest($getUserDataUrl); //此处使用curl进行访问
            $arrayResult = json_decode($getResult, true);  //将返回的json数据转化为数组
            $nickName = $arrayResult['nickname'];  //从返回的数据中获取到用户昵称
            $headimg = $arrayResult['headimgurl'];  //从返回的数据中获取到用户的头像url
            $inDBdata = array(  //将用户的昵称,头像以及openid还有自定义注册状态组合成一个数组
                'nickName' => $nickName,
                'headimg' => $headimg,
                'openid' => $openid,
                'status' => '0'
            );
            Db::table('user_basic_information')->save($inDBdata); //将获取到的数据存入数据库的用户信息表
            $getUserId = Db::table('user_basic_information')->where('openid', '=', $openid)->column('id');  //根据用户的openid获取到数据库中用户信息表的主键
            $userId = $getUserId['0'];  //获取到用户在用户信息表的主键id
            $this->fetch('enroll', ['id' => $userId]); //将id渲染至视图,并打开注册界面
        } else {
            $status = $userData['status'];  //如果在数据库中用户的数据存在则获取用户的注册状态status
            if ($status == 0) {  //当用户的注册状态为0时,意味着用户已经授权相关信息但是还未进行注册
                $getUserId = Db::table('user_basic_information')->where('openid', '=', $openid)->column('id'); //从用户数据表中根据用户的openid获取到用户在数据表中的主键
                $userId = $getUserId['0']; //获取到用户在信息表中的主键
                $this->fetch('enroll', ['id' => $userId]); //打开注册界面并且将用户id渲染到视图
            }else if($status == 1){  //当用户注册状态为1时,意味着用户已经授权相关信息并且已经进行注册,同时将用户的id渲染至个人中心界面
                $getUserId = Db::table('user_postage_information')->where('openid','=',$openid)->column('id');
                $userId = $getUserId['0'];
                $this -> fetch('index',['id'=>$userId]);  //直接打开用户中心,不再需要注册
            }
        }
    }

    /**
     * 获取数据库中省份的相关数据
     * @return string
     */
    public function getProvinceData(): string
    {
        $province = Db::table('base_postage_region')->where('level', '=', '1')->column('name,id'); //根据省份的等级在数据库中筛选出所有的省份与直辖市
        $resultData = ''; //遍历数组,生成xml数据
        foreach ($province as $val) {
            $resultData .= '<option value="' . $val['id'] . '">' . $val['name'] . '</option>';
        }
        return $resultData;  //返回给界面ajax
    }

    /**
     * 根据pid获取到城市或者县/区相关数据
     * @return string
     */
    public function getAreaData(): string
    {
        $getId = file_get_contents('php://input');  //获取到用户选择的地区的id
        $getData = Db::table('base_postage_region')->where('pid', '=', $getId)->column('name,id'); //根据id在数据库中查询他的下级的名称与id
        $result = ''; //遍历数组生成xml格式数据
        foreach ($getData as $val) {
            $result .= '<option value="' . $val['id'] . '">' . $val['name'] . '</option>';
        }
        return $result;  //返回数据给ajax
    }

    /**
     * 接收用户在注册界面传来的相关数据,将相关数据存入数据库中,并更改用户注册状态
     * @return void
     */
    public function getUserMassage()
    {
        $getUserData = file_get_contents('php://input');  //接收注册界面发送过来的用户填写的相关信息
        $userArrayData = json_decode($getUserData,true);  //将数据由json转化为数组格式
        $province_id = $userArrayData['province_id']; //获取到省市县的id
        $city_id = $userArrayData['city_id'];
        $county_id = $userArrayData['county_id'];

        $province = Db::table('base_postage_region')->where('id','=',$province_id)->value('name'); //在数据库中根据id获取到省市县的名称
        $city = Db::table('base_postage_region')->where('id','=',$city_id)->value('name');
        $county = Db::table('base_postage_region')->where('id','=',$county_id)->value('name');

        unset($userArrayData['province_id']); //将原数组中的省市县id数据删除
        unset($userArrayData['city_id']);
        unset($userArrayData['county_id']);

        $areaData = array(  //将获取到的省市县数据组合成新的数组
            'province' => $province,
            'city' => $city,
            'county' => $county
        );
        $userMassageData = array_merge($areaData,$userArrayData); //将新的数组与删除过数据之后的数组进行合并

        Db::table('user_basic_information')->save($userMassageData);  //将数据保存至数据库中,因为数组中包含有插入数据表的主键,因此此处不是插入数据而是更新数据
    }
}

注册界面

注册界面 : enroll.html
代码如下:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>注册界面</title>
</head>
<style>
    * {
        margin: 0;
        padding: 0;
    }

    html {
        width: 100%;
        height: 100%;
        background: url(/static/login/img/enrollBackground.png) no-repeat;
        background-size: 100% 100%;
        -moz-background-size: 100% 100%;
    }

    body {
        width: 100%;
        height: 100%;
        /*border: 1px solid red;*/
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
    }

    .shadowDiv {
        /*border: 1px solid yellow;*/
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        width: 80%;
        height: 50%;
        background-color: rgba(75, 81, 95, 0.3);
        box-shadow: 7px 7px 17px rgba(52, 56, 66, 0.5);
        border-radius: 5px;
    }

    .allIn {
        /*width: 30%;*/
        /*height: 70%;*/
        /*border: 1px solid black;*/
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
    }

    .group {
        display: flex;
        flex-direction: row;
        margin-top: 20px;
    }

    .inputArea {
        width: 100%;
        height: 120%;
        border: none;
        background-color: transparent;
        border-bottom: 1px solid black;
    }

    .selectArea {
        width: 65px;
    }

    .sub {
        display: flex;
        flex-direction: row;
        justify-content: center;
        margin-top: 20px;
    }

    .btn {
        background-color: rgba(100, 149, 237, .7);
        color: aliceblue;
        border-style: hidden;
        width: 100px;
        height: 31px;
        font-size: 16px;
        text-align: center;
        cursor: pointer;
        outline: none;
        border-radius: 5px;
        box-shadow: 7px 6px 28px 1px rgba(0, 0, 0, 0.24);
    }
    .btn:active{
        transform: scale(0.98);
        box-shadow: 3px 2px 22px 1px rgba(0, 0, 0, 0.24);
    }
</style>
<body>
<div class="shadowDiv">
    <div class="allIn">
        <div class="titleName">
            <p>用户注册</p>
        </div>
        <div class="inputDiv">
            <form class="inputForm" id="getMassage">
                <div class="group">
                    <div>
                        <p>用户姓名:</p>
                    </div>
                    <div>
                        <input class="inputArea" id="userName" placeholder="用户姓名" required="required">
                    </div>
                </div>
                <div class="group">
                    <div>
                        <p>联系电话:</p>
                    </div>
                    <div>
                        <input class="inputArea" id="phoneNumber" placeholder="电话号码" required="required">
                    </div>
                </div>
                <div class="group">
                    <div>
                        <p>性别:</p>
                    </div>
                    <div>
                        <input id="man" type="radio" checked="checked" name="sex" value="1"><input type="radio" id="woman" name="sex" value="0"></div>
                </div>
                <div class="group">
                    <div>
                        <p>地址:</p>
                    </div>
                    <div>
                        <select class="selectArea" id="province" onchange="getCityData()" form="getMassage">
                            <option></option>
                        </select>
                        <select class="selectArea" id="city" onchange="getCountyData()" form="getMassage">
                            <option></option>
                        </select>
                        <select class="selectArea" id="county" form="getMassage">
                            <option></option>
                        </select>
                    </div>
                </div>
                <div class="group">
                    <div>
                        <p>详细地址</p>
                    </div>
                    <div>
                        <input class="inputArea" id="address" placeholder="详细地址" required="required">
                    </div>
                </div>
                <div class="sub">
                    <button type="button" class="btn" id="btn" onclick="sub()">注册</button>
                </div>
            </form>
        </div>
    </div>
</div>
</body>
<script>
    var request = new XMLHttpRequest();
    request.open('post', 'getProvinceData', true);
    request.setRequestHeader("content-type", "application/x-www-form-urlencoded");
    request.send();
    request.onreadystatechange = function () {
        if (request.readyState == 4 && request.status == 200) {
            var insertData = document.getElementById('province');
            insertData.innerHTML = request.responseText;
        }
    }

    function getCityData() {
        var province_id = document.getElementById('province').value;
        var RequestData = new XMLHttpRequest();
        RequestData.open('post', 'getAreaData', true);
        RequestData.setRequestHeader("content-type", "application/x-www-form-urlencoded");
        RequestData.send(province_id);
        RequestData.onreadystatechange = function () {
            if (RequestData.readyState == 4 && RequestData.status == 200) {
                var insert = document.getElementById("city");
                insert.innerHTML = RequestData.responseText;
            }
        }
    }

    function getCountyData() {
        var city_id = document.getElementById('city').value;
        var RequestData = new XMLHttpRequest();
        RequestData.open('post', 'getAreaData', true);
        RequestData.setRequestHeader("content-type", "application/x-www-form-urlencoded");
        RequestData.send(city_id);
        RequestData.onreadystatechange = function () {
            if (RequestData.readyState == 4 && RequestData.status == 200) {
                var insert = document.getElementById("county");
                insert.innerHTML = RequestData.responseText;
            }
        }
    }

    function sub() {
        var userName = document.getElementById('userName').value;
        var phoneNumber = document.getElementById('phoneNumber').value;
        var obj = document.getElementsByName('sex');
        for (var i = 0; i < obj.length; i++) {
            if (obj[i].checked) {
                var sex = obj[i].value;
            }
        }
        var province_id = document.getElementById('province').value;
        var city_id = document.getElementById('city').value;
        var county_id = document.getElementById('county').value;
        var address = document.getElementById('address').value;

        var massageData = {
            "id": {$id},
            "userName": userName,
            "phoneNumber": phoneNumber,
            "sex": sex,
            "province_id": province_id,
            "city_id": city_id,
            "county_id": county_id,
            "address": address,
            "status": 1
        };
        var disposeData = JSON.stringify(massageData);
        var sendData = new XMLHttpRequest();
        sendData.open('post', 'getUserMassage', true);
        sendData.setRequestHeader("content-type", "application/x-www-form-urlencoded");
        sendData.send(disposeData);


    }
</script>
</html>

个人中心界面 : index.html
代码如下: (注:个人中心界面正在开发中,后续会放出完成版),现阶段仅仅只是用于测试,用户自定义注册状态判断后的跳转

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>个人中心</title>
</head>
<body>
<p>注册完毕后跳转至该界面或者已经注册过的用户直接跳转至该界面</p>
</body>
</html>

写在最后:应为此次的代码和以往小程序的不同,这些代码需要各位对框架进行相关配置之后才能够使用,对于框架的面熟此处就不再赘述,有需要的请自行前往搜索thinkadmin框架,里面有详细的使用说明,在完成框架的安装之后,再根据thinkphp的开发文档与thinkadmin的开发文档来开发就行了.


本文由CSDN用户: 缱绻淡蓝海 原创,代码具有时效性,作者会不定时进行更新

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值