下载 weixin-js-sdk-ts
yarn add weixin-js-sdk-ts
判断是否微信浏览器
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/)
}
调用微信授权登录
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 : '')
}
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 = ''
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 = ''
saveIosFirstLink() {
if (this.isIos && !this.iosFirstSignatureLink) {
this.iosFirstSignatureLink = location.href
}
}
async signature() {
const vm = this
const href = this.isIos ? this.iosFirstSignatureLink : location.href
if (this.isIos && this.signatured) {
return Promise.resolve()
}
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,
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage',
'updateAppMessageShareData',
'updateTimelineShareData',
'chooseWXPay',
],
openTagList: [],
})
wx.ready(function () {
vm.signatured = true
resolve(1)
})
wx.error(function (err) {
reject(err)
})
})
}
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 = ''
saveIosFirstLink() {
if (this.isIos && !this.iosFirstSignatureLink) {
this.iosFirstSignatureLink = location.href
}
}
async signature() {
const vm = this
const href = this.isIos ? this.iosFirstSignatureLink : location.href
if (this.isIos && this.signatured) {
return Promise.resolve()
}
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,
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage',
'updateAppMessageShareData',
'updateTimelineShareData',
'chooseWXPay',
],
openTagList: [],
})
wx.ready(function () {
vm.signatured = true
resolve(1)
})
wx.error(function (err) {
reject(err)
})
})
}
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
}
function ShareTimeline(option: ShareOptionType) {
wx.updateTimelineShareData({
title: option.title,
link: option.link,
imgUrl: option.imgUrl,
success: option.success,
cancel: option.cancel,
})
}
function ShareAppMessage(option: ShareOptionType) {
wx.updateAppMessageShareData({
title: option.title,
link: option.link,
imgUrl: option.imgUrl,
desc: option.desc,
success: option.success,
cancel: option.cancel,
})
}
export function iswx() {
const ua = window.navigator.userAgent.toLowerCase()
return !!ua.match(/MicroMessenger/i)
}
export function isIos() {
return !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
}
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 : '')
}
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()
wxApi.share().then()
wxApi.pay().then()