08335 / hivui-platform-template
hivui平台项目模板
Newer
Older
hivui-platform-template / project / hivuiLogin / views / index.vue
<template>
  <div class="bg">
    <div class="login_hd">
      <div class="login_hd_logo" :style="logoStyle">
        <!-- <div class="login_hd_logo_tip">登录</div>-->
      </div>
    </div>
    <div class="login_bd">
      <div class="login_bd_bg" :style="bgStyle"></div>
      <div :class="'login_form' + ((captchaObj&&captchaObj.captchaId)?' showCaptcha':'')">
        <!-- 用户名密码窗口 -->
        <div id="showQr" class="loginMainBox" :hidden="currLoginType != 'com'">
          <img
            @click="changeQr"
            class="icon-qrcode"
            :src="scanIcon"
            :hidden="!config.isScan"
          />
          <div class="login-tip" :hidden="!config.isScan">
            <div class="poptip">
              <div class="poptip-arrow">
                <em></em>
                <span></span>
              </div>
              <div class="poptip-content">{{$t('hivuiLogin_main_scan_login')}}</div>
            </div>
          </div>
          <div class="login_form_bd">
            <div class="error_tips"></div>
            <input type="hidden" name="directAction" value="" />
            <input type="hidden" name="refererurl" value="" />
            <div class="login_field">
              <label>{{$t('hivuiLogin_main_user')}}</label>
              <input
                class="login_field_text"
                v-model="username"
                type="text"
                id="txtUserName"
                name="userName"
                :placeholder="$t('hivuiLogin_main_user_ph')"
                autofocus
                required
                autocomplete="off"
                @keyup.enter="loginFunc"
              />
              <i class="fa fa-user"></i>
            </div>
            <div class="login_field">
              <label>{{$t('hivuiLogin_main_pw')}}</label>
              <input
                class="login_field_text"
                v-model="password"
                type="text"
                onfocus="this.type='password'"
                id="txtPassword"
                name="password"
                :placeholder="$t('hivuiLogin_main_pw_ph')"
                required
                autocomplete="off"
                @keyup.enter="loginFunc"
              />
              <i class="fa fa-unlock-alt"></i>
            </div>
            <div class="login_field captcha_field" v-if="captchaObj&&captchaObj.captchaId">
              <label>{{$t('hivuiLogin_main_captcha')}}</label>
              <div style="display:flex;align-items:center;">
                <input
                  class="login_field_text"
                  v-model="loginCaptcha"
                  type="text"
                  id="loginCaptcha"
                  name="captcha"
                  :placeholder="$t('hivuiLogin_main_captcha_ph')"
                  autofocus
                  required
                  autocomplete="off"
                  @keyup.enter="loginFunc"
                  style="width:50%;"
                />
                <img :src="captchaObj.imageData" @click="getCaptchaPicObj">
              </div>
            </div>
            <div class="saveCheckbox_box">
              <label for="saveCheckbox"
                ><i
                  :class="
                    'fa ' + (isCheckRu ? 'fa-check-square-o' : 'fa-square-o')
                  "
                ></i
                >{{$t('hivuiLogin_main_save_user')}}</label
              >
              <input
                type="checkbox"
                id="saveCheckbox"
                style="display: none"
                v-model="isCheckRu"
                @change="rememberUserEvent"
              />
              <span class="forgetPw" @click="showResetPw"
                ><i class="fa fa-lock"></i
                ><span style="margin-left: 5px">{{$t('hivuiLogin_main_forget_user')}}</span></span
              >
            </div>
            <div class="login_form_btn">
              <div class="login_btn_area">
                <button
                  :style="btnStyle"
                  :class="'loginBtn' + (loginLoading ? ' disabled' : '')"
                  @click="loginFunc"
                >
                  {{$t('hivuiLogin_main_login_btn')}}<i
                    :hidden="!loginLoading"
                    class="el-icon-loading"
                  ></i>
                </button>
              </div>
            </div>
            <div class="login_form_bottom">
              <div class="register_tips" :hidden="config.hideRegister">
                {{$t('hivuiLogin_main_register1')}}
                <span @click="goRegisterPage">{{$t('hivuiLogin_main_register2')}}</span>
              </div>
              <el-dropdown @command="changeLang" class="langDropdown" :hidden="!config.showChangeLangBtn">
                <span class="el-dropdown-link">
                  {{currLangDesc}}<i class="el-icon-arrow-down el-icon--right"></i>
                </span>
                <el-dropdown-menu slot="dropdown">
                  <template v-for="(item,index) in langList">
                    <el-dropdown-item :key="'langList'+index" :command="item.name+','+item.key">{{item.name}}</el-dropdown-item>
                  </template>
                </el-dropdown-menu>
              </el-dropdown>
            </div>
            <el-popover v-if="config.appQRcode" class="login_form_appqr" placement="bottom" width="210" popper-class="appQRPopper">
              <div ref="appQRcode" class="login_download_app">
                <canvas v-if="!config.appQRcode.startsWith('imgUrl:')"></canvas>
                <img v-else :src="config.appQRcode.replace('imgUrl:','')">
              </div>
              <span slot="reference" class="login_form_app" :title="$t('hivuiLogin_main_appdownload')"><i class="miniIcon" data-type="app"></i>{{$t('hivuiLogin_main_download')}}</span>
            </el-popover>
          </div>
        </div>
        <!-- 扫码窗口 -->
        <div
          id="showCom"
          class="loginMainBox"
          :hidden="!(config.isScan && currLoginType == 'scan')"
        >
          <div class="login_form_hd">
            <h3>{{$t('hivuiLogin_main_scan_login')}}</h3>
            <img @click="changeCom" class="icon-qrcode" :src="comIcon" alt="" />
            <div class="login-tip">
              <div class="poptip">
                <div class="poptip-arrow">
                  <em></em>
                  <span></span>
                </div>
                <div class="poptip-content">{{$t('hivuiLogin_main_pw_text')}}</div>
              </div>
            </div>
          </div>
          <!-- 扫码主体 -->
          <div class="scanMain">
            <img ref="scanQrCode" :src="scanQrCode" :load="scanLoading" v-show="scanState==-1||scanState==2"/>
            <div class="scanMask" v-show="scanState==2">
              <div class="scanMaskMsg">登录中 <dot>...</dot></div>
            </div>
            <!-- <div class="login-error" v-show="scanState==6">{{scanErrorMsg||$t('hivuiLogin_main_login_fail')}}</div> -->
            <div class="qrcode-img" v-show="scanState==1||scanState==3||scanState==4||scanState==6">
              <div class="qrcode-error">
                <p>{{scanErrorMsg||$t('hivuiLogin_main_qr_fail')}}</p>
                <button type="button" class="refresh" @click="refreshScanQrCode">{{$t('hivuiLogin_main_qr_refresh')}}</button>
              </div>
            </div>
          </div>
          <!-- 扫码成功 -->
          <div class="login-content nc-outer-box" v-show="scanState==0">
            <div class="qrcode-login">
              <div class="qrcode-success">
                <!-- <img src="" alt=""/> -->
                <p>{{$t('hivuiLogin_main_scan_success')}}</p>
                <h4>{{$t('hivuiLogin_main_scan_text')}}</h4>
              </div>
            </div>
          </div>
          <!-- 扫码QRCode -->
          <div class="qrDesc" v-show="scanState!=0&&scanState!=5">
            <div>
              <img :src="saomaIcon"/>
            </div>
            <div class="qrDesc_right">
              <span>
                {{$t('hivuiLogin_main_app_text1')}}<a style="color: #06c">{{config.appName}}</a><br />
                {{$t('hivuiLogin_main_app_text3')}}</span
              >
            </div>
          </div>
        </div>
        <div id="qrcode"></div>
      </div>
    </div>
    <el-dialog :title="$t('hivuiLogin_main_forget_title')" :visible.sync="isShowResetPw" width="400px" :close-on-click-modal="false" @close="cancelResetPw">
      <resetPw res="resetPw" @resetCb="cancelResetPw"></resetPw>
    </el-dialog>
    <el-dialog :title="$t('hivuiLogin_main_bz_title')" :visible.sync="isShowUserBz" width="300px" top="40vh" :close-on-click-modal="false" @close="cancelUserBz">
      <div class="seldUserBzDialog">
        <el-select v-model="seldUserBz" :placeholder="$t('hivuiLogin_main_bz_placeholder')" @change="changeUserBz">
          <el-option
            v-for="item in userBzList"
            :key="item.fbzid"
            :label="item.fbzname+'/'+item.fbzid"
            :value="item.fbzid">
          </el-option>
        </el-select>
      </div>
    </el-dialog>
    <!-- 管理员解锁 -->
    <el-dialog :title="$t('hivuiLogin_main_admin_forget_title')" :visible.sync="isShowAdminResetPw" width="430px" :close-on-click-modal="false" @close="cancelAdminResetPw">
      <div class="unlock_field">
        <label>{{$t('hivuiLogin_main_pw')}}</label>
        <div class="unlock_field_input">
          <input
            ref="aaaa"
            class="unlock_field_text"
            v-model="unlockPassword"
            type="password"
            name="unlockPassword"
            :placeholder="$t('hivuiLogin_main_pw_ph')"
            autocomplete="off"
            @keyup.enter="adminUnlock"
          />
          <i class="fa fa-unlock-alt"></i>
        </div>
      </div>
      <div class="unlock_field" v-if="captchaObj2&&captchaObj2.captchaId">
        <label>{{$t('hivuiLogin_main_captcha')}}</label>
        <div class="unlock_field_input">
          <input
            class="unlock_field_text"
            v-model="unlockCaptcha"
            type="text"
            name="unlockCaptcha"
            :placeholder="$t('hivuiLogin_main_captcha_ph')"
            autocomplete="off"
            @keyup.enter="adminUnlock"
            style="width:50%;"
          />
          <i class="fa fa-unlock-alt"></i>
          <img :src="captchaObj2.imageData" @click="getCaptchaPicObj(2)">
        </div>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button size="small" type="primary" @click="adminUnlock">{{$t('hivuiLogin_main_admin_unlock')}}</el-button>
      </span>
    </el-dialog>
    <div class="login_ft">
      <div class="login_ft_main" id="login_copyright" v-html="config.copyright"></div>
    </div>
  </div>
</template>
<script>
import { baseLogin,getScanQrCode,adminUnlock } from "../api/login";
import { getBzList,changeBz,getCaptchaPic } from "../api/user";
import md5 from "js-md5";
import Cookies from 'js-cookie';
import QRCode from 'qrcode';
import { utils } from "hi-ui";
import { projectName } from "../config";
import WebScoketManager from '../utils/websocket.js'
import "font-awesome/css/font-awesome.css";
import comIcon from "../assets/computer2.png"
import scanIcon from "../assets/qrcode2.png"
import saomaIcon from "../assets/saoma2.png"
import _loginLogoImg from "../assets/Logo1.png"
import _loginBgImg from "../assets/background.png"
import {
  getToken,
  setToken,
  removeToken,
  getUserId,
  setUserId,
  removeUserId,
} from "../utils/auth.js";
import {setUrlValue,getUrlValue} from "../utils/index.js";

import resetPw from "../components/resetPw.vue";
export default {
  components: {resetPw},
  data() {
    return {
      comIcon: comIcon,
      scanIcon: scanIcon,
      saomaIcon: saomaIcon,
      username: "",
      password: "",
      //登录输入验证码
      loginCaptcha:"",
      config: {
        title: window.customSysCofig?.loginTitle||this.$t('hivuiLogin_main_def_title'),
        loginLogoImg: window.customSysCofig?.loginLogo||_loginLogoImg,
        loginLogoImg_height: window.customSysCofig?.loginLogo_h||56,
        loginLogoImg_width: window.customSysCofig?.loginLogo_w||206,
        loginBgImg: window.customSysCofig?.loginBgImg||_loginBgImg,
        copyright: window.customSysCofig?.copyright||this.$t('hivuiLogin_main_def_copyright'),
        isScan: window.customSysCofig?.isScan||false,
        mainColor:window.customSysCofig?.mainColor||"#06c",
        appQRcode:window.customSysCofig?.appQRcode||"",
        hideRegister:window.customSysCofig?.hideRegister||false,
        showChangeLangBtn:window.customSysCofig?.showChangeLangBtn||false,
        appName:window.customSysCofig?.appName||this.$t('hivuiLogin_main_app_text2'),
      },
      currLoginType: "com",
      rememberUserId: getUserId(),
      loginLoading: false,
      
      isShowResetPw:false,
      isShowAdminResetPw:false,
      //是否显示选择登录岗位弹窗
      isShowUserBz:false,
      //已选用户岗位
      seldUserBz:"",
      //用户岗位数据列表
      userBzList:[],
      //扫码Socket
      scanWS:null,
      //扫码UUID
      scanUUID:"",
      //登录二维码
      scanQrCode:"",
      //二维码loading
      scanLoading:false,
      //扫码报错信息
      scanErrorMsg:"",
      //当前扫码登录状态 二维码状态(type):-1-待机 0-扫码中 1-扫码取消 2-登录中 3-已失效 4-已使用 5-登录成功 6-登录失败
      scanState:-1,
      //解锁密码
      unlockPassword:"",
      //解锁输入验证码
      unlockCaptcha:"",
      //验证码对象
      captchaObj:null,
      //解锁验证码对象
      captchaObj2:null,
    };
  },
  computed: {
    btnStyle(){
      return {
        "background-color": this.config.mainColor,
      };
    },
    bgStyle() {
      return {
        "background-image": "url(" + this.config.loginBgImg + ")",
      };
    },
    logoStyle() {
      return {
        "background-image": "url(" + this.config.loginLogoImg + ")",
        height: this.config.loginLogoImg_height + "px",
        width: this.config.loginLogoImg_width + "px",
      };
    },
    isCheckRu() {
      return !!this.rememberUserId;
    },
    currLangDesc(){
      return window.localStorage.getItem("locale")?(JSON.parse(window.localStorage.getItem("locale")).desc):"中文";
    },
    langList(){
      let arr=[
        {
            name:"中文",
            key:"zh-CN",
        }, {
            name:"English",
            key:"en",
        }, 
      ]
      if(window.customSysCofig?.addLangList?.length){
        window.customSysCofig?.addLangList.forEach((item,index)=>{
          arr.push({
            name:item.name,
            key:item.key,
          });
        });
      }
      return arr;
    }
  },
  
  async created() {
    let me=this;
    if (window.HIVUI_SETTING.isSingleLogin) {
        let loginUrl = window.HIVUI_SETTING.singleLoginUrl;
        if (loginUrl.endsWith("=")) {
          loginUrl = loginUrl + window.HIVUI_SETTING.mainPageUrl.replace(/#\//g, "");
      }
      window.location.href = loginUrl;
    }
    //获取验证码图片
    await me.getCaptchaPicObj();
  },
  mounted() {
    /*let me=this;
    me.$msgbox({
      title:"测试",
      message:"2136d5f4354gf",
      autofocus:false,
    });
    setTimeout(() => {
      me.isShowAdminResetPw=true;
      me.$refs.aaaa.focus();
    }, 0);*/
    







    if (this.isCheckRu) {
      this.username = this.rememberUserId;
    }
    if(!window.localStorage.getItem("locale")){
        window.localStorage.setItem("locale",JSON.stringify({
            desc:"中文",
            name:"zh-CN",
        }));
        Cookies.set("locale","zh-CN");
    }
    this.$refs.scanQrCode.onload = function() {
      // 清理创建的临时链接
      //URL.revokeObjectURL(imageUrl);
    }
    //生成二维码
    if(this.config.appQRcode){
      let isIMG=this.config.appQRcode.startsWith('imgUrl:');
      if(this.config.appQRcode.indexOf('http')==-1){
        this.config.appQRcode=(isIMG?'imgUrl:':'')+location.origin+this.config.appQRcode.replace('imgUrl:','');
      }
      if(!isIMG){
        let targetUrl=this.config.appQRcode;
        if(!window._global){//正式环境
            targetUrl=utils.string.setUrlValue(targetUrl,"pn",window.HIVUI_SETTING.projectName);
        }
        console.log("测试str",targetUrl);
        this.createDLQrCode(this.$refs.appQRcode.querySelector("canvas"),targetUrl);
      }
    }
  },
  methods: {
    loginFunc() {
      this.defaultLogin();
    },
    defaultLogin() {
      let me=this;
      /*this.$refs.loginForm.validate(valid => {
                if (valid) {*/
      if(me.captchaObj && me.captchaObj.captchaId && !me.loginCaptcha.trim()){
        me.$message.error(me.$t('hivuiLogin_main_valid_captcha'));
        return;
      }else if(!me.username.trim()){
        me.$message.error(me.$t('hivuiLogin_main_valid_user'));
        return;
      }else if(!me.password){
        me.$message.error(me.$t('hivuiLogin_main_valid_pw'));
        return;
      }
      removeToken();
      me.loginLoading = true;
      let _params={
        username: me.username.trim(),
        password: md5(me.password),
      };
      if(me.loginCaptcha && me.captchaObj && me.captchaObj.captchaId){
        _params.captchaId=me.captchaObj.captchaId;
        _params.captcha=me.loginCaptcha;
      }
      baseLogin(_params)
        .then((response) => {
          const data = response;
          setToken(data.token);
          if (me.isCheckRu) {
            setUserId(me.username);
          } else {
            removeUserId();
          }
          if(!data.isAuthorize){
            if(data.authorizeMsg){
              me.$message.warning(data.authorizeMsg);
            }
            me.$router.push("/authorize");
          }else if(window.customSysCofig?.isSelectUserBz){
            getBzList().then((res)=>{
              me.userBzList=res.dataPack;
              me.isShowUserBz=true;
            });
          }else{
            me.goMainPage();
          }
        })
        .catch((error) => {
          me.loginLoading = false;
          if(me.captchaObj && me.captchaObj.captchaId && error.status==500){
            me.getCaptchaPicObj();
          }
          if(me.username.trim()=="admin" && error&&error.dataPack&&error.dataPack.lock){
            me.isShowAdminResetPw=true;
            //获取验证码图片
            me.getCaptchaPicObj(2);
          }
        });
      /*} else {
                    console.log("error submit!!");
                    return false;
                }
            });*/
    },
    //关闭选岗弹窗
    cancelUserBz(){
      this.isShowUserBz=false;
      this.loginLoading=false;
    },
    //选择岗位
    changeUserBz(val){
      changeBz({
        bzid:val
      }).then((res)=>{
        this.goMainPage();
      });
    },
    //跳转到主页
    goMainPage(){
      if(!window.HIVUI_SETTING.isSingleLogin&&location.hash.indexOf("eapReturnUrl=")!=-1){
        let __eapReturnUrl=decodeURIComponent(location.hash.split("eapReturnUrl=")[1]);
        let hasTokenParams=getUrlValue(__eapReturnUrl,"access_token");
        if(false&&!window._global&&hasTokenParams){//正式环境
          location=setUrlValue(__eapReturnUrl,"access_token",getToken());
        }else{
          location=__eapReturnUrl;
        }
      }else{
        location = window.HIVUI_SETTING.mainPageUrl
        ? window.HIVUI_SETTING.mainPageUrl
        : "/" + projectName + "/hivuiMain/index.html#/";
      }
    },
    changeQr() {
      this.currLoginType = "scan";
      this.getScanQrCode();
    },
    changeCom() {
      this.currLoginType = "com";
    },
    
    showResetPw() {
      this.isShowResetPw=true;
    },
    cancelResetPw() {
      this.isShowResetPw=false;
    },
    cancelAdminResetPw(){
      this.isShowAdminResetPw=false;
    },
    rememberUserEvent() {
      if (this.isCheckRu) {
        this.rememberUserId = "";
      } else {
        this.rememberUserId = true;
      }
    },
		goRegisterPage(){
			this.$router.push("/register");
    },
    changeLang(command){
      let dataArr=command.split(",");
      window.localStorage.setItem("locale",JSON.stringify({
          desc:dataArr[0],
          name:dataArr[1],
      }));
      Cookies.set("locale",dataArr[1]);
      window.location.reload();
    },
    //生成下载二维码
    createDLQrCode(target,text){
      QRCode.toCanvas(target, text, function (error) { // 将文本转化为二维码并渲染到canvas上
        if (error) {
          console.error(error);
        }
      });
    },
    //解锁
    adminUnlock(){
      let me=this;
      if(!me.unlockPassword){
        me.$message.error(me.$t('hivuiLogin_main_valid_pw'));
        return;
      }
      let _params={
          userId: me.username.trim(),
          password: md5(me.unlockPassword)
      };
      if(me.unlockCaptcha && me.captchaObj2 && me.captchaObj2.captchaId){
        _params.captchaId=me.captchaObj2.captchaId;
        _params.captcha=me.unlockCaptcha;
      }
      adminUnlock(_params).then((response)=>{
        if(response.status==200){
          me.isShowAdminResetPw=false;
          if(!response.msg){
            me.$message.error(me.$t('hivuiLogin_main_unlock_success'));
          }
          me.password=me.unlockPassword;
          if(!me.captchaObj || !me.captchaObj.captchaId){
            me.loginFunc();
          }else{
            me.loginCaptcha="";
          }
        }
      }).catch((err)=>{
        if(me.captchaObj2 && me.captchaObj2.captchaId && err.status==500){
          me.getCaptchaPicObj(2);
        }else{
          me.isShowAdminResetPw=false;
        }
      });
    },
    //获取验证码
    getCaptchaPicObj(num){//num=2:管理员解锁时验证码
      let me=this;
      getCaptchaPic({
        type:"login"
      }).then((res)=>{
        if(res&&res.dataPack){
          if(num==2){
            me.captchaObj2=res.dataPack;
          }else{
            me.captchaObj=res.dataPack;
          }
        }
      });
    },



















    //获取扫码登录的二维码
    getScanQrCode(){
      let me=this;
      me.scanLoading=true;
      me.scanState=-1;
      if(me.scanWS){
        me.scanWS.end();
      }
      // eap.request({
      //   url: "http://e53.hieap.cn/login/sso-qr?pn=yypt/0000221",
      //   responseType:"arraybuffer"
      // }).then(res=>{
      getScanQrCode().then(res=>{
        me.scanLoading=false;
        if(res.headers.uuid){
          me.scanUUID=atob(res.headers.uuid);//base64解密
        }
        const blob = new Blob([res.data], { type: 'image/jpeg' });
        const imageUrl = URL.createObjectURL(blob);
        me.scanQrCode=imageUrl;
        me.createScanSocket();
      }).catch(()=>{
        me.scanLoading=false;
      });
    },
    //刷新二维码
    refreshScanQrCode(){
      let me=this;
      me.getScanQrCode();
    },
    //建立扫码登录socket
    createScanSocket(){
      let me=this;
      if ("WebSocket" in window){  
          // 打开一个 web socket
          var socketHost=window.HIVUI_SETTING?.serverUrl.replace("http","ws");
          me.scanWS = new WebScoketManager({
              "link": socketHost+"/ws/qr/login/pc/"+window.HIVUI_SETTING?.projectName+"/"+me.scanUUID,
              //"reConnect":true,
          });
          me.initWSEvent();
      }else{
          // 浏览器不支持 WebSocket
          alert("您的浏览器不支持 WebSocket!");
      }
    },
    //初始化WS事件
    initWSEvent() {
      let me=this;
      let _ws = me.scanWS;
      console.log('开始连接websocket');
      //建立连接
      _ws.on("onopen", () => {
          console.log('数据发送中...');
      });
      //连接失败
      _ws.on("onclose", () => {
          console.log('连接已关闭...');
      });
      //超时关闭
      _ws.on("overtime", () => {
          console.log('服务器连接超时');
      });
      _ws.on("reConnect", () => {
          console.log('重新连接websocket中');
      });
      _ws.on("endReConnect", () => {
          console.log('重新连接次数超出上限,终止连接');
      });
      //接受消息
      _ws.on("onmessage", (data) => {
          if(data.status + "" =="500"){
            console.log("异常",data.msg);
            me.scanErrorMsg=data.msg;
            me.scanState=6;
            return;
          }else if(data.status + "" =="200"){
            if(data.token){//登录成功
              setToken(data.token);
              if(window.customSysCofig?.isSelectUserBz){
                getBzList().then((res)=>{
                  me.userBzList=res.dataPack;
                  me.isShowUserBz=true;
                });
              }else{
                me.goMainPage();
              }
              return;
            }
          }
          if(typeof(data.type)!="undefined"){
            me.scanState=data.type;
            switch (data.type + "") {//二维码状态(type):-1-待机 0-扫码中 1-扫码取消 2-登录中 3-已失效 4-已使用 5-登录成功 6-登录失败
                case "0": 
                  
                  break;
                case "1": 
                  me.scanErrorMsg="扫码已取消";
                  break;
                case "2": 
                  
                  break;
                case "3": 
                  me.scanErrorMsg="二维码已失效";
                  break;
                case "4": 
                  me.scanErrorMsg="二维码已使用";
                  break;
            }  
          }
      });
    },
  },
};
</script>
<style lang="scss">
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
a {
  text-decoration: none;
}
ul,
li {
  list-style: none;
}
button {
  outline: none;
  border: none;
}
html,
body {
  height: 100%;
  width: 100%;
  background: #fff;
}
input,
body,
button {
  font-family: "Microsoft YaHei", proxima-nova, "Helvetica Neue", arial,
    helvetica, clean, sans-serif;
}
body {
  font-size: 14px;
  color: #333;
}
.bg {
  height: 100%;
  width: 100%;
  position: relative;
}
.login_hd,
.login_ft {
  height: 100px;
  width: 100%;
  position: fixed;
  z-index: 99;
  left: 0;
}
.login_hd_main,
.login_ft_main {
  width: 1000px;
  height: 100%;
  margin: 0 auto;
  a{
    color:#0f406c;
    margin-left:5px;
    &:hover{
      color:#409eff;
    }
  }
}
.login_hd {
  top: 0;
  .login_hd_logo {
    height: 60px;
    width: 265px;
    position: absolute;
    top: 50px;
    left: 50px;
    background: no-repeat;
    background-size: 100% 100%;
    img {
      height: 80px;
      width: 80px;
      margin-right: 90px;
      margin-top: 10px;
      float: right;
    }
    .login_hd_logo_tip {
      height: 32px;
      width: 84px;
      display: inline-block;
      padding: 0 20px;
      font-size: 22px;
      color: #fff;
      position: absolute;
      right: -104px;
      top: 0;
      bottom: 0;
      margin: auto;
      &:after {
        content: "";
        height: 20px;
        width: 2px;
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0px;
        background-color: #8691a8;
        margin: auto;
      }
    }
  }
}
.login_bd {
  overflow: hidden;
  min-width: 1210px;
  position: relative;
  height: 100%;
  background-color: #fff;
  .login_bd_bg {
    background: no-repeat center center;
    background-size: 100%;
    position: absolute;
    height: 100%;
    width: 100%;
  }
  .login_form {
    width: 370px;
    height: 380px;
    margin: auto;
    position: absolute;
    top: 0;
    left: 40%;
    right: 0;
    bottom: 0;
    background-color: #fff;
    padding: 18px 20px 0;
    z-index: 100;
    box-shadow: 0 0 5px 1px rgba(0, 0, 0, 0.5);
    .login_form_hd{
      position: relative;
      box-sizing: border-box;
      padding-left:30px;
      width: 100%;
      h3{
        font-size: 24px;
        text-align: left;
        line-height: 44px;
        color: #333;
        font-weight: normal;
      }
    }
    .login_form_bd {
      min-height: 231px;
      height: 100%;
      position: relative;
      padding: 24px 20px 0;
      .login_form_appqr {
        position: absolute;
        bottom: 0;
        left: 15px;
        .login_form_app{
          color: #409eff;
          cursor: pointer;
          display: flex;
          align-items: center;
          &:hover {
            color: #0f406c;
            &i {
              color: #0f406c;
            }
          }
        }
        .miniIcon {
          display: inline-block;
          height: 20px;
          width: 20px;
          background-position: center center;
          background-size: 100%;
          margin-right:5px;
          &[data-type="app"] {
            background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAbdJREFUWEftV0tOwzAQfUMoa24ARwA1XQMnoJyAVKLZUk7Q9AR0nSJRbhBOQPdtBUcoN2DdD0aTNiKOk9ZJYyGheBXF43nPz57xDCE5nPdjHC27ADUBnCrzxX7MABFgftjD8Pwr7oIUf+3xCEQXxXB2rgrg2zfZBO7Glzigt51u9jH4Fld4aowiF7IC7rQDiEfJv8ArSHwUwhR0BsK1vJYe4Nf7GQTGHkDd3wWycSESyqZED37D0yOQkKsQAeVY/xWBtbwz+HaQqY5RBdyJCIF9Ww3niFFFoFKgVAXakz4I9xDUwqA+RPwStqcOSDwDcpyjVAJuLFMyiRAQCAlF30YJMJg7GQK4zYj7F/i2I82VqkDkOZ2ECs72RgioSqSDGyXAzvlS8hjYnb9JxTrPo7Ej0AE3fgQ6JPZSAAgwt1rJSlYHN7QJK+wV5wqusDcjT0GijZTHsCJQlgJcri+sddqtLQP9ZqYsAvGKOVdDs5VASmOSeb9iPUNaQ6OzDoBcTObaCT/D4JeRvcgv4Lag2NqahfndYHPK92Zgx3JCUoEoedRW3Do1QTjJE+GZtgKf4KS2sLxkUvsBGpxuMP/zizEAAAAASUVORK5CYII=");
          }
          &[data-type="desk"] {
            background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjJGRUFBRDNFOTc2NTExRUI5OTdGOTE0QkVGODlDRDIwIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjJGRUFBRDNGOTc2NTExRUI5OTdGOTE0QkVGODlDRDIwIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MkZFQUFEM0M5NzY1MTFFQjk5N0Y5MTRCRUY4OUNEMjAiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MkZFQUFEM0Q5NzY1MTFFQjk5N0Y5MTRCRUY4OUNEMjAiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7jOkn1AAABSElEQVR42mL8//8/AymApXzd08fvfv36+58Rh4o///7LCrLZqPCEmQgCuYwMaWeINPv/TGOQDUC8OEkx2kzoHw63MTMxrjv/Yf/Nz1AnATE/JzMjIwMIYwO7rn3iZGWcHCGL0PDt1z9czrj7+qf7xNtAxslKDTMFbiCDCY+jP/3469B7C8J27L318O0vfBpuvfwhUXLpyftfEC7QFQpVl888/AZyEjsLFtdffvodGJRff/07dvcLkCvGy6IrzXnkDpCddmbN2Xf/cYD9Nz+Bwj3tTNOWZxARkA0hM+8JcDH//osSrEBuiau4uSI3hOupww8NpTJ3iXuvf37//Y8J1V3AuNeQ4AA6DMjWk+E0keeCxR9ewJJxFuiei4+/wUVwhtKbL39su28yMTGsz1QG2oCUQnCAE/e+1G58+vrzbzRxRlKTN0CAAQB1Gu32zyWjpAAAAABJRU5ErkJggg==");
          }
        }
      }
      .error_tips {
        position: absolute;
        line-height: 30px;
        font-size: 12px;
        color: #f60000;
        text-align: center;
        top: 0;
        left: 0;
        right: 0;
        width: 100%;
        margin: auto;
      }
      .login_field {
        position: relative;
        padding-bottom: 20px;
        label {
          line-height: 35px;
          display: block;
          height: 35px;
          font-size: 16px;
        }
        i {
          font-size: 20px;
          color: #aaa;
          width: 35px;
          text-align: center;
          line-height: 40px;
          height: 40px;
          position: absolute;
          top: 35px;
          left: 0;
          margin: auto;
        }
        .login_field_text {
          height: 40px;
          width: 100%;
          line-height: 40px;
          border: 1px solid #ccc;
          border-radius: 5px;
          background-color: #fff;
          font-size: 16px;
          color: #000;
          padding-left: 35px;
          box-sizing: border-box;
          font-family: "Microsoft YaHei", proxima-nova, "Helvetica Neue", arial,
            helvetica, clean, sans-serif;
          &::input-placeholder {
            color: #ccc;
          }
        }
        img{
          width:calc(50% - 10px);
          margin-left:10px;
          cursor: pointer;
        }
      }
      .saveCheckbox_box {
        height: 35px;
        line-height: 35px;
        padding-left: 30px;
        position: relative;
        top: 0px;
        label {
          cursor: pointer;
          user-select: none;
          i {
            font-size: 24px;
            position: absolute;
            top: 0;
            left: 2px;
            bottom: 0;
            margin: auto;
            height: 25px;
            width: 25px;
            color: #888;
            cursor: pointer;
            text-align: center;
          }
        }
        .occasion {
          float: right;
          &:after {
            content: "";
            background: no-repeat;
            width: 14px;
            height: 18px;
            position: absolute;
            top: 30%;
            pointer-events: none;
            right: 1px;
          }
          #selectStyle {
            border: none;
            outline: none;
            width: 62px;
            appearance: none;
            -webkit-appearance: none;
            -moz-appearance: none;
          }
        }
      }
      .forgetPw {
        float: right;
        color: #409eff;
        cursor: pointer;
        margin-left: 5px;
        &:hover {
          color: #0f406c;
          i {
            color: #0f406c;
          }
        }
      }
      .login_form_btn {
        font-size: 13px;
        margin-top: 20px;
        .loginBtn {
          /* background-color: #135189; */
          width: 100%;
          height: 40px;
          border: none;
          border-radius: 5px;
          color: #fff;
          font-size: 16px;
          font-weight: bold;
          text-align: center;
          cursor: pointer;
          display: inline-block;
          i {
            margin-left: 5px;
          }
          &:hover {
            filter: brightness(0.8);
          }
          &.disabled {
            background-color: #ccc!important;
            &:hover {
              filter: brightness(1);
            }
          }
        }
      }
      /*二维码*/
      .qrCodeImg {
        /* position: absolute; */
        height: 139px;
        width: 139px;
        /* left:40% !important;
                right:0 !important;
                bottom:12%; */
        margin-top: 10px;
        margin-left: 85px;
        z-index: 999;
      }
      .login_form_bottom{
        padding-top: 15px;
        min-height:36px;
        .register_tips{
          font-size: 14px;
          text-align: center;
          span{
            color:#409eff;
            cursor: pointer;
          }
        }
        .langDropdown{
          position: absolute;
          bottom:0;
          right:0;
          padding:0 20px;
        }
      }
      
    }
    .login_form_google {
      width: 280px;
      position: absolute;
      top: 317px;
      left: 0;
      bottom: 0;
      color: #fff;
      line-height: 20px;
      text-align: center;
      font-weight: bold;
      font-size: 13px;
      cursor: pointer;
      user-select: none;
      & > a {
        color: #fff;
      }
    }
    .loginMainBox {
      position: relative;
      .login-title {
        height: 18px;
        line-height: 18px;
        font-size: 16px;
        color: #889aa4;
        margin-top: 12px;
        margin-left: 12px;
        padding-bottom: 8px;
        font-weight: 700;
      }
      .login-tip{
          position: absolute;
          top: 8px;
          right: 52px;
          display: block;
          .poptip{
              background-color: #F2F7FC;
              line-height: 16px;
              position: relative;
              z-index: 9999;
              border: 1px solid #DAE9F7;
              padding: 5px 10px;
              border-radius: 4px;
              .poptip-arrow {
                  position: absolute;
                  z-index: 10;
                  top: 8px;
                  right: 0;
                  span{
                      position: absolute;
                      width: 0;
                      height: 0;
                      border-color: hsla(0,0%,100%,0);
                      border-style: solid;
                      overflow: hidden;
                      top: 0;
                      left: -1px;
                      border-width: 6px 0 6px 6px;
                      border-left-color: #F2F7FC;
                  }
                  em {
                      position: absolute;
                      width: 0;
                      height: 0;
                      border-color: hsla(0,0%,100%,0);
                      border-style: solid;
                      overflow: hidden;
                      top: 0;
                      left: 0;
                      border-width: 6px 0 6px 6px;
                      border-left-color: #DAE9F7;
                      border-right-color: #DAE9F7;
                  }
              }
              .poptip-content {
                  font-size: 12px;
                  font-weight: 400;
                  color: #06c;
              }
          }
      }
      .qrDesc {
        font-size: 12px;
        color: #666;
        width: 160px;
        margin: auto;
        overflow: hidden;
        line-height: 17px;
        margin-top: 230px;
        .qrDesc_right {
          position: relative;
          left: 50px;
          top: -35px;
        }
      }
      .scanMain {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        .qrcode-img {
          position: relative;
          margin: 20px auto;
          font-size: 14px;
          -webkit-box-shadow: 0 0 8px #ddd;
          box-shadow: 0 0 8px #ddd;
          opacity: 1;
          width: 140px;
          height: 140px;
          .qrcode-error {
            background: hsla(0, 0%, 100%, 0.95);
            position: absolute;
            left: 0;
            top: 0;
            z-index: 9999;
            width: 100%;
            height: 100%;
            p {
              font-weight: 700;
              color: #222;
              margin-top: 38px;
              margin-bottom: 8px;
              text-align: center;
            }
            .refresh {
              background: #f40;
              width: 110px;
              height: 34px;
              line-height: 34px;
              text-align: center;
              margin: 0 auto;
              background: #ff9000;
              border-color: #ff9000;
              display: block;
              color: #fff;
              border-radius: 3px;
              font-size: 14px;
              cursor: pointer;
            }
          }
          canvas {
            margin: 5px;
          }
        }
        .login-error {
          text-align: center;
          color: #222;
          font-weight: 700;
        }
      }
      .scanMask{
        position: absolute;
        top: 0;
        left: 0;
        height: 100%;
        width: 100%;
        background-color: rgba(255,255,255,0.7);
        display: flex;
        justify-content: center;
        align-items: center;
        .scanMaskMsg{
          padding: 0 10px;
          box-shadow: #000 0 0 10px 1px;
          background-color: #fff;
          line-height: 32px;
          border-radius: 5px;
          color: #06c;
          font-weight: bold;
        }
      }
      /*二维码切换登录*/
      .icon-qrcode {
        position: absolute;
        right: 0px;
        top: 0px;
        cursor: pointer;
        width: 44px;
        z-index: 999;
      }

      .login-content {
        width: 100%;
        margin: 0 auto;
        padding-top: 55px;
        .qrcode-success {
          text-align: center;
          margin-top: 20px;
          .iconfont {
            color: #c5c5c5;
            font-size: 36px;
          }
          h4,
          p {
            margin-top: 10px;
            font-size: 14px;
          }
        }
      }
    }
    &.showCaptcha{
      height:440px;
      .login_form_bd {
        .login_field{
          padding-bottom:10px;
        }
        .captcha_field{
          input{
            padding-left:10px;
          }
        }
      }
    }
  }
}
.login_ft {
  bottom: 0;
  .login_ft_main {
    line-height: 60px;
    text-align: center;
    font-size: 14px;
  }
}
/*登录对话框*/
.loginDialog {
  height: 300px;
  width: 500px;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  z-index: 199;
  .loginDialog_hd {
    height: 35px;
    background-color: #409eff;
    position: relative;
    h2 {
      height: 35px;
      line-height: 35px;
      font-size: 14px;
      color: #fff;
      padding: 0 20px;
    }
    .loginDialog_remove {
      position: absolute;
      top: 0;
      bottom: 0;
      right: 5px;
      height: 20px;
      width: 20px;
      background-color: #f30;
      cursor: pointer;
      margin: auto;
      text-align: center;
      &i {
        line-height: 20px;
        font-size: 18px;
        color: #fff;
      }
      &:hover {
        background-color: #f00;
      }
    }
  }
  .loginDialog_bd {
    width: 100%;
    height: 215px;
    background-color: #fff;
  }
  .loginDialog_ft {
    height: 50px;
    width: 100%;
    border-top: 1px solid #ccc;
    background-color: #f5f5f5;
    &:after {
      content: "";
      display: block;
      clear: both;
    }
    button {
      display: block;
      padding: 0 12px;
      font-size: 14px;
      margin-top: 11px;
      height: 28px;
      line-height: 28px;
      text-align: center;
      cursor: pointer;
      color: #333333;
      background-color: #e9e9e9;
      float: right;
      margin-right: 10px;
    }
    .loginDialog_confirmBtn {
      background-color: #5cb85c;
      color: #fff;
      &:hover {
        background-color: #47a447;
      }
    }
    .loginDialog_cancelmBtn:hover {
      background-color: #ddd;
    }
  }
}
.loginMask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #000;
  opacity: 0.5;
  z-index: 198;
}
#loginMsg {
  height: 170px;
  width: 400px;
  top: 10%;
  bottom: unset;
  z-index: 200;
  .loginDialog_bd {
    height: 85px;
    line-height: 85px;
    padding-left: 20px;
    font-size: 14px;
  }
}
.dropdown {
  border: 1px solid #bebebe;
  border-radius: 3px;
  width: 100px;
  position: absolute;
  right: 20px;
  top: 229px;
  background: #fff;
  -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  z-index: 100;
  overflow: auto;
  cursor: default;
  li {
    margin: 5px;
    :hover {
      background: #409eff;
      color: #fff;
    }
    &.sceneActive {
      background: #409eff;
      color: #fff;
    }
  }
}
.hideIframe {
  display: none;
}
.appQRPopper{
  text-align: center;
  .login_download_app{
    display:flex;
    justify-content:center;
    canvas{
      width:180px!important;
      height:180px!important;
    }
    img{
      max-width:180px;
    }
  }
}
.seldUserBzDialog{
  display: flex;
  justify-content: center;
  padding-bottom:10px;
}
.unlock_field {
  display:flex;
  padding-top:10px;
  label {
    line-height: 35px;
    display: block;
    height: 35px;
    width:80px;
    font-size: 14px;
    padding-left:20px;
  }
  .unlock_field_input{
    position: relative;
    margin-left:20px;
    flex: 0 0 calc(100% - 150px);
    display:flex;
    align-items: center;
    i {
      font-size: 20px;
      color: #aaa;
      width: 35px;
      text-align: center;
      line-height: 35px;
      height: 35px;
      position: absolute;
      top: 0;
      left: 0;
      margin: auto;
    }
    .unlock_field_text {
      height: 35px;
      width: 100%;
      line-height: 35px;
      border: 1px solid #ccc;
      border-radius: 5px;
      background-color: #fff;
      font-size: 14px;
      color: #000;
      padding-left: 35px;
      box-sizing: border-box;
      font-family: "Microsoft YaHei", proxima-nova, "Helvetica Neue", arial,
        helvetica, clean, sans-serif;
      &::input-placeholder {
        color: #ccc;
      }
    }
    img{
      width:calc(50% - 10px);
      margin-left:10px;
      cursor: pointer;
    }
  }
}

@supports (display:none) {
    dot {
        display: inline-block; 
        width: 3ch;
        text-indent: -1ch;
        vertical-align: bottom; 
        overflow: hidden;
        animation: dot 2s infinite step-start both;
        font-family: Consolas, Monaco, monospace;
    }
}

@keyframes dot {
    33% { text-indent: 0; }
    66% { text-indent: -2ch; }
}
</style>