import { invoke } from '../../bridge' import { warpPlusSuccessCallback, warpPlusErrorCallback } from '../util' import { isPlainObject, toRawType, callback } from 'uni-shared' let univerifyManager function getService (provider) { return new Promise((resolve, reject) => { plus.oauth.getServices(services => { const service = services.find(({ id }) => id === provider) service ? resolve(service) : reject(new Error('provider not find')) }, reject) }) } /** * 微信登录 */ export function login (params, callbackId, plus = true) { const provider = params.provider || 'weixin' const errorCallback = warpErrorCallback(callbackId, 'login', plus) const isAppleLogin = provider === 'apple' const authOptions = isAppleLogin ? { scope: 'email' } : params.univerifyStyle ? { univerifyStyle: univerifyButtonsClickHandling(params.univerifyStyle, errorCallback) } : {} const _invoke = plus ? invoke : callback.invoke getService(provider).then(service => { function login () { if (params.onlyAuthorize && provider === 'weixin') { service.authorize(({ code }) => { _invoke(callbackId, { code, authResult: '', errMsg: 'login:ok' }) }, errorCallback) return } service.login(res => { const authResult = res.target.authResult const appleInfo = res.target.appleInfo _invoke(callbackId, { code: authResult.code, authResult: authResult, appleInfo, errMsg: 'login:ok' }) }, errorCallback, authOptions) } // 先注销再登录 // apple登录logout之后无法重新触发获取email,fullname;一键登录无logout if (isAppleLogin || provider === 'univerify') { login() } else { service.logout(login, login) } }).catch(errorCallback) } export function getUserInfo (params, callbackId) { const provider = params.provider || 'weixin' const errorCallback = warpPlusErrorCallback(callbackId, 'operateWXData') getService(provider).then(loginService => { loginService.getUserInfo(res => { let userInfo if (provider === 'weixin') { const wechatUserInfo = loginService.userInfo userInfo = { openId: wechatUserInfo.openid, nickName: wechatUserInfo.nickname, gender: wechatUserInfo.sex, city: wechatUserInfo.city, province: wechatUserInfo.province, country: wechatUserInfo.country, avatarUrl: wechatUserInfo.headimgurl, unionId: wechatUserInfo.unionid } } else if (provider === 'apple') { const appleInfo = loginService.appleInfo userInfo = { openId: appleInfo.user, fullName: appleInfo.fullName, email: appleInfo.email, authorizationCode: appleInfo.authorizationCode, identityToken: appleInfo.identityToken, realUserStatus: appleInfo.realUserStatus } } else { userInfo = loginService.userInfo userInfo.openId = userInfo.openId || userInfo.openid || loginService.authResult.openid userInfo.nickName = userInfo.nickName || userInfo.nickname userInfo.avatarUrl = userInfo.avatarUrl || userInfo.headimgurl } const result = { errMsg: 'operateWXData:ok' } if (params.data && params.data.api_name === 'webapi_getuserinfo') { result.data = { data: JSON.stringify(userInfo), rawData: '', signature: '', encryptedData: '', iv: '' } } else { result.userInfo = userInfo } invoke(callbackId, result) }, errorCallback) }).catch(() => { invoke(callbackId, { errMsg: 'operateWXData:fail 请先调用 uni.login' }) }) } /** * 获取用户信息-兼容 */ export function getUserProfile (params, callbackId) { return getUserInfo(params, callbackId) } /** * 获取用户信息 */ export function operateWXData (params, callbackId) { switch (params.data.api_name) { case 'webapi_getuserinfo': getUserInfo(params, callbackId) break default: return { errMsg: 'operateWXData:fail' } } } export function preLogin (params, callbackId, plus) { const successCallback = warpSuccessCallback(callbackId, 'preLogin', plus) const errorCallback = warpErrorCallback(callbackId, 'preLogin', plus) getService(params.provider).then(service => service.preLogin(successCallback, errorCallback)).catch(errorCallback) } export function closeAuthView () { return getService('univerify').then(service => service.closeAuthView()) } export function getCheckBoxState (params, callbackId, plus) { const successCallback = warpSuccessCallback(callbackId, 'getCheckBoxState', plus) const errorCallback = warpErrorCallback(callbackId, 'getCheckBoxState', plus) try { getService('univerify').then(service => { const state = service.getCheckBoxState() successCallback({ state }) }) } catch (error) { errorCallback(error) } } /** * 一键登录自定义登陆按钮点击处理 */ function univerifyButtonsClickHandling (univerifyStyle, errorCallback) { if (isPlainObject(univerifyStyle) && isPlainObject(univerifyStyle.buttons) && toRawType(univerifyStyle.buttons.list) === 'Array') { univerifyStyle.buttons.list.forEach((button, index) => { univerifyStyle.buttons.list[index].onclick = function () { const res = { code: '30008', message: '用户点击了自定义按钮', index, provider: button.provider } isPlainObject(univerifyManager) ? univerifyManager._triggerUniverifyButtonsClick(res) : closeAuthView().then(() => { errorCallback(res) }) } }) } return univerifyStyle } class UniverifyManager { constructor () { this.provider = 'univerify' this.eventName = 'api.univerifyButtonsClick' } close () { closeAuthView() } login (options) { this._warp((data, callbackId) => login(data, callbackId, false), options) } getCheckBoxState (options) { this._warp((_, callbackId) => getCheckBoxState(_, callbackId, false), options) } preLogin (options) { this._warp((data, callbackId) => preLogin(data, callbackId, false), options) } onButtonsClick (callback) { UniServiceJSBridge.on(this.eventName, callback) } offButtonsClick (callback) { UniServiceJSBridge.off(this.eventName, callback) } _triggerUniverifyButtonsClick (res) { UniServiceJSBridge.emit(this.eventName, res) } _warp (fn, options) { return callback.warp(fn)(this._getOptions(options)) } _getOptions (options = {}) { return Object.assign({}, options, { provider: this.provider }) } } export function getUniverifyManager () { return univerifyManager || (univerifyManager = new UniverifyManager()) } function warpSuccessCallback (callbackId, name, plus = true) { return plus ? warpPlusSuccessCallback(callbackId, name) : (options) => { callback.invoke(callbackId, Object.assign({}, options, { errMsg: `${name}:ok` })) } } function warpErrorCallback (callbackId, name, plus = true) { return plus ? warpPlusErrorCallback(callbackId, name) : (error) => { const { code = 0, message: errorMessage } = error callback.invoke(callbackId, { errMsg: `${name}:fail ${errorMessage || ''}`, errCode: code, code }) } }