src/util.js
import qs from 'querystringify';
import extend from 'extend';
// 工具函数
/**
* 获取当前页面的 URL, 默认会追加当前页面的 query 参数
*
* @param {boolean} stripQuery 是否去除页面的 query 参数, 默认不去除
* @returns {string} 页面的 URL
*/
export function getCurrentPageUrl(stripQuery) {
var url = '';
// 获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面。
// 不要尝试修改页面栈,会导致路由以及页面状态错误
// 不要在 App.onLaunch 的时候调用 getCurrentPages(),此时 page 还没有生成
// https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/route.html
var pages = getCurrentPages();
if (pages) {
var currentPage = pages[pages.length - 1];
url = `/${currentPage.route}`;
if (!stripQuery) {
url = appendUrl(url, currentPage.options);
}
}
return url;
};
/**
* 获取当前页面的 URL 参数
*
* @returns {object} 页面的 URL 参数
*/
export function getCurrentPageUrlParams() {
var urlParams = {};
var pages = getCurrentPages();
if (pages) {
var currentPage = pages[pages.length - 1];
urlParams = currentPage.options;
}
return urlParams;
};
/**
* 刷新当前页面
*
* @param {boolean} stripQuery 是否去除页面的 query 参数, 默认不去除
*/
export function reloadCurrentPage(stripQuery) {
wx.redirectTo({
url: getCurrentPageUrl(stripQuery)
});
};
/**
* 调用某个页面的方法
*
* @param {string} methodName
* @param {Array} args
* @param {number} index 默认为当前页
* @return {any}
*/
export function invokePageMethod(methodName, args, index) {
var pages = getCurrentPages();
var lastIndex = pages.length - 1;
// 默认取当前页面
var _index = typeof index !== 'undefined' ? index : lastIndex;
if (_index <= 0) { // 首页
_index = 0;
} else if (_index >= lastIndex) { // 当前页
_index = lastIndex;
} else { // 传入的 index 可能不是数值
_index = lastIndex;
}
var page = pages[_index];
if (page && page[methodName]) {
return page[methodName].apply(page, args);
}
};
/**
* 在 URL 上追加参数
*
* @param {string} url
* @param {string | object} params 要追加在 URL 上的参数
* @param {boolean} replaceExistParams 如果原 URL 中已经有了待追加的参数, 是否覆盖, 默认不覆盖
* 注意会使原 URL 中的重复参数合并成一个
* 例如: https://domain.com?a=1&a=2&b=3
* 追加 a=4
* 最终 https://domain.com?a=4&b=3
* @return {string} 追加了参数的 URL
*/
export function appendUrl(url, params, replaceExistParams) {
var _url = url;
var _params = params;
if (typeof _params === 'object') {
// 排除 undefined 的属性
var filteredUndefined = {};
for (var key in _params) {
if (typeof _params[key] !== 'undefined') {
// 由于 `params` 中的参数可能已经做过 URL 编码了
// 如果再调用 `qs.stringify(params)` 会造成二次编码
// 外部使用时需要解码(`decodeURIComponent`)两次, 但对于外部来说只解码一次才是正常的
// 因此这里先解码一次
filteredUndefined[key] = decodeURIComponent(_params[key]);
}
}
_params = qs.stringify(filteredUndefined);
}
if (replaceExistParams && url.indexOf('?') !== -1) {
var urlAndQs = url.split('?');
var querystring = '';
_url = urlAndQs[0];
querystring = urlAndQs[1];
var originalParams = qs.parse(querystring);
_params = extend({}, originalParams, qs.parse(_params));
_params = qs.stringify(_params);
}
if (_params) {
if (_url.indexOf('?') === -1) {
_url = _url + '?' + _params;
} else {
_url = _url + '&' + _params;
}
}
return _url;
};
/**
* 检测是否有新版本
* 建议在 app.js#onShow 中调用
*
* @param {object} options
* options.showModal {boolean} 有新版本时是否显示新版本的提示框
* options.modalTitle {string} 新版本提示框的标题
* options.modalContent {string} 新版本提示框的内容
* options.forceUpdate {boolean} 是否强制升级, 开启强制升级新版本提示框不会有取消按钮
* options.checkCallback {Function} 检测更新的回调
*/
export function checkUpdate(options) {
var _options = extend({
showModal: true,
modalTitle: '更新提示',
modalContent: '新版本已经准备好了,是否重启应用?',
forceUpdate: true,
checkCallback: function() {}
}, options);
// https://developers.weixin.qq.com/miniprogram/dev/api/update/wx.getUpdateManager.html
if (wx.getUpdateManager) {
var updateManager = wx.getUpdateManager();
updateManager.onCheckForUpdate(function(result) {
_options.checkCallback.apply(updateManager, arguments);
if (result.hasUpdate) {
if (_options.showModal) {
wx.showModal({
title: _options.modalTitle,
content: _options.modalContent,
showCancel: !_options.forceUpdate,
success(result) {
if (result.confirm) {
updateManager.onUpdateReady(function() {
updateManager.applyUpdate();
});
}
}
});
}
}
});
} else {
console.log('没有获取到全局唯一的版本更新管理器, 支持版本 >= 1.9.90');
}
};
/**
* 获取用户信息回调时判断是否取到了用户信息
*
* - bindgetuserinfo
*
* @param {object} userInfoResult
* @return {boolean}
*/
export function isGetUserInfoSuccess(userInfoResult) {
return userInfoResult.errMsg.indexOf('getUserInfo:fail') == -1;
};
/**
* 获取用户手机号回调时判断是否取到了用户信息
*
* - bindgetphonenumber
*
* @param {object} phoneResult
* @return {boolean}
*/
export function isGetPhoneNumberSuccess(phoneResult) {
return phoneResult.errMsg.indexOf('getPhoneNumber:fail') == -1;
};
/**
* 获取 CSS 样式字符串
*
* {position:'absolute',top:'10rpx'} => position:absolute;top:10rpx;
*
* @param {object} styleObject
* @return {string}
*/
export function getCssString(styleObject) {
var style = [];
if (styleObject) {
for (var key in styleObject) {
style.push(`${key}:${styleObject[key]}`);
}
}
return style.join(';');
};
/**
* 判断用户是否有授权过某些权限
*
* - 如果用户未接受或拒绝过此权限,会弹窗询问用户,用户点击同意后方可调用接口
* - 如果用户已授权,可以直接调用接口;
* - 如果用户已拒绝授权,则不会出现弹窗,而是直接进入接口 fail 回调。请开发者兼容用户拒绝授权的场景。
*
* @param {string | array<string>} scopes 单个或者多个权限码
* @return Promise<boolean>
* @see https://developers.weixin.qq.com/miniprogram/dev/api/wx.getSetting.html
* @see https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/authorize.html
*/
export function hasAuth(scopes) {
return new Promise(function(resolve, reject) {
wx.getSetting({
success: function(result) {
var hasScopesAuth = false;
if (Object.prototype.toString.call(scopes) === '[object Array]') {
for (var i = 0, length = scopes.length > 0; i < length; i++) {
hasScopesAuth = result.authSetting[scopes[i]];
if (!hasScopesAuth) {
break;
}
}
} else {
hasScopesAuth = result.authSetting[scopes];
}
resolve(hasScopesAuth);
},
fail: function(result) {
console.error('hasAuth', result);
reject(result);
}
});
});
};
/**
* 获取 HTTP 返回结果中的 header 值
*
* 例如 header 的名称有如下类型
* - Connection 单个单词的
* - ETag 缩写没有使用连字符的
* - Content-Type 多个单词使用了连字符的
*
* @param {object} headerObject 开发者服务器返回的 HTTP Response Header
* @param {string} name
* @returns {string}
* @see https://developers.weixin.qq.com/miniprogram/dev/api/wx.request.html
*/
export function getHttpResponseHeaderValue(headerObject, name) {
var original = name;
var lowerCaseWords = name.split('-').map(function(item) {
return item.toLowerCase();
});
var lowerCaseHyphen = lowerCaseWords.map(function(item) {
return item.toLowerCase();
}).join('-');
var upperCaseHyphen = lowerCaseWords.map(function(item) {
return item.charAt(0).toUpperCase() + item.substring(1);
}).join('-');
return headerObject[original]
|| headerObject[lowerCaseHyphen]
|| headerObject[upperCaseHyphen];
};