提交 0b29030a 编写于 作者: Q qiang

Merge branch 'dev' into alpha

# Conflicts:
#	packages/uni-app-plus/dist/index.js
......@@ -256,14 +256,14 @@ export default {
|参数名 |类型 |说明 |平台差异说明|
|:- |:- |:- ||
|orientation|string |画面方向 |微信小程序|
|type |string |视频格式 |微信小程序|
|duration |number |视频长度 |微信小程序、App、H5|
|size |number |视频大小,单位 kB |微信小程序、App、H5|
|height |number |视频的长,单位 px |微信小程序、App、H5|
|width |number |视频的宽,单位 px |微信小程序、App、H5|
|fps |number |视频帧率 |微信小程序、App|
|bitrate |number |视频码率,单位 kbps|微信小程序|
|orientation|string |画面方向 |微信小程序、App(3.1.14+)|
|type |string |视频格式 |微信小程序、App(3.1.14+)|
|duration |number |视频长度 |微信小程序、App(3.1.10+)、H5|
|size |number |视频大小,单位 kB |微信小程序、App(3.1.10+)、H5|
|height |number |视频的长,单位 px |微信小程序、App(3.1.10+)、H5|
|width |number |视频的宽,单位 px |微信小程序、App(3.1.10+)、H5|
|fps |number |视频帧率 |微信小程序、App(3.1.14+)|
|bitrate |number |视频码率,单位 kbps|微信小程序、App(3.1.14+)|
**res.orientation参数说明**
......
......@@ -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)
预登录。
......
......@@ -14,7 +14,7 @@
|backgroundColor|Color |#EBEBEB |未选择的进度条的颜色 | |
|active |Boolean |false |进度条从左往右的动画 | |
|active-mode |String |backwards |backwards: 动画从头播;forwards:动画从上次结束点接着播|App、H5、微信小程序、QQ小程序 |
|duration|number|30|进度增加1%所需毫秒数|App-nvue2.6.1+、微信基础库2.8.2+|
|duration|number|30|进度增加1%所需毫秒数|App-nvue2.6.1+、微信基础库2.8.2+、H5 3.1.11+|
|@activeend |EventHandle| |动画完成事件 |微信小程序 |
**示例** [查看演示](https://hellouniapp.dcloud.net.cn/pages/component/progress/progress)
......
......@@ -214,6 +214,7 @@ const third = [
'login',
'checkSession',
'getUserInfo',
'getUserProfile',
'preLogin',
'closeAuthView',
'share',
......@@ -240,8 +241,9 @@ const third = [
const ad = [
'createRewardedVideoAd',
'createFullScreenVideoAd',
'createInterstitialAd'
'createFullScreenVideoAd',
'createInterstitialAd',
'createInteractiveAd'
]
const apis = [
......
......@@ -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,8 @@
"title": "广告",
"apiList": {
"uni.createRewardedVideoAd": true,
"uni.createFullScreenVideoAd": true,
"uni.'createInterstitialAd'": true
"uni.createFullScreenVideoAd": true,
"uni.'createInterstitialAd'": true,
"uni.'createInteractiveAd'": true
}
}]
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
......@@ -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";
......@@ -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
});
......@@ -1720,7 +1771,7 @@ function createSubpackageApp (vm) {
}
function createPlugin (vm) {
const appOptions = parseApp$1(vm);
const appOptions = parseApp(vm);
if (isFn(appOptions.onShow) && wx.onAppShow) {
wx.onAppShow((...args) => {
appOptions.onShow.apply(vm, args);
......@@ -1750,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]
......@@ -1770,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;
......@@ -1779,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;
}
}
......@@ -1810,7 +1861,7 @@ wx.createComponent = createComponent;
wx.createSubpackageApp = createSubpackageApp;
wx.createPlugin = createPlugin;
var uni$1 = uni;
var uni$2 = uni$1;
export default uni$1;
export default uni$2;
export { createApp, createComponent, createPage, createPlugin, createSubpackageApp };
......@@ -727,6 +727,16 @@ describe('mp:compiler-extra', () => {
'<block wx:for="{{[{x:[1,2,3,4]}]}}" wx:for-item="item" wx:for-index="index"><view><block wx:for="{{item.x}}" wx:for-item="item2" wx:for-index="__i0__"><view data-event-opts="{{[[\'tap\',[[\'e0\',[\'$event\']]]]]}}" data-event-params="{{({item2})}}" bindtap="__e">{{item2+"+"+index}}</view></block></view></block>',
'with(this){if(!_isMounted){e0=function($event,item2){var _temp=arguments[arguments.length-1].currentTarget.dataset,_temp2=_temp.eventParams||_temp["event-params"],item2=_temp2.item2;var _temp,_temp2;return test(item2)}}}'
)
assertCodegen(
'<view v-for="(item, index) in array()"><view @click="test"></view></view>',
'<block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index"><view><view data-event-opts="{{[[\'tap\',[[\'test\',[\'$event\']]]]]}}" bindtap="__e"></view></view></block>',
'with(this){var l0=array();$mp.data=Object.assign({},{$root:{l0:l0}})}'
)
assertCodegen(
'<view v-for="(item, index) in array()"><view @click="test(item)"></view></view>',
'<block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index"><view><view data-event-opts="{{[[\'tap\',[[\'e0\',[\'$event\']]]]]}}" data-event-params="{{({item})}}" bindtap="__e"></view></view></block>',
'with(this){var l0=array();if(!_isMounted){e0=function($event,item){var _temp=arguments[arguments.length-1].currentTarget.dataset,_temp2=_temp.eventParams||_temp["event-params"],item=_temp2.item;var _temp,_temp2;return test(item)}}$mp.data=Object.assign({},{$root:{l0:l0}})}'
)
})
it('generate bool attr', () => {
assertCodegen(
......
......@@ -206,6 +206,22 @@ function isValuePath (path) {
return path.key !== 'key' && path.key !== 'id' && (path.key !== 'property' || path.parent.computed) && !(path.key === 'value' && path.parentPath.parentPath.isObjectPattern()) && !(path.key === 'left' && path.parentPath.parentPath.parentPath.isObjectPattern())
}
/**
* 判断 v-for 中是否包含复杂表达式:数组、对象、方法
*/
const isSafeScoped = (state) => {
const scopedArray = state.scoped
for (let index = 0; index < scopedArray.length; index++) {
const scoped = scopedArray[index]
const arrayExtra = scoped.forExtra[0].elements[0].value
// 简易判断
if (typeof arrayExtra === 'string' && (arrayExtra.startsWith('[') || arrayExtra.startsWith('{') || /\(.*\)/.test(arrayExtra))) {
return false
}
}
return true
}
function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false, tagName, ret) {
const key = keyPath.node
let type = key.value || key.name || ''
......@@ -304,18 +320,9 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false,
}
}
// 判断是否是复杂表达式 数组 或 对象
const isNotDynamicExpression = (state) => {
if (!(state.scoped[0])) {
return true
}
const value = state.scoped[0].forExtra[0].elements[0].value
return !(typeof value === 'string' && (value.startsWith('[') || value.startsWith('}')))
}
// 如果v-for遍历的值为 数组、对象 则进入复杂表达式
if (isNotDynamicExpression(state)) {
anonymous && funcPath.traverse({
// 如果 v-for 遍历的值为 数组、对象、方法 则进入底部匿名表达式处理
if (anonymous && isSafeScoped(state)) {
funcPath.traverse({
noScope: true,
MemberExpression (path) {
if (path.node.object.name === '$event' && path.node.property.name ===
......
......@@ -30,5 +30,4 @@ module.exports = function getRenderSlot (path, state) {
state.renderSlotStatementArray.push(t.expressionStatement(t.callExpression(t.identifier('$setScopedSlotsParams'), [t.stringLiteral(name.node.value), valueNode])))
}
// TODO 组件嵌套
path.skip()
}
......@@ -26,6 +26,7 @@ module.exports = function initOptions (options) {
// 增加 src/node_modules 解析
options.transpileDependencies.push(genTranspileDepRegex(path.resolve(process.env.UNI_INPUT_DIR, 'node_modules')))
options.transpileDependencies.push('@dcloudio/uni-' + process.env.UNI_PLATFORM)
options.transpileDependencies.push('@dcloudio/uni-i18n')
options.transpileDependencies.push('@dcloudio/uni-stat')
options.transpileDependencies.push('@dcloudio/vue-cli-plugin-uni/packages/uni-cloud')
......@@ -85,7 +86,7 @@ module.exports = function initOptions (options) {
if (sassLoaderVersion < 8) {
options.css.loaderOptions.sass.data = sassData
} else {
} else {
const name = sassLoaderVersion >= 9 ? 'additionalData' : 'prependData'
options.css.loaderOptions.sass[name] = sassData
}
......
......@@ -8,6 +8,11 @@ const trim_1 = __importDefault(require("./stylePlugins/trim"));
const scoped_1 = __importDefault(require("./stylePlugins/scoped"));
const styleProcessors_1 = require("./styleProcessors");
const removeScoped_1 = __importDefault(require("./stylePlugins/remove-scoped"));
let comments;
try{
comments = require('postcss-discard-comments')
}catch(e){}
function compileStyle(options) {
return doCompileStyle(Object.assign({}, options, { isAsync: false }));
}
......@@ -31,6 +36,12 @@ function doCompileStyle(options) {
} else { // fixed by xxxxxx
plugins.push(removeScoped_1.default(id));
}
// fixed by xxxxxx
if (process.env.UNI_PLATFORM === 'app-plus' && process.env.NODE_ENV === 'production') {
if (comments) {
plugins.push(comments);
}
}
const postCSSOptions = Object.assign({}, postcssOptions, { to: filename, from: filename });
if (map) {
postCSSOptions.map = {
......
......@@ -12,6 +12,10 @@ const {
parseTabBar
} = require('../util')
function defaultCopy (name, value, json) {
json[name] = value
}
const pagesJson2AppJson = {
globalStyle: function (name, value, json) {
json.window = parseStyle(value)
......@@ -22,7 +26,8 @@ const pagesJson2AppJson = {
},
tabBar: function (name, value, json) {
json.tabBar = parseTabBar(value)
}
},
preloadRule: defaultCopy
}
function copyToJson (json, fromJson, options) {
......@@ -62,19 +67,19 @@ module.exports = function (pagesJson, manifestJson) {
app.subPackages.push(subPackages[root])
})
copyToJson(app, pagesJson, pagesJson2AppJson)
const platformJson = manifestJson['mp-alipay'] || {}
if (hasOwn(platformJson, 'plugins')) {
app.plugins = platformJson.plugins
}
copyToJson(app, pagesJson, pagesJson2AppJson)
const platformJson = manifestJson['mp-alipay'] || {}
if (hasOwn(platformJson, 'plugins')) {
app.plugins = platformJson.plugins
}
if (app.usingComponents) {
updateAppJsonUsingComponents(app.usingComponents)
}
const project = Object.assign({}, manifestJson['mp-alipay'] || {})
delete project.usingComponents
delete project.usingComponents
delete project.plugins
return [{
......@@ -84,4 +89,4 @@ module.exports = function (pagesJson, manifestJson) {
name: 'mini.project',
content: project
}]
}
}
......@@ -24,6 +24,10 @@ import {
getTabBarScrollPosition
} from './app/router-guard'
import {
uniIdMixin
} from 'uni-shared'
function getMinId (routes) {
let minId = 0
routes.forEach(route => {
......@@ -74,6 +78,8 @@ export default {
lifecycleMixin(Vue)
uniIdMixin(Vue)
/* eslint-disable no-undef */
if (typeof __UNI_ROUTER_BASE__ !== 'undefined') {
__uniConfig.router.base = __UNI_ROUTER_BASE__
......
......@@ -196,9 +196,9 @@ export default {
img.src = realImagePath
} else {
this._clearImage()
this._resetData()
// 与微信小程序保持一致,保留之前样式
// this._resetData()
this._resetSize()
// this._resetSize()
}
},
_clearImage () {
......
<template>
<uni-progress
class="uni-progress"
v-on="$listeners"
<uni-progress
class="uni-progress"
v-on="$listeners"
>
<div
:style="outerBarStyle"
class="uni-progress-bar"
<div
:style="outerBarStyle"
class="uni-progress-bar"
>
<div
:style="innerBarStyle"
class="uni-progress-inner-bar"
<div
:style="innerBarStyle"
class="uni-progress-inner-bar"
/>
</div>
<template v-if="showInfo">
<p class="uni-progress-info">
{{ currentPercent }}%
<p class="uni-progress-info">
{{ currentPercent }}%
</p>
</template>
</uni-progress>
......@@ -65,6 +65,13 @@ export default {
activeMode: {
type: String,
default: VALUES.activeMode
},
duration: {
type: [Number, String],
default: 30,
validator(value) {
return !isNaN(parseFloat(value, 10))
}
}
},
data () {
......@@ -117,7 +124,7 @@ export default {
} else {
this.currentPercent += 1
}
}, 30)
}, parseFloat(this.duration))
} else {
this.currentPercent = this.realPercent
}
......@@ -154,4 +161,4 @@ export default {
margin-left: 15px;
font-size: 16px;
}
</style>
</style>
......@@ -152,5 +152,7 @@ class AdBase {
}
export {
eventTypes,
eventNames,
AdBase
}
import {
requireNativePlugin
} from '../../bridge'
import {
eventTypes,
eventNames
} from './ad-base.js'
const sdkCache = {}
const sdkQueue = {}
function initSDK (options) {
const provider = options.provider
if (typeof sdkCache[provider] === 'object') {
options.success(sdkCache[provider])
return
}
if (!sdkQueue[provider]) {
sdkQueue[provider] = []
}
sdkQueue[provider].push(options)
if (sdkCache[provider] === true) {
return
}
sdkCache[provider] = true
const plugin = requireNativePlugin(provider)
if (!plugin || !plugin.initSDK) {
sdkQueue[provider].forEach((item) => {
item.fail({
code: -1,
message: 'provider [' + provider + '] invalid'
})
})
sdkQueue[provider].length = 0
sdkCache[provider] = false
return
}
options.__plugin = plugin
plugin.initSDK((res) => {
const isSuccess = (res.code === 1 || res.code === '1')
if (isSuccess) {
sdkCache[provider] = plugin
} else {
sdkCache[provider] = false
}
sdkQueue[provider].forEach((item) => {
if (isSuccess) {
item.success(item.__plugin)
} else {
item.fail(res)
}
})
sdkQueue[provider].length = 0
})
}
class InteractiveAd {
constructor (options) {
const _callbacks = this._callbacks = {}
eventNames.forEach(item => {
_callbacks[item] = []
const name = item[0].toUpperCase() + item.substr(1)
this[`on${name}`] = function (callback) {
_callbacks[item].push(callback)
}
})
this._ad = null
this._adError = ''
this._adpid = options.adpid
this._provider = options.provider
this._isLoaded = false
this._isLoading = false
this._loadPromiseResolve = null
this._loadPromiseReject = null
this._showPromiseResolve = null
this._showPromiseReject = null
setTimeout(() => {
this._init()
})
}
_init () {
this._adError = ''
initSDK({
provider: this._provider,
success: (res) => {
this._ad = res
this._loadAd()
},
fail: (err) => {
this._adError = err
this._dispatchEvent(eventTypes.error, err)
}
})
}
getProvider () {
return this._provider
}
load () {
return new Promise((resolve, reject) => {
this._loadPromiseResolve = resolve
this._loadPromiseReject = reject
if (this._isLoading) {
return
}
if (this._adError) {
this._init()
return
}
if (this._isLoaded) {
resolve()
} else {
this._loadAd()
}
})
}
show () {
return new Promise((resolve, reject) => {
this._showPromiseResolve = resolve
this._showPromiseReject = reject
if (this._isLoading) {
return
}
if (this._adError) {
this._init()
return
}
if (this._isLoaded) {
this._showAd()
resolve()
} else {
this._loadAd()
}
})
}
destroy () {
if (this._ad !== null && this._ad.destroy) {
this._ad.destroy({
adpid: this._adpid
})
}
}
_loadAd () {
if (this._ad !== null) {
if (this._isLoading === true) {
return
}
this._isLoading = true
this._ad.loadData({
adpid: this._adpid
}, (res) => {
this._isLoaded = true
this._isLoading = false
this._dispatchEvent(eventTypes.load, res)
if (this._loadPromiseResolve != null) {
this._loadPromiseResolve()
this._loadPromiseResolve = null
}
if (this._showPromiseResolve != null) {
this._showPromiseResolve()
this._showPromiseResolve = null
this._showAd()
}
}, (err) => {
this._isLoading = false
this._dispatchEvent(eventTypes.error, err)
if (this._showPromiseReject != null) {
this._showPromiseReject(this._createError(err))
this._showPromiseReject = null
}
})
}
}
_showAd () {
if (this._ad !== null && this._isLoaded === true) {
this._ad.show({
adpid: this._adpid
}, (res) => {
this._isLoaded = false
}, (err) => {
this._isLoaded = false
this._dispatchEvent(eventTypes.error, err)
if (this._showPromiseReject != null) {
this._showPromiseReject(this._createError(err))
this._showPromiseReject = null
}
})
}
}
_createError (err) {
const error = new Error(JSON.stringify(err))
error.code = err.code
error.errMsg = err.message
return error
}
_dispatchEvent (name, data) {
this._callbacks[name].forEach(callback => {
if (typeof callback === 'function') {
callback(data || {})
}
})
}
}
export function createInteractiveAd (options) {
if (!options.provider) {
return new Error('provider invalid')
}
if (!options.adpid) {
return new Error('adpid invalid')
}
return new InteractiveAd(options)
}
......@@ -6,7 +6,7 @@ class InterstitialAd extends AdBase {
constructor (options = {}) {
super(plus.ad.createInterstitialAd(options), options)
this.load()
this._loadAd()
}
}
......
......@@ -82,3 +82,4 @@ export * from './ad/ad'
export * from './ad/rewarded-video-ad'
export * from './ad/full-screen-video-ad'
export * from './ad/interstitial-ad'
export * from './ad/interactive-ad'
......@@ -7,10 +7,13 @@ export const getVideoInfo = warpPlusMethod('io', 'getVideoInfo', options => {
return options
}, data => {
return {
orientation: data.orientation,
type: data.type,
duration: data.duration,
fps: data.fps || 30,
size: data.size,
height: data.height,
width: data.width,
size: data.size
fps: data.fps || 30,
bitrate: data.bitrate,
}
})
......@@ -46,6 +46,7 @@ export function createRequestTaskById (requestTaskId, {
responseType,
sslVerify = true,
firstIpv4 = false,
tls,
timeout = (__uniConfig.networkTimeout && __uniConfig.networkTimeout.request) || 60 * 1000
} = {}) {
const stream = requireNativePlugin('stream')
......@@ -99,7 +100,8 @@ export function createRequestTaskById (requestTaskId, {
timeout: timeout || 6e5,
// 配置和weex模块内相反
sslVerify: !sslVerify,
firstIpv4: firstIpv4
firstIpv4: firstIpv4,
tls
}
if (method !== 'GET') {
options.body = typeof data === 'string' ? data : JSON.stringify(data)
......
......@@ -99,6 +99,12 @@ export function getUserInfo (params, callbackId) {
})
})
}
/**
* 获取用户信息-兼容
*/
export function getUserProfile (params, callbackId) {
return getUserInfo(params, callbackId)
}
/**
* 获取用户信息
......
......@@ -22,6 +22,10 @@ import {
vdSyncCallbacks
} from '../subscribe-handlers/on-vd-sync-callback'
import {
uniIdMixin
} from 'uni-shared'
export default {
install (Vue, options) {
initVue(Vue)
......@@ -31,6 +35,8 @@ export default {
initPolyfill(Vue)
uniIdMixin(Vue)
Vue.prototype.getOpenerEventChannel = function () {
if (!this.$root.$scope.eventChannel) {
this.$root.$scope.eventChannel = new EventChannel()
......@@ -94,4 +100,4 @@ export default {
return callback ? undefined : result
}
}
}
}
......@@ -23,10 +23,11 @@ const passiveOptions = supportsPassive ? {
function updateCssVar (vm) {
if (uni.canIUse('css.var')) {
const uniConfigTabbarHeight = parseFloat(__uniConfig.tabBar.height)
const pageVm = vm.$parent.$parent
const navigationBarType = pageVm.navigationBar.type
const windowTopValue = navigationBarType === 'default' || navigationBarType === 'float' ? NAVBAR_HEIGHT : 0
const windowBottomValue = getApp().$children[0].showTabBar ? TABBAR_HEIGHT : 0
const windowBottomValue = getApp().$children[0].showTabBar ? isNaN(uniConfigTabbarHeight) ? TABBAR_HEIGHT : uniConfigTabbarHeight : 0
const envMethod = uni.canIUse('css.env') ? 'env' : (uni.canIUse('css.constant') ? 'constant' : '')
const windowTop = windowTopValue && envMethod ? `calc(${windowTopValue}px + ${envMethod}(safe-area-inset-top))`
: `${windowTopValue}px`
......@@ -87,4 +88,4 @@ export default function initSubscribe (subscribe) {
})
}
})
}
}
......@@ -364,7 +364,7 @@ export default {
}
const danmuList = this.otherData.danmuList = JSON.parse(JSON.stringify(this.danmuList || []))
danmuList.sort(function (a, b) {
return (a.time || 0) - (a.time || 0)
return (a.time || 0) - (b.time || 0)
})
},
mounted () {
......
......@@ -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: {
......
......@@ -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'
}
}
......
......@@ -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'
......
......@@ -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',
......
......@@ -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
......
const oName = 'getUserInfo'
const nName = 'getUserProfile'
export default {
name: __GLOBAL__.canIUse(nName) ? nName : oName
}
......@@ -11,6 +11,10 @@ import {
getEventChannel
} from 'uni-helpers/navigate-to'
import {
uniIdMixin
} from 'uni-shared'
const hooks = [
'onShow',
'onHide',
......@@ -101,6 +105,7 @@ export default function parseBaseApp (vm, {
if (vm.$options.store) {
Vue.prototype.$store = vm.$options.store
}
uniIdMixin(Vue)
Vue.prototype.mpHost = __PLATFORM__
......
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 = (__PLATFORM__ === 'h5' || __PLATFORM__ === 'app-plus' ? uni : __GLOBAL__).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
}
export 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()
}
}
......@@ -193,3 +193,5 @@ export function deepClone (vnodes, createElement) {
return vnodes.map(cloneVNode)
}
export * from './uni-id-mixin'
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册