尚医通-手机登录-判断用户登录状态-用户网关整合(三十)

目录:

(1)前台用户系统-手机登录-前端整合

 (2)全局的登录事件-判断登录状态

 (3)登录注册-用户认证和网关整合


(1)前台用户系统-手机登录-前端整合

service-user模块的配置文件前面忘了配置Redis的配置,加上:

点击登录之后,再操作页面的其他部分,会判断当前的登录状态,在前端用一个对象叫做Cookie,登录之后把内容放到Cookie中,判断Cookie中是否有这个信息  

创建访问接口:userInfo.js 

 

import request from '@/utils/request'

const api_name = `/api/user`

export default {
    login(userInfo) {
        return request({
            url: `${api_name}/login`,
            method: `post`,
            data: userInfo
        })
    }
}

 创建发送短信的访问接口msm.js:

import request from '@/utils/request'

const api_name = `/api/msm`

export default {
    sendCode(mobile) {
        return request({
            url: `${api_name}/send/${mobile}`,
            method: `get`
        })
    }
}

 用户的前端主页面访问default.vue,这个页面进行了查分,头、中间内容、尾,登录的部分在头页面里面myheader.vue里面:

在myheader.vue中继续添加弹出框:

<template>
    <div class="header-container">
        <div class="wrapper">
        <!-- logo -->
            <div class="left-wrapper v-link selected">
                <img style="width: 50px" width="50" height="50" src="~assets/images/logo.png">
                <span class="text">尚医通 预约挂号统一平台</span>
            </div>
        <!-- 搜索框 -->
        <div class="search-wrapper">
            <div class="hospital-search animation-show">
                <el-autocomplete
                    class="search-input small"
                    prefix-icon="el-icon-search"
                    v-model="hosname"
                    :fetch-suggestions="querySearchAsync"
                    placeholder="点击输入医院名称"
                    @select="handleSelect"
                    >
                    <span slot="suffix" class="search-btn v-link highlight clickable selected">搜索 </span>
                </el-autocomplete>
            </div>
        </div>
        <!-- 右侧 -->
     <!-- 右侧 -->
		<div class="right-wrapper">
		  <span class="v-link clickable">帮助中心</span>
		  <span v-if="name == ''" class="v-link clickable" @click="showLogin()" id="loginDialog">登录/注册</span>
		  <el-dropdown v-if="name != ''" @command="loginMenu">
		        <span class="el-dropdown-link">
		          {{ name }}<i class="el-icon-arrow-down el-icon--right"></i>
		        </span>
		    <el-dropdown-menu class="user-name-wrapper" slot="dropdown">
		      <el-dropdown-item command="/user">实名认证</el-dropdown-item>
		      <el-dropdown-item command="/order">挂号订单</el-dropdown-item>
		      <el-dropdown-item command="/patient">就诊人管理</el-dropdown-item>
		      <el-dropdown-item command="/logout" divided>退出登录</el-dropdown-item>
		    </el-dropdown-menu>
		  </el-dropdown>
		</div>

        </div>
        
         <!-- 登录弹出层 -->
    <el-dialog :visible.sync="dialogUserFormVisible" style="text-align: left;display: none; " top="50px" :append-to-body="true"  width="960px" @close="closeDialog() ">
      <div class="container">
        <!-- 手机登录 #start -->
        <div class="operate-view" v-if="dialogAtrr.showLoginType === 'phone'">
          <div class="wrapper" style="width: 100%">
            <div class="mobile-wrapper" style="position: static; width: 70%">
              <span class="title">{{ dialogAtrr.labelTips }}</span>
              <el-form>
                <el-form-item>
                  <el-input v-model="dialogAtrr.inputValue" :placeholder="dialogAtrr.placeholder" :maxlength="dialogAtrr.maxlength" class="input v-input">
                    <span slot="suffix" class="sendText v-link" v-if="dialogAtrr.second > 0">{{ dialogAtrr.second }}s </span>
                    <span slot="suffix" class="sendText v-link highlight clickable selected" v-if="dialogAtrr.second == 0" @click="getCodeFun()">重新发送 </span>
                  </el-input>
                </el-form-item>
              </el-form>
              <div class="send-button v-button" @click="btnClick()"> {{ dialogAtrr.loginBtn }}</div>
            </div>
            <div class="bottom">
              <div class="wechat-wrapper" @click="weixinLogin()"><span
                class="iconfont icon"></span></div>
              <span class="third-text"> 第三方账号登录 </span></div>
          </div>
        </div>
        <!-- 手机登录 #end -->

        <!-- 微信登录 #start -->
        <div class="operate-view"  v-if="dialogAtrr.showLoginType === 'weixin'" >
          <div class="wrapper wechat" style="height: 400px">
            <div>
              <div id="weixinLogin"></div>
            </div>
            <div class="bottom wechat" style="margin-top: -80px;">
              <div class="phone-container">
                <div class="phone-wrapper"  @click="phoneLogin()"><span
                  class="iconfont icon"></span></div>
                <span class="third-text"> 手机短信验证码登录 </span></div>
            </div>
          </div>
        </div>
        <!-- 微信登录 #end -->

        <div class="info-wrapper">
          <div class="code-wrapper">
            <div><img src="//img.114yygh.com/static/web/code_login_wechat.png" class="code-img">
              <div class="code-text"><span class="iconfont icon"></span>微信扫一扫关注
              </div>
              <div class="code-text"> “快速预约挂号”</div>
            </div>
            <div class="wechat-code-wrapper"><img
              src="//img.114yygh.com/static/web/code_app.png"
              class="code-img">
              <div class="code-text"> 扫一扫下载</div>
              <div class="code-text"> “预约挂号”APP</div>
            </div>
          </div>
          <div class="slogan">
            <div>xxxxxx官方指定平台</div>
            <div>快速挂号 安全放心</div>
          </div>
        </div>
      </div>
    </el-dialog>
    
    <div></div>  <!--解决登录框样式不对-->

    </div>
</template>

 添加Cookie,而Cookie在java代码中,通过request得到Cookie,而现在是在前端中在Vue中进行操作,要用Cookie需要安装以下Cookie的 插件:

命令行执行:

npm install js-cookie

拷贝js代码:

<script>
import cookie from 'js-cookie'
import Vue from 'vue'

import userInfoApi from '@/api/userInfo'
import smsApi from '@/api/msm'
import hospitalApi from '@/api/hosp'

const defaultDialogAtrr = {
  showLoginType: 'phone', // 控制手机登录与微信登录切换

  labelTips: '手机号码', // 输入框提示

  inputValue: '', // 输入框绑定对象
  placeholder: '请输入您的手机号', // 输入框placeholder
  maxlength: 11, // 输入框长度控制

  loginBtn: '获取验证码', // 登录按钮或获取验证码按钮文本

  sending: true,      // 是否可以发送验证码
  second: -1,        // 倒计时间  second>0 : 显示倒计时 second=0 :重新发送 second=-1 :什么都不显示
  clearSmsTime: null  // 倒计时定时任务引用 关闭登录层清除定时任务
}
export default {
  data() {
    return {
      userInfo: {
        phone: '',
        code: '',
        openid: ''
      },

      dialogUserFormVisible: false,
      // 弹出层相关属性
      dialogAtrr:defaultDialogAtrr,

      name: '' // 用户登录显示的名称
    }
  },

  created() {
    this.showInfo()
  },
  methods: {
    // 绑定登录或获取验证码按钮
    btnClick() {
      // 判断是获取验证码还是登录
      if(this.dialogAtrr.loginBtn == '获取验证码') {
        this.userInfo.phone = this.dialogAtrr.inputValue

        // 获取验证码
        this.getCodeFun()
      } else {
        // 登录
        this.login()
      }
    },

    // 绑定登录,点击显示登录层
    showLogin() {
      this.dialogUserFormVisible = true

      // 初始化登录层相关参数
      this.dialogAtrr = { ...defaultDialogAtrr }
    },

    // 登录
    login() {
      this.userInfo.code = this.dialogAtrr.inputValue

      if(this.dialogAtrr.loginBtn == '正在提交...') {
        this.$message.error('重复提交')
        return;
      }
      if (this.userInfo.code == '') {
        this.$message.error('验证码必须输入')
        return;
      }
      if (this.userInfo.code.length != 6) {
        this.$message.error('验证码格式不正确')
        return;
      }
      this.dialogAtrr.loginBtn = '正在提交...'
      userInfoApi.login(this.userInfo).then(response => {
        console.log(response.data)
        // 登录成功 设置cookie
        this.setCookies(response.data.name, response.data.token)
      }).catch(e => {
        this.dialogAtrr.loginBtn = '马上登录'
      })
    },

    setCookies(name, token) {
      cookie.set('token', token, { domain: 'localhost' })
      cookie.set('name', name, { domain: 'localhost' })
      window.location.reload()
    },

    // 获取验证码
    getCodeFun() {
      if (!(/^1[34578]\d{9}$/.test(this.userInfo.phone))) {
        this.$message.error('手机号码不正确')
        return;
      }

      // 初始化验证码相关属性
      this.dialogAtrr.inputValue = ''
      this.dialogAtrr.placeholder = '请输入验证码'
      this.dialogAtrr.maxlength = 6
      this.dialogAtrr.loginBtn = '马上登录'

      // 控制重复发送
      if (!this.dialogAtrr.sending) return;

      // 发送短信验证码
      this.timeDown();
      this.dialogAtrr.sending = false;
      smsApi.sendCode(this.userInfo.phone).then(response => {
        this.timeDown();
      }).catch(e => {
        this.$message.error('发送失败,重新发送')
        // 发送失败,回到重新获取验证码界面
        this.showLogin()
      })
    },

    // 倒计时
    timeDown() {
      if(this.clearSmsTime) {
        clearInterval(this.clearSmsTime);
      }
      this.dialogAtrr.second = 60;

      this.dialogAtrr.labelTips = '验证码已发送至' + this.userInfo.phone
      this.clearSmsTime = setInterval(() => {
        --this.dialogAtrr.second;
        if (this.dialogAtrr.second < 1) {
          clearInterval(this.clearSmsTime);
          this.dialogAtrr.sending = true;
          this.dialogAtrr.second = 0;
        }
      }, 1000);
    },

    // 关闭登录层
    closeDialog() {
      if(this.clearSmsTime) {
        clearInterval(this.clearSmsTime);
      }
    },

    showInfo() {
      let token = cookie.get('token')
      if (token) {
        this.name = cookie.get('name')
        console.log(this.name)
      }
    },

    loginMenu(command) {
      if('/logout' == command) {
        cookie.set('name', '', {domain: 'localhost'})
        cookie.set('token', '', {domain: 'localhost'})

        //跳转页面
        window.location.href = '/'
      } else {
        window.location.href = command
      }
    },

    handleSelect(item) {
      window.location.href = '/hospital/' + item.hoscode
    },

    weixinLogin() {
      this.dialogAtrr.showLoginType = 'weixin'
    },

    phoneLogin() {
      this.dialogAtrr.showLoginType = 'phone'
      this.showLogin()
    }
  }
}
</script>

7.4.1 获取登录信息

  created() {

    this.showInfo()

  },
    showInfo() {

      let token = cookie.get('token')

      if (token) {

        this.name = cookie.get('name')

      }

    },

7.4.2 登录页面控制

<!-- 右侧 -->

<div class="right-wrapper">

  <span class="v-link clickable">帮助中心</span>

  <span v-if="name == ''" class="v-link clickable" @click="showLogin()" id="loginDialog">登录/注册</span>

  <el-dropdown v-if="name != ''" @command="loginMenu">

        <span class="el-dropdown-link">

          {{ name }}<i class="el-icon-arrow-down el-icon--right"></i>

        </span>

    <el-dropdown-menu class="user-name-wrapper" slot="dropdown">

      <el-dropdown-item command="/user">实名认证</el-dropdown-item>

      <el-dropdown-item command="/order">挂号订单</el-dropdown-item>

      <el-dropdown-item command="/patient">就诊人管理</el-dropdown-item>

      <el-dropdown-item command="/logout" divided>退出登录</el-dropdown-item>

    </el-dropdown-menu>

  </el-dropdown>

</div>

说明:<el-dropdown-item command="/user">实名认证</el-dropdown-item>“command”的值为下拉列表的访问路径,即:实名认证的访问路径,后续会有对应的页面,目前我们将它处理好,方便后续使用
添加下拉列表事件处理:

loginMenu(command) {

  if('/logout' == command) {

    cookie.set('name''', {domain: 'localhost'})

    cookie.set('token''', {domain: 'localhost'})

    //跳转页面

    window.location.href = '/'

  } else {

    window.location.href = command

  }

},

点击登录,就会设置属性为true: 

myheader.vue:

<template>
  <div class="header-container">
    <div class="wrapper">
      <!-- logo -->
      <div class="left-wrapper v-link selected">
        <img
          style="width: 50px"
          width="50"
          height="50"
          src="~assets/images/logo.png"
        />
        <span class="text">尚医通 预约挂号统一平台</span>
      </div>
      <!-- 搜索框 -->
      <div class="search-wrapper">
        <div class="hospital-search animation-show">
          <el-autocomplete
            class="search-input small"
            prefix-icon="el-icon-search"
            v-model="hosname"
            :fetch-suggestions="querySearchAsync"
            placeholder="点击输入医院名称"
            @select="handleSelect"
          >
            <span
              slot="suffix"
              class="search-btn v-link highlight clickable selected"
              >搜索
            </span>
          </el-autocomplete>
        </div>
      </div>
      <!-- 右侧 -->
      <!-- 右侧 -->
      <div class="right-wrapper">
        <span class="v-link clickable">帮助中心</span>
        <span
          v-if="name == ''"
          class="v-link clickable"
          @click="showLogin()"
          id="loginDialog"
          >登录/注册</span
        >
        <el-dropdown v-if="name != ''" @command="loginMenu">
          <span class="el-dropdown-link">
            {{ name }}<i class="el-icon-arrow-down el-icon--right"></i>
          </span>
          <el-dropdown-menu class="user-name-wrapper" slot="dropdown">
            <el-dropdown-item command="/user">实名认证</el-dropdown-item>
            <el-dropdown-item command="/order">挂号订单</el-dropdown-item>
            <el-dropdown-item command="/patient">就诊人管理</el-dropdown-item>
            <el-dropdown-item command="/logout" divided
              >退出登录</el-dropdown-item
            >
          </el-dropdown-menu>
        </el-dropdown>
      </div>
    </div>

    <!-- 登录弹出层 -->
    <el-dialog
      :visible.sync="dialogUserFormVisible"
      style="text-align: left; display: none"
      top="50px"
      :append-to-body="true"
      width="960px"
      @close="closeDialog()"
    >
      <div class="container">
        <!-- 手机登录 #start -->
        <div class="operate-view" v-if="dialogAtrr.showLoginType === 'phone'">
          <div class="wrapper" style="width: 100%">
            <div class="mobile-wrapper" style="position: static; width: 70%">
              <span class="title">{{ dialogAtrr.labelTips }}</span>
              <el-form>
                <el-form-item>
                  <el-input
                    v-model="dialogAtrr.inputValue"
                    :placeholder="dialogAtrr.placeholder"
                    :maxlength="dialogAtrr.maxlength"
                    class="input v-input"
                  >
                    <span
                      slot="suffix"
                      class="sendText v-link"
                      v-if="dialogAtrr.second > 0"
                      >{{ dialogAtrr.second }}s
                    </span>
                    <span
                      slot="suffix"
                      class="sendText v-link highlight clickable selected"
                      v-if="dialogAtrr.second == 0"
                      @click="getCodeFun()"
                      >重新发送
                    </span>
                  </el-input>
                </el-form-item>
              </el-form>
              <div class="send-button v-button" @click="btnClick()">
                {{ dialogAtrr.loginBtn }}
              </div>
            </div>
            <div class="bottom">
              <div class="wechat-wrapper" @click="weixinLogin()">
                <span class="iconfont icon"></span>
              </div>
              <span class="third-text"> 第三方账号登录 </span>
            </div>
          </div>
        </div>
        <!-- 手机登录 #end -->

        <!-- 微信登录 #start -->
        <div class="operate-view" v-if="dialogAtrr.showLoginType === 'weixin'">
          <div class="wrapper wechat" style="height: 400px">
            <div>
              <div id="weixinLogin"></div>
            </div>
            <div class="bottom wechat" style="margin-top: -80px">
              <div class="phone-container">
                <div class="phone-wrapper" @click="phoneLogin()">
                  <span class="iconfont icon"></span>
                </div>
                <span class="third-text"> 手机短信验证码登录 </span>
              </div>
            </div>
          </div>
        </div>
        <!-- 微信登录 #end -->

        <div class="info-wrapper">
          <div class="code-wrapper">
            <div>
              <img
                src="//img.114yygh.com/static/web/code_login_wechat.png"
                class="code-img"
              />
              <div class="code-text">
                <span class="iconfont icon"></span>微信扫一扫关注
              </div>
              <div class="code-text">“快速预约挂号”</div>
            </div>
            <div class="wechat-code-wrapper">
              <img
                src="//img.114yygh.com/static/web/code_app.png"
                class="code-img"
              />
              <div class="code-text">扫一扫下载</div>
              <div class="code-text">“预约挂号”APP</div>
            </div>
          </div>
          <div class="slogan">
            <div>xxxxxx官方指定平台</div>
            <div>快速挂号 安全放心</div>
          </div>
        </div>
      </div>
    </el-dialog>

    <div></div>
    <!--解决登录框样式不对-->
  </div>
</template>
<script>
import cookie from "js-cookie";
import Vue from "vue";

import userInfoApi from "@/api/userInfo";
import smsApi from "@/api/msm";
import hospitalApi from "@/api/hosp";
import weixinApi from "@/api/weixin";

const defaultDialogAtrr = {
  showLoginType: "phone", // 控制手机登录与微信登录切换

  labelTips: "手机号码", // 输入框提示

  inputValue: "", // 输入框绑定对象
  placeholder: "请输入您的手机号", // 输入框placeholder
  maxlength: 11, // 输入框长度控制

  loginBtn: "获取验证码", // 登录按钮或获取验证码按钮文本

  sending: true, // 是否可以发送验证码
  second: -1, // 倒计时间  second>0 : 显示倒计时 second=0 :重新发送 second=-1 :什么都不显示
  clearSmsTime: null, // 倒计时定时任务引用 关闭登录层清除定时任务
};
export default {
  data() {
    return {
      userInfo: {
        phone: "",
        code: "",
        openid: "",
        hosname: "",
      },

      dialogUserFormVisible: false,
      // 弹出层相关属性
      dialogAtrr: defaultDialogAtrr,

      name: "", // 用户登录显示的名称
    };
  },

  created() {
    this.showInfo();
  },
  mounted() {
    //在页面渲染之后执行的方法
    // 注册全局登录事件对象
    window.loginEvent = new Vue();
    // 监听登录事件
    loginEvent.$on("loginDialogEvent", function () {
      document.getElementById("loginDialog").click();
    });
    // 触发事件,显示登录层:loginEvent.$emit('loginDialogEvent')

    //初始化微信js   body下面追加一个文件
    const script = document.createElement("script");
    script.type = "text/javascript";
    script.src =
      "https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js";
    document.body.appendChild(script);

    // 微信登录回调处理
    let self = this;
    window["loginCallback"] = (name, token, openid) => {
      self.loginCallback(name, token, openid);
    };
  },

  methods: {
    //微信回调方法
    loginCallback(name, token, openid) {
      // 打开手机登录层,绑定手机号,改逻辑与手机登录一致
      if (openid != null || openid != "") {
        this.userInfo.openid = openid;
        this.showLogin();
      } else {
        this.setCookies(name, token);
      }
    },

    // 绑定登录或获取验证码按钮
    btnClick() {
      // 判断是获取验证码还是登录
      if (this.dialogAtrr.loginBtn == "获取验证码") {
        this.userInfo.phone = this.dialogAtrr.inputValue;

        // 获取验证码
        this.getCodeFun();
      } else {
        // 登录
        this.login();
      }
    },

    // 绑定登录,点击显示登录层
    showLogin() {
      this.dialogUserFormVisible = true;

      // 初始化登录层相关参数
      this.dialogAtrr = { ...defaultDialogAtrr };
    },

    // 登录
    login() {
      this.userInfo.code = this.dialogAtrr.inputValue;

      if (this.dialogAtrr.loginBtn == "正在提交...") {
        this.$message.error("重复提交");
        return;
      }
      if (this.userInfo.code == "") {
        this.$message.error("验证码必须输入");
        return;
      }
      if (this.userInfo.code.length != 6) {
        this.$message.error("验证码格式不正确");
        return;
      }
      this.dialogAtrr.loginBtn = "正在提交...";
      userInfoApi
        .login(this.userInfo)
        .then((response) => {
          console.log(response.data);
          // 登录成功 设置cookie
          this.setCookies(response.data.name, response.data.token);
        })
        .catch((e) => {
          this.dialogAtrr.loginBtn = "马上登录";
        });
    },

    setCookies(name, token) {
      cookie.set("token", token, { domain: "localhost" });
      cookie.set("name", name, { domain: "localhost" });
      window.location.reload();
    },

    // 获取验证码
    getCodeFun() {
      if (!/^1[34578]\d{9}$/.test(this.userInfo.phone)) {
        this.$message.error("手机号码不正确");
        return;
      }

      // 初始化验证码相关属性
      this.dialogAtrr.inputValue = "";
      this.dialogAtrr.placeholder = "请输入验证码";
      this.dialogAtrr.maxlength = 6;
      this.dialogAtrr.loginBtn = "马上登录";

      // 控制重复发送
      if (!this.dialogAtrr.sending) return;

      // 发送短信验证码
      this.timeDown();
      this.dialogAtrr.sending = false;
      smsApi
        .sendCode(this.userInfo.phone)
        .then((response) => {
          this.timeDown();
        })
        .catch((e) => {
          this.$message.error("发送失败,重新发送");
          // 发送失败,回到重新获取验证码界面
          this.showLogin();
        });
    },

    // 倒计时
    timeDown() {
      if (this.clearSmsTime) {
        clearInterval(this.clearSmsTime);
      }
      this.dialogAtrr.second = 60;

      this.dialogAtrr.labelTips = "验证码已发送至" + this.userInfo.phone;
      this.clearSmsTime = setInterval(() => {
        --this.dialogAtrr.second;
        if (this.dialogAtrr.second < 1) {
          clearInterval(this.clearSmsTime);
          this.dialogAtrr.sending = true;
          this.dialogAtrr.second = 0;
        }
      }, 1000);
    },

    // 关闭登录层
    closeDialog() {
      if (this.clearSmsTime) {
        clearInterval(this.clearSmsTime);
      }
    },

    showInfo() {
      let token = cookie.get("token");
      if (token) {
        this.name = cookie.get("name");
        console.log(this.name);
      }
    },

    loginMenu(command) {
      if ("/logout" == command) {
        cookie.set("name", "", { domain: "localhost" });
        cookie.set("token", "", { domain: "localhost" });

        //跳转页面
        window.location.href = "/";
      } else {
        window.location.href = command;
      }
    },

    handleSelect(item) {
      window.location.href = "/hospital/" + item.hoscode;
    },

    weixinLogin() {
      this.dialogAtrr.showLoginType = "weixin";
      //初始化微信的相关参数
      weixinApi.getLoginParam().then((response) => {
        var obj = new WxLogin({
          self_redirect: true,
          id: "weixinLogin", // 需要显示的容器id
          appid: response.data.appid, // 公众号appid wx*******
          scope: response.data.scope, // 网页默认即可
          redirect_uri: response.data.redirect_Uri, // 授权成功后回调的url
          state: response.data.state, // 可设置为简单的随机数加session用来校验
          style: "black", // 提供"black"、"white"可选。二维码的样式
          href: "", // 外部css文件url,需要https
        });
      });
    },

    phoneLogin() {
      this.dialogAtrr.showLoginType = "phone";
      this.showLogin();
    },
  },
};
</script>

 

 

点击登录:

输入验证码:

 

 

  

登录成功之后:右上角显示登录的手机号:

 多了这么一个下拉框的显示:

 (2)全局的登录事件-判断登录状态

在医院详情页面,点击某个科室,根据Cookie判断用户是否登录,没有登录,弹出登录框进行登录,医院详情页面在pages目录下,而弹框在myheader.vue页面下,是两个不同的页面,通过hoscode.vue页面无法调用myheader.vue的弹框,怎么办呢?可以使用全局事件方案

登录全局事件

目前登录层在myheader组件里面,登录按钮也在同一个组件里面,我们点击登录,调用showLogin()方法即可

目前的问题是,我们在预约挂号页面,选择科室去挂号时我们需要判断当前是否登录,如果登录可以进入下一个页面;如果没有登录需要显示登录层,那么这个问题怎么解决呢,我们不能直接调用头部登录方法,我们目前的组件是包含在nuxt里面的

问题总是能够解决的,其实很简单,我们可以注册一个全局登录事件,当需要登录层是,我们发送一个登录事件,头部监听登录事件,然后我们触发登录按钮的点击事件即可打开登录层,下面我们来试试

 在myheader.vue添加一个全局的登录事件,监听一下当前是否是登录状态,这个事件是一个全局的事件,在别的页面中也可以调用这个事件做操作

注册与监听事件

mounted() {

  // 注册全局登录事件对象

  window.loginEvent = new Vue();

  // 监听登录事件

  loginEvent.$on('loginDialogEvent', function () {

  document.getElementById("loginDialog").click();

  })

  // 触发事件,显示登录层:loginEvent.$emit('loginDialogEvent')

  }

在_hoscode.vue中引入Cookie:

1、引入cookie

import cookie from 'js-cookie'

2、添加方法

schedule(depcode) {

  // 登录判断

  let token = cookie.get('token')

  if (!token) {

    loginEvent.$emit('loginDialogEvent')

    return

  }

  window.location.href = '/hospital/schedule?hoscode=' + this.hospital.hoscode + "&depcode="depcode

},

 当点击科室的时候,触发事件进行判断cookie

 

目前是没有登录的,点击某一个科室:弹出弹框

 (3)登录注册-用户认证和网关整合

有些接口访问,必须是用户登录之后才能进行操作,比如说做预约挂号都是登录之后才能进行,这个登录过程可以在网关中做判断,当你访问接口,当你是登录才让你访问,不登录不让你访问,直接放回登录之后才让你操作,把登录验证放到网关中实现

  • 用户认证与网关整合

思路:

  1. 所有请求都会经过服务网关,服务网关对外暴露服务,在网关进行统一用户认证;
  2. 既然要在网关进行用户认证,网关得知道对哪些url进行认证,所以我们得对ur制定规则
  3. Api接口异步请求的,我们采取url规则匹配,如:/api/**/auth/**,如凡是满足该规则的都必须用户认证

 在service_gateway模块中先加入依赖:

创建类:AuthGlobalFilter 

package com.atguigu.yygh.gateway.filter;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.yygh.common.helper.JwtHelper;
import com.atguigu.yygh.common.result.Result;
import com.atguigu.yygh.common.result.ResultCodeEnum;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * <p>
 * 全局Filter,统一处理会员登录与外部不允许访问的服务
 * </p>
 *
 * @author qy
 * @since 2019-11-21
 */
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();//当前访问的路径
        System.out.println("==="+path);

        //内部服务接口,不允许外部访问
        if(antPathMatcher.match("/**/inner/**", path)) {
            ServerHttpResponse response = exchange.getResponse();
            return out(response, ResultCodeEnum.PERMISSION);
        }

        //api接口,异步请求,校验用户必须登录
        if(antPathMatcher.match("/api/**/auth/**", path)) {
            Long userId = this.getUserId(request);
            if(StringUtils.isEmpty(userId)) {
                ServerHttpResponse response = exchange.getResponse();
                return out(response, ResultCodeEnum.LOGIN_AUTH);//未登录放回未登录状态码208
            }
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }

    /**
     * api接口鉴权失败返回数据
     * @param response
     * @return
     */
    private Mono<Void> out(ServerHttpResponse response, ResultCodeEnum resultCodeEnum) {
        Result result = Result.build(null, resultCodeEnum);
        byte[] bits = JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bits);
        //指定编码,否则在浏览器中会中文乱码
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }

    /**
     * 获取当前登录用户id
     * @param request
     * @return
     */
    private Long getUserId(ServerHttpRequest request) {
        String token = "";
        List<String> tokenList = request.getHeaders().get("token");
        if(null  != tokenList) {
            token = tokenList.get(0);
        }
        if(!StringUtils.isEmpty(token)) {
            return JwtHelper.getUserId(token);
        }
        return null;
    }
}

修改前端:在request.js中添加代码:

import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import cookie from 'js-cookie'

// 创建axios实例
const service = axios.create({
    baseURL: 'http://localhost:83',
    timeout: 15000 // 请求超时时间
})
// http request 拦截器
service.interceptors.request.use(
    config => {
        // token 先不处理,后续使用时在完善
        //判断cookie是否有token值
        if (cookie.get('token')) {
            //token值放到cookie里面
            config.headers['token'] = cookie.get('token')
        }
        return config
    },
    err => {
        return Promise.reject(err)
    })
// http response 拦截器
service.interceptors.response.use(
    response => {
        //状态码是208
        if (response.data.code === 208) {
            //弹出登录输入框
            loginEvent.$emit('loginDialogEvent')
            return
        } else {
            if (response.data.code !== 200) {
                Message({
                    message: response.data.message,
                    type: 'error',
                    duration: 5 * 1000
                })
                return Promise.reject(response.data)
            } else {
                return response.data
            }
        }
    },
    error => {
        return Promise.reject(error.response)
    })
export default service

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喵俺第一专栏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值