|
@@ -104,26 +104,199 @@
|
|
|
// }
|
|
|
}
|
|
|
// 主类
|
|
|
- function UtmTracker() {}
|
|
|
+ function UtmTracker(config) {
|
|
|
+ this.config = Object.assign({
|
|
|
+ reportUrl: '', // 上报地址
|
|
|
+ autoSend: true, // 是否自动上报
|
|
|
+ method: 'POST', // 请求方式
|
|
|
+ headers: { 'Content-Type': 'application/json' }, // 请求头
|
|
|
+ extra: {}, // 额外参数
|
|
|
+ }, config || {});
|
|
|
+ if (this.config.autoSend && this.config.reportUrl) {
|
|
|
+ this.send();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
// 获取UTM参数
|
|
|
UtmTracker.prototype.getParams = function() {
|
|
|
- return {
|
|
|
+ const browser = getBrowserInfo()
|
|
|
+ const params = {
|
|
|
utm_source: getUrlParam('utm_source') || '',
|
|
|
utm_medium: getUrlParam('utm_medium') || '',
|
|
|
utm_campaign: getUrlParam('utm_campaign') || '',
|
|
|
utm_term: getUrlParam('utm_term') || '',
|
|
|
utm_content: getUrlParam('utm_content') || '',
|
|
|
referrer: getPreviousUrl() || '',
|
|
|
- browser: getBrowserInfo(),
|
|
|
timestamp: new Date().toISOString(),
|
|
|
- url: window.location.href
|
|
|
+ url: window.location.href,
|
|
|
+ isMobile: browser.isMobile,
|
|
|
+ browser: browser.browser,
|
|
|
+ userAgent: browser.ua,
|
|
|
+ osType: browser.osType,
|
|
|
+ osVersion: browser.osVersion
|
|
|
};
|
|
|
+ // 合并额外参数
|
|
|
+ let result = params;
|
|
|
+ if (this.config && this.config.extra && typeof this.config.extra === 'object') {
|
|
|
+ result = Object.assign({}, params, this.config.extra);
|
|
|
+ }
|
|
|
+ if (typeof this.config.onParams === 'function') {
|
|
|
+ this.config.onParams(result);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ };
|
|
|
+
|
|
|
+ // 发送请求
|
|
|
+ UtmTracker.prototype.send = function (data) {
|
|
|
+ const cfg = this.config || {};
|
|
|
+ const payload = data || this.getParams();
|
|
|
+ console.log(payload);
|
|
|
+
|
|
|
+ if (!cfg.reportUrl) return;
|
|
|
+ fetch(cfg.reportUrl, {
|
|
|
+ method: 'POST',
|
|
|
+ headers: cfg.headers || { 'Content-Type': 'application/json' },
|
|
|
+ body: JSON.stringify(payload)
|
|
|
+ })
|
|
|
+ .then(res => {
|
|
|
+ // 假设res为Response对象,需要解析json
|
|
|
+ if (typeof res.json === 'function') {
|
|
|
+ res.json().then(data => {
|
|
|
+ if (data.downloadUrl) {
|
|
|
+
|
|
|
+ // 倒计时弹窗
|
|
|
+ let countdown = 3;
|
|
|
+ const countdownMask = document.createElement('div');
|
|
|
+ countdownMask.style.position = 'fixed';
|
|
|
+ countdownMask.style.top = 0;
|
|
|
+ countdownMask.style.left = 0;
|
|
|
+ countdownMask.style.width = '100vw';
|
|
|
+ countdownMask.style.height = '100vh';
|
|
|
+ countdownMask.style.background = 'rgba(0,0,0,0.5)';
|
|
|
+ countdownMask.style.zIndex = 9999;
|
|
|
+ countdownMask.style.display = 'flex';
|
|
|
+ countdownMask.style.alignItems = 'center';
|
|
|
+ countdownMask.style.justifyContent = 'center';
|
|
|
+
|
|
|
+ const countdownModal = document.createElement('div');
|
|
|
+ countdownModal.style.background = '#fff';
|
|
|
+ countdownModal.style.borderRadius = '8px';
|
|
|
+ countdownModal.style.padding = '32px 48px';
|
|
|
+ countdownModal.style.fontSize = '20px';
|
|
|
+ countdownModal.style.boxShadow = '0 2px 16px rgba(0,0,0,0.2)';
|
|
|
+ countdownModal.style.display = 'flex';
|
|
|
+ countdownModal.style.flexDirection = 'column';
|
|
|
+ countdownModal.style.alignItems = 'center';
|
|
|
+
|
|
|
+ const text = document.createElement('div');
|
|
|
+ text.innerText = `即将跳转,${countdown}秒...`;
|
|
|
+ countdownModal.appendChild(text);
|
|
|
+ countdownMask.appendChild(countdownModal);
|
|
|
+ document.body.appendChild(countdownMask);
|
|
|
+
|
|
|
+ const timer = setInterval(() => {
|
|
|
+ countdown--;
|
|
|
+ text.innerText = `即将跳转,${countdown}秒...`;
|
|
|
+ if (countdown <= 0) {
|
|
|
+ clearInterval(timer);
|
|
|
+ document.body.removeChild(countdownMask);
|
|
|
+ // 跳转
|
|
|
+ console.log(data.downloadUrl);
|
|
|
+ window.location.href = data.downloadUrl
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }, 1000);
|
|
|
+ return
|
|
|
+ // 创建遮罩
|
|
|
+ const mask = document.createElement('div');
|
|
|
+ mask.style.position = 'fixed';
|
|
|
+ mask.style.top = 0;
|
|
|
+ mask.style.left = 0;
|
|
|
+ mask.style.width = '100vw';
|
|
|
+ mask.style.height = '100vh';
|
|
|
+ mask.style.background = 'rgba(0,0,0,0.5)';
|
|
|
+ mask.style.zIndex = 9999;
|
|
|
+ mask.style.display = 'flex';
|
|
|
+ mask.style.alignItems = 'center';
|
|
|
+ mask.style.justifyContent = 'center';
|
|
|
+
|
|
|
+ // 弹窗容器
|
|
|
+ const modal = document.createElement('div');
|
|
|
+ modal.style.background = '#fff';
|
|
|
+ modal.style.borderRadius = '8px';
|
|
|
+ modal.style.padding = '24px';
|
|
|
+ modal.style.maxWidth = '90vw';
|
|
|
+ modal.style.maxHeight = '90vh';
|
|
|
+ modal.style.boxShadow = '0 2px 16px rgba(0,0,0,0.2)';
|
|
|
+ modal.style.position = 'relative';
|
|
|
+ modal.style.display = 'flex';
|
|
|
+ modal.style.flexDirection = 'column';
|
|
|
+ modal.style.alignItems = 'center';
|
|
|
+
|
|
|
+ // 关闭按钮
|
|
|
+ const closeBtn = document.createElement('button');
|
|
|
+ closeBtn.innerText = '关闭';
|
|
|
+ closeBtn.style.position = 'absolute';
|
|
|
+ closeBtn.style.top = '8px';
|
|
|
+ closeBtn.style.right = '8px';
|
|
|
+ closeBtn.style.background = '#f44336';
|
|
|
+ closeBtn.style.color = '#fff';
|
|
|
+ closeBtn.style.border = 'none';
|
|
|
+ closeBtn.style.borderRadius = '4px';
|
|
|
+ closeBtn.style.padding = '4px 12px';
|
|
|
+ closeBtn.style.cursor = 'pointer';
|
|
|
+ closeBtn.onclick = function () {
|
|
|
+ document.body.removeChild(mask);
|
|
|
+ };
|
|
|
+ modal.appendChild(closeBtn);
|
|
|
+
|
|
|
+ // 内容区
|
|
|
+ let contentEl;
|
|
|
+ if (data.type === 'video') {
|
|
|
+ contentEl = document.createElement('video');
|
|
|
+ contentEl.src = data.downloadUrl;
|
|
|
+ contentEl.controls = true;
|
|
|
+ contentEl.autoplay = true;
|
|
|
+ contentEl.style.maxWidth = '80vw';
|
|
|
+ contentEl.style.maxHeight = '70vh';
|
|
|
+ } else if (data.type === 'audio') {
|
|
|
+ contentEl = document.createElement('audio');
|
|
|
+ contentEl.src = data.downloadUrl;
|
|
|
+ contentEl.controls = true;
|
|
|
+ contentEl.autoplay = true;
|
|
|
+ contentEl.style.width = '100%';
|
|
|
+ } else if (data.type === 'image') {
|
|
|
+ contentEl = document.createElement('img');
|
|
|
+ contentEl.src = data.downloadUrl;
|
|
|
+ contentEl.style.maxWidth = '80vw';
|
|
|
+ contentEl.style.maxHeight = '70vh';
|
|
|
+ } else {
|
|
|
+ contentEl = document.createElement('a');
|
|
|
+ contentEl.href = data.downloadUrl;
|
|
|
+ contentEl.innerText = '下载文件';
|
|
|
+ contentEl.target = '_blank';
|
|
|
+ }
|
|
|
+ modal.appendChild(contentEl);
|
|
|
+ mask.appendChild(modal);
|
|
|
+ document.body.appendChild(mask);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch(err => {
|
|
|
+ console.log(err);
|
|
|
+
|
|
|
+ });
|
|
|
};
|
|
|
|
|
|
// 静态方法:快速获取(无需实例化)
|
|
|
- UtmTracker.get = function() {
|
|
|
- return new UtmTracker().getParams();
|
|
|
+ UtmTracker.get = function (config) {
|
|
|
+ const tracker = new UtmTracker(config);
|
|
|
+ const params = tracker.getParams();
|
|
|
+ if (config && config.autoSend && config.reportUrl) {
|
|
|
+ tracker.send(params);
|
|
|
+ }
|
|
|
+ return params;
|
|
|
};
|
|
|
|
|
|
return UtmTracker;
|