提交 52dade77 编写于 作者: fxy060608's avatar fxy060608

feat: add uni-stat

上级 bc25bf5e
......@@ -6,7 +6,7 @@
],
"scripts": {
"build": "node scripts/build.js",
"build:h5": "node scripts/build.js uni-app uni-cli-shared uni-h5 uni-i18n uni-shared uni-h5-vite vite-plugin-uni",
"build:h5": "node scripts/build.js uni-app uni-cli-shared uni-h5 uni-i18n uni-stat uni-shared uni-h5-vite vite-plugin-uni",
"build:app": "node scripts/build.js uni-app-plus uni-app-vite uni-app-vue uni-cli-nvue",
"build:mp": "node scripts/build.js uni-mp-alipay uni-mp-baidu uni-mp-qq uni-mp-toutiao uni-mp-weixin uni-mp-kuaishou uni-quickapp-webview",
"size": "npm run build size-check",
......
......@@ -16,6 +16,7 @@
"@dcloudio/uni-h5-vue": "../../uni-h5-vue",
"@dcloudio/uni-i18n": "../../uni-i18n",
"@dcloudio/uni-shared": "../../uni-shared",
"@dcloudio/uni-stat": "../../uni-stat",
"@vue/shared": "^3.2.3",
"vue": "^3.2.3",
"vue-router": "^4.0.11",
......
......@@ -66,6 +66,6 @@
"usingComponents": true
},
"uniStatistics": {
"enable": false
"enable": true
}
}
......@@ -99,6 +99,9 @@
"@dcloudio/uni-shared@../../uni-shared":
version "3.0.0-alpha-3000020210813002"
"@dcloudio/uni-stat@../../uni-stat":
version "3.0.0-alpha-3000020210813002"
"@dcloudio/vite-plugin-uni@../../vite-plugin-uni":
version "3.0.0-alpha-3000020210813002"
dependencies:
......@@ -200,37 +203,37 @@
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-1.4.0.tgz#962ae01b7fd16ad4007898c64ed639136e12215b"
integrity sha512-RkqfJHz9wdLKBp5Yi+kQL8BAljdrvPoccQm2PTZc/UcL4EjD11xsv2PPCduYx2oV1a/bpSKA3sD5sxOHFhz+LA==
"@vue/compiler-core@3.2.3":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.3.tgz#96aa6692ad3819127f9f6256757f67f1c400ceb4"
integrity sha512-qQpACs40hClYqghS209OBh6NDArKPrS5emWMOH/hzDy0KtOV7Kfyy2ILWRfamIsygq8mg+xHcqtVXOjr21WvQw==
"@vue/compiler-core@3.2.4":
version "3.2.4"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.4.tgz#a98d295771998c1e8dccc4ee3d52feb14b02aea9"
integrity sha512-c8NuQq7mUXXxA4iqD5VUKpyVeklK53+DMbojYMyZ0VPPrb0BUWrZWFiqSDT+MFDv0f6Hv3QuLiHWb1BWMXBbrw==
dependencies:
"@babel/parser" "^7.12.0"
"@babel/types" "^7.12.0"
"@vue/shared" "3.2.3"
"@vue/shared" "3.2.4"
estree-walker "^2.0.1"
source-map "^0.6.1"
"@vue/compiler-dom@3.2.3":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.3.tgz#2576959b979dd8a765171943cfa5409437eb1e80"
integrity sha512-hEKd+h9eIT+et/l0Nmiup5CWFHC4KuhUcrdAIPLcv1uskVQA3gSDAAx9UGB/G9cRB2gmBpFONHEi8zKrlnsaWQ==
"@vue/compiler-dom@3.2.4":
version "3.2.4"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.4.tgz#3a43de243eba127abbe57e796a0b969d2df78c08"
integrity sha512-uj1nwO4794fw2YsYas5QT+FU/YGrXbS0Qk+1c7Kp1kV7idhZIghWLTjyvYibpGoseFbYLPd+sW2/noJG5H04EQ==
dependencies:
"@vue/compiler-core" "3.2.3"
"@vue/shared" "3.2.3"
"@vue/compiler-core" "3.2.4"
"@vue/shared" "3.2.4"
"@vue/compiler-sfc@^3.2.3":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.3.tgz#49195959e168cd7fbecb6c46badb5756b8edaf10"
integrity sha512-TlaDOChFUzt3lqqaFNRD2XI0lrRWYA0/jTgWKUrCLVEPZ0tNP8Vyjmml3+1QlAo4pyjaOjYacq0OS4eCGVFJ3w==
version "3.2.4"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.4.tgz#9807868cc950291f163c3930a81bb16e870df097"
integrity sha512-GM+ouDdDzhqgkLmBH4bgq4kiZxJQArSppJiZHWHIx9XRaefHLmc1LBNPmN8ivm4SVfi2i7M2t9k8ZnjsScgzPQ==
dependencies:
"@babel/parser" "^7.13.9"
"@babel/types" "^7.13.0"
"@types/estree" "^0.0.48"
"@vue/compiler-core" "3.2.3"
"@vue/compiler-dom" "3.2.3"
"@vue/compiler-ssr" "3.2.3"
"@vue/shared" "3.2.3"
"@vue/compiler-core" "3.2.4"
"@vue/compiler-dom" "3.2.4"
"@vue/compiler-ssr" "3.2.4"
"@vue/shared" "3.2.4"
consolidate "^0.16.0"
estree-walker "^2.0.1"
hash-sum "^2.0.0"
......@@ -242,55 +245,55 @@
postcss-selector-parser "^6.0.4"
source-map "^0.6.1"
"@vue/compiler-ssr@3.2.3":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.3.tgz#75518e43e52c3d50db2e06cbdf37b981d3b4e711"
integrity sha512-VMYXYBXPohxlPvg42tT8Gcc58Wo1fPP4IE+aLgpmnNmMFuTsGEKOBK4mZqtNpv9dxgF6ooro9gQlA6BfOy3lGg==
"@vue/compiler-ssr@3.2.4":
version "3.2.4"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.4.tgz#be51f219c2042b3e530373e60bc126ada6bb1cc0"
integrity sha512-bKZuXu9/4XwsFHFWIKQK+5kN7mxIIWmMmT2L4VVek7cvY/vm3p4WTsXYDGZJy0htOTXvM2ifr6sflg012T0hsw==
dependencies:
"@vue/compiler-dom" "3.2.3"
"@vue/shared" "3.2.3"
"@vue/compiler-dom" "3.2.4"
"@vue/shared" "3.2.4"
"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.0.0-beta.14":
version "6.0.0-beta.15"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.0.0-beta.15.tgz#ad7cb384e062f165bcf9c83732125bffbc2ad83d"
integrity sha512-quBx4Jjpexo6KDiNUGFr/zF/2A4srKM9S9v2uHgMXSU//hjgq1eGzqkIFql8T9gfX5ZaVOUzYBP3jIdIR3PKIA==
"@vue/reactivity@3.2.3":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.3.tgz#df466543542a2ae20553dea1efd57bec1da634f3"
integrity sha512-HGmciaVNb3VKn4f4wCswFWLXBcopKQbO1oEs+WunBtt5tym0SS2wFNEGvWfW0dzzlXRbM507ys09m68L+JTa/Q==
"@vue/reactivity@3.2.4":
version "3.2.4"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.4.tgz#a020ad7e50f674219a07764b105b5922e61597ea"
integrity sha512-ljWTR0hr8Tn09hM2tlmWxZzCBPlgGLnq/k8K8X6EcJhtV+C8OzFySnbWqMWataojbrQOocThwsC8awKthSl2uQ==
dependencies:
"@vue/shared" "3.2.3"
"@vue/shared" "3.2.4"
"@vue/runtime-core@3.2.3":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.3.tgz#6f34ec620d6d75c255a1e75e64a4b6f90a4a2039"
integrity sha512-yn6FL2fCKi5dauJYm8u6iiGs7VoXoIWdr+icIFtEW4eObUKOzDwYpBaqCf8orhI1LEnyZO7rLplbfoJJColBwg==
"@vue/runtime-core@3.2.4":
version "3.2.4"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.4.tgz#da5dde3dc1e48df99dd31ea9a972f5c02acdc3f5"
integrity sha512-W6PtEOs8P8jKYPo3JwaMAozZQivxInUleGfNwI2pK1t8ZLZIxn4kAf7p4VF4jJdQB8SZBzpfWdLUc06j7IOmpQ==
dependencies:
"@vue/reactivity" "3.2.3"
"@vue/shared" "3.2.3"
"@vue/reactivity" "3.2.4"
"@vue/shared" "3.2.4"
"@vue/runtime-dom@3.2.3":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.3.tgz#4f0930681efd9d11d99a593221bcae9423f69fcb"
integrity sha512-YpulzSn0ydzgbfE1i9O1MJAspUHTA9q6AmqRrDLIR5AP9jmoGA//TmnB90IhA7OOGpuSVm4f1VUZ+gm/URPPgA==
"@vue/runtime-dom@3.2.4":
version "3.2.4"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.4.tgz#1025595f2ae99a12fe0e1e6bce8df6761efec24b"
integrity sha512-HcVtLyn2SGwsf6BFPwkvDPDOhOqkOKcfHDpBp5R1coX+qMsOFrY8lJnGXIY+JnxqFjND00E9+u+lq5cs/W7ooA==
dependencies:
"@vue/runtime-core" "3.2.3"
"@vue/shared" "3.2.3"
"@vue/runtime-core" "3.2.4"
"@vue/shared" "3.2.4"
csstype "^2.6.8"
"@vue/server-renderer@^3.2.3":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.3.tgz#eb21198b52dce9657754c4119d1048caac1f45e2"
integrity sha512-vMklz+wqA1EGY42KcNUI4ZFEDNd0V6oHKQyyJ32djhihtUfNJ+HfWsBIlHZ8YrQoqXGEdfzDcelPNB4N8/StsA==
version "3.2.4"
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.4.tgz#7d465a0e3c8d4eefd45b21c4b968269880a02215"
integrity sha512-ai9WxJ78nnUDk+26vwZhlA1Quz3tA+90DgJX6iseen2Wwnndd91xicFW+6ROR/ZP0yFNuQ017eZJBw8OqoPL+w==
dependencies:
"@vue/compiler-ssr" "3.2.3"
"@vue/shared" "3.2.3"
"@vue/compiler-ssr" "3.2.4"
"@vue/shared" "3.2.4"
"@vue/shared@3.2.3", "@vue/shared@^3.2.3":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.3.tgz#89e338a5524450c876d3512b4cc6ba80a4205e2c"
integrity sha512-1f8kyoabSgoga0E89itGIoaCo2Ayr6i6jQq/kHhhYrrBxoK7LNNwuWQghW0k/bapimyIzQiN891XzquYP78aqg==
"@vue/shared@3.2.4", "@vue/shared@^3.2.3":
version "3.2.4"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.4.tgz#ba2a09527afff27b28d08f921b4a597e9504ca7a"
integrity sha512-j2j1MRmjalVKr3YBTxl/BClSIc8UQ8NnPpLYclxerK65JIowI4O7n8O8lElveEtEoHxy1d7BelPUDI0Q4bumqg==
accepts@~1.3.5, accepts@~1.3.7:
version "1.3.7"
......@@ -829,9 +832,9 @@ ee-first@1.1.1:
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
electron-to-chromium@^1.3.793:
version "1.3.807"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.807.tgz#c2eb803f4f094869b1a24151184ffbbdbf688b1f"
integrity sha512-p8uxxg2a23zRsvQ2uwA/OOI+O4BQxzaR7YKMIGGGQCpYmkFX2CVF5f0/hxLMV7yCr7nnJViCwHLhPfs52rIYCA==
version "1.3.811"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.811.tgz#df5a7b18267a0b8b6ffed0dde63b9fb701f777f8"
integrity sha512-hv3kgf6YSd+jQ7J+7Kdm44yux/1vxcAwfGV/6M6Nq4E9zJ3Bml/P2+vULCvqLS6Lh9knBCQ7iEMvyeDiGe5EbA==
emoji-regex@^8.0.0:
version "8.0.0"
......@@ -1324,9 +1327,9 @@ is-ci@^3.0.0:
ci-info "^3.1.1"
is-core-module@^2.2.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.5.0.tgz#f754843617c70bfd29b7bd87327400cda5c18491"
integrity sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg==
version "2.6.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.6.0.tgz#d7553b2526fe59b92ba3e40c8df757ec8a709e19"
integrity sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==
dependencies:
has "^1.0.3"
......@@ -1652,9 +1655,9 @@ negotiator@0.6.2:
integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
node-releases@^1.1.73:
version "1.1.74"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.74.tgz#e5866488080ebaa70a93b91144ccde06f3c3463e"
integrity sha512-caJBVempXZPepZoZAPCWRTNxYQ+xtG/KAi4ozTA5A+nJ7IU+kLQCbqaUjb5Rwy14M9upBWiQ4NutcmW04LJSRw==
version "1.1.75"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.75.tgz#6dd8c876b9897a1b8e5a02de26afa79bb54ebbfe"
integrity sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==
normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
......@@ -2320,13 +2323,13 @@ vue-router@^4.0.11:
"@vue/devtools-api" "^6.0.0-beta.14"
vue@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.3.tgz#7717e69ab6e8c7ae7ee12baa50a7ab5cab8a1c31"
integrity sha512-z3/maZr+As43eL42pJTLWG+mnOTXpdPvbhFN7cDs8ZpJgMWtKlbjInLcyOD2XRyH424yulupYhyEFITfybcKnw==
version "3.2.4"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.4.tgz#d94d88675e41c050d3a722d0848a7063b5e87a60"
integrity sha512-rNCFmoewm8IwmTK0nj3ysKq53iRpNEFKoBJ4inar6tIh7Oj7juubS39RI8UI+VE7x+Cs2z6PBsadtZu7z2qppg==
dependencies:
"@vue/compiler-dom" "3.2.3"
"@vue/runtime-dom" "3.2.3"
"@vue/shared" "3.2.3"
"@vue/compiler-dom" "3.2.4"
"@vue/runtime-dom" "3.2.4"
"@vue/shared" "3.2.4"
vuex@^4.0.2:
version "4.0.2"
......
......@@ -2269,7 +2269,6 @@ var serviceContext = (function (vue) {
UniServiceJSBridge.invokeViewMethod('removeMediaQueryObserver', {
reqId,
component: component.$el.nodeId,
// reqEnd: true
}, _pageId);
UniServiceJSBridge.unsubscribe(getEventName(reqId));
}
......@@ -5259,6 +5258,7 @@ var serviceContext = (function (vue) {
scopes: [String, Array],
timeout: Number,
univerifyStyle: Object,
onlyAuthorize: Boolean,
};
const API_GET_USER_INFO = 'getUserInfo';
const GetUserInfoProtocol = {
......@@ -5293,7 +5293,8 @@ var serviceContext = (function (vue) {
required: true,
},
};
const API_CLOSE_AUTH_VIEW = 'closeAuthView';
const API_CLOSE_AUTH_VIEW = 'closeAuthView';
const API_GET_CHECK_BOX_STATE = 'getCheckBoxState';
const API_SHREA = 'share';
const SCENE = [
......@@ -9092,26 +9093,35 @@ var serviceContext = (function (vue) {
}, reject);
});
}
/**
* 微信登录
*/
const baseLogin = (params, { resolve, reject, }) => {
const login = defineAsyncApi(API_LOGIN, (params, { resolve, reject }) => {
const provider = params.provider || 'weixin';
const errorCallback = warpPlusErrorCallback(reject);
const authOptions = provider === 'apple'
? { scope: 'email' }
: params.univerifyStyle
? {
univerifyStyle: univerifyButtonsClickHandling(params.univerifyStyle, errorCallback),
}
: {};
getService(provider)
.then((service) => {
function login() {
if (params.onlyAuthorize && provider === 'weixin') {
service.authorize(({ code }) => {
resolve({
code,
authResult: '',
});
}, errorCallback);
return;
}
service.login((res) => {
const authResult = res.target.authResult;
resolve({
code: authResult.code,
authResult: authResult,
});
}, errorCallback, provider === 'apple'
? { scope: 'email' }
: {
univerifyStyle: univerifyButtonsClickHandling(params.univerifyStyle, errorCallback),
} || {});
}, errorCallback, authOptions);
}
// 先注销再登录
// apple登录logout之后无法重新触发获取email,fullname;一键登录无logout
......@@ -9123,9 +9133,8 @@ var serviceContext = (function (vue) {
}
})
.catch(errorCallback);
};
const login = defineAsyncApi(API_LOGIN, baseLogin, LoginProtocol);
const getUserInfo = defineAsyncApi(API_GET_USER_INFO, (params, { resolve, reject }) => {
}, LoginProtocol);
const baseGetUserInfo = (params, { resolve, reject }) => {
const provider = params.provider || 'weixin';
const errorCallback = warpPlusErrorCallback(reject);
getService(provider)
......@@ -9189,22 +9198,35 @@ var serviceContext = (function (vue) {
.catch(() => {
reject('请先调用 uni.login');
});
}, GetUserInfoProtocol);
};
const getUserInfo = defineAsyncApi(API_GET_USER_INFO, baseGetUserInfo, GetUserInfoProtocol);
/**
* 获取用户信息-兼容
*/
const getUserProfile = defineAsyncApi(API_GET_USER_PROFILE, (params, { resolve, reject }) => {
return baseLogin(params, { resolve, reject });
}, GgetUserProfileProtocol);
const preLogin = defineAsyncApi(API_PRE_LOGIN, (params, { resolve, reject }) => {
const getUserProfile = defineAsyncApi(API_GET_USER_PROFILE, baseGetUserInfo, GgetUserProfileProtocol);
const preLogin = defineAsyncApi(API_PRE_LOGIN, ({ provider }, { resolve, reject }) => {
const successCallback = warpPlusSuccessCallback(resolve);
const errorCallback = warpPlusErrorCallback(reject);
getService(params.provider)
getService(provider)
.then((service) => service.preLogin(successCallback, errorCallback))
.catch(errorCallback);
}, PreLoginProtocol, PreLoginOptions);
const _closeAuthView = () => getService('univerify').then((service) => service.closeAuthView());
const closeAuthView = defineAsyncApi(API_CLOSE_AUTH_VIEW, _closeAuthView);
const closeAuthView = defineSyncApi(API_CLOSE_AUTH_VIEW, _closeAuthView);
const getCheckBoxState = defineAsyncApi(API_GET_CHECK_BOX_STATE, (_, { resolve, reject }) => {
const successCallback = warpPlusSuccessCallback(resolve);
const errorCallback = warpPlusErrorCallback(reject);
try {
getService('univerify').then((service) => {
// @ts-expect-error
const state = service.getCheckBoxState();
successCallback({ state });
});
}
catch (error) {
errorCallback(error);
}
});
/**
* 一键登录自定义登陆按钮点击处理
*/
......@@ -12139,6 +12161,7 @@ var serviceContext = (function (vue) {
getUserProfile: getUserProfile,
preLogin: preLogin,
closeAuthView: closeAuthView,
getCheckBoxState: getCheckBoxState,
registerRuntime: registerRuntime,
share: share,
shareWithSystem: shareWithSystem,
......
因为 它太大了无法显示 source diff 。你可以改为 查看blob
......@@ -42,3 +42,12 @@ export function normalizeNetworkTimeout(
...networkTimeout,
}
}
export function getUniStatistics(inputDir: string, platform: UniApp.PLATFORM) {
const manifest = parseManifestJsonOnce(inputDir)
return extend(
{},
manifest.uniStatistics,
manifest[platform] && manifest[platform].uniStatistics
)
}
......@@ -10,4 +10,6 @@ export const M = {
'dev.watching.end': 'DONE Build complete. Watching for changes...',
'dev.watching.end.pages': 'DONE Build complete. PAGES:{pages}',
'dev.watching.end.files': 'DONE Build complete. FILES:{files}',
'stat.warn.appid':
'当前应用未配置Appid,无法使用uni统计,详情参考:https://ask.dcloud.net.cn/article/36303',
}
import { inject, onBeforeUnmount, ref, getCurrentInstance } from 'vue'
import { inject, onBeforeUnmount, ref } from 'vue'
import { useI18n, initI18nButtonMsgsOnce } from '@dcloudio/uni-core'
import { defineBuiltInComponent } from '../../helpers/component'
import { useHover } from '../../helpers/useHover'
......
{
"input": {
"src/index.js": ["dist/uni-stat.es.js", "dist/uni-stat.cjs.js"]
}
}
'use strict';
var version = "3.0.0-alpha-3000020210813002";
const STAT_VERSION = version;
const STAT_URL = 'https://tongji.dcloud.io/uni/stat';
const STAT_H5_URL = 'https://tongji.dcloud.io/uni/stat.gif';
const PAGE_PVER_TIME = 1800;
const APP_PVER_TIME = 300;
const OPERATING_TIME = 10;
const DIFF_TIME = 60 * 1000 * 60 * 24;
const statConfig$1 = {
appid: process.env.UNI_APP_ID,
};
const UUID_KEY = '__DC_STAT_UUID';
const UUID_VALUE = '__DC_UUID_VALUE';
function getUuid() {
let uuid = '';
if (getPlatformName() === '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 getSgin = (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]] + '&';
}
// const options = sginStr.substr(0, sginStr.length - 1)
// sginStr = sginStr.substr(0, sginStr.length - 1) + '&key=' + STAT_KEY;
// const si = crypto.createHash('md5').update(sginStr).digest('hex');
return {
sign: '',
options: sginStr.substr(0, sginStr.length - 1),
}
};
const getSplicing = (data) => {
let str = '';
for (var i in data) {
str += i + '=' + data[i] + '&';
}
return str.substr(0, str.length - 1)
};
const getTime = () => {
return parseInt(new Date().getTime() / 1000)
};
const getPlatformName = () => {
const aliArr = ['y', 'a', 'p', 'mp-ali'];
const platformList = {
'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',
};
return platformList[process.env.VUE_APP_PLATFORM]
};
const getPackName = () => {
let packName = '';
if (getPlatformName() === 'wx' || getPlatformName() === 'qq') {
// 兼容微信小程序低版本基础库
if (uni.canIUse('getAccountInfoSync')) {
packName = uni.getAccountInfoSync().miniProgram.appId || '';
}
}
return packName
};
const getVersion = () => {
return getPlatformName() === 'n' ? plus.runtime.version : ''
};
const getChannel = () => {
const platformName = getPlatformName();
let channel = '';
if (platformName === 'n') {
channel = plus.runtime.channel;
}
return channel
};
const getScene = (options) => {
const platformName = getPlatformName();
let scene = '';
if (options) {
return options
}
if (platformName === 'wx') {
scene = uni.getLaunchOptionsSync().scene;
}
return scene
};
const First__Visit__Time__KEY = 'First__Visit__Time';
const Last__Visit__Time__KEY = 'Last__Visit__Time';
const getFirstVisitTime = () => {
const timeStorge = uni.getStorageSync(First__Visit__Time__KEY);
let time = 0;
if (timeStorge) {
time = timeStorge;
} else {
time = getTime();
uni.setStorageSync(First__Visit__Time__KEY, time);
uni.removeStorageSync(Last__Visit__Time__KEY);
}
return time
};
const getLastVisitTime = () => {
const timeStorge = uni.getStorageSync(Last__Visit__Time__KEY);
let time = 0;
if (timeStorge) {
time = timeStorge;
} else {
time = '';
}
uni.setStorageSync(Last__Visit__Time__KEY, getTime());
return time
};
const PAGE_RESIDENCE_TIME = '__page__residence__time';
let First_Page_residence_time = 0;
let Last_Page_residence_time = 0;
const setPageResidenceTime = () => {
First_Page_residence_time = getTime();
if (getPlatformName() === 'n') {
uni.setStorageSync(PAGE_RESIDENCE_TIME, getTime());
}
return First_Page_residence_time
};
const getPageResidenceTime = () => {
Last_Page_residence_time = getTime();
if (getPlatformName() === 'n') {
First_Page_residence_time = uni.getStorageSync(PAGE_RESIDENCE_TIME);
}
return Last_Page_residence_time - First_Page_residence_time
};
const TOTAL__VISIT__COUNT = 'Total__Visit__Count';
const getTotalVisitCount = () => {
const timeStorge = uni.getStorageSync(TOTAL__VISIT__COUNT);
let count = 1;
if (timeStorge) {
count = timeStorge;
count++;
}
uni.setStorageSync(TOTAL__VISIT__COUNT, count);
return count
};
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;
const getFirstTime = () => {
let time = new Date().getTime();
Set__First__Time = time;
Set__Last__Time = 0;
return time
};
const getLastTime = () => {
let time = new Date().getTime();
Set__Last__Time = time;
return time
};
const getResidenceTime = (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,
}
};
const getRoute = () => {
var pages = getCurrentPages();
var page = pages[pages.length - 1];
if (!page) return ''
let _self = page.$vm;
if (getPlatformName() === 'bd') {
return _self.$mp && _self.$mp.page.is
} else {
return (
(_self.$scope && _self.$scope.route) ||
(_self.$mp && _self.$mp.page.route)
)
}
};
const getPageRoute = (self) => {
var pages = getCurrentPages();
var page = pages[pages.length - 1];
if (!page) return ''
let _self = page.$vm;
let query = self._query;
let str =
query && JSON.stringify(query) !== '{}' ? '?' + JSON.stringify(query) : '';
// clear
self._query = '';
if (getPlatformName() === 'bd') {
return _self.$mp && _self.$mp.page.is + str
} else {
return (
(_self.$scope && _self.$scope.route + str) ||
(_self.$mp && _self.$mp.page.route + str)
)
}
};
const getPageTypes = (self) => {
if (
self.mpType === 'page' ||
(self.$mp && self.$mp.mpType === 'page') ||
self.$options.mpType === 'page'
) {
return true
}
return false
};
const calibration = (eventName, options) => {
// login 、 share 、pay_success 、pay_fail 、register 、title
if (!eventName) {
console.error(`uni.report 缺少 [eventName] 参数`);
return true
}
if (typeof eventName !== 'string') {
console.error(`uni.report [eventName] 参数类型错误,只能为 String 类型`);
return true
}
if (eventName.length > 255) {
console.error(`uni.report [eventName] 参数长度不能大于 255`);
return true
}
if (typeof options !== 'string' && typeof options !== 'object') {
console.error(
`uni.report [options] 参数类型错误,只能为 String 或 Object 类型`
);
return true
}
if (typeof options === 'string' && options.length > 255) {
console.error(`uni.report [options] 参数长度不能大于 255`);
return true
}
if (eventName === 'title' && typeof options !== 'string') {
console.error(
'uni.report [eventName] 参数为 title 时,[options] 参数只能为 String 类型'
);
return true
}
};
const Report_Data_Time = 'Report_Data_Time';
const Report_Status = 'Report_Status';
const isReportData = () => {
return new Promise((resolve, reject) => {
let start_time = '';
let end_time = new Date().getTime();
let diff_time = DIFF_TIME;
let report_status = 1;
try {
start_time = uni.getStorageSync(Report_Data_Time);
report_status = uni.getStorageSync(Report_Status);
} catch (e) {
start_time = '';
report_status = 1;
}
if (report_status === '') {
requestData(({ enable }) => {
uni.setStorageSync(Report_Data_Time, end_time);
uni.setStorageSync(Report_Status, enable);
if (enable === 1) {
resolve();
}
});
return
}
if (report_status === 1) {
resolve();
}
if (!start_time) {
uni.setStorageSync(Report_Data_Time, end_time);
start_time = end_time;
}
if (end_time - start_time > diff_time) {
requestData(({ enable }) => {
uni.setStorageSync(Report_Data_Time, end_time);
uni.setStorageSync(Report_Status, enable);
});
}
})
};
const requestData = (done) => {
let formData = {
usv: STAT_VERSION,
conf: JSON.stringify({
ak: statConfig$1.appid,
}),
};
uni.request({
url: STAT_URL,
method: 'GET',
data: formData,
success: (res) => {
const { data } = res;
if (data.ret === 0) {
typeof done === 'function' &&
done({
enable: data.enable,
});
}
},
fail: (e) => {
let report_status_code = 1;
try {
report_status_code = uni.getStorageSync(Report_Status);
} catch (e) {
report_status_code = 1;
}
if (report_status_code === '') {
report_status_code = 1;
}
typeof done === 'function' &&
done({
enable: report_status_code,
});
},
});
};
const titleJsons = process.env.UNI_STAT_PAGES_TITLE;
const statConfig = {
appid: process.env.UNI_APP_ID,
};
const resultOptions = uni.getSystemInfoSync();
class Util {
constructor() {
this.self = '';
this._retry = 0;
this._platform = '';
this._query = {};
this._navigationBarTitle = {
config: '',
page: '',
report: '',
lt: '',
};
this._operatingTime = 0;
this._reportingRequestData = {
1: [],
11: [],
};
this.__prevent_triggering = false;
this.__licationHide = false;
this.__licationShow = false;
this._lastPageRoute = '';
this.statData = {
uuid: getUuid(),
ut: getPlatformName(),
mpn: getPackName(),
ak: statConfig.appid,
usv: STAT_VERSION,
v: getVersion(),
ch: getChannel(),
cn: '',
pn: '',
ct: '',
t: getTime(),
tt: '',
p: resultOptions.platform === 'android' ? 'a' : 'i',
brand: resultOptions.brand || '',
md: resultOptions.model,
sv: resultOptions.system.replace(/(Android|iOS)\s/, ''),
mpsdk: resultOptions.SDKVersion || '',
mpv: resultOptions.version || '',
lang: resultOptions.language,
pr: resultOptions.pixelRatio,
ww: resultOptions.windowWidth,
wh: resultOptions.windowHeight,
sw: resultOptions.screenWidth,
sh: resultOptions.screenHeight,
};
}
getIsReportData() {
return isReportData()
}
_applicationShow() {
if (this.__licationHide) {
getLastTime();
const time = getResidenceTime('app');
if (time.overtime) {
let options = {
path: this._lastPageRoute,
scene: this.statData.sc,
};
this._sendReportRequest(options);
}
this.__licationHide = false;
}
}
_applicationHide(self, type) {
this.__licationHide = true;
getLastTime();
const time = getResidenceTime();
getFirstTime();
const route = getPageRoute(this);
this._sendHideRequest(
{
urlref: route,
urlref_ts: time.residenceTime,
},
type
);
}
_pageShow() {
const route = getPageRoute(this);
const routepath = getRoute();
this._navigationBarTitle.config = titleJsons[routepath] || '';
if (this.__licationShow) {
getFirstTime();
this.__licationShow = false;
// console.log('这是 onLauch 之后执行的第一次 pageShow ,为下次记录时间做准备');
this._lastPageRoute = route;
return
}
getLastTime();
this._lastPageRoute = route;
const time = getResidenceTime('page');
if (time.overtime) {
let options = {
path: this._lastPageRoute,
scene: this.statData.sc,
};
this._sendReportRequest(options);
}
getFirstTime();
}
_pageHide() {
if (!this.__licationHide) {
getLastTime();
const time = getResidenceTime('page');
this._sendPageRequest({
url: this._lastPageRoute,
urlref: this._lastPageRoute,
urlref_ts: time.residenceTime,
});
this._navigationBarTitle = {
config: '',
page: '',
report: '',
lt: '',
};
return
}
}
_login() {
this._sendEventRequest(
{
key: 'login',
},
0
);
}
_share() {
this._sendEventRequest(
{
key: 'share',
},
0
);
}
_payment(key) {
this._sendEventRequest(
{
key,
},
0
);
}
_sendReportRequest(options) {
this._navigationBarTitle.lt = '1';
let query =
options.query && JSON.stringify(options.query) !== '{}'
? '?' + JSON.stringify(options.query)
: '';
this.statData.lt = '1';
this.statData.url = options.path + query || '';
this.statData.t = getTime();
this.statData.sc = getScene(options.scene);
this.statData.fvts = getFirstVisitTime();
this.statData.lvts = getLastVisitTime();
this.statData.tvc = getTotalVisitCount();
if (getPlatformName() === 'n') {
this.getProperty();
} else {
this.getNetworkInfo();
}
}
_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: getTime(),
p: this.statData.p,
};
this.request(options);
}
_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: getTime(),
p: this.statData.p,
};
this.request(options, type);
}
_sendEventRequest({ key = '', value = '' } = {}) {
const route = this._lastPageRoute;
let options = {
ak: this.statData.ak,
uuid: this.statData.uuid,
lt: '21',
ut: this.statData.ut,
url: route,
ch: this.statData.ch,
e_n: key,
e_v: typeof value === 'object' ? JSON.stringify(value) : value.toString(),
usv: this.statData.usv,
t: getTime(),
p: this.statData.p,
};
this.request(options);
}
getNetworkInfo() {
uni.getNetworkType({
success: (result) => {
this.statData.net = result.networkType;
this.getLocation();
},
});
}
getProperty() {
plus.runtime.getProperty(plus.runtime.appid, (wgtinfo) => {
this.statData.v = wgtinfo.version || '';
this.getNetworkInfo();
});
}
getLocation() {
{
this.statData.lat = 0;
this.statData.lng = 0;
this.request(this.statData);
}
}
request(data, type) {
let time = getTime();
const title = this._navigationBarTitle;
data.ttn = title.page;
data.ttpj = title.config;
data.ttc = title.report;
let requestData = this._reportingRequestData;
if (getPlatformName() === 'n') {
requestData = uni.getStorageSync('__UNI__STAT__DATA') || {};
}
if (!requestData[data.lt]) {
requestData[data.lt] = [];
}
requestData[data.lt].push(data);
if (getPlatformName() === 'n') {
uni.setStorageSync('__UNI__STAT__DATA', requestData);
}
if (getPageResidenceTime() < OPERATING_TIME && !type) {
return
}
let uniStatData = this._reportingRequestData;
if (getPlatformName() === 'n') {
uniStatData = uni.getStorageSync('__UNI__STAT__DATA');
}
// 时间超过,重新获取时间戳
setPageResidenceTime();
let firstArr = [];
let contentArr = [];
let lastArr = [];
for (let i in uniStatData) {
const rd = uniStatData[i];
rd.forEach((elm) => {
const newData = getSplicing(elm);
if (i === 0) {
firstArr.push(newData);
} else if (i === 3) {
lastArr.push(newData);
} else {
contentArr.push(newData);
}
});
}
firstArr.push(...contentArr, ...lastArr);
let optionsData = {
usv: STAT_VERSION, //统计 SDK 版本号
t: time, //发送请求时的时间戮
requests: JSON.stringify(firstArr),
};
this._reportingRequestData = {};
if (getPlatformName() === 'n') {
uni.removeStorageSync('__UNI__STAT__DATA');
}
if (data.ut === 'h5') {
this.imageRequest(optionsData);
return
}
if (getPlatformName() === 'n' && this.statData.p === 'a') {
setTimeout(() => {
this._sendRequest(optionsData);
}, 200);
return
}
this._sendRequest(optionsData);
}
_sendRequest(optionsData) {
this.getIsReportData().then(() => {
uni.request({
url: STAT_URL,
method: 'POST',
// header: {
// 'content-type': 'application/json' // 默认值
// },
data: optionsData,
success: () => {
// if (process.env.NODE_ENV === 'development') {
// console.log('stat request success');
// }
},
fail: (e) => {
if (++this._retry < 3) {
setTimeout(() => {
this._sendRequest(optionsData);
}, 1000);
}
},
});
});
}
/**
* h5 请求
*/
imageRequest(data) {
this.getIsReportData().then(() => {
let image = new Image();
let options = getSgin(GetEncodeURIComponentOptions(data)).options;
image.src = STAT_H5_URL + '?' + options;
});
}
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
);
}
}
class Stat extends Util {
static getInstance() {
if (!this.instance) {
this.instance = new Stat();
}
return this.instance
}
constructor() {
super();
this.instance = null;
// 注册拦截器
if (
typeof uni.addInterceptor === 'function' &&
process.env.NODE_ENV !== 'development'
) {
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');
},
});
}
report(options, self) {
this.self = self;
// if (process.env.NODE_ENV === 'development') {
// console.log('report init');
// }
setPageResidenceTime();
this.__licationShow = true;
this._sendReportRequest(options, true);
}
load(options, self) {
if (!self.$scope && !self.$mp) {
const page = getCurrentPages();
self.$scope = page[page.length - 1];
}
this.self = self;
this._query = options;
}
show(self) {
this.self = self;
if (getPageTypes(self)) {
this._pageShow(self);
} else {
this._applicationShow(self);
}
}
ready(self) {
// this.self = self;
// if (getPageTypes(self)) {
// this._pageShow(self);
// }
}
hide(self) {
this.self = self;
if (getPageTypes(self)) {
this._pageHide(self);
} else {
this._applicationHide(self, true);
}
}
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: getTime(),
p: this.statData.p,
};
this.request(options);
}
}
var Stat$1 = Stat;
const stat = Stat$1.getInstance();
let isHide = false;
const lifecycle = {
onLaunch(options) {
stat.report(options, this);
},
onReady() {
stat.ready(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 {
const Vue = require('vue');
(Vue.default || Vue).mixin(lifecycle);
uni.report = function(type, options) {
stat.sendEvent(type, options);
};
}
}
main();
var version = "3.0.0-alpha-3000020210813002";
const STAT_VERSION = version;
const STAT_URL = 'https://tongji.dcloud.io/uni/stat';
const STAT_H5_URL = 'https://tongji.dcloud.io/uni/stat.gif';
const PAGE_PVER_TIME = 1800;
const APP_PVER_TIME = 300;
const OPERATING_TIME = 10;
const DIFF_TIME = 60 * 1000 * 60 * 24;
const statConfig$1 = {
appid: process.env.UNI_APP_ID,
};
const UUID_KEY = '__DC_STAT_UUID';
const UUID_VALUE = '__DC_UUID_VALUE';
function getUuid() {
let uuid = '';
if (getPlatformName() === '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 getSgin = (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]] + '&';
}
// const options = sginStr.substr(0, sginStr.length - 1)
// sginStr = sginStr.substr(0, sginStr.length - 1) + '&key=' + STAT_KEY;
// const si = crypto.createHash('md5').update(sginStr).digest('hex');
return {
sign: '',
options: sginStr.substr(0, sginStr.length - 1),
}
};
const getSplicing = (data) => {
let str = '';
for (var i in data) {
str += i + '=' + data[i] + '&';
}
return str.substr(0, str.length - 1)
};
const getTime = () => {
return parseInt(new Date().getTime() / 1000)
};
const getPlatformName = () => {
const aliArr = ['y', 'a', 'p', 'mp-ali'];
const platformList = {
'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',
};
return platformList[process.env.VUE_APP_PLATFORM]
};
const getPackName = () => {
let packName = '';
if (getPlatformName() === 'wx' || getPlatformName() === 'qq') {
// 兼容微信小程序低版本基础库
if (uni.canIUse('getAccountInfoSync')) {
packName = uni.getAccountInfoSync().miniProgram.appId || '';
}
}
return packName
};
const getVersion = () => {
return getPlatformName() === 'n' ? plus.runtime.version : ''
};
const getChannel = () => {
const platformName = getPlatformName();
let channel = '';
if (platformName === 'n') {
channel = plus.runtime.channel;
}
return channel
};
const getScene = (options) => {
const platformName = getPlatformName();
let scene = '';
if (options) {
return options
}
if (platformName === 'wx') {
scene = uni.getLaunchOptionsSync().scene;
}
return scene
};
const First__Visit__Time__KEY = 'First__Visit__Time';
const Last__Visit__Time__KEY = 'Last__Visit__Time';
const getFirstVisitTime = () => {
const timeStorge = uni.getStorageSync(First__Visit__Time__KEY);
let time = 0;
if (timeStorge) {
time = timeStorge;
} else {
time = getTime();
uni.setStorageSync(First__Visit__Time__KEY, time);
uni.removeStorageSync(Last__Visit__Time__KEY);
}
return time
};
const getLastVisitTime = () => {
const timeStorge = uni.getStorageSync(Last__Visit__Time__KEY);
let time = 0;
if (timeStorge) {
time = timeStorge;
} else {
time = '';
}
uni.setStorageSync(Last__Visit__Time__KEY, getTime());
return time
};
const PAGE_RESIDENCE_TIME = '__page__residence__time';
let First_Page_residence_time = 0;
let Last_Page_residence_time = 0;
const setPageResidenceTime = () => {
First_Page_residence_time = getTime();
if (getPlatformName() === 'n') {
uni.setStorageSync(PAGE_RESIDENCE_TIME, getTime());
}
return First_Page_residence_time
};
const getPageResidenceTime = () => {
Last_Page_residence_time = getTime();
if (getPlatformName() === 'n') {
First_Page_residence_time = uni.getStorageSync(PAGE_RESIDENCE_TIME);
}
return Last_Page_residence_time - First_Page_residence_time
};
const TOTAL__VISIT__COUNT = 'Total__Visit__Count';
const getTotalVisitCount = () => {
const timeStorge = uni.getStorageSync(TOTAL__VISIT__COUNT);
let count = 1;
if (timeStorge) {
count = timeStorge;
count++;
}
uni.setStorageSync(TOTAL__VISIT__COUNT, count);
return count
};
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;
const getFirstTime = () => {
let time = new Date().getTime();
Set__First__Time = time;
Set__Last__Time = 0;
return time
};
const getLastTime = () => {
let time = new Date().getTime();
Set__Last__Time = time;
return time
};
const getResidenceTime = (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,
}
};
const getRoute = () => {
var pages = getCurrentPages();
var page = pages[pages.length - 1];
if (!page) return ''
let _self = page.$vm;
if (getPlatformName() === 'bd') {
return _self.$mp && _self.$mp.page.is
} else {
return (
(_self.$scope && _self.$scope.route) ||
(_self.$mp && _self.$mp.page.route)
)
}
};
const getPageRoute = (self) => {
var pages = getCurrentPages();
var page = pages[pages.length - 1];
if (!page) return ''
let _self = page.$vm;
let query = self._query;
let str =
query && JSON.stringify(query) !== '{}' ? '?' + JSON.stringify(query) : '';
// clear
self._query = '';
if (getPlatformName() === 'bd') {
return _self.$mp && _self.$mp.page.is + str
} else {
return (
(_self.$scope && _self.$scope.route + str) ||
(_self.$mp && _self.$mp.page.route + str)
)
}
};
const getPageTypes = (self) => {
if (
self.mpType === 'page' ||
(self.$mp && self.$mp.mpType === 'page') ||
self.$options.mpType === 'page'
) {
return true
}
return false
};
const calibration = (eventName, options) => {
// login 、 share 、pay_success 、pay_fail 、register 、title
if (!eventName) {
console.error(`uni.report 缺少 [eventName] 参数`);
return true
}
if (typeof eventName !== 'string') {
console.error(`uni.report [eventName] 参数类型错误,只能为 String 类型`);
return true
}
if (eventName.length > 255) {
console.error(`uni.report [eventName] 参数长度不能大于 255`);
return true
}
if (typeof options !== 'string' && typeof options !== 'object') {
console.error(
`uni.report [options] 参数类型错误,只能为 String 或 Object 类型`
);
return true
}
if (typeof options === 'string' && options.length > 255) {
console.error(`uni.report [options] 参数长度不能大于 255`);
return true
}
if (eventName === 'title' && typeof options !== 'string') {
console.error(
'uni.report [eventName] 参数为 title 时,[options] 参数只能为 String 类型'
);
return true
}
};
const Report_Data_Time = 'Report_Data_Time';
const Report_Status = 'Report_Status';
const isReportData = () => {
return new Promise((resolve, reject) => {
let start_time = '';
let end_time = new Date().getTime();
let diff_time = DIFF_TIME;
let report_status = 1;
try {
start_time = uni.getStorageSync(Report_Data_Time);
report_status = uni.getStorageSync(Report_Status);
} catch (e) {
start_time = '';
report_status = 1;
}
if (report_status === '') {
requestData(({ enable }) => {
uni.setStorageSync(Report_Data_Time, end_time);
uni.setStorageSync(Report_Status, enable);
if (enable === 1) {
resolve();
}
});
return
}
if (report_status === 1) {
resolve();
}
if (!start_time) {
uni.setStorageSync(Report_Data_Time, end_time);
start_time = end_time;
}
if (end_time - start_time > diff_time) {
requestData(({ enable }) => {
uni.setStorageSync(Report_Data_Time, end_time);
uni.setStorageSync(Report_Status, enable);
});
}
})
};
const requestData = (done) => {
let formData = {
usv: STAT_VERSION,
conf: JSON.stringify({
ak: statConfig$1.appid,
}),
};
uni.request({
url: STAT_URL,
method: 'GET',
data: formData,
success: (res) => {
const { data } = res;
if (data.ret === 0) {
typeof done === 'function' &&
done({
enable: data.enable,
});
}
},
fail: (e) => {
let report_status_code = 1;
try {
report_status_code = uni.getStorageSync(Report_Status);
} catch (e) {
report_status_code = 1;
}
if (report_status_code === '') {
report_status_code = 1;
}
typeof done === 'function' &&
done({
enable: report_status_code,
});
},
});
};
const titleJsons = process.env.UNI_STAT_PAGES_TITLE;
const statConfig = {
appid: process.env.UNI_APP_ID,
};
const resultOptions = uni.getSystemInfoSync();
class Util {
constructor() {
this.self = '';
this._retry = 0;
this._platform = '';
this._query = {};
this._navigationBarTitle = {
config: '',
page: '',
report: '',
lt: '',
};
this._operatingTime = 0;
this._reportingRequestData = {
1: [],
11: [],
};
this.__prevent_triggering = false;
this.__licationHide = false;
this.__licationShow = false;
this._lastPageRoute = '';
this.statData = {
uuid: getUuid(),
ut: getPlatformName(),
mpn: getPackName(),
ak: statConfig.appid,
usv: STAT_VERSION,
v: getVersion(),
ch: getChannel(),
cn: '',
pn: '',
ct: '',
t: getTime(),
tt: '',
p: resultOptions.platform === 'android' ? 'a' : 'i',
brand: resultOptions.brand || '',
md: resultOptions.model,
sv: resultOptions.system.replace(/(Android|iOS)\s/, ''),
mpsdk: resultOptions.SDKVersion || '',
mpv: resultOptions.version || '',
lang: resultOptions.language,
pr: resultOptions.pixelRatio,
ww: resultOptions.windowWidth,
wh: resultOptions.windowHeight,
sw: resultOptions.screenWidth,
sh: resultOptions.screenHeight,
};
}
getIsReportData() {
return isReportData()
}
_applicationShow() {
if (this.__licationHide) {
getLastTime();
const time = getResidenceTime('app');
if (time.overtime) {
let options = {
path: this._lastPageRoute,
scene: this.statData.sc,
};
this._sendReportRequest(options);
}
this.__licationHide = false;
}
}
_applicationHide(self, type) {
this.__licationHide = true;
getLastTime();
const time = getResidenceTime();
getFirstTime();
const route = getPageRoute(this);
this._sendHideRequest(
{
urlref: route,
urlref_ts: time.residenceTime,
},
type
);
}
_pageShow() {
const route = getPageRoute(this);
const routepath = getRoute();
this._navigationBarTitle.config = titleJsons[routepath] || '';
if (this.__licationShow) {
getFirstTime();
this.__licationShow = false;
// console.log('这是 onLauch 之后执行的第一次 pageShow ,为下次记录时间做准备');
this._lastPageRoute = route;
return
}
getLastTime();
this._lastPageRoute = route;
const time = getResidenceTime('page');
if (time.overtime) {
let options = {
path: this._lastPageRoute,
scene: this.statData.sc,
};
this._sendReportRequest(options);
}
getFirstTime();
}
_pageHide() {
if (!this.__licationHide) {
getLastTime();
const time = getResidenceTime('page');
this._sendPageRequest({
url: this._lastPageRoute,
urlref: this._lastPageRoute,
urlref_ts: time.residenceTime,
});
this._navigationBarTitle = {
config: '',
page: '',
report: '',
lt: '',
};
return
}
}
_login() {
this._sendEventRequest(
{
key: 'login',
},
0
);
}
_share() {
this._sendEventRequest(
{
key: 'share',
},
0
);
}
_payment(key) {
this._sendEventRequest(
{
key,
},
0
);
}
_sendReportRequest(options) {
this._navigationBarTitle.lt = '1';
let query =
options.query && JSON.stringify(options.query) !== '{}'
? '?' + JSON.stringify(options.query)
: '';
this.statData.lt = '1';
this.statData.url = options.path + query || '';
this.statData.t = getTime();
this.statData.sc = getScene(options.scene);
this.statData.fvts = getFirstVisitTime();
this.statData.lvts = getLastVisitTime();
this.statData.tvc = getTotalVisitCount();
if (getPlatformName() === 'n') {
this.getProperty();
} else {
this.getNetworkInfo();
}
}
_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: getTime(),
p: this.statData.p,
};
this.request(options);
}
_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: getTime(),
p: this.statData.p,
};
this.request(options, type);
}
_sendEventRequest({ key = '', value = '' } = {}) {
const route = this._lastPageRoute;
let options = {
ak: this.statData.ak,
uuid: this.statData.uuid,
lt: '21',
ut: this.statData.ut,
url: route,
ch: this.statData.ch,
e_n: key,
e_v: typeof value === 'object' ? JSON.stringify(value) : value.toString(),
usv: this.statData.usv,
t: getTime(),
p: this.statData.p,
};
this.request(options);
}
getNetworkInfo() {
uni.getNetworkType({
success: (result) => {
this.statData.net = result.networkType;
this.getLocation();
},
});
}
getProperty() {
plus.runtime.getProperty(plus.runtime.appid, (wgtinfo) => {
this.statData.v = wgtinfo.version || '';
this.getNetworkInfo();
});
}
getLocation() {
{
this.statData.lat = 0;
this.statData.lng = 0;
this.request(this.statData);
}
}
request(data, type) {
let time = getTime();
const title = this._navigationBarTitle;
data.ttn = title.page;
data.ttpj = title.config;
data.ttc = title.report;
let requestData = this._reportingRequestData;
if (getPlatformName() === 'n') {
requestData = uni.getStorageSync('__UNI__STAT__DATA') || {};
}
if (!requestData[data.lt]) {
requestData[data.lt] = [];
}
requestData[data.lt].push(data);
if (getPlatformName() === 'n') {
uni.setStorageSync('__UNI__STAT__DATA', requestData);
}
if (getPageResidenceTime() < OPERATING_TIME && !type) {
return
}
let uniStatData = this._reportingRequestData;
if (getPlatformName() === 'n') {
uniStatData = uni.getStorageSync('__UNI__STAT__DATA');
}
// 时间超过,重新获取时间戳
setPageResidenceTime();
let firstArr = [];
let contentArr = [];
let lastArr = [];
for (let i in uniStatData) {
const rd = uniStatData[i];
rd.forEach((elm) => {
const newData = getSplicing(elm);
if (i === 0) {
firstArr.push(newData);
} else if (i === 3) {
lastArr.push(newData);
} else {
contentArr.push(newData);
}
});
}
firstArr.push(...contentArr, ...lastArr);
let optionsData = {
usv: STAT_VERSION, //统计 SDK 版本号
t: time, //发送请求时的时间戮
requests: JSON.stringify(firstArr),
};
this._reportingRequestData = {};
if (getPlatformName() === 'n') {
uni.removeStorageSync('__UNI__STAT__DATA');
}
if (data.ut === 'h5') {
this.imageRequest(optionsData);
return
}
if (getPlatformName() === 'n' && this.statData.p === 'a') {
setTimeout(() => {
this._sendRequest(optionsData);
}, 200);
return
}
this._sendRequest(optionsData);
}
_sendRequest(optionsData) {
this.getIsReportData().then(() => {
uni.request({
url: STAT_URL,
method: 'POST',
// header: {
// 'content-type': 'application/json' // 默认值
// },
data: optionsData,
success: () => {
// if (process.env.NODE_ENV === 'development') {
// console.log('stat request success');
// }
},
fail: (e) => {
if (++this._retry < 3) {
setTimeout(() => {
this._sendRequest(optionsData);
}, 1000);
}
},
});
});
}
/**
* h5 请求
*/
imageRequest(data) {
this.getIsReportData().then(() => {
let image = new Image();
let options = getSgin(GetEncodeURIComponentOptions(data)).options;
image.src = STAT_H5_URL + '?' + options;
});
}
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
);
}
}
class Stat extends Util {
static getInstance() {
if (!this.instance) {
this.instance = new Stat();
}
return this.instance
}
constructor() {
super();
this.instance = null;
// 注册拦截器
if (
typeof uni.addInterceptor === 'function' &&
process.env.NODE_ENV !== 'development'
) {
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');
},
});
}
report(options, self) {
this.self = self;
// if (process.env.NODE_ENV === 'development') {
// console.log('report init');
// }
setPageResidenceTime();
this.__licationShow = true;
this._sendReportRequest(options, true);
}
load(options, self) {
if (!self.$scope && !self.$mp) {
const page = getCurrentPages();
self.$scope = page[page.length - 1];
}
this.self = self;
this._query = options;
}
show(self) {
this.self = self;
if (getPageTypes(self)) {
this._pageShow(self);
} else {
this._applicationShow(self);
}
}
ready(self) {
// this.self = self;
// if (getPageTypes(self)) {
// this._pageShow(self);
// }
}
hide(self) {
this.self = self;
if (getPageTypes(self)) {
this._pageHide(self);
} else {
this._applicationHide(self, true);
}
}
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: getTime(),
p: this.statData.p,
};
this.request(options);
}
}
var Stat$1 = Stat;
const stat = Stat$1.getInstance();
let isHide = false;
const lifecycle = {
onLaunch(options) {
stat.report(options, this);
},
onReady() {
stat.ready(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 {
const Vue = require('vue');
(Vue.default || Vue).mixin(lifecycle);
uni.report = function(type, options) {
stat.sendEvent(type, options);
};
}
}
main();
const debug = require('debug')
const {
M,
defineUniMainJsPlugin,
getUniStatistics,
parseManifestJsonOnce,
parsePagesJsonOnce,
} = require('@dcloudio/uni-cli-shared')
module.exports = [
defineUniMainJsPlugin((opts) => {
let isEnable = false
return {
name: 'vite:uni-stat',
enforce: 'pre',
config(config, env) {
if (isSsr(env.command, config)) {
return
}
const inputDir = process.env.UNI_INPUT_DIR
const platform = process.env.UNI_PLATFORM
isEnable = getUniStatistics(inputDir, platform).enable === true
if (process.env.NODE_ENV === 'production') {
const manifestJson = parseManifestJsonOnce(inputDir)
if (!manifestJson.appid) {
console.log()
console.warn(M['stat.warn.appid'])
console.log()
isEnable = false
}
}
const titlesJson = Object.create(null)
if (isEnable) {
parsePagesJsonOnce(inputDir, platform).pages.forEach((page) => {
const titleText = page.style.navigationBar.titleText || ''
if (titleText) {
titlesJson[page.path] = titleText
}
})
}
debug('vite:uni:stat')('isEnable', isEnable)
return {
define: {
'process.env.UNI_STAT_TITLE_JSON': JSON.stringify(titlesJson),
},
}
},
transform(code, id) {
if (isEnable && opts.filter(id)) {
return {
code: code + `;import '@dcloudio/uni-stat';`,
map: null,
}
}
},
}
}),
]
function isSsr(command, config) {
if (command === 'serve') {
return !!(config.server && config.server.middlewareMode)
}
if (command === 'build') {
return !!(config.build && config.build.ssr)
}
return false
}
{
"name": "@dcloudio/uni-stat",
"version": "3.0.0-alpha-3000020210813002",
"description": "@dcloudio/uni-stat",
"main": "dist/uni-stat.cjs.js",
"module": "dist/uni-stat.es.js",
"files": [
"dist",
"lib"
],
"sideEffects": false,
"repository": {
"type": "git",
"url": "git+https://github.com/dcloudio/uni-app.git",
"directory": "packages/uni-stat"
},
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/dcloudio/uni-app/issues"
},
"uni-app": {
"name": "uniStat"
},
"gitHead": "d5896d19315a106039411c16bbf8b804a865450d"
}
import { version } from '../package.json'
export const STAT_VERSION = version
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
export const APP_PVER_TIME = 300
export const OPERATING_TIME = 10
export const DIFF_TIME = 60 * 1000 * 60 * 24
import Stat from './stat.js'
const stat = Stat.getInstance()
let isHide = false
const lifecycle = {
onLaunch(options) {
stat.report(options, this)
},
onReady() {
stat.ready(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 {
const Vue = require('vue')
;(Vue.default || Vue).mixin(lifecycle)
uni.report = function (type, options) {
stat.sendEvent(type, options)
}
}
}
main()
import {
PAGE_PVER_TIME,
APP_PVER_TIME,
STAT_URL,
STAT_VERSION,
DIFF_TIME,
} from './config'
const statConfig = {
appid: process.env.UNI_APP_ID,
}
const UUID_KEY = '__DC_STAT_UUID'
const UUID_VALUE = '__DC_UUID_VALUE'
export function getUuid() {
let uuid = ''
if (getPlatformName() === '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 getSgin = (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]] + '&'
}
// const options = sginStr.substr(0, sginStr.length - 1)
// sginStr = sginStr.substr(0, sginStr.length - 1) + '&key=' + STAT_KEY;
// const si = crypto.createHash('md5').update(sginStr).digest('hex');
return {
sign: '',
options: sginStr.substr(0, sginStr.length - 1),
}
}
export const getSplicing = (data) => {
let str = ''
for (var i in data) {
str += i + '=' + data[i] + '&'
}
return str.substr(0, str.length - 1)
}
export const getTime = () => {
return parseInt(new Date().getTime() / 1000)
}
export const getPlatformName = () => {
const aliArr = ['y', 'a', 'p', 'mp-ali']
const platformList = {
'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',
}
return platformList[process.env.VUE_APP_PLATFORM]
}
export const getPackName = () => {
let packName = ''
if (getPlatformName() === 'wx' || getPlatformName() === 'qq') {
// 兼容微信小程序低版本基础库
if (uni.canIUse('getAccountInfoSync')) {
packName = uni.getAccountInfoSync().miniProgram.appId || ''
}
}
return packName
}
export const getVersion = () => {
return getPlatformName() === 'n' ? plus.runtime.version : ''
}
export const getChannel = () => {
const platformName = getPlatformName()
let channel = ''
if (platformName === 'n') {
channel = plus.runtime.channel
}
if (platformName === 'wx') {
// TODO;
}
return channel
}
export const getScene = (options) => {
const platformName = getPlatformName()
let scene = ''
if (options) {
return options
}
if (platformName === 'wx') {
scene = uni.getLaunchOptionsSync().scene
}
return scene
}
const First__Visit__Time__KEY = 'First__Visit__Time'
const Last__Visit__Time__KEY = 'Last__Visit__Time'
export const getFirstVisitTime = () => {
const timeStorge = uni.getStorageSync(First__Visit__Time__KEY)
let time = 0
if (timeStorge) {
time = timeStorge
} else {
time = getTime()
uni.setStorageSync(First__Visit__Time__KEY, time)
uni.removeStorageSync(Last__Visit__Time__KEY)
}
return time
}
export const getLastVisitTime = () => {
const timeStorge = uni.getStorageSync(Last__Visit__Time__KEY)
let time = 0
if (timeStorge) {
time = timeStorge
} else {
time = ''
}
uni.setStorageSync(Last__Visit__Time__KEY, getTime())
return time
}
const PAGE_RESIDENCE_TIME = '__page__residence__time'
let First_Page_residence_time = 0
let Last_Page_residence_time = 0
export const setPageResidenceTime = () => {
First_Page_residence_time = getTime()
if (getPlatformName() === 'n') {
uni.setStorageSync(PAGE_RESIDENCE_TIME, getTime())
}
return First_Page_residence_time
}
export const getPageResidenceTime = () => {
Last_Page_residence_time = getTime()
if (getPlatformName() === 'n') {
First_Page_residence_time = uni.getStorageSync(PAGE_RESIDENCE_TIME)
}
return Last_Page_residence_time - First_Page_residence_time
}
const TOTAL__VISIT__COUNT = 'Total__Visit__Count'
export const getTotalVisitCount = () => {
const timeStorge = uni.getStorageSync(TOTAL__VISIT__COUNT)
let count = 1
if (timeStorge) {
count = timeStorge
count++
}
uni.setStorageSync(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 getFirstTime = () => {
let time = new Date().getTime()
Set__First__Time = time
Set__Last__Time = 0
return time
}
export const getLastTime = () => {
let time = new Date().getTime()
Set__Last__Time = time
return time
}
export const getResidenceTime = (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,
}
}
export const getRoute = () => {
var pages = getCurrentPages()
var page = pages[pages.length - 1]
if (!page) return ''
let _self = page.$vm
if (getPlatformName() === 'bd') {
return _self.$mp && _self.$mp.page.is
} else {
return (
(_self.$scope && _self.$scope.route) ||
(_self.$mp && _self.$mp.page.route)
)
}
}
export const getPageRoute = (self) => {
var pages = getCurrentPages()
var page = pages[pages.length - 1]
if (!page) return ''
let _self = page.$vm
let query = self._query
let str =
query && JSON.stringify(query) !== '{}' ? '?' + JSON.stringify(query) : ''
// clear
self._query = ''
if (getPlatformName() === 'bd') {
return _self.$mp && _self.$mp.page.is + str
} else {
return (
(_self.$scope && _self.$scope.route + str) ||
(_self.$mp && _self.$mp.page.route + str)
)
}
}
export const getPageTypes = (self) => {
if (
self.mpType === 'page' ||
(self.$mp && self.$mp.mpType === 'page') ||
self.$options.mpType === 'page'
) {
return true
}
return false
}
export const calibration = (eventName, options) => {
// login 、 share 、pay_success 、pay_fail 、register 、title
if (!eventName) {
console.error(`uni.report 缺少 [eventName] 参数`)
return true
}
if (typeof eventName !== 'string') {
console.error(`uni.report [eventName] 参数类型错误,只能为 String 类型`)
return true
}
if (eventName.length > 255) {
console.error(`uni.report [eventName] 参数长度不能大于 255`)
return true
}
if (typeof options !== 'string' && typeof options !== 'object') {
console.error(
`uni.report [options] 参数类型错误,只能为 String 或 Object 类型`
)
return true
}
if (typeof options === 'string' && options.length > 255) {
console.error(`uni.report [options] 参数长度不能大于 255`)
return true
}
if (eventName === 'title' && typeof options !== 'string') {
console.error(
'uni.report [eventName] 参数为 title 时,[options] 参数只能为 String 类型'
)
return true
}
}
const Report_Data_Time = 'Report_Data_Time'
const Report_Status = 'Report_Status'
export const isReportData = () => {
return new Promise((resolve, reject) => {
let start_time = ''
let end_time = new Date().getTime()
let diff_time = DIFF_TIME
let report_status = 1
try {
start_time = uni.getStorageSync(Report_Data_Time)
report_status = uni.getStorageSync(Report_Status)
} catch (e) {
start_time = ''
report_status = 1
}
if (report_status === '') {
requestData(({ enable }) => {
uni.setStorageSync(Report_Data_Time, end_time)
uni.setStorageSync(Report_Status, enable)
if (enable === 1) {
resolve()
}
})
return
}
if (report_status === 1) {
resolve()
}
if (!start_time) {
uni.setStorageSync(Report_Data_Time, end_time)
start_time = end_time
}
if (end_time - start_time > diff_time) {
requestData(({ enable }) => {
uni.setStorageSync(Report_Data_Time, end_time)
uni.setStorageSync(Report_Status, enable)
})
}
})
}
const requestData = (done) => {
let formData = {
usv: STAT_VERSION,
conf: JSON.stringify({
ak: statConfig.appid,
}),
}
uni.request({
url: STAT_URL,
method: 'GET',
data: formData,
success: (res) => {
const { data } = res
if (data.ret === 0) {
typeof done === 'function' &&
done({
enable: data.enable,
})
}
},
fail: (e) => {
let report_status_code = 1
try {
report_status_code = uni.getStorageSync(Report_Status)
} catch (e) {
report_status_code = 1
}
if (report_status_code === '') {
report_status_code = 1
}
typeof done === 'function' &&
done({
enable: report_status_code,
})
},
})
}
import {
getUuid,
getSgin,
getSplicing,
getPackName,
getPlatformName,
getVersion,
getChannel,
getScene,
getTime,
getFirstVisitTime,
getLastVisitTime,
setPageResidenceTime,
getPageResidenceTime,
getTotalVisitCount,
GetEncodeURIComponentOptions,
getFirstTime,
getLastTime,
getResidenceTime,
getPageRoute,
getRoute,
getPageTypes,
calibration,
isReportData,
} from './parameter'
import { STAT_URL, STAT_VERSION, STAT_H5_URL, OPERATING_TIME } from './config'
const titleJsons = process.env.UNI_STAT_PAGES_TITLE
const statConfig = {
appid: process.env.UNI_APP_ID,
}
const resultOptions = uni.getSystemInfoSync()
class Util {
constructor() {
this.self = ''
this._retry = 0
this._platform = ''
this._query = {}
this._navigationBarTitle = {
config: '',
page: '',
report: '',
lt: '',
}
this._operatingTime = 0
this._reportingRequestData = {
1: [],
11: [],
}
this.__prevent_triggering = false
this.__licationHide = false
this.__licationShow = false
this._lastPageRoute = ''
this.statData = {
uuid: getUuid(),
ut: getPlatformName(),
mpn: getPackName(),
ak: statConfig.appid,
usv: STAT_VERSION,
v: getVersion(),
ch: getChannel(),
cn: '',
pn: '',
ct: '',
t: getTime(),
tt: '',
p: resultOptions.platform === 'android' ? 'a' : 'i',
brand: resultOptions.brand || '',
md: resultOptions.model,
sv: resultOptions.system.replace(/(Android|iOS)\s/, ''),
mpsdk: resultOptions.SDKVersion || '',
mpv: resultOptions.version || '',
lang: resultOptions.language,
pr: resultOptions.pixelRatio,
ww: resultOptions.windowWidth,
wh: resultOptions.windowHeight,
sw: resultOptions.screenWidth,
sh: resultOptions.screenHeight,
}
}
getIsReportData() {
return isReportData()
}
_applicationShow() {
if (this.__licationHide) {
getLastTime()
const time = getResidenceTime('app')
if (time.overtime) {
let options = {
path: this._lastPageRoute,
scene: this.statData.sc,
}
this._sendReportRequest(options)
}
this.__licationHide = false
}
}
_applicationHide(self, type) {
this.__licationHide = true
getLastTime()
const time = getResidenceTime()
getFirstTime()
const route = getPageRoute(this)
this._sendHideRequest(
{
urlref: route,
urlref_ts: time.residenceTime,
},
type
)
}
_pageShow() {
const route = getPageRoute(this)
const routepath = getRoute(this)
this._navigationBarTitle.config = titleJsons[routepath] || ''
if (this.__licationShow) {
getFirstTime()
this.__licationShow = false
// console.log('这是 onLauch 之后执行的第一次 pageShow ,为下次记录时间做准备');
this._lastPageRoute = route
return
}
getLastTime()
this._lastPageRoute = route
const time = getResidenceTime('page')
if (time.overtime) {
let options = {
path: this._lastPageRoute,
scene: this.statData.sc,
}
this._sendReportRequest(options)
}
getFirstTime()
}
_pageHide() {
if (!this.__licationHide) {
getLastTime()
const time = getResidenceTime('page')
this._sendPageRequest({
url: this._lastPageRoute,
urlref: this._lastPageRoute,
urlref_ts: time.residenceTime,
})
this._navigationBarTitle = {
config: '',
page: '',
report: '',
lt: '',
}
return
}
}
_login() {
this._sendEventRequest(
{
key: 'login',
},
0
)
}
_share() {
this._sendEventRequest(
{
key: 'share',
},
0
)
}
_payment(key) {
this._sendEventRequest(
{
key,
},
0
)
}
_sendReportRequest(options) {
this._navigationBarTitle.lt = '1'
let query =
options.query && JSON.stringify(options.query) !== '{}'
? '?' + JSON.stringify(options.query)
: ''
this.statData.lt = '1'
this.statData.url = options.path + query || ''
this.statData.t = getTime()
this.statData.sc = getScene(options.scene)
this.statData.fvts = getFirstVisitTime()
this.statData.lvts = getLastVisitTime()
this.statData.tvc = getTotalVisitCount()
if (getPlatformName() === 'n') {
this.getProperty()
} else {
this.getNetworkInfo()
}
}
_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: getTime(),
p: this.statData.p,
}
this.request(options)
}
_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: getTime(),
p: this.statData.p,
}
this.request(options, type)
}
_sendEventRequest({ key = '', value = '' } = {}) {
const route = this._lastPageRoute
let options = {
ak: this.statData.ak,
uuid: this.statData.uuid,
lt: '21',
ut: this.statData.ut,
url: route,
ch: this.statData.ch,
e_n: key,
e_v: typeof value === 'object' ? JSON.stringify(value) : value.toString(),
usv: this.statData.usv,
t: getTime(),
p: this.statData.p,
}
this.request(options)
}
getNetworkInfo() {
uni.getNetworkType({
success: (result) => {
this.statData.net = result.networkType
this.getLocation()
},
})
}
getProperty() {
plus.runtime.getProperty(plus.runtime.appid, (wgtinfo) => {
this.statData.v = wgtinfo.version || ''
this.getNetworkInfo()
})
}
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)
}
}
request(data, type) {
let time = getTime()
const title = this._navigationBarTitle
data.ttn = title.page
data.ttpj = title.config
data.ttc = title.report
let requestData = this._reportingRequestData
if (getPlatformName() === 'n') {
requestData = uni.getStorageSync('__UNI__STAT__DATA') || {}
}
if (!requestData[data.lt]) {
requestData[data.lt] = []
}
requestData[data.lt].push(data)
if (getPlatformName() === 'n') {
uni.setStorageSync('__UNI__STAT__DATA', requestData)
}
if (getPageResidenceTime() < OPERATING_TIME && !type) {
return
}
let uniStatData = this._reportingRequestData
if (getPlatformName() === 'n') {
uniStatData = uni.getStorageSync('__UNI__STAT__DATA')
}
// 时间超过,重新获取时间戳
setPageResidenceTime()
let firstArr = []
let contentArr = []
let lastArr = []
for (let i in uniStatData) {
const rd = uniStatData[i]
rd.forEach((elm) => {
const newData = getSplicing(elm)
if (i === 0) {
firstArr.push(newData)
} else if (i === 3) {
lastArr.push(newData)
} else {
contentArr.push(newData)
}
})
}
firstArr.push(...contentArr, ...lastArr)
let optionsData = {
usv: STAT_VERSION, //统计 SDK 版本号
t: time, //发送请求时的时间戮
requests: JSON.stringify(firstArr),
}
this._reportingRequestData = {}
if (getPlatformName() === 'n') {
uni.removeStorageSync('__UNI__STAT__DATA')
}
if (data.ut === 'h5') {
this.imageRequest(optionsData)
return
}
if (getPlatformName() === 'n' && this.statData.p === 'a') {
setTimeout(() => {
this._sendRequest(optionsData)
}, 200)
return
}
this._sendRequest(optionsData)
}
_sendRequest(optionsData) {
this.getIsReportData().then(() => {
uni.request({
url: STAT_URL,
method: 'POST',
// header: {
// 'content-type': 'application/json' // 默认值
// },
data: optionsData,
success: () => {
// if (process.env.NODE_ENV === 'development') {
// console.log('stat request success');
// }
},
fail: (e) => {
if (++this._retry < 3) {
setTimeout(() => {
this._sendRequest(optionsData)
}, 1000)
}
},
})
})
}
/**
* h5 请求
*/
imageRequest(data) {
this.getIsReportData().then(() => {
let image = new Image()
let options = getSgin(GetEncodeURIComponentOptions(data)).options
image.src = STAT_H5_URL + '?' + options
})
}
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
)
}
}
class Stat extends Util {
static getInstance() {
if (!this.instance) {
this.instance = new Stat()
}
return this.instance
}
constructor() {
super()
this.instance = null
// 注册拦截器
if (
typeof uni.addInterceptor === 'function' &&
process.env.NODE_ENV !== 'development'
) {
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')
},
})
}
report(options, self) {
this.self = self
// if (process.env.NODE_ENV === 'development') {
// console.log('report init');
// }
setPageResidenceTime()
this.__licationShow = true
this._sendReportRequest(options, true)
}
load(options, self) {
if (!self.$scope && !self.$mp) {
const page = getCurrentPages()
self.$scope = page[page.length - 1]
}
this.self = self
this._query = options
}
show(self) {
this.self = self
if (getPageTypes(self)) {
this._pageShow(self)
} else {
this._applicationShow(self)
}
}
ready(self) {
// this.self = self;
// if (getPageTypes(self)) {
// this._pageShow(self);
// }
}
hide(self) {
this.self = self
if (getPageTypes(self)) {
this._pageHide(self)
} else {
this._applicationHide(self, true)
}
}
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: getTime(),
p: this.statData.p,
}
this.request(options)
}
}
export default Stat
{
"compilerOptions": {
"outDir": "dist",
"sourceMap": false,
"target": "es2015",
"module": "esnext",
"moduleResolution": "node",
"allowJs": false,
"strict": true,
"noUnusedLocals": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"removeComments": false,
"lib": ["ESNext", "DOM"],
"types": ["node", "@dcloudio/types"]
},
"include": ["src"]
}
import path from 'path'
import { Plugin } from 'vite'
import { parse } from 'jsonc-parser'
import { normalizePath } from '@dcloudio/uni-cli-shared'
import { preJs } from '@dcloudio/uni-cli-shared'
import { VitePluginUniResolvedOptions } from '../..'
const jsonExtRE = /\.json($|\?)(?!commonjs-proxy)/
const SPECIAL_QUERY_RE = /[\?&](?:worker|sharedworker|raw|url)\b/
export function uniJsonPlugin(options: VitePluginUniResolvedOptions): Plugin {
const pagesJsonPath = normalizePath(
path.resolve(options.inputDir, 'pages.json')
)
const manifestJsonPath = normalizePath(
path.resolve(options.inputDir, 'manifest.json')
)
return {
name: 'vite:uni-json',
transform(code, id) {
if (
(id.startsWith(pagesJsonPath) || id.startsWith(manifestJsonPath)) &&
!id.endsWith('.json.js')
) {
code = JSON.stringify(parse(code))
if (!jsonExtRE.test(id)) return null
if (SPECIAL_QUERY_RE.test(id)) return null
if (id.endsWith('.json.js')) return null
// preprocess
if (code.includes('#endif')) {
code = preJs(code)
}
return {
code,
map: this.getCombinedSourcemap(),
code: JSON.stringify(parse(code)),
map: null,
}
},
}
......
......@@ -13,6 +13,7 @@ const BUILT_IN_MODULES = {
'vue-router': 'dist/vue-router.esm-bundler.js',
vuex: 'dist/vuex.esm-bundler.js',
'@dcloudio/uni-app': 'dist/uni-app.es.js',
'@dcloudio/uni-stat': 'dist/uni-stat.es.js',
'@dcloudio/uni-cloud': 'dist/uni-cloud.es.js',
'@dcloudio/uni-i18n': 'dist/uni-i18n.es.js',
'@dcloudio/uni-shared': 'dist/uni-shared.es.js',
......
......@@ -117,7 +117,7 @@ function createConfig(entryFile, output, buildOption) {
nodeResolve(),
commonjs(),
json({
namedExports: false,
// namedExports: false,
}),
tsPlugin,
createReplacePlugin(buildOption, output.format),
......
......@@ -5,6 +5,7 @@ const chalk = require('chalk')
const priority = {
'uni-shared': 100,
'uni-app': 90,
'uni-stat': 90,
'uni-i18n': 90,
'uni-mp-vue': 80,
'uni-mp-alipay': 70,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册