admin 发表于 2025-1-4 18:27:10

fastadmin+uniapp实现公众号登录

代码:


   
    /**
   * 公众号登录
   */
    public function mplogin()
    {
      // 参数
      $params = $this->request->param();
      // 公众号CODE
      if (!empty($params['code'])) {
            // 系统配置
            $config = Config::get('nianbao');
            // 未开启登录
            if ($config['login_type'] == 0) {
                $this->error('系统未开启登录');
            }
            // 用户已登录
            if ($this->auth->isLogin()) {
                $this->error('用户已登录', null, 300);
            }
            \think\Log::record('未登录执行1');
            // 支付配置
            $epay = get_addon_config('epay');
            $appid = $epay['wechat']['app_id'];
            $secret = $epay['wechat']['app_secret'];
            $code = $params['code'];
            $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$appid}&secret={$secret}&code={$code}&grant_type=authorization_code";
            $response = Http::post($url);
            \think\Log::record($response);
            $data = json_decode($response, true);
            if (isset($data['errcode'])) {
                $this->error('错误码:'.$data['errcode'].',错误信息:'.$data['errmsg']);
            }
            // 公众号注册登录
            $third = null;
            //存在openid则先判断是否存在对应账号
            if ($data['openid']) {
                $third = Third::get(['platform' => 'wechat', 'openid' => $data['openid']], 'user');
            }
            if ($third) {
                \think\Log::record('已存在第三方粉丝数据');
                if (!$third->user) {
                  \think\Log::record('第三方粉丝数据未绑定用户ID');
                  $third->delete();
                  $third = null;
                } else {
                  //如果已存在第三方账号且已绑定用户ID则直接登录
                  \think\Log::record('已存在第三方粉丝数据且已绑定');
                  $direct = $this->auth->direct($third->user_id);
                  if ($direct) {
                        \think\Log::record('已存在第三方粉丝数据且已绑定并登录成功');
                        $userinfo = $this->auth->getUserinfo();
                        $userinfo['openid'] = $data['openid'];
                        $third->save(['logintime' => time()]);
                        // 处理头像
                        $userinfo['avatarUrl'] = cdnurl($userinfo['avatar'], true);
                        // 返回值
                        $return = [
                            'openid' => $data['openid'],
                            'userinfo' => $userinfo
                        ];
                        $this->success('登录成功', $return);
                  } else {
                        \think\Log::record('已存在第三方粉丝数据且已绑定并登录失败');
                        $this->error('授权登录失败,请重试!');
                  }
                }
            }
            // 当前时间戳
            $time = time();
            // 默认昵称
            $nickname = '微信用户';
            // 第三方粉丝表单
            $values = [
                'platform'      => 'wechat',
                'apptype'       => 'mp',
                'openid'      => $data['openid'],
                'openname'      => $nickname,
                'access_token'=> $data['access_token'] ?? '',
                'refresh_token' => $data['refresh_token'] ?? '',
                'expires_in'    => $data['expires_in'],
                'logintime'   => $time,
                'expiretime'    => $time + $data['expires_in'],
            ];
            // 如果用户已登录则第三方粉丝表直接绑定该用户
            if ($this->auth->id) {
                \think\Log::record('已存在第三方粉丝数据且已绑定并登录成功');
                $values['user_id'] = $this->auth->id;
                Third::create($values, true);
                $userinfo = $this->auth->getUserinfo();
                $userinfo['openid'] = $data['openid'];
                // 处理头像
                $userinfo['avatarUrl'] = cdnurl($userinfo['avatar'], true);
                // 返回值
                $return = [
                  'openid' => $data['openid'],
                  'userinfo' => $userinfo
                ];
                $this->success('登录成功', $return);
            }
            // 用户未登录也未创建第三方粉丝账号执行以下代码
            // 先随机一个用户名,随后再变更为u+数字id
            $username = Random::alnum(20);
            $email = $data['openid'] . '@wechat.com';
            Db::startTrans();
            $result = false;
            try {
                // 注册会员账号
                $extend = [
                  'group_id' => 1,
                  'avatar' => $config['avatar']
                ];
                $register = $this->auth->register($username, Random::alnum(6), $email, '', $extend);
                if (!$register) {
                  throw new Exception($this->auth->getError());
                }
                // 注册后获取会员信息
                $user = $this->auth->getUser();
                // 重置用户名
                $username = $time . 'u' . $user->id;
                $fields = [];
   
                //判断用户名和邮箱是否已存在
                $existusername = UserModel::getByUsername($username);
                if (!$existusername) {
                  $fields['username'] = $username;
                }
                $existemail = UserModel::getByEmail($email);
                if (!$existemail) {
                  $fields['email'] = $email;
                }
   
                //如果昵称为空或为微信用户则修改
                if (!$user['nickname'] || $user['nickname'] == '微信用户') {
                  $fields['nickname'] = $nickname = $fields['username'];
                }
   
                if ($nickname) {
                  $fields['nickname'] = xss_clean(strip_tags($nickname));
                }
   
                // 更新会员资料
                $user = UserModel::get($user->id);
                $user->save($fields);
                if (!$third) {
                  // 保存第三方信息
                  $values['user_id'] = $this->auth->id;
                  Third::create($values, true);
                }
                $result = true;
                Db::commit();
            } catch (\Exception $e) {
                Db::rollback();
                \think\Log::record($e->getMessage());
                $this->auth->logout();
                $result = false;
            }
            if ($result === false) {
                $this->error('公众号登录失败');
            }
            $userinfo = $this->auth->getUserinfo();
            $userinfo['openid'] = $data['openid'];
            // 处理头像
            $userinfo['avatarUrl'] = cdnurl($userinfo['avatar'], true);
            // 返回值
            $return = [
                'openid' => $data['openid'],
                'userinfo' => $userinfo
            ];
            $this->success('登录成功', $return);
      }
      $this->error('code参数不正确');
    }
uniapp端:
<template>
        <view class="container">
                <view class="nui-userbox">
                        <view class="nui-user-left">
                                <image :src="userinfo.avatarUrl" class="nui-avatar" mode="widthFix"></image>
                        </view>
                        <view class="nui-user-right">
                                <view class="nui-nickname">
                                        {{userinfo.nickname}}
                                </view>
                        </view>
                </view>
                <tui-footer :fixed="false" :copyright="copyright"></tui-footer>
                <!-- 登录弹窗 -->
                <tui-modal :show="loginbox" :maskClosable="false" @cancel="hideLogin" :custom="true">
                        <view class="tui-modal-custom">
                                <view class="tui-prompt-title">提示</view>
                                <view class="tui-modal-custom-text">您尚未登录,请先登录</view>
                                <view class="tui-btn-box">
                                        <view class="nui-btn">
                                                <tui-button height="72rpx" :size="28" type="gray" shape="circle" @click="notLogin">暂不登录</tui-button>
                                        </view>
                                        <view class="nui-btn">
                                                <!-- #ifdef H5 -->
                                                <tui-button height="72rpx" :size="28" type="warning" shape="circle" @click="hfivelogin">去登录</tui-button>
                                                <!-- #endif -->
                                                <!-- #ifdef MP-WEIXIN -->
                                                <tui-button height="72rpx" :size="28" type="green" shape="circle" @click="authlogin">授权登录</tui-button>
                                                <!-- #endif -->
                                        </view>
                                </view>
                        </view>
                </tui-modal>
                <!-- 授权获取手机号 -->
                <tui-modal :show="mobileloginbox" :maskClosable="false" @cancel="hideMobileLogin" :custom="true">
                        <view class="tui-modal-custom">
                                <view class="tui-prompt-title">授权获取您的手机号</view>
                                <view class="tui-modal-custom-text">只差最后一步,绑定手机即可登录哦</view>
                                <view class="tui-btn-box">
                                        <view class="nui-btn">
                                                <tui-button height="72rpx" :size="28" type="gray" shape="circle" @click="notLogin">拒绝授权</tui-button>
                                        </view>
                                        <view class="nui-btn">
                                                <!-- #ifdef MP-WEIXIN -->
                                                <tui-button height="72rpx" :size="28" type="green" shape="circle" openType="getPhoneNumber" @getphonenumber="bindgetphonenumber">授权手机号</tui-button>
                                                <!-- #endif -->
                                        </view>
                                </view>
                        </view>
                </tui-modal>
        </view>
</template>

<script>
        const app = getApp();
        export default {
                data() {
                        return {
                                userinfo: {
                                        avatarUrl: '/static/mine_def_touxiang_3x.png',
                                        nickname: '请先登录'
                                },
                                appid: '',//公众号appid
                                scope: 'snsapi_base',
                                openid: '',
                                loginbox: false,//登录弹框
                                mobileloginbox: false,//授权手机号弹框
                                copyright: '©2024 企业登记',
                        }
                },
                onLoad() {
                        uni.setNavigationBarColor({
                                backgroundColor: app.globalData.topbgcolor,
                                frontColor: app.globalData.toptcolor
                        })
                        let that = this;
                        that.tui.request('user/index').then((res) => {
                                console.log(res)
                                if (res.code == 1) {
                                        that.appid = res.data.appid,//公众号appid
                                        that.copyright = res.data.copyright;
                                        if (res.data.userinfo) {
                                                that.userinfo = res.data.userinfo;
                                                that.openid = res.data.openid;
                                                uni.setStorageSync('userinfo', res.data.userinfo);
                                                uni.setStorageSync('openid', res.data.openid);
                                        }
                                        // #ifdef H5
                                        if (!res.data.login) {
                                                if (that.isWeiXin()) {
                                                        console.log('在微信内')
                                                        let code = that.getUrlCode('code');
                                                        if (code) {
                                                                console.log(code)
                                                                // Url有code参数
                                                                that.checkWeChatCode(code);
                                                        } else {
                                                                // Url没有code参数,需要发起公众号授权
                                                                that.getWeChatCode();
                                                        }
                                                } else {
                                                        that.loginbox = true;
                                                }
                                        }
                                        // #endif
                                }
                        })
                },
                onShow() {
                        let that = this;
                        var userinfo = uni.getStorageSync('userinfo');
                        if (!that.isWeiXin()) {
                                if (!userinfo) {
                                        that.loginbox = true;
                                } else {
                                        that.tui.request('user/checklogin').then((res) => {
                                                console.log(res);
                                                if (res.code == 1) {
                                                        that.hideLogin();
                                                        that.userinfo = res.data.userinfo;
                                                        that.openid = res.data.openid;
                                                        uni.setStorageSync('userinfo', res.data.userinfo);
                                                        uni.setStorageSync('openid', res.data.openid);
                                                } else if (res.code == 200) {
                                                        uni.removeStorageSync('userinfo');
                                                        that.loginbox = true;
                                                } else {
                                                        uni.showModal({
                                                                title: '提示',
                                                                content: res.msg,
                                                                showCancel: false,
                                                                success() {
                                                                        uni.reLaunch({
                                                                                url: '/pages/index/index'
                                                                        })
                                                                }
                                                        })
                                                }
                                        })
                                }
                        }
                },
                methods: {
                        // 关闭登录框
                        hideLogin() {
                                this.loginbox = false;
                        },
                        // 关闭授权手机号弹框
                        hideMobileLogin() {
                                this.mobileloginbox = false;
                        },
                        // 暂不登录
                        notLogin() {
                                this.hideLogin();
                                uni.navigateBack();
                        },
                        // H5登录
                        hfivelogin() {
                                this.hideLogin();
                                uni.navigateTo({
                                        url: '/pages/user/login'
                                })
                        },
                        // 小程序授权登录
                        authlogin() {
                                // #ifdef MP-WEIXIN
                                uni.login({
                                        onlyAuthorize: true,
                                        success(t) {
                                                console.log(t)
                                                that.tui.request('user/authlogin', {
                                                        code: t.code
                                                }).then((res) => {
                                                        console.log(res)
                                                        if (res.code == 1) {
                                                                that.userinfo = res.data.userinfo;
                                                                uni.setStorageSync('userinfo', res.data.userinfo);
                                                                uni.setStorageSync('openid', res.data.openid);
                                                                uni.showToast({
                                                                        title: res.msg,
                                                                        icon: 'none'
                                                                })
                                                        } else if (res.code == 2) {
                                                                // 获取openid成功
                                                                that.openid = res.data.openid;
                                                                that.loginbox = true;
                                                        } else {
                                                                uni.showModal({
                                                                        title: '提示',
                                                                        content: res.msg,
                                                                        success() {
                                                                                uni.reLaunch({
                                                                                        url: '/pages/index/index'
                                                                                })
                                                                        }
                                                                })
                                                        }
                                                })
                                        },
                                        fail(t) {
                                                console.log(t)
                                                uni.showModal({
                                                        title: '提示',
                                                        content: '授权失败,请稍后重试!',
                                                        success() {
                                                                uni.reLaunch({
                                                                        url: '/pages/index/index'
                                                                })
                                                        }
                                                })
                                        }
                                })
                                // #endif
                        },
                        // 微信授权登录
                        bindgetphonenumber(e) {
                                console.log(e)
                                this.hideLogin();
                                var that = this;
                                if (e.errMsg == 'getPhoneNumber:fail user deny') {
                                        uni.showModal({
                                                title: '提示',
                                                content: '无法获取你的手机号',
                                                showCancel: false,
                                                success() {
                                                        that.loginbox = true;
                                                }
                                        })
                                        return;
                                }
                                // 推广商户
                                var hotel_id = uni.getStorageSync('hotel_id') || 0;
                                // 注册登录
                                that.tui.request('user/mobilelogin', {
                                        code: e.code,
                                        openid: that.openid,
                                        hotel_id: hotel_id
                                }).then((res) => {
                                        // console.log(res)
                                        if (res.code == 1) {
                                                // uni.removeStorageSync('hotel_id');
                                                that.userinfo = res.data.userinfo;
                                                uni.setStorageSync('userinfo', res.data.userinfo);
                                        }
                                        uni.showToast({
                                                title: res.msg,
                                                icon: 'none'
                                        })
                                })
                        },
                        // 判断是否微信内访问
                        isWeiXin() {
                                let ua = window.navigator.userAgent.toLowerCase();
                                // console.log(ua)
                                if (ua.match(/MicroMessenger/i) == 'micromessenger') {
                                        return true;
                                } else {
                                        return false;
                                }
                        },
                        // 获取公众号授权登录回调结果code
                        getUrlCode(name) {
                                return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, '']).replace(/\+/g, '%20')) || null
                        },
                        // 发起公众号授权获取code
                        getWeChatCode() {
                                // console.log(this.appid)
                                let appid = this.appid;
                                let local = encodeURIComponent(window.location.href);
                                let scope = this.scope;
                                window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${local}&response_type=code&scope=${scope}&state=1#wechat_redirect`;
                        },
                        // 将code发送服务端获取用户openid
                        checkWeChatCode(code) {
                                var that = this;
                                if (code) {
                                        // 这里需要有一个逻辑判断公众号授权用户未注册自动注册并登录,已注册就登录
                                        that.tui.request('user/mplogin', {
                                                code: code
                                        }).then((res) => {
                                                console.log(res)
                                                if (res.code == 1) {
                                                        that.openid = res.data.openid;
                                                        that.userinfo = res.data.userinfo;
                                                        uni.setStorageSync('userinfo', res.data.userinfo);
                                                        uni.setStorageSync('openid', res.data.openid);
                                                } else {
                                                        uni.showModal({
                                                                title: '提示',
                                                                content: res.msg,
                                                                showCancel: false,
                                                                success() {
                                                                        uni.reLaunch({
                                                                                url: '/pages/index/index'
                                                                        })
                                                                }
                                                        })
                                                }
                                        })
                                }
                        }
                }
        }
</script>

<style>
        page {
                background-color: #f5f5f5;
        }
       
        .nui-userbox {
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 30rpx;
                box-sizing: border-box;
                background-color: #ffffff;
        }
        .nui-user-left {
                width: 25%;
        }
        .nui-avatar {
                width: 90%;
                height: auto;
                display: block;
                border-radius: 50%;
        }
        .nui-user-right {
                width: 75%;
        }
        /* 登录框 */
        .tui-modal-custom {
                text-align: center;
        }
       
        .tui-modal-custom-text {
                font-size: 30rpx;
                color: #333;
                padding: 30rpx 0 50rpx;
        }
       
        .tui-prompt-title {
                padding-bottom: 20rpx;
                font-size: 34rpx;
        }
        .tui-btn-box {
                display: flex;
                justify-content: space-between;
                align-items: center;
        }
        .nui-btn {
                width: 45%;
        }
</style>

admin 发表于 2025-1-6 10:55:41

/**
   * 检查登录
   */
    public function checklogin()
    {
      // 系统配置
      $config = Config::get('nianbao');
      // 请求参数
      $params = $this->request->param();
      // 开启登录
      if ($config['login_type'] == 1) {
            if (!$this->auth->isLogin()) {
                $this->error('您尚未登录或登录已失效', null, 200);
            } else {
                $userinfo = $this->auth->getUserinfo();
                // 头像
                $userinfo['avatarUrl'] = cdnurl($userinfo['avatar'], true);
                // 第三方会员
                $third = Third::where(['user_id'=>$this->auth->id, 'platform'=>$params['platform'], 'apptype'=>$params['apptype']])->find();
                $openid = '';
                if (!empty($third)) {
                  $openid = $third->openid;
                }
                $this->success('用户已登录', ['userinfo'=>$userinfo, 'openid'=>$openid]);
            }
      }
      $this->error('系统未开启登录');
    }

页: [1]
查看完整版本: fastadmin+uniapp实现公众号登录