UNPKG

vtils

Version:

一个面向业务的 JavaScript/TypeScript 实用程序库。

687 lines (653 loc) 18.5 kB
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator"; import _extends from "@babel/runtime/helpers/esm/extends"; import _regeneratorRuntime from "@babel/runtime/regenerator"; import { mapValues, noop } from 'lodash-uni'; import { EventBus } from "./EventBus.js"; import { asyncLimit } from "./asyncLimit.js"; import { isUrl } from "./isUrl.js"; import { LoadResourceUrlType, loadResource } from "./loadResource.js"; /** * 微信 JSSDK 支持的 API。 * * @public */ /** * @public */ /** * @public */ /** * @public */ /** * @public */ /** * @public */ /** * @public */ /** * @public */ /** * @public */ /** * @public */ /** * @public */ /** * @public */ /** * 微信内网页的非基础菜单列表。 * * @public */ /** * 微信 JSSDK 支持的分享 API 列表。 */ var shareJsApiList = ['updateAppMessageShareData', 'updateTimelineShareData', 'onMenuShareAppMessage', 'onMenuShareTimeline', 'onMenuShareQQ', 'onMenuShareQZone']; /** * 对微信 JSSDK 的封装。 * * @public * @example * ```typescript * const wechat = new Wechat() * getWechatConfigAsync().then(config => { * wechat.config(config) * }) * wechat.updateShareData({ * title: '分享标题', * desc: '分享描述', * link: '分享链接', * imgUrl: '缩略图地址', * }) * wechat.invoke('scanQRCode').then(res => { * // => API 调用结果 * }) * ``` */ export var Wechat = /*#__PURE__*/function () { /** * 构造函数。 * * @param params 注入微信 `JSSDK` 的权限验证配置参数 */ function Wechat(_params) { var _this = this; /** * 微信 JSSDK 是否已准备完成。 */ this.ready = false; /** * 消息巴士。 */ this.bus = new EventBus(); /** * 上一次设置分享时的参数。 */ this.prevShareParams = {}; this.beforeInvokeCallbacks = []; /** * 注入微信 `JSSDK` 的权限验证配置参数。 */ this.configParams = {}; /** * 上传图片。 * * 内部已作处理保证同时只能有一个图片在上传。 * * **备注:** 上传图片有效期3天, * 可用微信多媒体接口下载图片到自己的服务器, * 此处获得的服务器端 ID 即 `media_id`。 * * @param params 参数 */ this.uploadImage = asyncLimit(function (params) { return _this.invoke('uploadImage', { localId: params.localId, isShowProgressTips: params.isShowProgressTips ? 1 : 0 }); }, { // https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html // 附录5-常见错误及解决方法 // 9.uploadImage怎么传多图(目前只支持一次上传一张,多张图片需等前一张图片上传之后再调用该接口) concurrency: 1 }); this.audioElMap = Object.create(null); if (_params) { this.config(_params); } } /** * 注入微信 `JSSDK` 的权限验证配置。 * * @param params 配置参数 */ var _proto = Wechat.prototype; _proto.config = function config(params) { var _this2 = this; if (params === void 0) { params = this.configParams; } return new Promise(function (resolve, reject) { _this2.configParams = params; var config = function config() { var sharable = typeof params.sharable === 'boolean' ? params.sharable : true; wx.config(_extends({}, params, { jsApiList: [].concat(params.jsApiList || [], sharable ? shareJsApiList : []) })); if (!_this2.ready) { wx.ready(function () { _this2.ready = true; _this2.bus.emit('ready'); wx.onVoiceRecordEnd({ complete: function complete(res) { return _this2.bus.emit('voiceRecordEnd', res); } }); wx.onVoicePlayEnd({ success: function success(res) { return _this2.bus.emit('voicePlayEnd', res); } }); resolve(); }); wx.error(function (err) { _this2.bus.emit('error', err); reject(err); }); } else { resolve(); } }; if (typeof wx !== 'undefined') { config(); } else { var autoLoadJSSDK = params.autoLoadJSSDK == null ? '1.6.0' : params.autoLoadJSSDK; if (autoLoadJSSDK !== false) { var jssdkUrl = /^[0-9.]+$/.test(autoLoadJSSDK) ? "https://res.wx.qq.com/open/js/jweixin-" + autoLoadJSSDK + ".js" : autoLoadJSSDK; var alternateJssdkUrl = jssdkUrl.replace(/^https:\/\/res\.wx\.qq\.com\//, 'https://res2.wx.qq.com/'); loadResource({ type: LoadResourceUrlType.js, path: jssdkUrl, alternatePath: alternateJssdkUrl }).then(function (_ref) { var _scriptEl$parentNode; var scriptEl = _ref[0]; (_scriptEl$parentNode = scriptEl.parentNode) == null || _scriptEl$parentNode.removeChild(scriptEl); }, noop).then(function () { if (typeof wx === 'undefined') { reject('微信 JSSDK 加载失败'); } else { config(); } }); } else { if (typeof wx === 'undefined') { reject('请先引入微信 JSSDK'); } else { config(); } } } }); } /** * 微信 JSSDK 是否准备好可用。 */; _proto.isReady = function isReady() { return this.ready; } /** * 判断当前客户端版本是否支持指定 JS 接口。 * * @param jsApiList 需要检测的 JS 接口列表 * @returns 以键值对的形式返回,可用的 `api` 值 `true`,不可用为 `false` */; _proto.checkJsApi = function checkJsApi(jsApiList) { return this.invoke('checkJsApi', { jsApiList: jsApiList }).then(function (res) { return res.checkResult; }); } /** * 设置分享数据。 * * **注意**:每次分享的数据会和上次分享的数据合并作为最终分享的数据,因此,可以设置全局的分享数据。 * * @param params 分享数据 */; _proto.updateShareData = function updateShareData(params) { var _this3 = this; params = _extends({}, this.prevShareParams, params); this.prevShareParams = params; params = mapValues(params, function (value) { return typeof value === 'function' ? value() : value; }); return shareJsApiList.reduce(function (prev, jsApi) { var next = function next() { return _this3.invoke(jsApi, params); }; return prev.then(next, next); }, Promise.resolve()); } /** * 选择图片。 * * @param params 参数 * @returns 选定照片的本地 ID 列表,它们可以作为 img 标签的 src 属性显示图片 */; _proto.chooseImage = function chooseImage(params) { var _this4 = this; return this.invoke('chooseImage', params).then(function (res) { // @ts-ignore if (window.__wxjs_is_wkwebview) { return Promise.all(res.localIds.map(function (localId) { return _this4.invoke('getLocalImgData', { localId: localId }).then(function (res) { return { localId: localId, previewUrl: res.localData }; }); })); } return res.localIds.map(function (localId) { return { localId: localId, previewUrl: localId }; }); }); } /** * 预览图片。 * * @param params 参数 */; _proto.previewImage = function previewImage(params) { return this.invoke('previewImage', { urls: params.urls, current: params.current || params.urls[0] }); }; /** * 获取地理位置接口。 * * @param params 参数 */ _proto.getLocation = function getLocation(params) { return this.invoke('getLocation', params || {}); } /** * 使用微信内置地图查看位置。 * * @param params 参数 */; _proto.openLocation = function openLocation(params) { return this.invoke('openLocation', params); } /** * 关闭当前网页窗口。 */; _proto.closeWindow = function closeWindow() { return this.invoke('closeWindow'); } /** * 批量隐藏非基础菜单项。 * * @param menuList 要隐藏的非基础菜单项列表 */; _proto.hideNonBaseMenuItems = function hideNonBaseMenuItems(menuList) { return this.invoke('hideMenuItems', { menuList: menuList }); } /** * 批量显示非基础菜单项。 * * @param menuList 要显示的非基础菜单项列表 */; _proto.showNonBaseMenuItems = function showNonBaseMenuItems(menuList) { return this.invoke('showMenuItems', { menuList: menuList }); } /** * 隐藏所有的非基础菜单项。 */; _proto.hideAllNonBaseMenuItems = function hideAllNonBaseMenuItems() { return this.invoke('hideAllNonBaseMenuItem'); } /** * 显示所有的非基础菜单项。 */; _proto.showAllNonBaseMenuItems = function showAllNonBaseMenuItems() { return this.invoke('showAllNonBaseMenuItem'); } /** * 发起微信支付。 * * @param params 参数 */; _proto.requestPayment = function requestPayment(params) { return this.invoke('chooseWXPay', params); } /** * 开始音频录制。 */; _proto.startVoiceRecord = function startVoiceRecord(params) { var _this5 = this; var dispose = function dispose() { offStart(); offStop(); offEnd(); offError(); }; var offStart = this.bus.on('voiceRecordStart', function () { params.on == null || params.on('start'); }); var offStop = this.bus.on('voiceRecordStop', function (payload) { dispose(); params.on == null || params.on('stop', payload.localId); params.on == null || params.on('end', payload.localId); }); var offEnd = this.bus.on('voiceRecordEnd', function (payload) { dispose(); params.on == null || params.on('end', payload.localId); }); var offError = this.bus.on('voiceRecordError', function () { dispose(); params.on == null || params.on('error'); }); return new Promise(function (resolve, reject) { wx.startRecord({ success: function success() { _this5.bus.emit('voiceRecordStart'); resolve(); }, fail: function fail() { _this5.bus.emit('voiceRecordError'); reject(); }, cancel: function cancel() { _this5.bus.emit('voiceRecordError'); reject(); } }); }); } /** * 停止音频录制。 */; _proto.stopVoiceRecord = function stopVoiceRecord() { var _this6 = this; return new Promise(function (resolve, reject) { wx.stopRecord({ success: function success(res) { _this6.bus.emit('voiceRecordStop', res); resolve(res); }, fail: reject, cancel: reject }); }); }; /** * 开始音频播放。 */ _proto.startVoicePlay = function startVoicePlay(params) { var _this7 = this; var isAudioUrl = isUrl(params.localId); var dispose = function dispose() { offStart(); offPause(); offStop(); offEnd(); offError(); if (isAudioUrl) { var _this7$audioElMap$par; (_this7$audioElMap$par = _this7.audioElMap[params.localId]) == null || _this7$audioElMap$par.remove(); delete _this7.audioElMap[params.localId]; } }; var offStart = this.bus.on('voicePlayStart', function (payload) { if (payload.localId === params.localId) { params.on == null || params.on('start'); } }); var offPause = this.bus.on('voicePlayPause', function (payload) { if (payload.localId === params.localId) { dispose(); params.on == null || params.on('pause'); } }); var offStop = this.bus.on('voicePlayStop', function (payload) { if (payload.localId === params.localId) { dispose(); params.on == null || params.on('stop'); } }); var offEnd = this.bus.on('voicePlayEnd', function (payload) { if (payload.localId === params.localId) { dispose(); params.on == null || params.on('end'); } }); var offError = this.bus.on('voicePlayError', function (payload) { if (payload.localId === params.localId) { dispose(); params.on == null || params.on('error'); } }); if (isAudioUrl) { var resolve; var reject; var promise = new Promise(function (rs, rj) { resolve = rs; reject = rj; }); var audioEl = document.createElement('audio'); audioEl.src = params.localId; audioEl.onplay = function () { _this7.bus.emit('voicePlayStart', params); resolve(); }; audioEl.onended = function () { _this7.bus.emit('voicePlayEnd', params); }; audioEl.onerror = function () { _this7.bus.emit('voicePlayError', params); reject(); }; audioEl.play(); this.audioElMap[params.localId] = audioEl; return promise; } return new Promise(function (resolve, reject) { wx.playVoice({ localId: params.localId, success: function success() { _this7.bus.emit('voicePlayStart', params); resolve(); }, fail: function fail() { _this7.bus.emit('voicePlayError', params); reject(); }, cancel: function cancel() { _this7.bus.emit('voicePlayError', params); reject(); } }); }); } /** * 暂停音频播放。 */; _proto.pauseVoicePlay = function pauseVoicePlay(params) { var _this8 = this; var isAudioUrl = isUrl(params.localId); if (isAudioUrl) { var audioEl = this.audioElMap[params.localId]; if (audioEl) { audioEl.pause(); this.bus.emit('voicePlayPause', params); return Promise.resolve(); } return Promise.reject(); } return new Promise(function (resolve, reject) { wx.pauseVoice({ localId: params.localId, success: function success() { _this8.bus.emit('voicePlayPause', params); resolve(); }, fail: function fail() { reject(); }, cancel: function cancel() { reject(); } }); }); } /** * 停止音频播放。 */; _proto.stopVoicePlay = function stopVoicePlay(params) { var _this9 = this; var isAudioUrl = isUrl(params.localId); if (isAudioUrl) { var audioEl = this.audioElMap[params.localId]; if (audioEl) { audioEl.pause(); audioEl.currentTime = 0; this.bus.emit('voicePlayStop', params); return Promise.resolve(); } return Promise.reject(); } return new Promise(function (resolve, reject) { wx.stopVoice({ localId: params.localId, success: function success() { _this9.bus.emit('voicePlayStop', params); resolve(); }, fail: function fail() { reject(); }, cancel: function cancel() { reject(); } }); }); } /** * 开始音频上传。 * * 上传语音有效期3天,可用微信多媒体接口下载语音到自己的服务器,此处获得的 serverId 即 media_id。 */; _proto.startVoiceUpload = function startVoiceUpload(params) { return new Promise(function (resolve, reject) { wx.uploadVoice({ localId: params.localId, isShowProgressTips: params.isShowProgressTips ? 1 : 0, success: resolve, fail: function fail() { reject(); }, cancel: function cancel() { reject(); } }); }); } /** * 错误处理。 * * @param callback 出错时的回调函数 */; _proto.onError = function onError(callback) { return this.bus.on('error', callback); }; _proto.beforeInvoke = function beforeInvoke(cb) { this.beforeInvokeCallbacks.push(cb); } /** * 调用 JSSDK 的 API 方法。 * * @param jsApi 要调用的 API 名称 * @param params 传给 API 的参数 * @returns 调用结果 */; _proto.invoke = function invoke(jsApi, params) { var _this10 = this; if (params === void 0) { params = {}; } return new Promise(function (resolve, reject) { var invoke = /*#__PURE__*/function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() { return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: if (wx[jsApi]) { _context.next = 2; break; } return _context.abrupt("return", reject("wx." + jsApi + " \u4E0D\u53EF\u7528")); case 2: _context.prev = 2; _this10.config(); if (!_this10.beforeInvokeCallbacks.length) { _context.next = 7; break; } _context.next = 7; return Promise.all(_this10.beforeInvokeCallbacks.map(function (cb) { return cb(jsApi, params); })); case 7: wx[jsApi](_extends({}, params, { success: resolve, fail: reject, cancel: reject })); _context.next = 13; break; case 10: _context.prev = 10; _context.t0 = _context["catch"](2); reject(_context.t0); case 13: case "end": return _context.stop(); } }, _callee, null, [[2, 10]]); })); return function invoke() { return _ref2.apply(this, arguments); }; }(); if (typeof wx === 'undefined' || !_this10.ready) { _this10.bus.once('ready', invoke); } else { invoke(); } }); }; return Wechat; }();