ソースを参照

页面登录调整

lipenghui 4 ヶ月 前
コミット
d1a697fd49

+ 3 - 3
src/locales/zh-CN.ts

@@ -115,7 +115,7 @@ export default {
   },
   login: {
     welcome: '欢迎使用本系统',
-    message: '开箱即用的中后台管理系统',
+    message: '',
     tenantname: '租户名称',
     username: '用户名',
     password: '密码',
@@ -138,7 +138,7 @@ export default {
     backLogin: '返回',
     getSmsCode: '获取验证码',
     btnMobile: '手机登录',
-    btnQRCode: '二维码登录',
+    btnQRCode: '钉钉扫码登录',
     qrcode: '扫描二维码登录',
     btnRegister: '注册',
     SmsSendMsg: '验证码已发送',
@@ -369,7 +369,7 @@ export default {
       signInFormTitle: '登录',
       ssoFormTitle: '三方授权',
       mobileSignInFormTitle: '手机登录',
-      qrSignInFormTitle: '二维码登录',
+      qrSignInFormTitle: '钉钉扫码登录',
       signUpFormTitle: '注册',
       forgetFormTitle: '重置密码',
       signInTitle: '开箱即用的中后台管理系统',

+ 167 - 31
src/views/Login/Login.vue

@@ -3,7 +3,30 @@
     :class="prefixCls"
     class="relative h-[100%] lt-md:px-10px lt-sm:px-10px lt-xl:px-10px lt-xl:px-10px"
   >
-    <div class="relative mx-auto h-full flex" :style="{ backgroundImage: `url(${bgImage})` }">
+    <div class="relative mx-auto h-full flex">
+      <div
+        :class="`${prefixCls}__left flex-1 bg-gray-500 bg-opacity-20 relative p-30px lt-xl:hidden overflow-x-hidden overflow-y-auto`"
+      >
+        <!-- 左上角的 logo + 系统标题 -->
+        <div class="relative flex items-center text-white">
+          <img alt="" class="mr-10px h-48px w-48px" src="@/assets/imgs/logo.png" />
+          <span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span>
+        </div>
+        <!-- 左边的背景图 + 欢迎语 -->
+        <div class="h-[calc(100%-60px)] flex items-center justify-center">
+          <TransitionGroup
+            appear
+            enter-active-class="animate__animated animate__bounceInLeft"
+            tag="div"
+          >
+            <img key="1" alt="" class="w-350px" src="@/assets/svgs/login-box-bg.svg" />
+            <div key="2" class="text-3xl text-white">{{ t('login.welcome') }}</div>
+            <div key="3" class="mt-5 text-14px font-normal text-white">
+              {{ t('login.message') }}
+            </div>
+          </TransitionGroup>
+        </div>
+      </div>
       <div
         class="relative flex-1 p-30px dark:bg-[var(--login-bg-color)] lt-sm:p-10px overflow-x-hidden overflow-y-auto"
       >
@@ -12,26 +35,30 @@
           class="flex items-center justify-between at-2xl:justify-end at-xl:justify-end"
           style="color: var(--el-text-color-primary);"
         >
+          <div class="flex items-center at-2xl:hidden at-xl:hidden">
+            <img alt="" class="mr-10px h-48px w-48px" src="@/assets/imgs/logo.png" />
+            <span class="text-20px font-bold" >{{ underlineToHump(appStore.getTitle) }}</span>
+          </div>
           <div class="flex items-center justify-end space-x-10px h-48px">
+            <ThemeSwitch />
             <LocaleDropdown />
           </div>
         </div>
         <!-- 右边的登录界面 -->
         <Transition appear enter-active-class="animate__animated animate__bounceInRight">
           <div
-            class="m-auto h-[calc(60%)] w-[100%] flex items-center at-2xl:max-w-500px at-lg:max-w-500px at-md:max-w-500px at-xl:max-w-500px"
-            :style="{backgroundImage: `url(${loginBox})`,minHeight: '650px', minWidth: '250px',backgroundSize: 'cover',marginTop:'5%'}"
+            class="m-auto h-[calc(100%-60px)] w-[100%] flex items-center at-2xl:max-w-500px at-lg:max-w-500px at-md:max-w-500px at-xl:max-w-500px"
           >
             <!-- 账号登录 -->
-            <LoginForm class="m-auto h-auto p-50px lt-xl:(rounded-3xl)" />
+            <LoginForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
             <!-- 手机登录 -->
 <!--            <MobileForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />-->
-<!--            &lt;!&ndash; 二维码登录 &ndash;&gt;-->
-<!--            <QrCodeForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />-->
-<!--            &lt;!&ndash; 注册 &ndash;&gt;-->
-<!--            <RegisterForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />-->
-<!--            &lt;!&ndash; 三方登录 &ndash;&gt;-->
-<!--            <SSOLoginVue class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />-->
+            <!-- 二维码登录 -->
+            <QrCodeForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
+            <!-- 注册 -->
+            <RegisterForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
+            <!-- 三方登录 -->
+            <SSOLoginVue class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
             <!-- 忘记密码 -->
             <ForgetPasswordForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
           </div>
@@ -41,34 +68,21 @@
   </div>
 </template>
 <script lang="ts" setup>
+import { underlineToHump } from '@/utils'
+
 import { useDesign } from '@/hooks/web/useDesign'
 import { useAppStore } from '@/store/modules/app'
+import { ThemeSwitch } from '@/layout/components/ThemeSwitch'
 import { LocaleDropdown } from '@/layout/components/LocaleDropdown'
-import bgImage from '@/assets/imgs/loginindex.jpg'
-import loginBox from '@/assets/imgs/login-box.png'
-import { LoginForm, ForgetPasswordForm } from './components'
+
+import { LoginForm, MobileForm, QrCodeForm, RegisterForm, SSOLoginVue, ForgetPasswordForm } from './components'
+
 defineOptions({ name: 'Login' })
+
 const { t } = useI18n()
 const appStore = useAppStore()
 const { getPrefixCls } = useDesign()
 const prefixCls = getPrefixCls('login')
-// const handleDingTalkLogin=async (code) => {
-//   try {
-//     const type = 20;
-//     const state = "22";
-//     return await request.post({
-//       url: '/system/auth/social-login',
-//       method: 'post',
-//       data: {
-//         type,
-//         code,
-//         state
-//       }
-//     });
-//   } catch (error) {
-//     throw error;
-//   }
-// }
 </script>
 
 <style lang="scss" scoped>
@@ -85,7 +99,7 @@ $prefix-cls: #{$namespace}-login;
       z-index: -1;
       width: 100%;
       height: 100%;
-      background-image: url('@/assets/imgs/loginbg.png');
+      background-image: url('@/assets/svgs/login-bg.svg');
       background-position: center;
       background-repeat: no-repeat;
       content: '';
@@ -105,3 +119,125 @@ $prefix-cls: #{$namespace}-login;
   }
 }
 </style>
+
+<!--<template>-->
+<!--  <div-->
+<!--    :class="prefixCls"-->
+<!--    class="relative h-[100%] lt-md:px-10px lt-sm:px-10px lt-xl:px-10px lt-xl:px-10px"-->
+<!--  >-->
+<!--    <div class="relative mx-auto h-full flex">-->
+<!--      <div-->
+<!--        :class="`${prefixCls}__left flex-1 bg-gray-500 bg-opacity-20 relative p-30px lt-xl:hidden overflow-x-hidden overflow-y-auto`"-->
+<!--      >-->
+<!--        &lt;!&ndash; 左上角的 logo + 系统标题 &ndash;&gt;-->
+<!--        <div class="relative flex items-center text-white">-->
+<!--          <img alt="" class="mr-10px h-48px w-48px" src="@/assets/imgs/logo.png" />-->
+<!--          <span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span>-->
+<!--        </div>-->
+<!--        &lt;!&ndash; 左边的背景图 + 欢迎语 &ndash;&gt;-->
+<!--        <div class="h-[calc(100%-60px)] flex items-center justify-center">-->
+<!--          <TransitionGroup-->
+<!--            appear-->
+<!--            enter-active-class="animate__animated animate__bounceInLeft"-->
+<!--            tag="div"-->
+<!--          >-->
+<!--            <img key="1" alt="" class="w-350px" src="@/assets/svgs/login-box-bg.svg" />-->
+<!--            <div key="2" class="text-3xl text-white">{{ t('login.welcome') }}</div>-->
+<!--            <div key="3" class="mt-5 text-14px font-normal text-white">-->
+<!--              {{ t('login.message') }}-->
+<!--            </div>-->
+<!--          </TransitionGroup>-->
+<!--        </div>-->
+<!--      </div>-->
+<!--      <div-->
+<!--        class="relative flex-1 p-30px dark:bg-[var(&#45;&#45;login-bg-color)] lt-sm:p-10px overflow-x-hidden overflow-y-auto"-->
+<!--      >-->
+<!--        &lt;!&ndash; 右上角的主题、语言选择 &ndash;&gt;-->
+<!--        <div-->
+<!--          class="flex items-center justify-between at-2xl:justify-end at-xl:justify-end"-->
+<!--          style="color: var(&#45;&#45;el-text-color-primary);"-->
+<!--        >-->
+<!--          <div class="flex items-center at-2xl:hidden at-xl:hidden">-->
+<!--            <img alt="" class="mr-10px h-48px w-48px" src="@/assets/imgs/logo.png" />-->
+<!--            <span class="text-20px font-bold" >{{ underlineToHump(appStore.getTitle) }}</span>-->
+<!--          </div>-->
+<!--          <div class="flex items-center justify-end space-x-10px h-48px">-->
+<!--            <ThemeSwitch />-->
+<!--            <LocaleDropdown />-->
+<!--          </div>-->
+<!--        </div>-->
+<!--        &lt;!&ndash; 右边的登录界面 &ndash;&gt;-->
+<!--        <Transition appear enter-active-class="animate__animated animate__bounceInRight">-->
+<!--          <div-->
+<!--            class="m-auto h-[calc(100%-60px)] w-[100%] flex items-center at-2xl:max-w-500px at-lg:max-w-500px at-md:max-w-500px at-xl:max-w-500px"-->
+<!--          >-->
+<!--            &lt;!&ndash; 账号登录 &ndash;&gt;-->
+<!--            <LoginForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />-->
+<!--            &lt;!&ndash; 手机登录 &ndash;&gt;-->
+<!--            <MobileForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />-->
+<!--            &lt;!&ndash; 二维码登录 &ndash;&gt;-->
+<!--            <QrCodeForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />-->
+<!--            &lt;!&ndash; 注册 &ndash;&gt;-->
+<!--            <RegisterForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />-->
+<!--            &lt;!&ndash; 三方登录 &ndash;&gt;-->
+<!--            <SSOLoginVue class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />-->
+<!--            &lt;!&ndash; 忘记密码 &ndash;&gt;-->
+<!--            <ForgetPasswordForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />-->
+<!--          </div>-->
+<!--        </Transition>-->
+<!--      </div>-->
+<!--    </div>-->
+<!--  </div>-->
+<!--</template>-->
+<!--<script lang="ts" setup>-->
+<!--import { underlineToHump } from '@/utils'-->
+
+<!--import { useDesign } from '@/hooks/web/useDesign'-->
+<!--import { useAppStore } from '@/store/modules/app'-->
+<!--import { ThemeSwitch } from '@/layout/components/ThemeSwitch'-->
+<!--import { LocaleDropdown } from '@/layout/components/LocaleDropdown'-->
+
+<!--import { LoginForm, MobileForm, QrCodeForm, RegisterForm, SSOLoginVue, ForgetPasswordForm } from './components'-->
+
+<!--defineOptions({ name: 'Login' })-->
+
+<!--const { t } = useI18n()-->
+<!--const appStore = useAppStore()-->
+<!--const { getPrefixCls } = useDesign()-->
+<!--const prefixCls = getPrefixCls('login')-->
+<!--</script>-->
+
+<!--<style lang="scss" scoped>-->
+<!--$prefix-cls: #{$namespace}-login;-->
+
+<!--.#{$prefix-cls} {-->
+<!--  overflow: auto;-->
+
+<!--  &__left {-->
+<!--    &::before {-->
+<!--      position: absolute;-->
+<!--      top: 0;-->
+<!--      left: 0;-->
+<!--      z-index: -1;-->
+<!--      width: 100%;-->
+<!--      height: 100%;-->
+<!--      background-image: url('@/assets/svgs/login-bg.svg');-->
+<!--      background-position: center;-->
+<!--      background-repeat: no-repeat;-->
+<!--      content: '';-->
+<!--    }-->
+<!--  }-->
+<!--}-->
+<!--</style>-->
+
+<!--<style lang="scss">-->
+<!--.dark .login-form {-->
+<!--  .el-divider__text {-->
+<!--    background-color: var(&#45;&#45;login-bg-color);-->
+<!--  }-->
+
+<!--  .el-card {-->
+<!--    background-color: var(&#45;&#45;login-bg-color);-->
+<!--  }-->
+<!--}-->
+<!--</style>-->

+ 521 - 158
src/views/Login/components/LoginForm.vue

@@ -1,3 +1,4 @@
+
 <template>
   <el-form
     v-show="getShow"
@@ -9,17 +10,33 @@
     label-width="120px"
     size="large"
   >
-    <el-row style="display: flex;justify-content: center">
-      <el-image v-if="loginType === 'uname'" :src="imgsaoma" class="clickable-image" alt="扫码登录" title="扫码登录" @click="changeLogin('dingding')"/>
-      <el-image v-if="loginType === 'dingding'" :src="imgreturn" class="clickable-image" alt="返回" title="返回" @click="changeLogin('uname')"/>
-        <el-image :src="img" class=" h-100px" style="margin-top: 16%"/>
-      <div v-if="loginType === 'uname'" style="width: 90%">
-      <el-col :span="24" style="padding-right: 10px; padding-left: 10px; margin-top: 85px">
-        <el-form-item prop="username" >
-          <el-input  v-model="loginData.loginForm.username" :placeholder="t('login.usernamePlaceholder')" type="text" auto-complete="off"  :prefix-icon="iconAvatar"/>
+    <el-row style="margin-right: -10px; margin-left: -10px">
+      <el-col :span="24" style="padding-right: 10px; padding-left: 10px">
+        <el-form-item>
+          <LoginFormTitle style="width: 100%" />
         </el-form-item>
       </el-col>
-      <el-col :span="24" style="padding-right: 10px; padding-left: 10px;margin-top: 15px">
+<!--      <el-col :span="24" style="padding-right: 10px; padding-left: 10px">-->
+<!--        <el-form-item v-if="loginData.tenantEnable === 'true'" prop="tenantName">-->
+<!--          <el-input-->
+<!--            v-model="loginData.loginForm.tenantName"-->
+<!--            :placeholder="t('login.tenantNamePlaceholder')"-->
+<!--            :prefix-icon="iconHouse"-->
+<!--            link-->
+<!--            type="primary"-->
+<!--          />-->
+<!--        </el-form-item>-->
+<!--      </el-col>-->
+      <el-col :span="24" style="padding-right: 10px; padding-left: 10px;margin-top: 30px">
+        <el-form-item prop="username">
+          <el-input
+            v-model="loginData.loginForm.username"
+            :placeholder="t('login.usernamePlaceholder')"
+            :prefix-icon="iconAvatar"
+          />
+        </el-form-item>
+      </el-col>
+      <el-col :span="24" style="padding-right: 10px; padding-left: 10px; margin-top: 15px">
         <el-form-item prop="password">
           <el-input
             v-model="loginData.loginForm.password"
@@ -33,10 +50,10 @@
       </el-col>
       <el-col
         :span="24"
-        style="padding-right: 10px; padding-left: 10px; margin-top: 20px;"
+        style="padding-right: 10px; padding-left: 10px; margin-top: 10px; margin-bottom: -20px"
       >
         <el-form-item>
-          <el-row justify="space-between" style="width: 100%;">
+          <el-row justify="space-between" style="width: 100%">
             <el-col :span="6">
               <el-checkbox v-model="loginData.loginForm.rememberMe">
                 {{ t('login.remember') }}
@@ -54,10 +71,9 @@
           </el-row>
         </el-form-item>
       </el-col>
-      <el-col :span="24" style="padding-right: 10px; padding-left: 10px;margin-bottom: 10px">
+      <el-col :span="24" style="padding-right: 10px; padding-left: 10px">
         <el-form-item>
           <XButton
-            style="height: 4em;background-color: rgb(11, 26, 50);border: none;opacity: 1;color: rgb(186, 205, 224)"
             :loading="loginLoading"
             :title="t('login.login')"
             class="w-[100%]"
@@ -74,129 +90,86 @@
         mode="pop"
         @success="handleLogin"
       />
-      </div>
-      <div v-if="loginType === 'dingding'" id="login_container"  style="margin-left: 8%;margin-top: 18%">
-      </div>
+      <el-col :span="24" style="padding-right: 10px; padding-left: 10px">
+        <el-form-item>
+          <el-row :gutter="5" justify="space-between" style="width: 100%">
+<!--            <el-col :span="8">-->
+<!--              <XButton-->
+<!--                :title="t('login.btnMobile')"-->
+<!--                class="w-[100%]"-->
+<!--                @click="setLoginState(LoginStateEnum.MOBILE)"-->
+<!--              />-->
+<!--            </el-col>-->
+            <el-col :span="24">
+              <XButton
+                :title="t('login.btnQRCode')"
+                class="w-[100%]"
+                @click="setLoginState(LoginStateEnum.QR_CODE)"
+              />
+            </el-col>
+<!--            <el-col :span="12">-->
+<!--              <XButton-->
+<!--                :title="t('login.btnRegister')"-->
+<!--                class="w-[100%]"-->
+<!--                @click="setLoginState(LoginStateEnum.REGISTER)"-->
+<!--              />-->
+<!--            </el-col>-->
+          </el-row>
+        </el-form-item>
+      </el-col>
+<!--      <el-divider content-position="center">{{ t('login.otherLogin') }}</el-divider>-->
+<!--      <el-col :span="24" style="padding-right: 10px; padding-left: 10px">-->
+<!--        <el-form-item>-->
+<!--          <div class="w-[100%] flex justify-between">-->
+<!--            <Icon-->
+<!--              v-for="(item, key) in socialList"-->
+<!--              :key="key"-->
+<!--              :icon="item.icon"-->
+<!--              :size="30"-->
+<!--              class="anticon cursor-pointer"-->
+<!--              color="#999"-->
+<!--              @click="doSocialLogin(item.type)"-->
+<!--            />-->
+<!--          </div>-->
+<!--        </el-form-item>-->
+<!--      </el-col>-->
+<!--      <el-divider content-position="center">萌新必读</el-divider>-->
+<!--      <el-col :span="24" style="padding-right: 10px; padding-left: 10px">-->
+<!--        <el-form-item>-->
+<!--          <div class="w-[100%] flex justify-between">-->
+<!--            <el-link href="https://doc.iocoder.cn/" target="_blank">📚开发指南</el-link>-->
+<!--            <el-link href="https://doc.iocoder.cn/video/" target="_blank">🔥视频教程</el-link>-->
+<!--            <el-link href="https://www.iocoder.cn/Interview/good-collection/" target="_blank">-->
+<!--              ⚡面试手册-->
+<!--            </el-link>-->
+<!--            <el-link href="http://static.yudao.iocoder.cn/mp/Aix9975.jpeg" target="_blank">-->
+<!--              🤝外包咨询-->
+<!--            </el-link>-->
+<!--          </div>-->
+<!--        </el-form-item>-->
+<!--      </el-col>-->
     </el-row>
   </el-form>
 </template>
 <script lang="ts" setup>
-import img from '@/assets/imgs/img.png'
-import imgsaoma from '@/assets/imgs/saoma.png'
-import imgreturn from '@/assets/imgs/return.png'
 import { ElLoading } from 'element-plus'
+import LoginFormTitle from './LoginFormTitle.vue'
 import type { RouteLocationNormalizedLoaded } from 'vue-router'
+
 import { useIcon } from '@/hooks/web/useIcon'
-import * as DictDataApi from '@/api/system/dict/dict.data'
+
 import * as authUtil from '@/utils/auth'
 import { usePermissionStore } from '@/store/modules/permission'
 import * as LoginApi from '@/api/login'
 import { LoginStateEnum, useFormValid, useLoginState } from './useLogin'
 
-import { ref,nextTick,onMounted } from 'vue';
-const appId = 'dingik345qmyhtysvs2x'
-const dingRedirectUrl = 'http://1.94.244.160:91/login?loginType=dingding&type=20'
-
-onMounted(()=>{
-  getTenantName();
-})
-const getTenantName=async ()=>{
-  const queryParams = reactive({
-    pageNo: 1,
-    pageSize: 10,
-    label: '',
-    status: undefined,
-    dictType: 'tenant_name'
-  })
-  const data = await DictDataApi.getDictDataPage(queryParams)
-  loginData.loginForm.tenantName = data.list[0].label;
-}
-const loginType = ref('uname');
-const changeLogin = async (type) => {
-  console.log(loginData.loginForm.tenantName)
-  await getTenantId()
-  loginType.value = type;
-  if (type === 'dingding') {
-    initDingLogin();
-  }
-};
-
-
-const initDingLogin=()=> {
-  // if (window.DDLogin) {
-  var url = dingRedirectUrl
-  var state = _getRandomString(10);
-  var gotoUrl = encodeURIComponent(
-    "https://oapi.dingtalk.com/connect/oauth2/sns_authorize?" +
-    "appid=" + appId +
-    "&response_type=code" +
-    "&scope=snsapi_login" +
-    "&state=" + state +
-    "&redirect_uri=" + url
-  );
-
-  nextTick(() => {
-    var obj = window.DDLogin({
-      id: "login_container",
-      goto: gotoUrl,
-      style: "border:none;background-color:#FFFFFF;",
-      width: '90%', // 二维码的宽度
-      height: "290", // 二维码的高度
-    })
-    // 重置扫码登录框的样式,让登录框居中
-    let box = document.getElementById('login_container')
-    box.querySelector('iframe').style.top = '0'
-    box.querySelector('iframe').style.bottom = '0'
-    box.querySelector('iframe').style.left = '0'
-    box.querySelector('iframe').style.right = '0'
-    box.querySelector('iframe').style.margin = 'auto'
-  })
-
-  /* new window.DDLogin({
-    id: "login_container",
-    goto: gotoUrl,
-    style: "border:none;background-color:#FFFFFF;",
-    width: "350",
-    height: "350",
-  }); */
-  var handleMessage = function (event) {
-    var origin = event.origin;
-    if (origin === "https://login.dingtalk.com") {
-      var loginTmpCode = event.data;
-      console.log(loginTmpCode)
-      window.location.href =
-        "https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=dingik345qmyhtysvs2x&response_type=code&scope=snsapi_login&state=" +
-        state +
-        "&redirect_uri=" +
-        url +
-        "&loginTmpCode=" +
-        loginTmpCode;
-    }
-  };
-  if (typeof window.addEventListener != "undefined") {
-    window.addEventListener("message", handleMessage, false);
-  } else if (typeof window.attachEvent != "undefined") {
-    window.attachEvent("onmessage", handleMessage);
-  }
-  // }
-}
-const _getRandomString=(len)=> {
-  len = len || 10;
-  let $chars = "ABCDEFGHIJKMNOPQRSTUVWXYZ"; // 默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1
-  let maxPos = $chars.length;
-  let pwd = "";
-  for (var i = 0; i < len; i++) {
-    pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
-  }
-  return pwd;
-}
 defineOptions({ name: 'LoginForm' })
 
 const { t } = useI18n()
 const message = useMessage()
 const iconHouse = useIcon({ icon: 'ep:house' })
-const iconAvatar = useIcon({ icon: 'ep:avatar',size:26 })
-const iconLock = useIcon({ icon: 'ep:lock',size:26 })
+const iconAvatar = useIcon({ icon: 'ep:avatar' })
+const iconLock = useIcon({ icon: 'ep:lock' })
 const formLogin = ref()
 const { validForm } = useFormValid(formLogin)
 const { setLoginState, getLoginState } = useLoginState()
@@ -219,7 +192,7 @@ const loginData = reactive({
   captchaEnable: import.meta.env.VITE_APP_CAPTCHA_ENABLE,
   tenantEnable: import.meta.env.VITE_APP_TENANT_ENABLE,
   loginForm: {
-    tenantName: '瑞气能源',
+    tenantName: import.meta.env.VITE_APP_DEFAULT_LOGIN_TENANT || '',
     username: import.meta.env.VITE_APP_DEFAULT_LOGIN_USERNAME || '',
     password: import.meta.env.VITE_APP_DEFAULT_LOGIN_PASSWORD || '',
     captchaVerification: '',
@@ -227,12 +200,12 @@ const loginData = reactive({
   }
 })
 
-// const socialList = [
-//   { icon: 'ant-design:wechat-filled', type: 30 },
-//   { icon: 'ant-design:dingtalk-circle-filled', type: 20 },
-//   { icon: 'ant-design:github-filled', type: 0 },
-//   { icon: 'ant-design:alipay-circle-filled', type: 0 }
-// ]
+const socialList = [
+  { icon: 'ant-design:wechat-filled', type: 30 },
+  { icon: 'ant-design:dingtalk-circle-filled', type: 20 },
+  { icon: 'ant-design:github-filled', type: 0 },
+  { icon: 'ant-design:alipay-circle-filled', type: 0 }
+]
 
 // 获取验证码
 const getCode = async () => {
@@ -317,6 +290,40 @@ const handleLogin = async (params: any) => {
 }
 
 // 社交登录
+const doSocialLogin = async (type: number) => {
+  if (type === 0) {
+    message.error('此方式未配置')
+  } else {
+    loginLoading.value = true
+    if (loginData.tenantEnable === 'true') {
+      // 尝试先通过 tenantName 获取租户
+      await getTenantId()
+      // 如果获取不到,则需要弹出提示,进行处理
+      if (!authUtil.getTenantId()) {
+        try {
+          const data = await message.prompt('请输入租户名称', t('common.reminder'))
+          if (data?.action !== 'confirm') throw 'cancel'
+          const res = await LoginApi.getTenantIdByName(data.value)
+          authUtil.setTenantId(res)
+        } catch (error) {
+          if (error === 'cancel') return
+        } finally {
+          loginLoading.value = false
+        }
+      }
+    }
+    // 计算 redirectUri
+    // tricky: type、redirect需要先encode一次,否则钉钉回调会丢失。
+    // 配合 Login/SocialLogin.vue#getUrlValue() 使用
+    const redirectUri =
+      location.origin +
+      '/social-login?' +
+      encodeURIComponent(`type=${type}&redirect=${redirect.value || '/'}`)
+
+    // 进行跳转
+    window.location.href = await LoginApi.socialAuthRedirect(type, encodeURIComponent(redirectUri))
+  }
+}
 watch(
   () => currentRoute.value,
   (route: RouteLocationNormalizedLoaded) => {
@@ -333,16 +340,6 @@ onMounted(() => {
 </script>
 
 <style lang="scss" scoped>
-::v-deep .el-input__wrapper {
-  background-color: transparent !important;
-  height: 3.5em;
-  color: white;
-  box-shadow: none !important;
-  border-radius: 0;
-  border: none !important;
-  border-bottom: 1px solid #bacde0 !important;
-  outline: none;
-}
 :deep(.anticon) {
   &:hover {
     color: var(--el-color-primary) !important;
@@ -362,26 +359,392 @@ onMounted(() => {
     cursor: pointer;
   }
 }
-::v-deep .rqinput .el-input__inner  {
-  background-color: transparent !important;
-  border: none !important;
-  border-bottom: 1px solid rgb(186, 205, 224) !important;
-  border-radius: 0;
-  height: 2.8em;
-  //left: 18%;
-  padding-left: 3em;
-  color: white;
-}
-.clickable-image {
-  cursor: pointer;
-  position:absolute;
-  //top: 2%;
-  //right: 2%;
-  width: 6%;
-  margin-top: -9%;
-  margin-left: 111%;
-}
-::v-deep .el-input__inner {
-  color: white;
-}
 </style>
+
+<!--<template>-->
+<!--  <el-form-->
+<!--    v-show="getShow"-->
+<!--    ref="formLogin"-->
+<!--    :model="loginData.loginForm"-->
+<!--    :rules="LoginRules"-->
+<!--    class="login-form"-->
+<!--    label-position="top"-->
+<!--    label-width="120px"-->
+<!--    size="large"-->
+<!--  >-->
+<!--    <el-row style="display: flex;justify-content: center">-->
+<!--      <el-image v-if="loginType === 'uname'" :src="imgsaoma" class="clickable-image" alt="扫码登录" title="扫码登录" @click="changeLogin('dingding')"/>-->
+<!--      <el-image v-if="loginType === 'dingding'" :src="imgreturn" class="clickable-image" alt="返回" title="返回" @click="changeLogin('uname')"/>-->
+<!--        <el-image :src="img" class=" h-100px" style="margin-top: 16%"/>-->
+<!--      <div v-if="loginType === 'uname'" style="width: 90%">-->
+<!--      <el-col :span="24" style="padding-right: 10px; padding-left: 10px; margin-top: 85px">-->
+<!--        <el-form-item prop="username" >-->
+<!--          <el-input  v-model="loginData.loginForm.username" :placeholder="t('login.usernamePlaceholder')" type="text" auto-complete="off"  :prefix-icon="iconAvatar"/>-->
+<!--        </el-form-item>-->
+<!--      </el-col>-->
+<!--      <el-col :span="24" style="padding-right: 10px; padding-left: 10px;margin-top: 15px">-->
+<!--        <el-form-item prop="password">-->
+<!--          <el-input-->
+<!--            v-model="loginData.loginForm.password"-->
+<!--            :placeholder="t('login.passwordPlaceholder')"-->
+<!--            :prefix-icon="iconLock"-->
+<!--            show-password-->
+<!--            type="password"-->
+<!--            @keyup.enter="getCode()"-->
+<!--          />-->
+<!--        </el-form-item>-->
+<!--      </el-col>-->
+<!--      <el-col-->
+<!--        :span="24"-->
+<!--        style="padding-right: 10px; padding-left: 10px; margin-top: 20px;"-->
+<!--      >-->
+<!--        <el-form-item>-->
+<!--          <el-row justify="space-between" style="width: 100%;">-->
+<!--            <el-col :span="6">-->
+<!--              <el-checkbox v-model="loginData.loginForm.rememberMe">-->
+<!--                {{ t('login.remember') }}-->
+<!--              </el-checkbox>-->
+<!--            </el-col>-->
+<!--            <el-col :offset="6" :span="12">-->
+<!--              <el-link-->
+<!--                style="float: right"-->
+<!--                type="primary"-->
+<!--                @click="setLoginState(LoginStateEnum.RESET_PASSWORD)"-->
+<!--              >-->
+<!--                {{ t('login.forgetPassword') }}-->
+<!--              </el-link>-->
+<!--            </el-col>-->
+<!--          </el-row>-->
+<!--        </el-form-item>-->
+<!--      </el-col>-->
+<!--      <el-col :span="24" style="padding-right: 10px; padding-left: 10px;margin-bottom: 10px">-->
+<!--        <el-form-item>-->
+<!--          <XButton-->
+<!--            style="height: 4em;background-color: rgb(11, 26, 50);border: none;opacity: 1;color: rgb(186, 205, 224)"-->
+<!--            :loading="loginLoading"-->
+<!--            :title="t('login.login')"-->
+<!--            class="w-[100%]"-->
+<!--            type="primary"-->
+<!--            @click="getCode()"-->
+<!--          />-->
+<!--        </el-form-item>-->
+<!--      </el-col>-->
+<!--      <Verify-->
+<!--        v-if="loginData.captchaEnable === 'true'"-->
+<!--        ref="verify"-->
+<!--        :captchaType="captchaType"-->
+<!--        :imgSize="{ width: '400px', height: '200px' }"-->
+<!--        mode="pop"-->
+<!--        @success="handleLogin"-->
+<!--      />-->
+<!--      </div>-->
+<!--      <div v-if="loginType === 'dingding'" id="login_container"  style="margin-left: 8%;margin-top: 18%">-->
+<!--      </div>-->
+<!--    </el-row>-->
+<!--  </el-form>-->
+<!--</template>-->
+<!--<script lang="ts" setup>-->
+<!--import img from '@/assets/imgs/img.png'-->
+<!--import imgsaoma from '@/assets/imgs/saoma.png'-->
+<!--import imgreturn from '@/assets/imgs/return.png'-->
+<!--import { ElLoading } from 'element-plus'-->
+<!--import type { RouteLocationNormalizedLoaded } from 'vue-router'-->
+<!--import { useIcon } from '@/hooks/web/useIcon'-->
+<!--import * as DictDataApi from '@/api/system/dict/dict.data'-->
+<!--import * as authUtil from '@/utils/auth'-->
+<!--import { usePermissionStore } from '@/store/modules/permission'-->
+<!--import * as LoginApi from '@/api/login'-->
+<!--import { LoginStateEnum, useFormValid, useLoginState } from './useLogin'-->
+
+<!--import { ref,nextTick,onMounted } from 'vue';-->
+<!--const appId = 'dingik345qmyhtysvs2x'-->
+<!--const dingRedirectUrl = 'http://1.94.244.160:91/login?loginType=dingding&type=20'-->
+
+<!--onMounted(()=>{-->
+<!--  getTenantName();-->
+<!--})-->
+<!--const getTenantName=async ()=>{-->
+<!--  const queryParams = reactive({-->
+<!--    pageNo: 1,-->
+<!--    pageSize: 10,-->
+<!--    label: '',-->
+<!--    status: undefined,-->
+<!--    dictType: 'tenant_name'-->
+<!--  })-->
+<!--  const data = await DictDataApi.getDictDataPage(queryParams)-->
+<!--  loginData.loginForm.tenantName = data.list[0].label;-->
+<!--}-->
+<!--const loginType = ref('uname');-->
+<!--const changeLogin = async (type) => {-->
+<!--  console.log(loginData.loginForm.tenantName)-->
+<!--  await getTenantId()-->
+<!--  loginType.value = type;-->
+<!--  if (type === 'dingding') {-->
+<!--    initDingLogin();-->
+<!--  }-->
+<!--};-->
+
+
+<!--const initDingLogin=()=> {-->
+<!--  // if (window.DDLogin) {-->
+<!--  var url = dingRedirectUrl-->
+<!--  var state = _getRandomString(10);-->
+<!--  var gotoUrl = encodeURIComponent(-->
+<!--    "https://oapi.dingtalk.com/connect/oauth2/sns_authorize?" +-->
+<!--    "appid=" + appId +-->
+<!--    "&response_type=code" +-->
+<!--    "&scope=snsapi_login" +-->
+<!--    "&state=" + state +-->
+<!--    "&redirect_uri=" + url-->
+<!--  );-->
+
+<!--  nextTick(() => {-->
+<!--    var obj = window.DDLogin({-->
+<!--      id: "login_container",-->
+<!--      goto: gotoUrl,-->
+<!--      style: "border:none;background-color:#FFFFFF;",-->
+<!--      width: '90%', // 二维码的宽度-->
+<!--      height: "290", // 二维码的高度-->
+<!--    })-->
+<!--    // 重置扫码登录框的样式,让登录框居中-->
+<!--    let box = document.getElementById('login_container')-->
+<!--    box.querySelector('iframe').style.top = '0'-->
+<!--    box.querySelector('iframe').style.bottom = '0'-->
+<!--    box.querySelector('iframe').style.left = '0'-->
+<!--    box.querySelector('iframe').style.right = '0'-->
+<!--    box.querySelector('iframe').style.margin = 'auto'-->
+<!--  })-->
+
+<!--  /* new window.DDLogin({-->
+<!--    id: "login_container",-->
+<!--    goto: gotoUrl,-->
+<!--    style: "border:none;background-color:#FFFFFF;",-->
+<!--    width: "350",-->
+<!--    height: "350",-->
+<!--  }); */-->
+<!--  var handleMessage = function (event) {-->
+<!--    var origin = event.origin;-->
+<!--    if (origin === "https://login.dingtalk.com") {-->
+<!--      var loginTmpCode = event.data;-->
+<!--      console.log(loginTmpCode)-->
+<!--      window.location.href =-->
+<!--        "https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=dingik345qmyhtysvs2x&response_type=code&scope=snsapi_login&state=" +-->
+<!--        state +-->
+<!--        "&redirect_uri=" +-->
+<!--        url +-->
+<!--        "&loginTmpCode=" +-->
+<!--        loginTmpCode;-->
+<!--    }-->
+<!--  };-->
+<!--  if (typeof window.addEventListener != "undefined") {-->
+<!--    window.addEventListener("message", handleMessage, false);-->
+<!--  } else if (typeof window.attachEvent != "undefined") {-->
+<!--    window.attachEvent("onmessage", handleMessage);-->
+<!--  }-->
+<!--  // }-->
+<!--}-->
+<!--const _getRandomString=(len)=> {-->
+<!--  len = len || 10;-->
+<!--  let $chars = "ABCDEFGHIJKMNOPQRSTUVWXYZ"; // 默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1-->
+<!--  let maxPos = $chars.length;-->
+<!--  let pwd = "";-->
+<!--  for (var i = 0; i < len; i++) {-->
+<!--    pwd += $chars.charAt(Math.floor(Math.random() * maxPos));-->
+<!--  }-->
+<!--  return pwd;-->
+<!--}-->
+<!--defineOptions({ name: 'LoginForm' })-->
+
+<!--const { t } = useI18n()-->
+<!--const message = useMessage()-->
+<!--const iconHouse = useIcon({ icon: 'ep:house' })-->
+<!--const iconAvatar = useIcon({ icon: 'ep:avatar',size:26 })-->
+<!--const iconLock = useIcon({ icon: 'ep:lock',size:26 })-->
+<!--const formLogin = ref()-->
+<!--const { validForm } = useFormValid(formLogin)-->
+<!--const { setLoginState, getLoginState } = useLoginState()-->
+<!--const { currentRoute, push } = useRouter()-->
+<!--const permissionStore = usePermissionStore()-->
+<!--const redirect = ref<string>('')-->
+<!--const loginLoading = ref(false)-->
+<!--const verify = ref()-->
+<!--const captchaType = ref('blockPuzzle') // blockPuzzle 滑块 clickWord 点击文字-->
+
+<!--const getShow = computed(() => unref(getLoginState) === LoginStateEnum.LOGIN)-->
+
+<!--const LoginRules = {-->
+<!--  tenantName: [required],-->
+<!--  username: [required],-->
+<!--  password: [required]-->
+<!--}-->
+<!--const loginData = reactive({-->
+<!--  isShowPassword: false,-->
+<!--  captchaEnable: import.meta.env.VITE_APP_CAPTCHA_ENABLE,-->
+<!--  tenantEnable: import.meta.env.VITE_APP_TENANT_ENABLE,-->
+<!--  loginForm: {-->
+<!--    tenantName: '瑞气能源',-->
+<!--    username: import.meta.env.VITE_APP_DEFAULT_LOGIN_USERNAME || '',-->
+<!--    password: import.meta.env.VITE_APP_DEFAULT_LOGIN_PASSWORD || '',-->
+<!--    captchaVerification: '',-->
+<!--    rememberMe: true // 默认记录我。如果不需要,可手动修改-->
+<!--  }-->
+<!--})-->
+
+<!--// const socialList = [-->
+<!--//   { icon: 'ant-design:wechat-filled', type: 30 },-->
+<!--//   { icon: 'ant-design:dingtalk-circle-filled', type: 20 },-->
+<!--//   { icon: 'ant-design:github-filled', type: 0 },-->
+<!--//   { icon: 'ant-design:alipay-circle-filled', type: 0 }-->
+<!--// ]-->
+
+<!--// 获取验证码-->
+<!--const getCode = async () => {-->
+<!--  // 情况一,未开启:则直接登录-->
+<!--  if (loginData.captchaEnable === 'false') {-->
+<!--    await handleLogin({})-->
+<!--  } else {-->
+<!--    // 情况二,已开启:则展示验证码;只有完成验证码的情况,才进行登录-->
+<!--    // 弹出验证码-->
+<!--    verify.value.show()-->
+<!--  }-->
+<!--}-->
+<!--// 获取租户 ID-->
+<!--const getTenantId = async () => {-->
+<!--  if (loginData.tenantEnable === 'true') {-->
+<!--    const res = await LoginApi.getTenantIdByName(loginData.loginForm.tenantName)-->
+<!--    authUtil.setTenantId(res)-->
+<!--  }-->
+<!--}-->
+<!--// 记住我-->
+<!--const getLoginFormCache = () => {-->
+<!--  const loginForm = authUtil.getLoginForm()-->
+<!--  if (loginForm) {-->
+<!--    loginData.loginForm = {-->
+<!--      ...loginData.loginForm,-->
+<!--      username: loginForm.username ? loginForm.username : loginData.loginForm.username,-->
+<!--      password: loginForm.password ? loginForm.password : loginData.loginForm.password,-->
+<!--      rememberMe: loginForm.rememberMe,-->
+<!--      tenantName: loginForm.tenantName ? loginForm.tenantName : loginData.loginForm.tenantName-->
+<!--    }-->
+<!--  }-->
+<!--}-->
+<!--// 根据域名,获得租户信息-->
+<!--const getTenantByWebsite = async () => {-->
+<!--  const website = location.host-->
+<!--  const res = await LoginApi.getTenantByWebsite(website)-->
+<!--  if (res) {-->
+<!--    loginData.loginForm.tenantName = res.name-->
+<!--    authUtil.setTenantId(res.id)-->
+<!--  }-->
+<!--}-->
+<!--const loading = ref() // ElLoading.service 返回的实例-->
+<!--// 登录-->
+<!--const handleLogin = async (params: any) => {-->
+<!--  loginLoading.value = true-->
+<!--  try {-->
+<!--    await getTenantId()-->
+<!--    const data = await validForm()-->
+<!--    if (!data) {-->
+<!--      return-->
+<!--    }-->
+<!--    const loginDataLoginForm = { ...loginData.loginForm }-->
+<!--    loginDataLoginForm.captchaVerification = params.captchaVerification-->
+<!--    const res = await LoginApi.login(loginDataLoginForm)-->
+<!--    if (!res) {-->
+<!--      return-->
+<!--    }-->
+<!--    loading.value = ElLoading.service({-->
+<!--      lock: true,-->
+<!--      text: '正在加载系统中...',-->
+<!--      background: 'rgba(0, 0, 0, 0.7)'-->
+<!--    })-->
+<!--    if (loginDataLoginForm.rememberMe) {-->
+<!--      authUtil.setLoginForm(loginDataLoginForm)-->
+<!--    } else {-->
+<!--      authUtil.removeLoginForm()-->
+<!--    }-->
+<!--    authUtil.setToken(res)-->
+<!--    if (!redirect.value) {-->
+<!--      redirect.value = '/'-->
+<!--    }-->
+<!--    // 判断是否为SSO登录-->
+<!--    if (redirect.value.indexOf('sso') !== -1) {-->
+<!--      window.location.href = window.location.href.replace('/login?redirect=', '')-->
+<!--    } else {-->
+<!--      await push({ path: redirect.value || permissionStore.addRouters[0].path })-->
+<!--    }-->
+<!--  } finally {-->
+<!--    loginLoading.value = false-->
+<!--    loading.value.close()-->
+<!--  }-->
+<!--}-->
+
+<!--// 社交登录-->
+<!--watch(-->
+<!--  () => currentRoute.value,-->
+<!--  (route: RouteLocationNormalizedLoaded) => {-->
+<!--    redirect.value = route?.query?.redirect as string-->
+<!--  },-->
+<!--  {-->
+<!--    immediate: true-->
+<!--  }-->
+<!--)-->
+<!--onMounted(() => {-->
+<!--  getLoginFormCache()-->
+<!--  getTenantByWebsite()-->
+<!--})-->
+<!--</script>-->
+
+<!--<style lang="scss" scoped>-->
+<!--::v-deep .el-input__wrapper {-->
+<!--  background-color: transparent !important;-->
+<!--  height: 3.5em;-->
+<!--  color: white;-->
+<!--  box-shadow: none !important;-->
+<!--  border-radius: 0;-->
+<!--  border: none !important;-->
+<!--  border-bottom: 1px solid #bacde0 !important;-->
+<!--  outline: none;-->
+<!--}-->
+<!--:deep(.anticon) {-->
+<!--  &:hover {-->
+<!--    color: var(&#45;&#45;el-color-primary) !important;-->
+<!--  }-->
+<!--}-->
+
+<!--.login-code {-->
+<!--  float: right;-->
+<!--  width: 100%;-->
+<!--  height: 38px;-->
+
+<!--  img {-->
+<!--    width: 100%;-->
+<!--    height: auto;-->
+<!--    max-width: 100px;-->
+<!--    vertical-align: middle;-->
+<!--    cursor: pointer;-->
+<!--  }-->
+<!--}-->
+<!--::v-deep .rqinput .el-input__inner  {-->
+<!--  background-color: transparent !important;-->
+<!--  border: none !important;-->
+<!--  border-bottom: 1px solid rgb(186, 205, 224) !important;-->
+<!--  border-radius: 0;-->
+<!--  height: 2.8em;-->
+<!--  //left: 18%;-->
+<!--  padding-left: 3em;-->
+<!--  color: white;-->
+<!--}-->
+<!--.clickable-image {-->
+<!--  cursor: pointer;-->
+<!--  position:absolute;-->
+<!--  //top: 2%;-->
+<!--  //right: 2%;-->
+<!--  width: 6%;-->
+<!--  margin-top: -9%;-->
+<!--  margin-left: 111%;-->
+<!--}-->
+<!--::v-deep .el-input__inner {-->
+<!--  color: white;-->
+<!--}-->
+<!--</style>-->

+ 78 - 2
src/views/Login/components/QrCodeForm.vue

@@ -5,10 +5,11 @@
     </el-col>
     <el-col :span="24" style="padding-right: 10px; padding-left: 10px">
       <el-card class="mb-10px text-center" shadow="hover">
-        <Qrcode :logo="logoImg" />
+<!--        <Qrcode :logo="logoImg" />-->
+        <div id="login_container" ></div>
       </el-card>
     </el-col>
-    <el-divider class="enter-x">{{ t('login.qrcode') }}</el-divider>
+<!--    <el-divider class="enter-x">{{ t('login.qrcode') }}</el-divider>-->
     <el-col :span="24" style="padding-right: 10px; padding-left: 10px">
       <div class="mt-15px w-[100%]">
         <XButton :title="t('login.backLogin')" class="w-[100%]" @click="handleBackLogin()" />
@@ -27,4 +28,79 @@ defineOptions({ name: 'QrCodeForm' })
 const { t } = useI18n()
 const { handleBackLogin, getLoginState } = useLoginState()
 const getShow = computed(() => unref(getLoginState) === LoginStateEnum.QR_CODE)
+
+const appId = 'dingik345qmyhtysvs2x'
+const dingRedirectUrl = 'http://1.94.244.160:91/login?loginType=dingding&type=20'
+
+onMounted(()=>{
+  initDingLogin()
+})
+const _getRandomString=(len)=> {
+  len = len || 10;
+  let $chars = "ABCDEFGHIJKMNOPQRSTUVWXYZ"; // 默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1
+  let maxPos = $chars.length;
+  let pwd = "";
+  for (var i = 0; i < len; i++) {
+    pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
+  }
+  return pwd;
+}
+const initDingLogin=()=> {
+  // if (window.DDLogin) {
+  var url = dingRedirectUrl
+  var state = _getRandomString(10);
+  var gotoUrl = encodeURIComponent(
+    "https://oapi.dingtalk.com/connect/oauth2/sns_authorize?" +
+    "appid=" + appId +
+    "&response_type=code" +
+    "&scope=snsapi_login" +
+    "&state=" + state +
+    "&redirect_uri=" + url
+  );
+
+  nextTick(() => {
+    var obj = window.DDLogin({
+      id: "login_container",
+      goto: gotoUrl,
+      style: "border:none;background-color:#FFFFFF;",
+      width: '100%', // 二维码的宽度
+      height: "290", // 二维码的高度
+    })
+    // 重置扫码登录框的样式,让登录框居中
+    let box = document.getElementById('login_container')
+    box.querySelector('iframe').style.top = '0'
+    box.querySelector('iframe').style.bottom = '0'
+    box.querySelector('iframe').style.left = '0'
+    box.querySelector('iframe').style.right = '0'
+    box.querySelector('iframe').style.margin = 'auto'
+  })
+
+  /* new window.DDLogin({
+    id: "login_container",
+    goto: gotoUrl,
+    style: "border:none;background-color:#FFFFFF;",
+    width: "350",
+    height: "350",
+  }); */
+  var handleMessage = function (event) {
+    var origin = event.origin;
+    if (origin === "https://login.dingtalk.com") {
+      var loginTmpCode = event.data;
+      console.log(loginTmpCode)
+      window.location.href =
+        "https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=dingik345qmyhtysvs2x&response_type=code&scope=snsapi_login&state=" +
+        state +
+        "&redirect_uri=" +
+        url +
+        "&loginTmpCode=" +
+        loginTmpCode;
+    }
+  };
+  if (typeof window.addEventListener != "undefined") {
+    window.addEventListener("message", handleMessage, false);
+  } else if (typeof window.attachEvent != "undefined") {
+    window.attachEvent("onmessage", handleMessage);
+  }
+  // }
+}
 </script>