vue3+ts封装钉钉扫码登录

2022-01-12 22:37
椰子皮
2053
0
0
vue

最近做到一个vue3+typescript的后台管理需要使用钉钉扫码登录,官方给的示例实在太烂了,于是自己整理了一下

新建一个dingtalk.ts文件

/**
 * 钉钉扫码登录
 * @version 2021-11-09 zzc
 */
import UserApi, { DingtalkLoginConfig } from '@/api/user'
import cookide from '@/utils/cookie'
import config from '@/config'

class Dingtalk {
  goto: string
  backUrl: string
  state: number
  urlPreffix: string
  appid: string
  domain: string

  constructor() {
    // 文档地址:https://open.dingtalk.com/document/orgapp-server/scan-qr-code-to-log-on-to-third-party-websites
    this.state = Math.random()
    this.appid = config.IS_TEST ? '测试环境appid' : '正式环境appid'
    this.domain = config.IS_TEST ? '测试域名' : '正式域名'
    this.urlPreffix = `https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=${this.appid}&response_type=code&scope=snsapi_login&state=`
    this.backUrl = encodeURIComponent(`${this.domain}appadmin/#/login`) // 扫码后跳转的地址
    this.goto = `${this.urlPreffix}${this.state}&redirect_uri=${this.backUrl}`
  }

  /**
   * 初始化钉钉二维码
   * @version 2023-06-19 zzc
   * @param { String } codeId 显示二维码的id
   * @param { Function } callback 回调
   */
   public init(codeId: string, callback?: Function) {
    const scriptEle = document.createElement('script')
    const win: any = window

    const handleMessage = (event: any) => {
      const { origin, data } = event
      if (origin === 'https://login.dingtalk.com') {
        const redirectUri = `${this.goto}&loginTmpCode=${data}`
        if (win.parent === window ) {
          parent.location.href = redirectUri
        } else {
          win.parent.location.href = redirectUri
        }
      }
    }
    scriptEle.id = 'dinglogin'
    scriptEle.src = 'https://g.alicdn.com/dingding/dinglogin/0.0.5/ddLogin.js'
    document.head.appendChild(scriptEle)

    scriptEle.onload = () => {
      // @ts-ignore
      DDLogin({
        id: codeId,
        goto: encodeURIComponent(this.goto),
        style: 'background-color: transparent;border: none',
        with: '210',
        height: '310'
      })
      callback && callback()
    }

    if (typeof win.addEventListener !== 'undefined') {
      win.addEventListener('message', handleMessage, false)
    } else if (typeof win.attachEvent !== 'undefined') {
      win.attachEvent('onmessage', handleMessage)
    }
    
  }

  /**
   * 钉钉扫码登陆
   * @param { Object } params 参数对象
   * @param { String } params.code code
   * @param { Object } params.state state
   * @version 2021-11-09 zzc
   */
  public async login(params: DingtalkLoginConfig) {
    const { code, state } = params
    if (!code || !state) {
      return
    }
    // UserApi.dingtalkLogin 是请求后端接口,这里改成你自己的
    const { result } = await UserApi.dingtalkLogin(params)
    // 这里进行扫码成功后的操作
    return result
  }

}

export default new Dingtalk();

 

在vue中使用

 

<script lang="ts" setup>
import { onMounted, nextTick } from 'vue'
import dingtalk from '@/utils/dingtalk'
import { useRoute } from 'vue-router'

const route = useRoute()

dingtalk.init('dingtalk-qrcode', () => {
  // 加载完的回调
  showCode.value = false
})

</script>
<templete>
  <div id="dingtalk-qrcode"></div>
</templete>

 

支付宝微信
0
关注公众号获取更多内容
聊聊javascript中算法时间复杂度,空间复杂度
结合lazyload实现文章页里面的图片预加载
暂无评论,快抢沙发吧
不支持canvas
春季
夏季
秋季
冬季
暗黑
简约
小清新