diff --git a/build/rollup.config.cloudstat.js b/build/rollup.config.cloudstat.js deleted file mode 100644 index 574abd5b8d9a678f14cf2882d837096046744792..0000000000000000000000000000000000000000 --- a/build/rollup.config.cloudstat.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - input: 'packages/uni-cloud-stat/src/index.js', - output: { - file: 'packages/uni-cloud-stat/dist/index.js', - format: 'es' - }, - external: ['vue', '../package.json'], - plugins: [] -} diff --git a/packages/uni-cloud-stat/LICENSE b/packages/uni-cloud-stat/LICENSE deleted file mode 100644 index 7a4a3ea2424c09fbe48d455aed1eaa94d9124835..0000000000000000000000000000000000000000 --- a/packages/uni-cloud-stat/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/packages/uni-cloud-stat/dist/index.js b/packages/uni-cloud-stat/dist/index.js deleted file mode 100644 index 4453182ea0b9013f8abee6e22faf01a6257437d8..0000000000000000000000000000000000000000 --- a/packages/uni-cloud-stat/dist/index.js +++ /dev/null @@ -1,1067 +0,0 @@ -import pagesTitle from 'uni-pages?{"type":"style"}'; -import Vue from 'vue'; - -/** - * 获取系统信息 - */ -const sys = uni.getSystemInfoSync(); - -// 访问开始即启动小程序,访问结束结分为:进入后台超过5min、在前台无任何操作超过30min、在新的来源打开小程序; -const STAT_VERSION = '0.0.1'; -const PAGE_PVER_TIME = 1800; // 页面在前台无操作结束访问时间 单位s -const APP_PVER_TIME = 300; // 应用在后台结束访问时间 单位s -const OPERATING_TIME = 10; // 数据上报时间 单位s - -let pagesData = pagesTitle.pages; -let titleJsons = {}; -for (let i in pagesData) { - titleJsons[i] = pagesData[i].navigationBarTitleText || ''; -} - -const UUID_KEY = '__DC_STAT_UUID'; -const UUID_VALUE = '__DC_UUID_VALUE'; - -function getUuid() { - let uuid = ''; - if (get_platform_name() === 'n') { - try { - uuid = plus.runtime.getDCloudId(); - } catch (e) { - uuid = ''; - } - return uuid - } - - try { - uuid = uni.getStorageSync(UUID_KEY); - } catch (e) { - uuid = UUID_VALUE; - } - - if (!uuid) { - uuid = Date.now() + '' + Math.floor(Math.random() * 1e7); - try { - uni.setStorageSync(UUID_KEY, uuid); - } catch (e) { - uni.setStorageSync(UUID_KEY, UUID_VALUE); - } - } - return uuid -} - -const get_uuid = (statData) => { - // 有可能不存在 deviceId(一般不存在就是出bug了),就自己生成一个 - return sys.deviceId || getUuid() -}; - -/** - * 获取当前平台 - * 移动端 : 'n', - * h5 : 'h5', - * 微信 : 'wx', - * 阿里 : 'ali', - * 百度 : 'bd', - * 头条 : 'tt', - * qq : 'qq', - * 快应用 : 'qn', - * 快手 : 'ks', - * 飞书 : 'lark', - * 快应用 : 'qw', - * 钉钉 : 'dt' - */ -const get_platform_name = () => { - // 苹果审核代码中禁止出现 alipay 字样 ,需要特殊处理一下 - const aliArr = ['y', 'a', 'p', 'mp-ali']; - const platformList = { - 'app': 'n', - 'app-plus': 'n', - h5: 'h5', - 'mp-weixin': 'wx', - [aliArr.reverse().join('')]: 'ali', - 'mp-baidu': 'bd', - 'mp-toutiao': 'tt', - 'mp-qq': 'qq', - 'quickapp-native': 'qn', - 'mp-kuaishou': 'ks', - 'mp-lark': 'lark', - 'quickapp-webview': 'qw' - }; - if (platformList[process.env.VUE_APP_PLATFORM] === 'ali') { - if (my && my.env) { - const clientName = my.env.clientName; - if (clientName === 'ap') return 'ali' - if (clientName === 'dingtalk') return 'dt' - // TODO 缺少 ali 下的其他平台 - } - } - return platformList[process.env.VUE_APP_PLATFORM] -}; - -/** - * 获取小程序 appid - */ -const get_pack_name = () => { - let packName = ''; - if (get_platform_name() === 'wx' || get_platform_name() === 'qq') { - // 兼容微信小程序低版本基础库 - if (uni.canIUse('getAccountInfoSync')) { - packName = uni.getAccountInfoSync().miniProgram.appId || ''; - } - } - if (get_platform_name() === 'n') ; - return packName -}; - -/** - * 应用版本 - */ -const get_version = () => { - return get_platform_name() === 'n' ? plus.runtime.version : '' -}; - -/** - * 获取渠道 - */ -const get_channel = () => { - const platformName = get_platform_name(); - let channel = ''; - if (platformName === 'n') { - channel = plus.runtime.channel; - } - return channel -}; - -/** - * 获取小程序场景值 - * @param {Object} options 页面信息 - */ -const get_scene = (options) => { - const platformName = get_platform_name(); - let scene = ''; - if (options) { - return options - } - if (platformName === 'wx') { - scene = uni.getLaunchOptionsSync().scene; - } - return scene -}; - -/** - * 获取拼接参数 - */ -const get_splicing = (data) => { - let str = ''; - for (var i in data) { - str += i + '=' + data[i] + '&'; - } - return str.substr(0, str.length - 1) -}; - -/** - * 获取页面url,不包含参数 - */ -const get_route = (pageVm) => { - let _self = pageVm || get_page_vm(); - if (get_platform_name() === 'bd') { - let mp_route = _self.$mp && _self.$mp.page && _self.$mp.page.is; - let scope_route = _self.$scope && _self.$scope.is; - return mp_route || scope_route || '' - } else { - return _self.route || (_self.$scope && _self.$scope.route) || (_self.$mp && _self.$mp.page.route) - } -}; - -/** - * 获取页面url, 包含参数 - */ -const get_page_route = (pageVm) => { - // 从 app 进入应用 ,没有 $page ,获取不到路由 ,需要获取页面 尝试从 getCurrentPages 获取也页面实例 - // FIXME 尽量不使用 getCurrentPages ,大部分获取路由是从 onHide 获取 ,这时可以获取到,如果是 onload ,则可能获取不到,比如 百度 - - let page = pageVm.$page || (pageVm.$scope && pageVm.$scope.$page); - let lastPageRoute = uni.getStorageSync('_STAT_LAST_PAGE_ROUTE'); - if (!page) return lastPageRoute || '' - return page.fullPath === '/' ? page.route : page.fullPath -}; - -/** - * 获取页面实例 - */ -const get_page_vm = () => { - let pages = getCurrentPages(); - let $page = pages[pages.length - 1]; - if (!$page) return null - return $page.$vm -}; - -/** - * 获取页面类型 - */ -const get_page_types = (self) => { - // XXX 百度有问题 ,获取的都是 componet ,等待修复 - if (self.mpType === 'page' || self.$mpType === 'page' || (self.$mp && self.$mp.mpType === 'page') || self - .$options.mpType === 'page') { - return 'page'; - } - if (self.mpType === 'app' || self.$mpType === 'app' || (self.$mp && self.$mp.mpType === 'app') || self.$options - .mpType === 'app') { - return 'app' - } - return null; -}; - -/** - * 处理上报参数 - * @param {Object} 需要处理的数据 - */ -const handle_data = (statData) => { - let firstArr = []; - let contentArr = []; - let lastArr = []; - for (let i in statData) { - const rd = statData[i]; - rd.forEach((elm) => { - const newData = get_splicing(elm); - if (i === 0) { - firstArr.push(newData); - } else if (i === 3) { - lastArr.push(newData); - } else { - contentArr.push(newData); - } - }); - } - - firstArr.push(...contentArr, ...lastArr); - // 参数需要处理成字符串,方便上传 - return JSON.stringify(firstArr) -}; - - -/** - * 自定义事件参数校验 - */ -const calibration = (eventName, options) => { - // login 、 share 、pay_success 、pay_fail 、register 、title - if (!eventName) { - console.error(`uni.report Missing [eventName] parameter`); - return true - } - if (typeof eventName !== 'string') { - console.error(`uni.report [eventName] Parameter type error, it can only be of type String`); - return true - } - if (eventName.length > 255) { - console.error(`uni.report [eventName] Parameter length cannot be greater than 255`); - return true - } - - if (typeof options !== 'string' && typeof options !== 'object') { - console.error('uni.report [options] Parameter type error, Only supports String or Object type'); - return true - } - - if (typeof options === 'string' && options.length > 255) { - console.error(`uni.report [options] Parameter length cannot be greater than 255`); - return true - } - - if (eventName === 'title' && typeof options !== 'string') { - console.error( - `uni.report [eventName] When the parameter is title, the [options] parameter can only be of type String` - ); - return true - } -}; - -const get_page_name = (routepath) => { - return (titleJsons && titleJsons[routepath]) || '' -}; - -const dbSet = (name, value) => { - let data = uni.getStorageSync('$$STAT__DBDATA') || {}; - if (!data) { - data = {}; - } - data[name] = value; - uni.setStorageSync('$$STAT__DBDATA', data); -}; - -const dbGet = (name) => { - let data = uni.getStorageSync('$$STAT__DBDATA') || {}; - if (!data) { - data = {}; - } - if (!data[name]) { - return undefined - } - return data[name] -}; - -const dbRemove = (name) => { - let data = uni.getStorageSync('$$STAT__DBDATA') || {}; - if (data[name]) { - delete data[name]; - uni.setStorageSync('$$STAT__DBDATA', data); - } else { - data = uni.getStorageSync('$$STAT__DBDATA'); - if (data[name]) { - delete data[name]; - uni.setStorageSync('$$STAT__DBDATA', data); - } - } -}; - -// 首次访问时间 -const FIRST_VISIT_TIME_KEY = '__first__visit__time'; -// 最后访问时间 -const LAST_VISIT_TIME_KEY = '__last__visit__time'; -/** - * 获取当前时间 - */ -const get_time = () => { - return parseInt(new Date().getTime() / 1000) -}; - -/** - * 获取首次访问时间 - */ -const get_first_visit_time = () => { - const timeStorge = dbGet(FIRST_VISIT_TIME_KEY); - let time = 0; - if (timeStorge) { - time = timeStorge; - } else { - time = get_time(); - dbSet(FIRST_VISIT_TIME_KEY, time); - // 首次访问需要 将最后访问时间置 0 - dbRemove(LAST_VISIT_TIME_KEY); - } - return time -}; - -/** - * 最后访问时间 - */ -const get_last_visit_time = () => { - const timeStorge = dbGet(LAST_VISIT_TIME_KEY); - let time = 0; - if (timeStorge) { - time = timeStorge; - } - dbSet(LAST_VISIT_TIME_KEY, get_time()); - return time -}; - -// 页面停留时间记录key -const PAGE_RESIDENCE_TIME = '__page__residence__time'; - -/** - * 设置页面停留时间 - */ -const set_page_residence_time = () => { - let First_Page_Residence_Time = get_time(); - dbSet(PAGE_RESIDENCE_TIME, First_Page_Residence_Time); - return First_Page_Residence_Time -}; - -/** - * 获取页面停留时间 - */ -const get_page_residence_time = () => { - let Last_Page_Residence_Time = get_time(); - let First_Page_Residence_Time = dbGet(PAGE_RESIDENCE_TIME); - return Last_Page_Residence_Time - First_Page_Residence_Time -}; - -/** - * 获取总访问次数 - */ -const TOTAL_VISIT_COUNT = '__total__visit__count'; -const get_total_visit_count = () => { - const timeStorge = dbGet(TOTAL_VISIT_COUNT); - let count = 1; - if (timeStorge) { - count = timeStorge; - count++; - } - dbSet(TOTAL_VISIT_COUNT, count); - return count -}; - -let Set__First__Time = 0; -let Set__Last__Time = 0; - -/** - * 获取第一次时间 - */ -const get_first_time = () => { - let time = new Date().getTime(); - Set__First__Time = time; - Set__Last__Time = 0; - return time -}; - -/** - * 获取最后一次时间 - */ -const get_last_time = () => { - let time = new Date().getTime(); - Set__Last__Time = time; - return time -}; - -/** - * 获取页面 \ 应用停留时间 - */ -const get_residence_time = (type) => { - let residenceTime = 0; - if (Set__First__Time !== 0) { - residenceTime = Set__Last__Time - Set__First__Time; - } - - residenceTime = parseInt(residenceTime / 1000); - residenceTime = residenceTime < 1 ? 1 : residenceTime; - if (type === 'app') { - let overtime = residenceTime > APP_PVER_TIME ? true : false; - return { - residenceTime, - overtime, - } - } - if (type === 'page') { - let overtime = residenceTime > PAGE_PVER_TIME ? true : false; - return { - residenceTime, - overtime, - } - } - return { - residenceTime, - } -}; - -let statConfig = require('uni-stat-config').default || require('uni-stat-config'); - -// 统计数据默认值 -let statData = { - uuid: get_uuid(), // 设备标识 - ut: get_platform_name(), // 平台类型 - mpn: get_pack_name(), // 原生平台包名、小程序 appid - ak: statConfig.appid, // uni-app 应用 Appid - usv: STAT_VERSION, // 统计 sdk 版本 - v: get_version(), // 应用版本,仅app - ch: get_channel(), // 渠道信息 - cn: '', // 国家 - pn: '', // 省份 - ct: '', // 城市 - t: get_time(), // 上报数据时的时间戳 - tt: '', - p: sys.platform === 'android' ? 'a' : 'i', // 手机系统 - brand: sys.brand || '', // 手机品牌 - md: sys.model, // 手机型号 - sv: sys.system.replace(/(Android|iOS)\s/, ''), // 手机系统版本 - mpsdk: sys.SDKVersion || '', // x程序 sdk version - mpv: sys.version || '', // 小程序平台版本 ,如微信、支付宝 - lang: sys.language, // 语言 - pr: sys.pixelRatio, // pixelRatio 设备像素比 - ww: sys.windowWidth, // windowWidth 可使用窗口宽度 - wh: sys.windowHeight, // windowHeight 可使用窗口高度 - sw: sys.screenWidth, // screenWidth 屏幕宽度 - sh: sys.screenHeight, // screenHeight 屏幕高度 -}; -class Report { - constructor() { - // 页面实例 - this.self = ''; - // 进入应用标识 - this.__licationShow = false; - // 离开应用标识 - this.__licationHide = false; - // 统计默认值 - this.statData = statData; - // 标题默认值 - this._navigationBarTitle = { - config: '', - page: '', - report: '', - lt: '', - }; - - // 页面参数 - this._query = {}; - // 页面最后停留页面的 url - // this._lastPageRoute = '' - - // 注册拦截器 - let registerInterceptor = typeof uni.addInterceptor === 'function'; - if (registerInterceptor) { - this.addInterceptorInit(); - this.interceptLogin(); - this.interceptShare(true); - this.interceptRequestPayment(); - } - } - - addInterceptorInit() { - let self = this; - uni.addInterceptor('setNavigationBarTitle', { - invoke(args) { - self._navigationBarTitle.page = args.title; - }, - }); - } - - interceptLogin() { - let self = this; - uni.addInterceptor('login', { - complete() { - self._login(); - }, - }); - } - - interceptShare(type) { - let self = this; - if (!type) { - self._share(); - return - } - uni.addInterceptor('share', { - success() { - self._share(); - }, - fail() { - self._share(); - }, - }); - } - - interceptRequestPayment() { - let self = this; - uni.addInterceptor('requestPayment', { - success() { - self._payment('pay_success'); - }, - fail() { - self._payment('pay_fail'); - }, - }); - } - - _login() { - this.sendEventRequest({ - key: 'login', - }, - 0 - ); - } - - _share() { - this.sendEventRequest({ - key: 'share', - }, 0); - } - _payment(key) { - this.sendEventRequest({ - key, - }, 0); - } - - /** - * 进入应用触发 - */ - applicationShow() { - // 通过 __licationHide 判断保证是进入后台后在次进入应用,避免重复上报数据 - if (this.__licationHide) { - get_last_time(); - const time = get_residence_time('app'); - // 需要判断进入后台是否超过时限 ,默认是 30min ,是的话需要执行进入应用的上报 - if (time.overtime) { - let lastPageRoute = uni.getStorageSync('_STAT_LAST_PAGE_ROUTE'); - let options = { - path: lastPageRoute, - scene: this.statData.sc, - }; - this.sendReportRequest(options); - } - // 状态重置 - this.__licationHide = false; - } - } - - /** - * 离开应用触发 - * @param {Object} self - * @param {Object} type - */ - applicationHide(self, type) { - // 进入应用后台保存状态,方便进入前台后判断是否上报应用数据 - this.__licationHide = true; - get_last_time(); - const time = get_residence_time(); - const route = get_page_route(self); - // this._lastPageRoute = route - uni.setStorageSync('_STAT_LAST_PAGE_ROUTE', route); - this.sendHideRequest({ - urlref: route, - urlref_ts: time.residenceTime, - }, - type - ); - // 重置时间 - get_first_time(); - } - - /** - * 进入页面触发 - */ - pageShow(self) { - // 清空值 ,初始化 ,避免污染后面的上报数据 - this._navigationBarTitle = { - config: '', - page: '', - report: '', - lt: '', - }; - - const route = get_page_route(self); - const routepath = get_route(self); - - this._navigationBarTitle.config = get_page_name(routepath); - // 表示应用触发 ,页面切换不触发之后的逻辑 - if (this.__licationShow) { - get_first_time(); - // this._lastPageRoute = route - uni.setStorageSync('_STAT_LAST_PAGE_ROUTE', route); - this.__licationShow = false; - return - } - - get_last_time(); - - const time = get_residence_time('page'); - // 停留时间 - if (time.overtime) { - let options = { - path: route, - scene: this.statData.sc, - }; - this.sendReportRequest(options); - } - // 重置时间 - get_first_time(); - } - - /** - * 离开页面触发 - */ - pageHide(self) { - if (!this.__licationHide) { - get_last_time(); - const time = get_residence_time('page'); - let route = get_page_route(self); - let lastPageRoute = uni.getStorageSync('_STAT_LAST_PAGE_ROUTE'); - if (!lastPageRoute) { - lastPageRoute = route; - } - uni.setStorageSync('_STAT_LAST_PAGE_ROUTE', route); - this.sendPageRequest({ - url: route, - urlref: lastPageRoute, - urlref_ts: time.residenceTime, - }); - // this._lastPageRoute = route - return - } - } - - - /** - * 发送请求,应用维度上报 - * @param {Object} options 页面信息 - */ - sendReportRequest(options) { - this._navigationBarTitle.lt = '1'; - this._navigationBarTitle.config = get_page_name(options.path); - let is_opt = options.query && JSON.stringify(options.query) !== '{}'; - let query = is_opt ? '?' + JSON.stringify(options.query) : ''; - Object.assign(this.statData, { - lt: '1', - url: (options.path + query) || '', - t: get_time(), - sc: get_scene(options.scene), - fvts: get_first_visit_time(), - lvts: get_last_visit_time(), - tvc: get_total_visit_count() - }); - if (get_platform_name() === 'n') { - this.getProperty(); - } else { - this.getNetworkInfo(); - } - } - - /** - * 发送请求,页面维度上报 - * @param {Object} opt - */ - sendPageRequest(opt) { - let { - url, - urlref, - urlref_ts - } = opt; - this._navigationBarTitle.lt = '11'; - let options = { - ak: this.statData.ak, - uuid: this.statData.uuid, - lt: '11', - ut: this.statData.ut, - url, - tt: this.statData.tt, - urlref, - urlref_ts, - ch: this.statData.ch, - usv: this.statData.usv, - t: get_time(), - p: this.statData.p, - }; - this.request(options); - } - - /** - * 进入后台上报数据 - * @param {Object} opt - * @param {Object} type - */ - sendHideRequest(opt, type) { - let { - urlref, - urlref_ts - } = opt; - let options = { - ak: this.statData.ak, - uuid: this.statData.uuid, - lt: '3', - ut: this.statData.ut, - urlref, - urlref_ts, - ch: this.statData.ch, - usv: this.statData.usv, - t: get_time(), - p: this.statData.p, - }; - this.request(options, type); - } - - /** - * 自定义事件上报 - */ - sendEventRequest({ - key = '', - value = '' - } = {}) { - // const route = this._lastPageRoute - const routepath = get_route(); - this._navigationBarTitle.config = get_page_name(routepath); - this._navigationBarTitle.lt = '21'; - let options = { - ak: this.statData.ak, - uuid: this.statData.uuid, - lt: '21', - ut: this.statData.ut, - url: routepath, - ch: this.statData.ch, - e_n: key, - e_v: typeof value === 'object' ? JSON.stringify(value) : value.toString(), - usv: this.statData.usv, - t: get_time(), - p: this.statData.p, - }; - this.request(options); - } - - /** - * 获取wgt资源版本 - */ - getProperty() { - plus.runtime.getProperty(plus.runtime.appid, (wgtinfo) => { - this.statData.v = wgtinfo.version || ''; - this.getNetworkInfo(); - }); - } - - /** - * 获取网络信息 - */ - getNetworkInfo() { - uni.getNetworkType({ - success: (result) => { - this.statData.net = result.networkType; - this.getLocation(); - }, - }); - } - - /** - * 获取位置信息 - */ - getLocation() { - if (statConfig.getLocation) { - uni.getLocation({ - type: 'wgs84', - geocode: true, - success: (result) => { - if (result.address) { - this.statData.cn = result.address.country; - this.statData.pn = result.address.province; - this.statData.ct = result.address.city; - } - - this.statData.lat = result.latitude; - this.statData.lng = result.longitude; - this.request(this.statData); - }, - }); - } else { - this.statData.lat = 0; - this.statData.lng = 0; - this.request(this.statData); - } - } - - /** - * 发送请求 - * @param {Object} data 上报数据 - * @param {Object} type 类型 - */ - request(data, type) { - let time = get_time(); - const title = this._navigationBarTitle; - Object.assign(data, { - ttn: title.page, - ttpj: title.config, - ttc: title.report - }); - - let uniStatData = dbGet('__UNI__STAT__DATA') || {}; - if (!uniStatData[data.lt]) { - uniStatData[data.lt] = []; - } - // 加入队列 - uniStatData[data.lt].push(data); - dbSet('__UNI__STAT__DATA', uniStatData); - - let page_residence_time = get_page_residence_time(); - // 判断时候到达上报时间 ,默认 10 秒上报 - if (page_residence_time < OPERATING_TIME && !type) return - - // 时间超过,重新获取时间戳 - set_page_residence_time(); - const stat_data = handle_data(uniStatData); - let optionsData = { - usv: STAT_VERSION, //统计 SDK 版本号 - t: time, //发送请求时的时间戮 - requests: stat_data, - }; - - // 重置队列 - dbRemove('__UNI__STAT__DATA'); - - // XXX 安卓需要延迟上报 ,否则会有未知错误,需要验证处理 - if (get_platform_name() === 'n' && this.statData.p === 'a') { - setTimeout(() => { - this.sendRequest(optionsData); - }, 200); - return - } - - this.sendRequest(optionsData); - } - - - /** - * 数据上报 - * @param {Object} optionsData 需要上报的数据 - */ - sendRequest(optionsData) { - - if (!uniCloud.config) { - console.error('当前尚未绑定服务空间.'); - return - } - uniCloud.callFunction({ - name: 'uni-stat-report', - data: optionsData, - success: (res) => {}, - fail: (err) => { - console.log(err); - } - }); - } - - sendEvent(key, value) { - // 校验 type 参数 - if (calibration(key, value)) return - - if (key === 'title') { - this._navigationBarTitle.report = value; - return - } - this.sendEventRequest({ - key, - value: typeof value === 'object' ? JSON.stringify(value) : value, - }, - 1 - ); - } -} - -let vue = (Vue.default || Vue); - -class Stat extends Report { - static getInstance() { - if (!vue.instance) { - vue.instance = new Stat(); - } - return vue.instance - } - constructor() { - super(); - this.instance = null; - } - - /** - * 进入应用 - * @param {Object} options 页面参数 - * @param {Object} self 当前页面实例 - */ - launch(options, self) { - // 初始化页面停留时间 start - let residence_time = set_page_residence_time(); - this.__licationShow = true; - this.sendReportRequest(options, true); - } - load(options, self) { - this.self = self; - this._query = options; - } - - appHide(self){ - this.applicationHide(self, true); - } - - appShow(self){ - this.applicationShow(self); - } - - show(self) { - this.self = self; - if (get_page_types(self) === 'page') { - this.pageShow(self); - } - if (get_page_types(self) === 'app') { - this.appShow(self); - } - } - - hide(self) { - this.self = self; - if (get_page_types(self) === 'page') { - this.pageHide(self); - } - if (get_page_types(self) === 'app') { - this.appHide(self); - } - } - - error(em) { - // 开发工具内不上报错误 - if (this._platform === 'devtools') { - if (process.env.NODE_ENV === 'development') { - console.info('当前运行环境为开发者工具,不上报数据。'); - return; - } - } - let emVal = ''; - if (!em.message) { - emVal = JSON.stringify(em); - } else { - emVal = em.stack; - } - let options = { - ak: this.statData.ak, - uuid: this.statData.uuid, - lt: '31', - ut: this.statData.ut, - ch: this.statData.ch, - mpsdk: this.statData.mpsdk, - mpv: this.statData.mpv, - v: this.statData.v, - em: emVal, - usv: this.statData.usv, - t: parseInt(new Date().getTime() / 1000), - p: this.statData.p, - }; - this.request(options); - } -} - -const stat = Stat.getInstance(); - -// 用于判断是隐藏页面还是卸载页面 -let isHide = false; - -const lifecycle = { - onLaunch(options) { - // 进入应用上报数据 - stat.launch(options, this); - }, - onLoad(options) { - stat.load(options, this); - // 重写分享,获取分享上报事件 - if (this.$scope && this.$scope.onShareAppMessage) { - let oldShareAppMessage = this.$scope.onShareAppMessage; - this.$scope.onShareAppMessage = function(options) { - stat.interceptShare(false); - return oldShareAppMessage.call(this, options) - }; - } - }, - onShow() { - isHide = false; - stat.show(this); - }, - onHide() { - isHide = true; - stat.hide(this); - }, - onUnload() { - if (isHide) { - isHide = false; - return - } - stat.hide(this); - }, - onError(e) { - stat.error(e); - } -}; - - -function main() { - if (process.env.NODE_ENV === 'development') { - uni.report = function(type, options) {}; - } else { - console.log('uniCloud统计已开启'); - const Vue = require('vue'); - (Vue.default || Vue).mixin(lifecycle); - uni.report = function(type, options) { - stat.sendEvent(type, options); - }; - } -} - -main(); diff --git a/packages/uni-cloud-stat/package.json b/packages/uni-cloud-stat/package.json deleted file mode 100644 index 8a128915d5aced120398a3a0c9fbb2b0d32f6231..0000000000000000000000000000000000000000 --- a/packages/uni-cloud-stat/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "@dcloudio/uni-cloud-stat", - "version": "2.0.0-32920211029001", - "description": "", - "main": "dist/index.js", - "repository": { - "type": "git", - "url": "git+https://github.com/dcloudio/uni-app.git", - "directory": "packages/uni-cloud-stat" - }, - "scripts": { - "dev": "NODE_ENV=development rollup -w -c rollup.config.js", - "build": "NODE_ENV=production rollup -c rollup.config.js" - }, - "files": [ - "dist", - "package.json", - "LICENSE" - ], - "author": "", - "license": "Apache-2.0", - "devDependencies": { - "@babel/core": "^7.5.5", - "@babel/preset-env": "^7.5.5", - "eslint": "^6.1.0", - "rollup": "^1.19.3", - "rollup-plugin-babel": "^4.3.3", - "rollup-plugin-clear": "^2.0.7", - "rollup-plugin-commonjs": "^10.0.2", - "rollup-plugin-copy": "^3.1.0", - "rollup-plugin-eslint": "^7.0.0", - "rollup-plugin-json": "^4.0.0", - "rollup-plugin-node-resolve": "^5.2.0", - "rollup-plugin-replace": "^2.2.0", - "rollup-plugin-uglify": "^6.0.2" - }, - "gitHead": "9e2d0f8e244724fcd64880316c57d837d1778cf8" -} diff --git a/packages/uni-cloud-stat/src/config.js b/packages/uni-cloud-stat/src/config.js deleted file mode 100644 index 22ddb49ee80f1ea05f900e97fb478466098fe121..0000000000000000000000000000000000000000 --- a/packages/uni-cloud-stat/src/config.js +++ /dev/null @@ -1,11 +0,0 @@ -// 访问开始即启动小程序,访问结束结分为:进入后台超过5min、在前台无任何操作超过30min、在新的来源打开小程序; -export const STAT_VERSION = '0.0.1' -export const STAT_URL = 'https://tongji.dcloud.io/uni/stat' -export const STAT_H5_URL = 'https://tongji.dcloud.io/uni/stat.gif' -export const STAT_KEY = 'qkTHEIegZGcL5iy3' -export const PAGE_PVER_TIME = 1800 // 页面在前台无操作结束访问时间 单位s -export const APP_PVER_TIME = 300 // 应用在后台结束访问时间 单位s -export const OPERATING_TIME = 10 // 数据上报时间 单位s -export const DIFF_TIME = 60 * 1000 * 60 * 24 - -export const DEBUG = true diff --git a/packages/uni-cloud-stat/src/core/report.js b/packages/uni-cloud-stat/src/core/report.js deleted file mode 100644 index 705750a7e6345f59b4a06b4a1c2ded30c08ac84d..0000000000000000000000000000000000000000 --- a/packages/uni-cloud-stat/src/core/report.js +++ /dev/null @@ -1,523 +0,0 @@ -let statConfig = require('uni-stat-config').default || require('uni-stat-config'); - -import { - get_time, - set_page_residence_time, - get_first_visit_time, - get_last_visit_time, - get_total_visit_count, - get_page_residence_time, - get_first_time, - get_last_time, - get_residence_time -} from '../utils/pageTime.js' - -import { - get_uuid, - get_platform_name, - get_pack_name, - get_scene, - get_version, - get_channel, - get_splicing, - get_page_route, - get_route, - handle_data, - calibration, - get_page_name, - get_sgin, - get_encodeURIComponent_options -} from '../utils/pageInfo.js' - -import { - sys -} from '../utils/util.js' - -import { - STAT_VERSION, - OPERATING_TIME, - STAT_URL, - STAT_H5_URL, - DEBUG -} from '../config.js'; - -import { - dbSet, - dbGet, - dbRemove -} from '../utils/db.js' - -// 统计数据默认值 -let statData = { - uuid: get_uuid(), // 设备标识 - ut: get_platform_name(), // 平台类型 - mpn: get_pack_name(), // 原生平台包名、小程序 appid - ak: statConfig.appid, // uni-app 应用 Appid - usv: STAT_VERSION, // 统计 sdk 版本 - v: get_version(), // 应用版本,仅app - ch: get_channel(), // 渠道信息 - cn: '', // 国家 - pn: '', // 省份 - ct: '', // 城市 - t: get_time(), // 上报数据时的时间戳 - tt: '', - p: sys.platform === 'android' ? 'a' : 'i', // 手机系统 - brand: sys.brand || '', // 手机品牌 - md: sys.model, // 手机型号 - sv: sys.system.replace(/(Android|iOS)\s/, ''), // 手机系统版本 - mpsdk: sys.SDKVersion || '', // x程序 sdk version - mpv: sys.version || '', // 小程序平台版本 ,如微信、支付宝 - lang: sys.language, // 语言 - pr: sys.pixelRatio, // pixelRatio 设备像素比 - ww: sys.windowWidth, // windowWidth 可使用窗口宽度 - wh: sys.windowHeight, // windowHeight 可使用窗口高度 - sw: sys.screenWidth, // screenWidth 屏幕宽度 - sh: sys.screenHeight, // screenHeight 屏幕高度 -} -export default class Report { - constructor() { - // 页面实例 - this.self = '' - // 进入应用标识 - this.__licationShow = false - // 离开应用标识 - this.__licationHide = false - // 统计默认值 - this.statData = statData - // 标题默认值 - this._navigationBarTitle = { - config: '', - page: '', - report: '', - lt: '', - } - - // 页面参数 - this._query = {} - // 页面最后停留页面的 url - // this._lastPageRoute = '' - - // 注册拦截器 - let registerInterceptor = typeof uni.addInterceptor === 'function' - if (registerInterceptor) { - this.addInterceptorInit() - this.interceptLogin() - this.interceptShare(true) - this.interceptRequestPayment() - } - } - - addInterceptorInit() { - let self = this - uni.addInterceptor('setNavigationBarTitle', { - invoke(args) { - self._navigationBarTitle.page = args.title - }, - }) - } - - interceptLogin() { - let self = this - uni.addInterceptor('login', { - complete() { - self._login() - }, - }) - } - - interceptShare(type) { - let self = this - if (!type) { - self._share() - return - } - uni.addInterceptor('share', { - success() { - self._share() - }, - fail() { - self._share() - }, - }) - } - - interceptRequestPayment() { - let self = this - uni.addInterceptor('requestPayment', { - success() { - self._payment('pay_success') - }, - fail() { - self._payment('pay_fail') - }, - }) - } - - _login() { - this.sendEventRequest({ - key: 'login', - }, - 0 - ) - } - - _share() { - this.sendEventRequest({ - key: 'share', - }, 0) - } - _payment(key) { - this.sendEventRequest({ - key, - }, 0) - } - - /** - * 进入应用触发 - */ - applicationShow() { - // 通过 __licationHide 判断保证是进入后台后在次进入应用,避免重复上报数据 - if (this.__licationHide) { - get_last_time() - const time = get_residence_time('app') - // 需要判断进入后台是否超过时限 ,默认是 30min ,是的话需要执行进入应用的上报 - if (time.overtime) { - let lastPageRoute = uni.getStorageSync('_STAT_LAST_PAGE_ROUTE') - let options = { - path: lastPageRoute, - scene: this.statData.sc, - } - this.sendReportRequest(options) - } - // 状态重置 - this.__licationHide = false - } - } - - /** - * 离开应用触发 - * @param {Object} self - * @param {Object} type - */ - applicationHide(self, type) { - // 进入应用后台保存状态,方便进入前台后判断是否上报应用数据 - this.__licationHide = true - get_last_time() - const time = get_residence_time() - const route = get_page_route(self) - // this._lastPageRoute = route - uni.setStorageSync('_STAT_LAST_PAGE_ROUTE', route) - this.sendHideRequest({ - urlref: route, - urlref_ts: time.residenceTime, - }, - type - ) - // 重置时间 - get_first_time() - } - - /** - * 进入页面触发 - */ - pageShow(self) { - // 清空值 ,初始化 ,避免污染后面的上报数据 - this._navigationBarTitle = { - config: '', - page: '', - report: '', - lt: '', - } - - const route = get_page_route(self) - const routepath = get_route(self) - - this._navigationBarTitle.config = get_page_name(routepath) - // 表示应用触发 ,页面切换不触发之后的逻辑 - if (this.__licationShow) { - get_first_time() - // this._lastPageRoute = route - uni.setStorageSync('_STAT_LAST_PAGE_ROUTE', route) - this.__licationShow = false - return - } - - get_last_time() - - const time = get_residence_time('page') - // 停留时间 - if (time.overtime) { - let options = { - path: route, - scene: this.statData.sc, - } - this.sendReportRequest(options) - } - // 重置时间 - get_first_time() - } - - /** - * 离开页面触发 - */ - pageHide(self) { - if (!this.__licationHide) { - get_last_time() - const time = get_residence_time('page') - let route = get_page_route(self) - let lastPageRoute = uni.getStorageSync('_STAT_LAST_PAGE_ROUTE') - if (!lastPageRoute) { - lastPageRoute = route - } - uni.setStorageSync('_STAT_LAST_PAGE_ROUTE', route) - this.sendPageRequest({ - url: route, - urlref: lastPageRoute, - urlref_ts: time.residenceTime, - }) - // this._lastPageRoute = route - return - } - } - - - /** - * 发送请求,应用维度上报 - * @param {Object} options 页面信息 - */ - sendReportRequest(options) { - this._navigationBarTitle.lt = '1' - this._navigationBarTitle.config = get_page_name(options.path) - let is_opt = options.query && JSON.stringify(options.query) !== '{}' - let query = is_opt ? '?' + JSON.stringify(options.query) : '' - Object.assign(this.statData, { - lt: '1', - url: (options.path + query) || '', - t: get_time(), - sc: get_scene(options.scene), - fvts: get_first_visit_time(), - lvts: get_last_visit_time(), - tvc: get_total_visit_count() - }) - if (get_platform_name() === 'n') { - this.getProperty() - } else { - this.getNetworkInfo() - } - } - - /** - * 发送请求,页面维度上报 - * @param {Object} opt - */ - sendPageRequest(opt) { - let { - url, - urlref, - urlref_ts - } = opt - this._navigationBarTitle.lt = '11' - let options = { - ak: this.statData.ak, - uuid: this.statData.uuid, - lt: '11', - ut: this.statData.ut, - url, - tt: this.statData.tt, - urlref, - urlref_ts, - ch: this.statData.ch, - usv: this.statData.usv, - t: get_time(), - p: this.statData.p, - } - this.request(options) - } - - /** - * 进入后台上报数据 - * @param {Object} opt - * @param {Object} type - */ - sendHideRequest(opt, type) { - let { - urlref, - urlref_ts - } = opt - let options = { - ak: this.statData.ak, - uuid: this.statData.uuid, - lt: '3', - ut: this.statData.ut, - urlref, - urlref_ts, - ch: this.statData.ch, - usv: this.statData.usv, - t: get_time(), - p: this.statData.p, - } - this.request(options, type) - } - - /** - * 自定义事件上报 - */ - sendEventRequest({ - key = '', - value = '' - } = {}) { - // const route = this._lastPageRoute - const routepath = get_route() - this._navigationBarTitle.config = get_page_name(routepath) - this._navigationBarTitle.lt = '21' - let options = { - ak: this.statData.ak, - uuid: this.statData.uuid, - lt: '21', - ut: this.statData.ut, - url: routepath, - ch: this.statData.ch, - e_n: key, - e_v: typeof value === 'object' ? JSON.stringify(value) : value.toString(), - usv: this.statData.usv, - t: get_time(), - p: this.statData.p, - } - this.request(options) - } - - /** - * 获取wgt资源版本 - */ - getProperty() { - plus.runtime.getProperty(plus.runtime.appid, (wgtinfo) => { - this.statData.v = wgtinfo.version || '' - this.getNetworkInfo() - }) - } - - /** - * 获取网络信息 - */ - getNetworkInfo() { - uni.getNetworkType({ - success: (result) => { - this.statData.net = result.networkType - this.getLocation() - }, - }) - } - - /** - * 获取位置信息 - */ - getLocation() { - if (statConfig.getLocation) { - uni.getLocation({ - type: 'wgs84', - geocode: true, - success: (result) => { - if (result.address) { - this.statData.cn = result.address.country - this.statData.pn = result.address.province - this.statData.ct = result.address.city - } - - this.statData.lat = result.latitude - this.statData.lng = result.longitude - this.request(this.statData) - }, - }) - } else { - this.statData.lat = 0 - this.statData.lng = 0 - this.request(this.statData) - } - } - - /** - * 发送请求 - * @param {Object} data 上报数据 - * @param {Object} type 类型 - */ - request(data, type) { - let time = get_time() - const title = this._navigationBarTitle - Object.assign(data, { - ttn: title.page, - ttpj: title.config, - ttc: title.report - }) - - let uniStatData = dbGet('__UNI__STAT__DATA') || {} - if (!uniStatData[data.lt]) { - uniStatData[data.lt] = [] - } - // 加入队列 - uniStatData[data.lt].push(data) - dbSet('__UNI__STAT__DATA', uniStatData) - - let page_residence_time = get_page_residence_time() - // 判断时候到达上报时间 ,默认 10 秒上报 - if (page_residence_time < OPERATING_TIME && !type) return - - // 时间超过,重新获取时间戳 - set_page_residence_time() - const stat_data = handle_data(uniStatData) - let optionsData = { - usv: STAT_VERSION, //统计 SDK 版本号 - t: time, //发送请求时的时间戮 - requests: stat_data, - } - - // 重置队列 - dbRemove('__UNI__STAT__DATA') - - // XXX 安卓需要延迟上报 ,否则会有未知错误,需要验证处理 - if (get_platform_name() === 'n' && this.statData.p === 'a') { - setTimeout(() => { - this.sendRequest(optionsData) - }, 200) - return - } - - this.sendRequest(optionsData) - } - - - /** - * 数据上报 - * @param {Object} optionsData 需要上报的数据 - */ - sendRequest(optionsData) { - - if (!uniCloud.config) { - console.error('当前尚未绑定服务空间.') - return - } - uniCloud.callFunction({ - name: 'uni-stat-report', - data: optionsData, - success: (res) => {}, - fail: (err) => { - console.log(err); - } - }) - } - - sendEvent(key, value) { - // 校验 type 参数 - if (calibration(key, value)) return - - if (key === 'title') { - this._navigationBarTitle.report = value - return - } - this.sendEventRequest({ - key, - value: typeof value === 'object' ? JSON.stringify(value) : value, - }, - 1 - ) - } -} diff --git a/packages/uni-cloud-stat/src/core/stat.js b/packages/uni-cloud-stat/src/core/stat.js deleted file mode 100644 index f7bd623893bfaf80185758bc60938894e5f6720a..0000000000000000000000000000000000000000 --- a/packages/uni-cloud-stat/src/core/stat.js +++ /dev/null @@ -1,99 +0,0 @@ -import Report from './report.js' -import Vue from 'vue' -let vue = (Vue.default || Vue) -import { - set_page_residence_time -} from '../utils/pageTime.js' -import { - get_page_types, - get_platform_name -} from '../utils/pageInfo.js' - -class Stat extends Report { - static getInstance() { - if (!vue.instance) { - vue.instance = new Stat() - } - return vue.instance - } - constructor() { - super() - this.instance = null - } - - /** - * 进入应用 - * @param {Object} options 页面参数 - * @param {Object} self 当前页面实例 - */ - launch(options, self) { - // 初始化页面停留时间 start - let residence_time = set_page_residence_time() - this.__licationShow = true - this.sendReportRequest(options, true) - } - load(options, self) { - this.self = self - this._query = options - } - - appHide(self){ - this.applicationHide(self, true) - } - - appShow(self){ - this.applicationShow(self) - } - - show(self) { - this.self = self - if (get_page_types(self) === 'page') { - this.pageShow(self) - } - if (get_page_types(self) === 'app') { - this.appShow(self) - } - } - - hide(self) { - this.self = self - if (get_page_types(self) === 'page') { - this.pageHide(self) - } - if (get_page_types(self) === 'app') { - this.appHide(self) - } - } - - error(em) { - // 开发工具内不上报错误 - if (this._platform === 'devtools') { - if (process.env.NODE_ENV === 'development') { - console.info('当前运行环境为开发者工具,不上报数据。') - return; - } - } - let emVal = '' - if (!em.message) { - emVal = JSON.stringify(em) - } else { - emVal = em.stack - } - let options = { - ak: this.statData.ak, - uuid: this.statData.uuid, - lt: '31', - ut: this.statData.ut, - ch: this.statData.ch, - mpsdk: this.statData.mpsdk, - mpv: this.statData.mpv, - v: this.statData.v, - em: emVal, - usv: this.statData.usv, - t: parseInt(new Date().getTime() / 1000), - p: this.statData.p, - } - this.request(options) - } -} -export default Stat diff --git a/packages/uni-cloud-stat/src/index.js b/packages/uni-cloud-stat/src/index.js deleted file mode 100644 index a6485a953893070311201ef74685c6b89ffc4f65..0000000000000000000000000000000000000000 --- a/packages/uni-cloud-stat/src/index.js +++ /dev/null @@ -1,61 +0,0 @@ -import { - get_platform_name, - get_page_vm -} from './utils/pageInfo.js' -import Stat from './core/stat.js' -const stat = Stat.getInstance() - -// 用于判断是隐藏页面还是卸载页面 -let isHide = false - -const lifecycle = { - onLaunch(options) { - // 进入应用上报数据 - stat.launch(options, this); - }, - onLoad(options) { - stat.load(options, this); - // 重写分享,获取分享上报事件 - if (this.$scope && this.$scope.onShareAppMessage) { - let oldShareAppMessage = this.$scope.onShareAppMessage; - this.$scope.onShareAppMessage = function(options) { - stat.interceptShare(false); - return oldShareAppMessage.call(this, options) - } - } - }, - onShow() { - isHide = false - stat.show(this); - }, - onHide() { - isHide = true - stat.hide(this); - }, - onUnload() { - if (isHide) { - isHide = false - return - } - stat.hide(this); - }, - onError(e) { - stat.error(e) - } -} - - -function main() { - if (process.env.NODE_ENV === 'development') { - uni.report = function(type, options) {}; - } else { - console.log('uniCloud统计已开启'); - const Vue = require('vue'); - (Vue.default || Vue).mixin(lifecycle); - uni.report = function(type, options) { - stat.sendEvent(type, options); - }; - } -} - -main() diff --git a/packages/uni-cloud-stat/src/utils/config.js b/packages/uni-cloud-stat/src/utils/config.js deleted file mode 100644 index 24c21c6bb405c6b2028704f54b4ee8d2d0b95612..0000000000000000000000000000000000000000 --- a/packages/uni-cloud-stat/src/utils/config.js +++ /dev/null @@ -1,11 +0,0 @@ -// 访问开始即启动小程序,访问结束结分为:进入后台超过5min、在前台无任何操作超过30min、在新的来源打开小程序; -export const STAT_VERSION = '0.0.1' - -export const PAGE_PVER_TIME = 1800 // 页面在前台无操作结束访问时间 单位s -// export const PAGE_PVER_TIME = 0 -export const APP_PVER_TIME = 300 // 应用在后台结束访问时间 单位s -// export const APP_PVER_TIME = 0 -// export const OPERATING_TIME = 10 // 数据上报时间 单位s -export const OPERATING_TIME = 10 // 数据上报时间 单位s - -export const DEBUG = true diff --git a/packages/uni-cloud-stat/src/utils/db.js b/packages/uni-cloud-stat/src/utils/db.js deleted file mode 100755 index 434f7114b95ddfe3ceaf31aad34f91c1c1a42ef1..0000000000000000000000000000000000000000 --- a/packages/uni-cloud-stat/src/utils/db.js +++ /dev/null @@ -1,33 +0,0 @@ -export const dbSet = (name, value) => { - let data = uni.getStorageSync('$$STAT__DBDATA') || {} - if (!data) { - data = {} - } - data[name] = value - uni.setStorageSync('$$STAT__DBDATA', data) -} - -export const dbGet = (name) => { - let data = uni.getStorageSync('$$STAT__DBDATA') || {} - if (!data) { - data = {} - } - if (!data[name]) { - return undefined - } - return data[name] -} - -export const dbRemove = (name) => { - let data = uni.getStorageSync('$$STAT__DBDATA') || {} - if (data[name]) { - delete data[name] - uni.setStorageSync('$$STAT__DBDATA', data) - } else { - data = uni.getStorageSync('$$STAT__DBDATA') - if (data[name]) { - delete data[name] - uni.setStorageSync('$$STAT__DBDATA', data) - } - } -} diff --git a/packages/uni-cloud-stat/src/utils/deepClone.js b/packages/uni-cloud-stat/src/utils/deepClone.js deleted file mode 100755 index d356c5491442764272a0076d98765c0720bcecfe..0000000000000000000000000000000000000000 --- a/packages/uni-cloud-stat/src/utils/deepClone.js +++ /dev/null @@ -1,22 +0,0 @@ -// 判断arr是否为一个数组,返回一个bool值 -function isArray (arr) { - return Object.prototype.toString.call(arr) === '[object Array]'; -} - -// 深度克隆 -export const deepClone = (obj)=> { - // 对常见的“非”值,直接返回原来值 - if([null, undefined, NaN, false].includes(obj)) return obj; - if(typeof obj !== "object" && typeof obj !== 'function') { - //原始类型直接返回 - return obj; - } - var o = isArray(obj) ? [] : {}; - for(let i in obj) { - if(obj.hasOwnProperty(i)){ - o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i]; - } - } - return o; -} - diff --git a/packages/uni-cloud-stat/src/utils/deepMerge.js b/packages/uni-cloud-stat/src/utils/deepMerge.js deleted file mode 100755 index 23d664cac58823849c27761bdae700f58e5491ea..0000000000000000000000000000000000000000 --- a/packages/uni-cloud-stat/src/utils/deepMerge.js +++ /dev/null @@ -1,27 +0,0 @@ -import {deepClone} from './deepClone.js' -// JS对象深度合并 -export const deepMerge = (target = {}, source = {})=> { - target = deepClone(target); - if (typeof target !== 'object' || typeof source !== 'object') return false; - for (var prop in source) { - if (!source.hasOwnProperty(prop)) continue; - if (prop in target) { - if (typeof target[prop] !== 'object') { - target[prop] = source[prop]; - } else { - if (typeof source[prop] !== 'object') { - target[prop] = source[prop]; - } else { - if (target[prop].concat && source[prop].concat) { - target[prop] = target[prop].concat(source[prop]); - } else { - target[prop] = deepMerge(target[prop], source[prop]); - } - } - } - } else { - target[prop] = source[prop]; - } - } - return target; -} diff --git a/packages/uni-cloud-stat/src/utils/index.js b/packages/uni-cloud-stat/src/utils/index.js deleted file mode 100755 index 656d30279b07eef4f6be47f85a8d3112da83caa5..0000000000000000000000000000000000000000 --- a/packages/uni-cloud-stat/src/utils/index.js +++ /dev/null @@ -1,10 +0,0 @@ -// 批量导出文件 -const requireApi = require.context('.', false, /.js$/) -let module = {} -let noAllowPaht = ['./index.js'] -requireApi.keys().forEach((key, index) => { - if ( noAllowPaht.indexOf(key) !== -1 ) return - Object.assign(module, requireApi(key)) -}) -export default module - diff --git a/packages/uni-cloud-stat/src/utils/pageInfo.js b/packages/uni-cloud-stat/src/utils/pageInfo.js deleted file mode 100644 index 2e7c0ef014c4aee917c16188683976f23e8198c1..0000000000000000000000000000000000000000 --- a/packages/uni-cloud-stat/src/utils/pageInfo.js +++ /dev/null @@ -1,307 +0,0 @@ -import pagesTitle from 'uni-pages?{"type":"style"}' -let pagesData = pagesTitle.pages -let titleJsons = {} -for (let i in pagesData) { - titleJsons[i] = pagesData[i].navigationBarTitleText || '' -} - -import { - sys -} from './util.js' - - -import { - STAT_URL, - STAT_VERSION, - DIFF_TIME -} from '../config.js'; - -const UUID_KEY = '__DC_STAT_UUID' -const UUID_VALUE = '__DC_UUID_VALUE' - -function getUuid() { - let uuid = '' - if (get_platform_name() === 'n') { - try { - uuid = plus.runtime.getDCloudId() - } catch (e) { - uuid = '' - } - return uuid - } - - try { - uuid = uni.getStorageSync(UUID_KEY) - } catch (e) { - uuid = UUID_VALUE - } - - if (!uuid) { - uuid = Date.now() + '' + Math.floor(Math.random() * 1e7) - try { - uni.setStorageSync(UUID_KEY, uuid) - } catch (e) { - uni.setStorageSync(UUID_KEY, UUID_VALUE) - } - } - return uuid -} - -export const get_uuid = (statData) => { - // 有可能不存在 deviceId(一般不存在就是出bug了),就自己生成一个 - return sys.deviceId || getUuid() -} - -export const get_sgin = (statData) => { - let arr = Object.keys(statData) - let sortArr = arr.sort() - let sgin = {} - let sginStr = '' - for (var i in sortArr) { - sgin[sortArr[i]] = statData[sortArr[i]] - sginStr += sortArr[i] + '=' + statData[sortArr[i]] + '&' - } - - return { - sign: '', - options: sginStr.substr(0, sginStr.length - 1), - } -} - -export const get_encodeURIComponent_options = (statData) => { - let data = {} - for (let prop in statData) { - data[prop] = encodeURIComponent(statData[prop]) - } - return data -} - -/** - * 获取当前平台 - * 移动端 : 'n', - * h5 : 'h5', - * 微信 : 'wx', - * 阿里 : 'ali', - * 百度 : 'bd', - * 头条 : 'tt', - * qq : 'qq', - * 快应用 : 'qn', - * 快手 : 'ks', - * 飞书 : 'lark', - * 快应用 : 'qw', - * 钉钉 : 'dt' - */ -export const get_platform_name = () => { - // 苹果审核代码中禁止出现 alipay 字样 ,需要特殊处理一下 - const aliArr = ['y', 'a', 'p', 'mp-ali'] - const platformList = { - 'app': 'n', - 'app-plus': 'n', - h5: 'h5', - 'mp-weixin': 'wx', - [aliArr.reverse().join('')]: 'ali', - 'mp-baidu': 'bd', - 'mp-toutiao': 'tt', - 'mp-qq': 'qq', - 'quickapp-native': 'qn', - 'mp-kuaishou': 'ks', - 'mp-lark': 'lark', - 'quickapp-webview': 'qw' - } - if (platformList[process.env.VUE_APP_PLATFORM] === 'ali') { - if (my && my.env) { - const clientName = my.env.clientName - if (clientName === 'ap') return 'ali' - if (clientName === 'dingtalk') return 'dt' - // TODO 缺少 ali 下的其他平台 - } - } - return platformList[process.env.VUE_APP_PLATFORM] -} - -/** - * 获取小程序 appid - */ -export const get_pack_name = () => { - let packName = '' - if (get_platform_name() === 'wx' || get_platform_name() === 'qq') { - // 兼容微信小程序低版本基础库 - if (uni.canIUse('getAccountInfoSync')) { - packName = uni.getAccountInfoSync().miniProgram.appId || '' - } - } - if (get_platform_name() === 'n') { - // TODO APP 获取包名 - } - return packName -} - -/** - * 应用版本 - */ -export const get_version = () => { - return get_platform_name() === 'n' ? plus.runtime.version : '' -} - -/** - * 获取渠道 - */ -export const get_channel = () => { - const platformName = get_platform_name() - let channel = '' - if (platformName === 'n') { - channel = plus.runtime.channel - } - if (platformName === 'wx') { - // TODO 需要调研小程序二维码渠道如何获取; - } - return channel -} - -/** - * 获取小程序场景值 - * @param {Object} options 页面信息 - */ -export const get_scene = (options) => { - const platformName = get_platform_name() - let scene = '' - if (options) { - return options - } - if (platformName === 'wx') { - scene = uni.getLaunchOptionsSync().scene - } - return scene -} - -/** - * 获取拼接参数 - */ -export const get_splicing = (data) => { - let str = '' - for (var i in data) { - str += i + '=' + data[i] + '&' - } - return str.substr(0, str.length - 1) -} - -/** - * 获取页面url,不包含参数 - */ -export const get_route = (pageVm) => { - let _self = pageVm || get_page_vm(); - if (get_platform_name() === 'bd') { - let mp_route = _self.$mp && _self.$mp.page && _self.$mp.page.is; - let scope_route = _self.$scope && _self.$scope.is; - return mp_route || scope_route || '' - } else { - return _self.route || (_self.$scope && _self.$scope.route) || (_self.$mp && _self.$mp.page.route) - } -}; - -/** - * 获取页面url, 包含参数 - */ -export const get_page_route = (pageVm) => { - // 从 app 进入应用 ,没有 $page ,获取不到路由 ,需要获取页面 尝试从 getCurrentPages 获取也页面实例 - // FIXME 尽量不使用 getCurrentPages ,大部分获取路由是从 onHide 获取 ,这时可以获取到,如果是 onload ,则可能获取不到,比如 百度 - - let page = pageVm.$page || (pageVm.$scope && pageVm.$scope.$page) - let lastPageRoute = uni.getStorageSync('_STAT_LAST_PAGE_ROUTE'); - if (!page) return lastPageRoute || '' - return page.fullPath === '/' ? page.route : page.fullPath -}; - -/** - * 获取页面实例 - */ -export const get_page_vm = () => { - let pages = getCurrentPages() - let $page = pages[pages.length - 1] - if (!$page) return null - return $page.$vm -} - -/** - * 获取页面类型 - */ -export const get_page_types = (self) => { - // XXX 百度有问题 ,获取的都是 componet ,等待修复 - if (self.mpType === 'page' || self.$mpType === 'page' || (self.$mp && self.$mp.mpType === 'page') || self - .$options.mpType === 'page') { - return 'page'; - } - if (self.mpType === 'app' || self.$mpType === 'app' || (self.$mp && self.$mp.mpType === 'app') || self.$options - .mpType === 'app') { - return 'app' - } - return null; -} - -/** - * 处理上报参数 - * @param {Object} 需要处理的数据 - */ -export const handle_data = (statData) => { - let firstArr = [] - let contentArr = [] - let lastArr = [] - for (let i in statData) { - const rd = statData[i] - rd.forEach((elm) => { - const newData = get_splicing(elm) - if (i === 0) { - firstArr.push(newData) - } else if (i === 3) { - lastArr.push(newData) - } else { - contentArr.push(newData) - } - }) - } - - firstArr.push(...contentArr, ...lastArr) - // 参数需要处理成字符串,方便上传 - return JSON.stringify(firstArr) -} - - -/** - * 自定义事件参数校验 - */ -export const calibration = (eventName, options) => { - // login 、 share 、pay_success 、pay_fail 、register 、title - if (!eventName) { - console.error(`uni.report Missing [eventName] parameter`); - return true - } - if (typeof eventName !== 'string') { - console.error(`uni.report [eventName] Parameter type error, it can only be of type String`); - return true - } - if (eventName.length > 255) { - console.error(`uni.report [eventName] Parameter length cannot be greater than 255`); - return true - } - - if (typeof options !== 'string' && typeof options !== 'object') { - console.error('uni.report [options] Parameter type error, Only supports String or Object type'); - return true - } - - if (typeof options === 'string' && options.length > 255) { - console.error(`uni.report [options] Parameter length cannot be greater than 255`); - return true - } - - if (eventName === 'title' && typeof options !== 'string') { - console.error( - `uni.report [eventName] When the parameter is title, the [options] parameter can only be of type String` - ); - return true - } -} - -export const get_page_name = (routepath) => { - return (titleJsons && titleJsons[routepath]) || '' -} diff --git a/packages/uni-cloud-stat/src/utils/pageTime.js b/packages/uni-cloud-stat/src/utils/pageTime.js deleted file mode 100644 index f4183eb8eb6bf4a9eaa56b45cbbdabceae4a4181..0000000000000000000000000000000000000000 --- a/packages/uni-cloud-stat/src/utils/pageTime.js +++ /dev/null @@ -1,148 +0,0 @@ -import { - get_platform_name -} from './pageInfo.js' -import { - dbSet, - dbGet, - dbRemove -} from './db.js' -import { - PAGE_PVER_TIME, - APP_PVER_TIME -} from '../config.js'; -// 首次访问时间 -const FIRST_VISIT_TIME_KEY = '__first__visit__time' -// 最后访问时间 -const LAST_VISIT_TIME_KEY = '__last__visit__time' -/** - * 获取当前时间 - */ -export const get_time = () => { - return parseInt(new Date().getTime() / 1000) -} - -/** - * 获取首次访问时间 - */ -export const get_first_visit_time = () => { - const timeStorge = dbGet(FIRST_VISIT_TIME_KEY) - let time = 0 - if (timeStorge) { - time = timeStorge - } else { - time = get_time() - dbSet(FIRST_VISIT_TIME_KEY, time) - // 首次访问需要 将最后访问时间置 0 - dbRemove(LAST_VISIT_TIME_KEY) - } - return time -} - -/** - * 最后访问时间 - */ -export const get_last_visit_time = () => { - const timeStorge = dbGet(LAST_VISIT_TIME_KEY) - let time = 0 - if (timeStorge) { - time = timeStorge - } - dbSet(LAST_VISIT_TIME_KEY, get_time()) - return time -} - -// 页面停留时间记录key -const PAGE_RESIDENCE_TIME = '__page__residence__time' - -/** - * 设置页面停留时间 - */ -export const set_page_residence_time = () => { - let First_Page_Residence_Time = get_time() - dbSet(PAGE_RESIDENCE_TIME, First_Page_Residence_Time) - return First_Page_Residence_Time -} - -/** - * 获取页面停留时间 - */ -export const get_page_residence_time = () => { - let Last_Page_Residence_Time = get_time() - let First_Page_Residence_Time = dbGet(PAGE_RESIDENCE_TIME) - return Last_Page_Residence_Time - First_Page_Residence_Time -} - -/** - * 获取总访问次数 - */ -const TOTAL_VISIT_COUNT = '__total__visit__count' -export const get_total_visit_count = () => { - const timeStorge = dbGet(TOTAL_VISIT_COUNT) - let count = 1 - if (timeStorge) { - count = timeStorge - count++ - } - dbSet(TOTAL_VISIT_COUNT, count) - return count -} - -export const GetEncodeURIComponentOptions = (statData) => { - let data = {} - for (let prop in statData) { - data[prop] = encodeURIComponent(statData[prop]) - } - return data -} - -let Set__First__Time = 0 -let Set__Last__Time = 0 - -/** - * 获取第一次时间 - */ -export const get_first_time = () => { - let time = new Date().getTime() - Set__First__Time = time - Set__Last__Time = 0 - return time -} - -/** - * 获取最后一次时间 - */ -export const get_last_time = () => { - let time = new Date().getTime() - Set__Last__Time = time - return time -} - -/** - * 获取页面 \ 应用停留时间 - */ -export const get_residence_time = (type) => { - let residenceTime = 0 - if (Set__First__Time !== 0) { - residenceTime = Set__Last__Time - Set__First__Time - } - - residenceTime = parseInt(residenceTime / 1000) - residenceTime = residenceTime < 1 ? 1 : residenceTime - if (type === 'app') { - let overtime = residenceTime > APP_PVER_TIME ? true : false - return { - residenceTime, - overtime, - } - } - if (type === 'page') { - let overtime = residenceTime > PAGE_PVER_TIME ? true : false - return { - residenceTime, - overtime, - } - } - return { - residenceTime, - } -} diff --git a/packages/uni-cloud-stat/src/utils/util.js b/packages/uni-cloud-stat/src/utils/util.js deleted file mode 100755 index 9e0254efee4fb3d5122e5e333d1562d933bbc6b4..0000000000000000000000000000000000000000 --- a/packages/uni-cloud-stat/src/utils/util.js +++ /dev/null @@ -1,5 +0,0 @@ -/** - * 获取系统信息 - */ -export const sys = uni.getSystemInfoSync() -