From cedeedc78e16111e826a3c0aae8cc24de285de0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8A=8A=E9=87=8C?= <1227971437@qq.com> Date: Thu, 22 Apr 2021 19:50:43 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Euni.getUserProfile;=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E7=99=BE=E5=BA=A6=E5=B0=8F=E7=A8=8B=E5=BA=8Funi.login?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/api/plugins/login.md | 87 +++++++++- lib/apis.js | 3 +- lib/modules.json | 3 +- packages/uni-app-plus/dist/index.js | 151 +++++++++++++----- .../app-plus/service/api/plugin/oauth.js | 6 + .../mp-alipay/runtime/api/protocols.js | 17 ++ .../mp-baidu/runtime/api/protocols.js | 5 + .../mp-kuaishou/runtime/api/protocols.js | 4 +- src/platforms/mp-qq/runtime/api/protocols.js | 4 +- .../mp-toutiao/runtime/api/protocols.js | 2 + .../mp-weixin/helpers/get-user-profile.js | 6 + 11 files changed, 240 insertions(+), 48 deletions(-) create mode 100644 src/platforms/mp-weixin/helpers/get-user-profile.js diff --git a/docs/api/plugins/login.md b/docs/api/plugins/login.md index b88593eb1..7cd694bdc 100644 --- a/docs/api/plugins/login.md +++ b/docs/api/plugins/login.md @@ -12,6 +12,9 @@ H5平台登录注意事项: - 普通浏览器上实现微信登录,并非开放API,需要向微信申请,仅个别开发者有此权限 - H5平台的其他登录,比如QQ登录、微博登录,uni-app未封装,请在条件编译里按普通H5写法编写。 +百度小程序登录注意事项: +- 百度小程序平台需要在button组件的@login事件后再调用 uni.login ,[详见](https://smartprogram.baidu.com/docs/develop/function/login/),否则会返回“请登录”的错误信息,建议在@login事件中调用。 + **OBJECT 参数说明** |参数名|类型|必填|说明|平台差异说明| @@ -91,7 +94,7 @@ uni.login({ **OBJECT 参数说明** |参数名|类型|必填|说明|平台差异说明| -|:-|:-|:-|:-|:-|:-| +|:-|:-|:-|:-|:-| |provider|String|否|登录服务提供商,通过 uni.getProvider 获取|| |withCredentials|Boolean|否|是否带上登录态信息。|微信小程序、字节跳动小程序| |lang|String|否|指定返回用户信息的语言,默认为 en。更多值请参考下面的说明。|微信小程序| @@ -108,12 +111,12 @@ uni.login({ |zh_TW|繁体中文| |en|英文| -**注意:**在小程序 withCredentials 为 true 时或是在 App 调用 uni.getUserInfo,要求此前有调用过 uni.login 且登录态尚未过期。 +**注意:**在小程序 withCredentials 为 true 时或是在 App 调用 uni.getUserInfo,要求此前有调用过 uni.login 且登录态尚未过期。微信基础库2.10.4版本对用户信息相关接口进行了调整,使用 uni.getUserInfo 获取得到的 userInfo 为匿名数据,建议使用 uni.getUserProfile 获取用户信息。 **success 返回参数说明** |参数|类型|说明|平台差异说明| -|:-|:-|:-|| +|:-|:-|:-|:-| |userInfo|OBJECT|用户信息对象|| |rawData|String|不包括敏感信息的原始数据字符串,用于计算签名。|| |signature|String|使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息。|微信小程序、字节跳动小程序| @@ -124,7 +127,7 @@ uni.login({ **userInfo 参数说明** |参数|类型|说明|平台差异说明| -|:-|:-|:-|| +|:-|:-|:-|:-| |nickName|String|用户昵称|| |openId|String|该服务商唯一用户标识|App| |avatarUrl|String|用户头像| | @@ -166,6 +169,82 @@ uni.login({ 1. [支付宝登录](https://ext.dcloud.net.cn/search?q=%E6%94%AF%E4%BB%98%E5%AE%9D%E7%99%BB%E9%99%86)、[淘宝登录](https://ext.dcloud.net.cn/search?q=%E7%99%BE%E5%B7%9D)、[抖音登录](https://ext.dcloud.net.cn/search?q=%E6%8A%96%E9%9F%B3%E7%99%BB%E5%BD%95)、[facebook登录](https://ext.dcloud.net.cn/search?q=facebook%E7%99%BB%E5%BD%95)等在插件市场均已有插件,还有[sharesdk](https://ext.dcloud.net.cn/search?q=sharesdk)等专业集成多家登录分享的插件。 2. 也可以内嵌web-view组件,使用web登录模式集成这些三方登录 + +### uni.getUserProfile(OBJECT) + +获取用户信息。每次请求都会弹出授权窗口,用户同意后返回 userInfo。 + + + +**平台差异说明** + +|App|H5|微信小程序(基础库2.10.4)|支付宝小程序|百度小程序|字节跳动小程序|QQ小程序| +|:-:|:-:|:-:|:-:|:-:|:-:|:-:| +|x|x|√|x|x|x|x| + +**注意:** 该API仅支持微信小程序端,微信小程序调整了相关接口(详见[《小程序登录、用户信息相关接口调整说明》](https://developers.weixin.qq.com/community/develop/doc/000cacfa20ce88df04cb468bc52801?highLine=getUserProfile%253Afail))。每次触发 uni.getUserProfile 均会弹出授权窗口,用户授权后可成功获取用户信息。 + +**OBJECT 参数说明** + +|参数名|类型|必填|说明| +|:-|:-|:-|:-| +|desc|String|是|声明获取用户个人信息后的用途,不超过30个字符| +|lang|String|否|指定返回用户信息的语言,默认为 en。更多值请参考下面的说明。| +|success|Function|否|接口调用成功的回调| +|fail|Function|否|接口调用失败的回调函数| +|complete|Function|否|接口调用结束的回调函数(调用成功、失败都会执行)| + +**lang 值说明** + +|值|说明| +|:-|:-| +|zh_CN|简体中文| +|zh_TW|繁体中文| +|en|英文| + +**注意:**可以使用 if(uni.getUserProfile) 判断uni.getUserProfile是否可用。 + +**success 返回参数说明** + +|参数|类型|说明| +|:-|:-|:-| +|userInfo|OBJECT|用户信息对象| +|rawData|String|不包括敏感信息的原始数据字符串,用于计算签名。| +|signature|String|使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息。| +|encryptedData|String|包括敏感数据在内的完整用户信息的加密数据,详细见加密数据解密算法。| +|iv|String|加密算法的初始向量,详细见加密数据解密算法。| +|cloudID|String|敏感数据对应的云 ID,开通云开发的小程序才会返回,可通过云调用直接获取开放数据,详细见云调用直接获取开放数据| +|errMsg|String|描述信息| + +**userInfo 参数说明** + +|参数|类型|说明|平台差异说明(仅支持微信小程序)| +|:-|:-|:-|| +|nickName|String|用户昵称|| +|avatarUrl|String|用户头像| | +|gender|Number|用户性别|| +|country|String|用户所在国家|| +|province|String|用户所在省份|| +|city|String|用户所在城市|| +|language|String|显示 country,province,city 所用的语言|| + +**gender 的合法值** + +|值|说明| +|:-|:-| +|0|未知| +|1|男性| +|2|女性| + +**language 的合法值** + +|值|说明| +|:-|:-| +|en|英文| +|zh_CN|简体中文| +|zh_TW|繁体中文| + + ### uni.preLogin(OBJECT) 预登录。 diff --git a/lib/apis.js b/lib/apis.js index d9e6d7188..3b5595dc3 100644 --- a/lib/apis.js +++ b/lib/apis.js @@ -214,6 +214,7 @@ const third = [ 'login', 'checkSession', 'getUserInfo', + 'getUserProfile', 'preLogin', 'closeAuthView', 'share', @@ -240,7 +241,7 @@ const third = [ const ad = [ 'createRewardedVideoAd', - 'createFullScreenVideoAd', + 'createFullScreenVideoAd', 'createInterstitialAd' ] diff --git a/lib/modules.json b/lib/modules.json index dd0c32dfd..a889e9323 100644 --- a/lib/modules.json +++ b/lib/modules.json @@ -206,6 +206,7 @@ "uni.login": true, "uni.checkSession": true, "uni.getUserInfo": true, + "uni.getUserProfile": true, "uni.share": true, "uni.showShareMenu": true, "uni.hideShareMenu": true, @@ -223,7 +224,7 @@ "title": "广告", "apiList": { "uni.createRewardedVideoAd": true, - "uni.createFullScreenVideoAd": true, + "uni.createFullScreenVideoAd": true, "uni.'createInterstitialAd'": true } }] diff --git a/packages/uni-app-plus/dist/index.js b/packages/uni-app-plus/dist/index.js index 7abbb0a05..05b3ff576 100644 --- a/packages/uni-app-plus/dist/index.js +++ b/packages/uni-app-plus/dist/index.js @@ -1,5 +1,55 @@ import Vue from 'vue'; +function b64DecodeUnicode (str) { + return decodeURIComponent(atob(str).split('').map(function (c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2) + }).join('')) +} + +function getCurrentUserInfo () { + const token = (uni ).getStorageSync('uni_id_token') || ''; + const tokenArr = token.split('.'); + if (!token || tokenArr.length !== 3) { + return { + uid: null, + role: [], + permission: [], + tokenExpired: 0 + } + } + let userInfo; + try { + userInfo = JSON.parse(b64DecodeUnicode(tokenArr[1])); + } catch (error) { + throw new Error('获取当前用户信息出错,详细错误信息为:' + error.message) + } + userInfo.tokenExpired = userInfo.exp * 1000; + delete userInfo.exp; + delete userInfo.iat; + return userInfo +} + +function uniIdMixin (Vue) { + Vue.prototype.uniIDHasRole = function (roleId) { + const { + role + } = getCurrentUserInfo(); + return role.indexOf(roleId) > -1 + }; + Vue.prototype.uniIDHasPermission = function (permissionId) { + const { + permission + } = getCurrentUserInfo(); + return this.uniIDHasRole('admin') || permission.indexOf(permissionId) > -1 + }; + Vue.prototype.uniIDTokenValid = function () { + const { + tokenExpired + } = getCurrentUserInfo(); + return tokenExpired > Date.now() + }; +} + const _toString = Object.prototype.toString; const hasOwnProperty = Object.prototype.hasOwnProperty; @@ -411,7 +461,7 @@ function processReturnValue (methodName, res, returnValue, keepReturnValue = fal return processArgs(methodName, res, returnValue, {}, keepReturnValue) } -function wrapper (methodName, method) { +function wrapper$2 (methodName, method) { if (hasOwn(protocols, methodName)) { const protocol = protocols[methodName]; if (!protocol) { // 暂不支持的 api @@ -602,7 +652,7 @@ const customize = cached((str) => { function initTriggerEvent (mpInstance) { { - if (!wx.canIUse('nextTick')) { + if (!wx.canIUse || !wx.canIUse('nextTick')) { return } } @@ -899,7 +949,7 @@ function initProperties (props, isBehavior = false, file = '') { return properties } -function wrapper$2 (event) { +function wrapper (event) { // TODO 又得兼容 mpvue 的 mp 对象 try { event.mp = JSON.parse(JSON.stringify(event)); @@ -1092,7 +1142,7 @@ function getContextVm (vm) { } function handleEvent (event) { - event = wrapper$2(event); + event = wrapper(event); // [['tap',[['handle',[1,2,a]],['handle1',[1,2,a]]]]] const dataset = (event.currentTarget || event.target).dataset; @@ -1258,7 +1308,7 @@ function getEventChannel (id) { return eventChannelStack.shift() } -const hooks = [ +const hooks$3 = [ 'onShow', 'onHide', 'onError', @@ -1292,6 +1342,7 @@ function parseBaseApp (vm, { if (vm.$options.store) { Vue.prototype.$store = vm.$options.store; } + uniIdMixin(Vue); Vue.prototype.mpHost = "app-plus"; @@ -1312,7 +1363,7 @@ function parseBaseApp (vm, { delete this.$options.mpType; delete this.$options.mpInstance; - if (this.mpType === 'page') { // hack vue-i18n + if (this.mpType === 'page' && typeof getApp === 'function') { // hack vue-i18n const app = getApp(); if (app.$vm && app.$vm.$i18n) { this._i18n = app.$vm.$i18n; @@ -1358,7 +1409,7 @@ function parseBaseApp (vm, { }); } - initHooks(appOptions, hooks); + initHooks(appOptions, hooks$3); return appOptions } @@ -1443,27 +1494,27 @@ function handleLink (event) { vueOptions.parent = parentVm; } -function parseApp (vm) { +function parseApp$1 (vm) { return parseBaseApp(vm, { mocks, initRefs }) } -const hooks$1 = [ +const hooks$2 = [ 'onUniNViewMessage' ]; -function parseApp$1 (vm) { - const appOptions = parseApp(vm); +function parseApp (vm) { + const appOptions = parseApp$1(vm); - initHooks(appOptions, hooks$1); + initHooks(appOptions, hooks$2); return appOptions } function createApp (vm) { - App(parseApp$1(vm)); + App(parseApp(vm)); return vm } @@ -1602,15 +1653,15 @@ function parseBaseComponent (vueComponentOptions, { return [componentOptions, VueComponent] } -function parseComponent (vueComponentOptions) { +function parseComponent$1 (vueComponentOptions) { return parseBaseComponent(vueComponentOptions, { isPage, initRelation }) } -function parseComponent$1 (vueComponentOptions) { - const componentOptions = parseComponent(vueComponentOptions); +function parseComponent (vueComponentOptions) { + const componentOptions = parseComponent$1(vueComponentOptions); componentOptions.methods.$getAppWebview = function () { return plus.webview.getWebviewById(`${this.__wxWebviewId__}`) @@ -1618,21 +1669,21 @@ function parseComponent$1 (vueComponentOptions) { return componentOptions } -const hooks$2 = [ +const hooks$1 = [ 'onShow', 'onHide', 'onUnload' ]; -hooks$2.push(...PAGE_EVENT_HOOKS); +hooks$1.push(...PAGE_EVENT_HOOKS); function parseBasePage (vuePageOptions, { isPage, initRelation }) { - const pageOptions = parseComponent$1(vuePageOptions); + const pageOptions = parseComponent(vuePageOptions); - initHooks(pageOptions.methods, hooks$2, vuePageOptions); + initHooks(pageOptions.methods, hooks$1, vuePageOptions); pageOptions.methods.onLoad = function (query) { this.options = query; @@ -1648,14 +1699,14 @@ function parseBasePage (vuePageOptions, { return pageOptions } -function parsePage (vuePageOptions) { +function parsePage$1 (vuePageOptions) { return parseBasePage(vuePageOptions, { isPage, initRelation }) } -const hooks$3 = [ +const hooks = [ 'onBackPress', 'onNavigationBarButtonTap', 'onNavigationBarSearchInputChanged', @@ -1664,28 +1715,28 @@ const hooks$3 = [ 'onNavigationBarSearchInputFocusChanged' ]; -function parsePage$1 (vuePageOptions) { - const pageOptions = parsePage(vuePageOptions); +function parsePage (vuePageOptions) { + const pageOptions = parsePage$1(vuePageOptions); - initHooks(pageOptions.methods, hooks$3); + initHooks(pageOptions.methods, hooks); return pageOptions } function createPage (vuePageOptions) { { - return Component(parsePage$1(vuePageOptions)) + return Component(parsePage(vuePageOptions)) } } function createComponent (vueOptions) { { - return Component(parseComponent$1(vueOptions)) + return Component(parseComponent(vueOptions)) } } function createSubpackageApp (vm) { - const appOptions = parseApp$1(vm); + const appOptions = parseApp(vm); const app = getApp({ allowDefault: true }); @@ -1719,6 +1770,25 @@ function createSubpackageApp (vm) { return vm } +function createPlugin (vm) { + const appOptions = parseApp(vm); + if (isFn(appOptions.onShow) && wx.onAppShow) { + wx.onAppShow((...args) => { + appOptions.onShow.apply(vm, args); + }); + } + if (isFn(appOptions.onHide) && wx.onAppHide) { + wx.onAppHide((...args) => { + appOptions.onHide.apply(vm, args); + }); + } + if (isFn(appOptions.onLaunch)) { + const args = wx.getLaunchOptionsSync && wx.getLaunchOptionsSync(); + appOptions.onLaunch.call(vm, args); + } + return vm +} + todos.forEach(todoApi => { protocols[todoApi] = false; }); @@ -1731,10 +1801,10 @@ canIUses.forEach(canIUseApi => { } }); -let uni = {}; +let uni$1 = {}; if (typeof Proxy !== 'undefined' && "app-plus" !== 'app-plus') { - uni = new Proxy({}, { + uni$1 = new Proxy({}, { get (target, name) { if (hasOwn(target, name)) { return target[name] @@ -1751,7 +1821,7 @@ if (typeof Proxy !== 'undefined' && "app-plus" !== 'app-plus') { if (!hasOwn(wx, name) && !hasOwn(protocols, name)) { return } - return promisify(name, wrapper(name, wx[name])) + return promisify(name, wrapper$2(name, wx[name])) }, set (target, name, value) { target[name] = value; @@ -1760,27 +1830,27 @@ if (typeof Proxy !== 'undefined' && "app-plus" !== 'app-plus') { }); } else { Object.keys(baseApi).forEach(name => { - uni[name] = baseApi[name]; + uni$1[name] = baseApi[name]; }); Object.keys(eventApi).forEach(name => { - uni[name] = eventApi[name]; + uni$1[name] = eventApi[name]; }); Object.keys(api).forEach(name => { - uni[name] = promisify(name, api[name]); + uni$1[name] = promisify(name, api[name]); }); Object.keys(wx).forEach(name => { if (hasOwn(wx, name) || hasOwn(protocols, name)) { - uni[name] = promisify(name, wrapper(name, wx[name])); + uni$1[name] = promisify(name, wrapper$2(name, wx[name])); } }); } { if (typeof global !== 'undefined') { - global.uni = uni; + global.uni = uni$1; global.UniEmitter = eventApi; } } @@ -1788,9 +1858,10 @@ if (typeof Proxy !== 'undefined' && "app-plus" !== 'app-plus') { wx.createApp = createApp; wx.createPage = createPage; wx.createComponent = createComponent; -wx.createSubpackageApp = createSubpackageApp; +wx.createSubpackageApp = createSubpackageApp; +wx.createPlugin = createPlugin; -var uni$1 = uni; +var uni$2 = uni$1; -export default uni$1; -export { createApp, createComponent, createPage, createSubpackageApp }; +export default uni$2; +export { createApp, createComponent, createPage, createPlugin, createSubpackageApp }; diff --git a/src/platforms/app-plus/service/api/plugin/oauth.js b/src/platforms/app-plus/service/api/plugin/oauth.js index e07b8738f..b3ac6168a 100644 --- a/src/platforms/app-plus/service/api/plugin/oauth.js +++ b/src/platforms/app-plus/service/api/plugin/oauth.js @@ -99,6 +99,12 @@ export function getUserInfo (params, callbackId) { }) }) } +/** + * 获取用户信息-兼容 + */ +export function getUserProfile (params, callbackId) { + return getUserInfo(params, callbackId) +} /** * 获取用户信息 diff --git a/src/platforms/mp-alipay/runtime/api/protocols.js b/src/platforms/mp-alipay/runtime/api/protocols.js index 80cae6382..658459e0b 100644 --- a/src/platforms/mp-alipay/runtime/api/protocols.js +++ b/src/platforms/mp-alipay/runtime/api/protocols.js @@ -381,6 +381,23 @@ const protocols = { // 需要做转换的 API 列表 } } }, + getUserProfile: { + name: my.canIUse('getOpenUserInfo') ? 'getOpenUserInfo' : 'getAuthUserInfo', + returnValue (result) { + if (my.canIUse('getOpenUserInfo')) { + let response = {} + try { + response = JSON.parse(result.response).response + } catch (e) {} + result.nickName = response.nickName + result.avatar = response.avatar + } + result.userInfo = { + nickName: result.nickName, + avatarUrl: result.avatar + } + } + }, requestPayment: { name: 'tradePay', args: { diff --git a/src/platforms/mp-baidu/runtime/api/protocols.js b/src/platforms/mp-baidu/runtime/api/protocols.js index 6739ba5fc..a094ce94c 100644 --- a/src/platforms/mp-baidu/runtime/api/protocols.js +++ b/src/platforms/mp-baidu/runtime/api/protocols.js @@ -2,6 +2,7 @@ import navigateTo from 'uni-helpers/navigate-to' import redirectTo from '../../../mp-weixin/helpers/redirect-to' import previewImage from '../../../mp-weixin/helpers/normalize-preview-image' import getSystemInfo from '../../../mp-weixin/helpers/system-info' +import getUserProfile from '../../../mp-weixin/helpers/get-user-profile' // 不支持的 API 列表 const todos = [ @@ -89,6 +90,7 @@ const protocols = { previewImage, getSystemInfo, getSystemInfoSync: getSystemInfo, + getUserProfile, getRecorderManager: { returnValue (fromRet) { fromRet.onFrameRecorded = createTodoMethod('RecorderManager', 'onFrameRecorded') @@ -122,6 +124,9 @@ const protocols = { getAccountInfoSync: { name: 'getEnvInfoSync', returnValue: _handleEnvInfo + }, + login:{ + name:'getLoginCode' } } diff --git a/src/platforms/mp-kuaishou/runtime/api/protocols.js b/src/platforms/mp-kuaishou/runtime/api/protocols.js index 06d3e8ad6..fd596f57e 100644 --- a/src/platforms/mp-kuaishou/runtime/api/protocols.js +++ b/src/platforms/mp-kuaishou/runtime/api/protocols.js @@ -2,13 +2,15 @@ import navigateTo from 'uni-helpers/navigate-to' import redirectTo from '../../../mp-weixin/helpers/redirect-to' import previewImage from '../../../mp-weixin/helpers/normalize-preview-image' import getSystemInfo from '../../../mp-weixin/helpers/system-info' +import getUserProfile from '../../../mp-weixin/helpers/get-user-profile' export const protocols = { navigateTo, redirectTo, previewImage, getSystemInfo, - getSystemInfoSync: getSystemInfo + getSystemInfoSync: getSystemInfo, + getUserProfile } export const todos = [ 'vibrate' diff --git a/src/platforms/mp-qq/runtime/api/protocols.js b/src/platforms/mp-qq/runtime/api/protocols.js index 8d9061d4c..04986c6c2 100644 --- a/src/platforms/mp-qq/runtime/api/protocols.js +++ b/src/platforms/mp-qq/runtime/api/protocols.js @@ -2,13 +2,15 @@ import navigateTo from 'uni-helpers/navigate-to' import redirectTo from '../../../mp-weixin/helpers/redirect-to' import previewImage from '../../../mp-weixin/helpers/normalize-preview-image' import getSystemInfo from '../../../mp-weixin/helpers/system-info' +import getUserProfile from '../../../mp-weixin/helpers/get-user-profile' export const protocols = { navigateTo, redirectTo, previewImage, getSystemInfo, - getSystemInfoSync: getSystemInfo + getSystemInfoSync: getSystemInfo, + getUserProfile } export const todos = [ 'preloadPage', diff --git a/src/platforms/mp-toutiao/runtime/api/protocols.js b/src/platforms/mp-toutiao/runtime/api/protocols.js index f40ace052..e09f87a10 100644 --- a/src/platforms/mp-toutiao/runtime/api/protocols.js +++ b/src/platforms/mp-toutiao/runtime/api/protocols.js @@ -2,6 +2,7 @@ import navigateTo from 'uni-helpers/navigate-to' import redirectTo from '../../../mp-weixin/helpers/redirect-to' import previewImage from '../../../mp-weixin/helpers/normalize-preview-image' import getSystemInfo from '../../../mp-weixin/helpers/system-info' +import getUserProfile from '../../../mp-weixin/helpers/get-user-profile' // 不支持的 API 列表 const todos = [ @@ -107,6 +108,7 @@ const protocols = { previewImage, getSystemInfo, getSystemInfoSync: getSystemInfo, + getUserProfile, connectSocket: { args: { method: false diff --git a/src/platforms/mp-weixin/helpers/get-user-profile.js b/src/platforms/mp-weixin/helpers/get-user-profile.js new file mode 100644 index 000000000..c7695a8fb --- /dev/null +++ b/src/platforms/mp-weixin/helpers/get-user-profile.js @@ -0,0 +1,6 @@ +const oName = 'getUserInfo' +const nName = 'getUserProfile' + +export default { + name: __GLOBAL__.canIUse(nName) ? nName : oName +} -- GitLab