Analysis For Pacific Of Meituan

Analysis For Pacific!

// ==UserScript==
// @name         Analysis For Pacific Of Meituan
// @namespace    http://tampermonkey.net/
// @version      1.0.1
// @description  Analysis For Pacific!
// @author       xbf321
// @match        *://*.sankuai.com/*
// @match        https://h5.51ping.com/*
// @grant        unsafeWindow
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_info
// @grant        GM_xmlhttpRequest
// @connect      sankuai.com
// @license      AGPL License
// ==/UserScript==

(function() {
    'use strict';
    const CURRENT_MIS_NAME = 'current-mis-name';
    const DEVICE_ID_KEY = 'device-id';
    const VERSION = GM_info.script.version;

    function S4() {
        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    };
    function genderUUID() {
        return (
            S4() +
            S4() +
            "-" +
            S4() +
            "-" +
            S4() +
            "-" +
            S4() +
            "-" +
            S4() +
            S4() +
            S4()
        );
    };

    function getElementLeft(element) {
        let actualLeft = element.offsetLeft;
        let current = element.offsetParent;
        while (current !== null) {
            actualLeft += current.offsetLeft;
            current = current.offsetParent;
        }
        return actualLeft;
    }

    function getElementTop(element) {
        let actualTop = element.offsetTop;
        let current = element.offsetParent;

        while (current !== null) {
            actualTop += current.offsetTop;
            current = current.offsetParent;
        }
        return actualTop;
    }

    function getXPath(element) {
        let selector = "";
        let foundRoot;
        let currentElement = element;
        do {
            const tagName = currentElement.tagName.toLowerCase();
            const parentElement = currentElement.parentElement;
            if (parentElement.childElementCount > 1) {
                const parentsChildren = [...parentElement.children];
                let tag = [];
                parentsChildren.forEach((child) => {
                    if (child.tagName.toLowerCase() === tagName) tag.push(child);
                });

                if (tag.length === 1) {
                    selector = `/${tagName}${selector}`;
                } else {
                    const position = tag.indexOf(currentElement) + 1;
                    selector = `/${tagName}[${position}]${selector}`;
                }
            } else {
                selector = `/${tagName}${selector}`;
            }

            currentElement = parentElement;
            foundRoot = parentElement.tagName.toLowerCase() === "html";
            if (foundRoot) selector = `/html${selector}`;
        } while (foundRoot === false);
        return selector;
    }

    function getDeviceId() {
        let deviceId = GM_getValue(DEVICE_ID_KEY, null);
        if (!deviceId) {
            deviceId = genderUUID();
            GM_setValue(DEVICE_ID_KEY, deviceId);
        }
        return deviceId;
    }

    async function sendBackend(param) {
        const requestURL = "https://worker.service.test.sankuai.com/felog/api/fe/logs?logType=OTHER_LOGS";
        // const requestURL = "https://sep-pacific.sankuai.com/felog/api/fe/logs?logType=OTHER_LOGS";
        // 附加公共参数
        const deviceId = getDeviceId();

        Object.assign(param, {
            timestamp: +new Date().getTime(),
            version: VERSION,
            // 每一个设备唯一码,便于定位问题
            deviceId,
        });

        const postData = {
            info: param,
            logType: "GLOBAL_CLICK",
        };
       const promise = new Promise((resolve, reject) => {
           GM_xmlhttpRequest({
               url: requestURL,
               method: "POST",
               headers: {
                   "content-type": "application/json",
                   "user-agent": navigator.userAgent,
               },
               data: JSON.stringify(postData),
               responseType: "json",
               onload(response) {
                   if (response.status === 200) {
                       const data = response.response;
                       resolve(data);
                   } else {
                       reject(response);
                   }
               },
               onerror: (err) => {
                   reject(err);
               },
           });
        });
        return promise;
    }

    function getMISName() {
        let misName = GM_getValue(CURRENT_MIS_NAME);
        if (!misName) {
          try {
              let misInfo = localStorage.getItem("csMisInfo");
              misInfo = JSON.parse(misInfo);
              misName = misInfo.loginName || '';
              if (misName) {
                  GM_setValue(CURRENT_MIS_NAME, misName);
              }
          } catch (err) {
              misName = '';
          }
        }
        return misName;
    }

    function registerGlobalClickEvent() {
      window.addEventListener(
          "click",
          async (e) => {
              const { target } = e;
              const { nodeName, innerText } = target;
              const { title } = document;
              const { hostname, href } = document.location;
              const { width: screenWidth, height: screenHeight } = window.screen;
              let pageY = 0;
              let pageX = 0;
              let xpath = '';
              const misName = getMISName();
              try {
                  xpath = getXPath(target);
              } catch(err) {
                  xpath = '';
              }
              try {
                  pageY = getElementTop(target);
                  pageX = getElementLeft(target);
              } catch(err) {
                  pageY = 0;
                  pageX = 0;
              }
              const data = {
                  // 点击X位置
                  pageX,
                  // 点击Y位置
                  pageY,
                  // 节点名称,如:div/input/span/button ..
                  nodeName,
                  // 节点内容
                  innerText,
                  // 页面 URL
                  url: href,
                  // mis号,只有登陆太平洋才会有
                  misName,
                  // 节点路径
                  xpath,
                  // 页面标题
                  title,
                  // 屏幕尺寸
                  screenWidth,
                  screenHeight,
              };
              await sendBackend(data);
          });
    }

    async function registerTabChangeEvent() {
        const { document, pageUrl, outerHeight: screenHeight, outerWidth: screenWidth } = unsafeWindow;
        const { title } = document;
        const misName = getMISName();
        const data = {
            pageX: 0,
            pageY: 0,
            innerText: "",
            xpath: "",
            nodeName: "tab",
            url: pageUrl,
            title,
            screenWidth,
            screenHeight,
            misName,
        };
        await sendBackend(data);
    }

    registerTabChangeEvent();

    registerGlobalClickEvent();

})();