ts写一个微信授权的公用方法

758 阅读1分钟

下载 weixin-js-sdk-ts

yarn add weixin-js-sdk-ts

判断是否微信浏览器

/**
 * [iswx 判断是否微信浏览器]
 */
export function iswx() {
  const ua = window.navigator.userAgent.toLowerCase()
  return !!ua.match(/MicroMessenger/i)
}

判断ios

export function isIos() {
  return !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
}

调用微信授权登录

/**
 * 调用微信授权登录 h5调用
 * @param {} redirect 回调链接
 * @param {*} state 额外参数
 */
export function wxOAuth2(redirect = location.href, state = '') {
  const AuthBase = 'https://open.weixin.qq.com/connect/oauth2/authorize?'
  const appid = import.meta.env.VITE_APP_WX_APPID
  const redirect_uri = encodeURIComponent(getWxOAuth2Location(redirect))
  const response_type = 'code'
  const scope = 'snsapi_userinfo'
  const result =
    AuthBase +
    `appid=${appid}&redirect_uri=${redirect_uri}&response_type=${response_type}&scope=${scope}&state=${state}#wechat_redirect`
  location.href = result
}

// 删除链接中的`code`query参数
export function getWxOAuth2Location(href: string) {
  const query = getQueryObject(href)
  delete query.code
  const queryStr = Object.entries(query)
    .map(([k, v]) => `${k}=${v}`)
    .join('&')
  return href.split('?')[0] + (queryStr ? '?' + queryStr : '')
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function getQueryObject(url: string) {
  url = url == null ? window.location.href : url
  const search = url.substring(url.lastIndexOf('?') + 1)
  const obj: any = {}
  const reg = /([^?&=]+)=([^?&=]*)/g
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1)
    let val = decodeURIComponent($2)
    val = String(val)
    obj[name] = val
    return rs
  })
  return obj
}

微信 signature 核心方法


class WXAPI{
  constructor() {}
  public signatured = false
  public isIos = isIos()
  public isWx = iswx()
  private iosFirstSignatureLink = ''
  // 保存ios第一次进入系统的链接
  saveIosFirstLink() { /**/ }

  // 微信授权
  async signature() { /**/ }

  // 微信分享 
  async share() { /**/ }

  // 微信支付
  async pay(data: any) { /**/ }
}

完整授权方法


import wx from 'weixin-js-sdk-ts'
import { wxSinature } from '@/api/datas'

export class WXAPI {
  constructor() {}
  public signatured = false
  public isIos = isIos()
  public isWx = iswx()
  private iosFirstSignatureLink = ''
  // 保存ios第一次进入系统的链接
  saveIosFirstLink() {
    if (this.isIos && !this.iosFirstSignatureLink) {
      this.iosFirstSignatureLink = location.href
    }
  }
  /**
   * [wxRegister 微信Api初始化]
   */
  async signature() {
    const vm = this
    const href = this.isIos ? this.iosFirstSignatureLink : location.href
    if (this.isIos && this.signatured) {
      return Promise.resolve()
    }
    // const href = location.href
    console.log('signature~~')
    const { data: config } = await wxSinature(href)
    return new Promise((resolve, reject) => {
      wx.config({
        debug: false, // 开启调试模式
        appId: config.appId, // 必填,公众号的唯一标识
        timestamp: config.timeStamp, // 必填,生成签名的时间戳
        nonceStr: config.nonceStr, // 必填,生成签名的随机串
        signature: config.signature, // 必填,签名,见附录1
        jsApiList: [
          'onMenuShareTimeline',
          'onMenuShareAppMessage',
          'updateAppMessageShareData',
          'updateTimelineShareData',
          'chooseWXPay',
        ],
        openTagList: [],
      })
      wx.ready(function () {
        vm.signatured = true
        resolve(1)
      })
      wx.error(function (err) {
        reject(err)
      })
    })
  }

  /**
   * 微信分享
   * @param {*}
   */
  async share(option: ShareOptionType) {
    if (!this.isWx) return false
    await this.signature()

    ShareTimeline(option)
    ShareAppMessage(option)
  }

  async pay(data: any) {
    if (!this.isWx) return Promise.reject()
    await this.signature()
    return new Promise((resolve, reject) => {
      wx.chooseWXPay({
        timestamp: data.timeStamp,
        nonceStr: data.nonceStr,
        package: data.package,
        signType: data.signType,
        paySign: data.paySign,
        success: function () {
          resolve(1)
        },
        fail: function (err) {
          reject(err)
        },
        cancel: function (err) {
          reject(err)
        },
      })
    })
  }
}

export default new WXAPI()

完整文件

import wx from 'weixin-js-sdk-ts'
import { wxSinature } from '@/api/datas'

export class WXAPI {
  constructor() {}
  public signatured = false
  public isIos = isIos()
  public isWx = iswx()
  private iosFirstSignatureLink = ''
  // 保存ios第一次进入系统的链接
  saveIosFirstLink() {
    if (this.isIos && !this.iosFirstSignatureLink) {
      this.iosFirstSignatureLink = location.href
    }
  }
  /**
   * [wxRegister 微信Api初始化]
   */
  async signature() {
    const vm = this
    const href = this.isIos ? this.iosFirstSignatureLink : location.href
    if (this.isIos && this.signatured) {
      return Promise.resolve()
    }
    // const href = location.href
    console.log('signature~~')
    const { data: config } = await wxSinature(href)
    return new Promise((resolve, reject) => {
      wx.config({
        debug: false, // 开启调试模式
        appId: config.appId, // 必填,公众号的唯一标识
        timestamp: config.timeStamp, // 必填,生成签名的时间戳
        nonceStr: config.nonceStr, // 必填,生成签名的随机串
        signature: config.signature, // 必填,签名,见附录1
        jsApiList: [
          'onMenuShareTimeline',
          'onMenuShareAppMessage',
          'updateAppMessageShareData',
          'updateTimelineShareData',
          'chooseWXPay',
        ],
        openTagList: [],
      })
      wx.ready(function () {
        vm.signatured = true
        resolve(1)
      })
      wx.error(function (err) {
        reject(err)
      })
    })
  }

  /**
   * 微信分享
   * @param {*}
   */
  async share(option: ShareOptionType) {
    if (!this.isWx) return false
    await this.signature()

    ShareTimeline(option)
    ShareAppMessage(option)
  }

  async pay(data: any) {
    if (!this.isWx) return Promise.reject()
    await this.signature()
    return new Promise((resolve, reject) => {
      wx.chooseWXPay({
        timestamp: data.timeStamp,
        nonceStr: data.nonceStr,
        package: data.package,
        signType: data.signType,
        paySign: data.paySign,
        success: function () {
          resolve(1)
        },
        fail: function (err) {
          reject(err)
        },
        cancel: function (err) {
          reject(err)
        },
      })
    })
  }
}

export default new WXAPI()

export interface ShareOptionType {
  title: string
  link: string
  imgUrl: string
  desc?: string
  success?: () => void
  cancel?: () => void
}

/**
 * [ShareTimeline 微信分享到朋友圈]
 */
function ShareTimeline(option: ShareOptionType) {
  wx.updateTimelineShareData({
    title: option.title,
    link: option.link,
    imgUrl: option.imgUrl,
    success: option.success,
    cancel: option.cancel,
  })
}

/**
 * [ShareAppMessage 微信分享给朋友]
 */
function ShareAppMessage(option: ShareOptionType) {
  wx.updateAppMessageShareData({
    title: option.title,
    link: option.link,
    imgUrl: option.imgUrl,
    desc: option.desc,
    success: option.success,
    cancel: option.cancel,
  })
}

/**
 * [iswx 判断是否微信浏览器]
 */
export function iswx() {
  const ua = window.navigator.userAgent.toLowerCase()
  return !!ua.match(/MicroMessenger/i)
}

// 判断ios
export function isIos() {
  return !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
}

/**
 * 调用微信授权登录 h5调用
 * @param {} redirect 回调链接
 * @param {*} state 额外参数
 */

export function wxOAuth2(redirect = location.href, state = '') {
  const AuthBase = 'https://open.weixin.qq.com/connect/oauth2/authorize?'
  const appid = import.meta.env.VITE_APP_WX_APPID
  const redirect_uri = encodeURIComponent(getWxOAuth2Location(redirect))
  const response_type = 'code'
  const scope = 'snsapi_userinfo'
  const result =
    AuthBase +
    `appid=${appid}&redirect_uri=${redirect_uri}&response_type=${response_type}&scope=${scope}&state=${state}#wechat_redirect`
  location.href = result
}

export function getWxOAuth2Location(href: string) {
  const query = getQueryObject(href)
  delete query.code
  const queryStr = Object.entries(query)
    .map(([k, v]) => `${k}=${v}`)
    .join('&')
  return href.split('?')[0] + (queryStr ? '?' + queryStr : '')
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function getQueryObject(url: string) {
  url = url == null ? window.location.href : url
  const search = url.substring(url.lastIndexOf('?') + 1)
  const obj: any = {}
  const reg = /([^?&=]+)=([^?&=]*)/g
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1)
    let val = decodeURIComponent($2)
    val = String(val)
    obj[name] = val
    return rs
  })
  return obj
}

使用

import wxApi from '@/utils/wx'

wxApi.saveIosFirstLink() // 保存ios第一次进入系统的链接
wxApi.share().then() // 分享
wxApi.pay().then() // 支付