浏览代码

Merge branch 'test' of DeNet/de-net into master

zhangwei 3 年之前
父节点
当前提交
f4af68ddbe

+ 17 - 7
src/entry/background.js

@@ -1,8 +1,9 @@
 console.log("hello world background todo something~");
-import {pageUrl } from '@/http/configAPI'
+import { pageUrl } from '@/http/configAPI'
 import {
     backTwitterPinLoginToken,
     backTwitterPinLoginCode,
+    backHttpTwitterShortUrl
 } from "../logic/twitter.js";
 
 import { setChromeStorage, getChromeCookie, LANDING_PAGE, setChromeCookie, removeChromeCookie, LANDING_PAGE_MIND } from "@/uilts/chromeExtension";
@@ -45,7 +46,7 @@ function onInstalledMethod() {
     })
 
     chrome.action.getUserSettings().then(res => {
-        setChromeStorage({ userSettings: JSON.stringify({res})})    
+        setChromeStorage({ userSettings: JSON.stringify({ res }) })
         // 无刷新插入js
         chrome.tabs.query({}, (tab) => {
             for (let i in tab) {
@@ -55,7 +56,7 @@ function onInstalledMethod() {
                         files: ['js/content.js'],
                     }, () => {
                         setTimeout(() => {
-                            setChromeStorage({ executeScript: JSON.stringify({executeScript:1}) })    
+                            setChromeStorage({ executeScript: JSON.stringify({ executeScript: 1 }) })
                         }, 2000);
                     })
                 }
@@ -105,18 +106,27 @@ chrome.runtime.onConnect.addListener(function (port) {
             case "CONTENT_TWITTER_LOGIN":
                 backTwitterPinLoginToken();
                 break;
+            case "CONTENT_TWITTER_SHORT_LINK":
+                backHttpTwitterShortUrl(res.url).then((item) => {
+                    // port.postMessage({
+                    //     state: "BACK_TWITTER_SHORT_LINK",
+                    //     post_id: item.post_id,
+                    //     tweet_id: res.tweet_id
+                    // });
+                })
+                break
         }
     });
 });
 
 chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
     sendResponse('');
-    switch(req.actionType) {
+    switch (req.actionType) {
         case 'CONTENT_GET_PINED':
             chrome.action.getUserSettings(res => {
-                let {isOnToolbar} = res;
+                let { isOnToolbar } = res;
                 console.log('isOnToolbar', isOnToolbar)
-                if(!isOnToolbar) {
+                if (!isOnToolbar) {
                     sendActivetabMessage({
                         actionType: 'BG_SHOW_PIN_TIPS'
                     });
@@ -127,7 +137,7 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
 })
 
 
-function sendActivetabMessage (message = {}) {
+function sendActivetabMessage(message = {}) {
     chrome.tabs.query({
         active: true,
         currentWindow: true

+ 10 - 3
src/entry/content.js

@@ -11,7 +11,7 @@ import {
     showTwitterPublishDialogHandler,
     setIframeRedPacket,
     showPinTips,
-    addPinedPop
+    addPinedPop,
 } from "../logic/twitter.js";
 
 import { getChromeStorage } from "@/uilts/chromeExtension";
@@ -21,6 +21,13 @@ port.onMessage.addListener(function (res) {
         case "BACK_TWITTER_LOGIN_SUCCESS":
             showGiveDialogHandler();
             break;
+        // case "BACK_TWITTER_SHORT_LINK":
+        //     console.log('BACK_TWITTER_SHORT_LINK', res)
+        //     console.log('needBind', bindTwitterArt.needBind)
+        //     if (bindTwitterArt.needBind) {
+        //         bindTwitterArtMethod({ postId: res.post_id, twitterId: res.tweet_id });
+        //     }
+        //     break
     }
 });
 
@@ -43,7 +50,7 @@ function init() {
     }
     contentTwitterPinLogin(port);
     renderDom(port);
-    setIframeRedPacket();
+    setIframeRedPacket(port);
 
     getChromeStorage("popupShowPublishDialog", (res) => {
         console.log("popupShowPublishDialog", res);
@@ -86,7 +93,7 @@ window.onmessage = (res) => {
 
 chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
     sendResponse('');
-    switch(req.actionType) {
+    switch (req.actionType) {
         case 'BG_SHOW_PIN_TIPS':
             showPinTips()
             break;

+ 12 - 3
src/http/configAPI.js

@@ -1,4 +1,4 @@
-export const appVersionCode = 1
+export const appVersionCode = 2
 
 const api = {
 	production: 'https://api.denetme.net',
@@ -6,7 +6,11 @@ const api = {
 	development: 'https://testapi.denetme.net'
 }
 
-export const baseAPIUrl = api[process.env.NODE_ENV] + '/denet'
+const logApi = {
+	production: 'https://log.weiqumeta.com',
+	pre: 'https://prelog.weiqumeta.com',
+	development: 'https://testlog.weiqumeta.com'
+}
 
 const page = {
 	production: "https://h5.denetme.net",
@@ -14,4 +18,9 @@ const page = {
 	development: 'https://testh5.denetme.net'
 }
 
-export const pageUrl = page[process.env.NODE_ENV] 
+export const baseAPIUrl = api[process.env.NODE_ENV] + '/denet'
+
+export const logAPIUrl = logApi[process.env.NODE_ENV] + '/log-center'
+
+export const pageUrl = page[process.env.NODE_ENV] 
+

+ 11 - 0
src/http/logApi.js

@@ -0,0 +1,11 @@
+import { service } from "./request";
+import { logAPIUrl } from '@/http/configAPI.js'
+
+export function logApi(params) {
+    return service({
+        url: `${logAPIUrl}/statistics/uploadLogFromFrontend
+        `,
+        method: 'post',
+        data: params
+    })
+}

+ 8 - 0
src/http/publishApi.js

@@ -72,4 +72,12 @@ export function syncChainTokenRechargeRecord(params) {
     method: 'post',
     data: params
   })
+}
+
+export function getCurrencyInfoByCode(params) {
+  return service({
+    url: `/currency/getCurrencyInfoByCode`,
+    method: 'post',
+    data: params
+  })
 }

+ 34 - 12
src/http/request.js

@@ -16,36 +16,58 @@ export const service = axios.create({
 })
 
 function checkParams(config) {
-  const { accessToken: token = '' } = userInfo || {};
-  const { mid } = storage_mid || {}
+  const { accessToken: token = '', uid = '' } = userInfo || {};
+  const { mid } = storage_mid || {};
 
   if (config.method === 'get') {
     let { baseInfo = null } = config.params || {};
+    let params = {
+      ...config.params
+    }
+
+    let {pageSource} = params.params || {};
+    if(pageSource) {
+      delete params.params.pageSource;
+    }
+
     if (!baseInfo || !baseInfo.token) {
-      config['params']['baseInfo'] = {
+      params['baseInfo'] = {
         token: token,
         mid,
-        appVersionCode
+        appVersionCode,
+        loginUid: uid,
+        uid,
+        appType:1,
+        machineCode: mid,
+        pageSource: pageSource || ''
       }
     }
-    let params = {
-      ...config.params
-    }
     config['params'] = params;
   }
 
   if (config.method === 'post') {
     let { baseInfo = null } = config.data || {};
+    let data = {
+      ...config.data
+    }
+    console.log('data', data)
+    let {pageSource} = data.params || {};
+    if(pageSource) {
+      delete data.params.pageSource;
+    }
+
     if (!baseInfo || !baseInfo.token) {
-      config['data']['baseInfo'] = {
+      data['baseInfo'] = {
         token: token,
         mid,
-        appVersionCode
+        appVersionCode,
+        loginUid: uid,
+        uid,
+        appType:1,
+        machineCode: mid,
+        pageSource: pageSource || ''
       }
     }
-    let data = {
-      ...config.data
-    }
     config['data'] = data;
   }
   return config

+ 9 - 0
src/log-center/log.js

@@ -0,0 +1,9 @@
+import * as logger from './logger'
+import * as logEnum from './logEnum'
+
+
+
+export default {
+  ...logger,
+  ...logEnum
+}

+ 67 - 0
src/log-center/logEnum.js

@@ -0,0 +1,67 @@
+export const logType = {
+    'denet': '150',//denet-event-log
+}
+
+export const businessType = {
+    buttonView: "buttonView",
+    buttonClick: "buttonClick",
+    // 页面曝光
+    pageView: "pageView",
+}
+
+export const objectType = {
+    buttonMain: "button-main",
+    buttonSecond: "button-second",
+    confirmButton: "confirm-button",
+    tweetPostBinded: "TweetPostBinded",
+    loginButton: "login-button",
+    withdrawButton: "withdraw-button",
+    topupButton: "topup-button",
+    // 按钮点击
+    open_button: 'open-button',
+    // 关注全部
+    follow_button: 'follow-button',
+    follow: 'follow',
+    retweet: 'retweet',
+    like: 'like',
+    // 查看已领取红包列表
+    received_list: 'received-list',
+    // 点击检测任务
+    get_giveaway: 'get-giveaway',
+    // 成功领取到钱包
+    wallet_button: 'wallet-button'
+}
+
+export const pageSource = {
+    mainPage: "main-page",
+    publisherDialog: "publisher-dialog",
+    currencySelectorPage: "currency-selector-page",
+    rechargePage: "recharge-page",
+    previewPage: "preview-page",
+    denetLogin: "denet-login",
+    denetHomePage: "denet-home-page",
+    denetWithdrawSelector: "denet-withdraw-selector",
+    denetWithdrawForm: "denet-withdraw-form",
+    denetWithdrawConfirm: "denet-withdraw-confirm",
+    denetTopupSelector: "denet-topup-selector",
+    denetSelector: "denet-selector",
+    // 待开红包页
+    pending_page: 'pending-page',
+    // 已领取任务页
+    task_page: 'task-page',
+    // 领取列表页
+    received_list_page: 'received-list-page',
+    // 红包过期
+    expired_page: 'expired-page',
+    // 红包被领完
+    been_claimed_page: 'been-claimed-page',
+    // 机器人检测未通过
+    robot_detection_failed_page: 'robot-detection-failed-page',
+    // 成功领取到钱包
+    received_success_page: 'received-success-page',
+}
+
+export const extParams = {
+    success:'success',
+    failure:'failure'
+}

+ 41 - 0
src/log-center/logger.js

@@ -0,0 +1,41 @@
+import {logApi} from '@/http/logApi'
+import { logType } from './logEnum.js';
+
+
+/**
+ * @eventData 以键值对存储,会在最终上报里解开的参数
+ * @extParams 最终上报到阿里云以json字符串存储的参数,如果extparams传入的不是obj会转换成obj
+ */
+export function reportLog(eventData = {}, extParams = {}) {
+    paramsPretreatmentAndRequest(logType.denet, eventData, extParams)
+}
+
+function paramsPretreatmentAndRequest(logType, eventData, extParams) {
+    extParams = wrapObject(extParams)
+    let obj = {};
+    let pageSource = eventData.pageSource;
+    if(eventData.hasOwnProperty('pageSource')) {
+        delete eventData.pageSource;
+    }
+    obj.logType = logType;
+    obj.eventData = JSON.stringify(eventData)
+    obj.extParams = JSON.stringify(extParams)
+    logApi({params: {
+        pageSource,
+        ...obj
+    }})
+}
+
+function wrapObject(extParams) {
+    if (typeDecide(extParams, 'Object')) {
+        return extParams
+    }
+    return { 'defaultExt': extParams }
+}
+
+/**
+ * 检测对象类型
+ */
+function typeDecide(o, type) {
+    return Object.prototype.toString.call(o) === `[object ${type}]`;
+}

+ 243 - 22
src/logic/twitter.js

@@ -1,7 +1,8 @@
 import { getChromeStorage, setChromeStorage, LANDING_PAGE } from '@/uilts/chromeExtension.js'
 import { throttle } from '@/uilts/help'
-import { getTtwitterRequestToken, twitterLogin } from '../server/twitter.js'
+import { getTtwitterRequestToken, twitterLogin, httpTwitterShortUrl } from '../server/twitter.js'
 import { srcPublishSuccess } from '@/http/publishApi'
+import Report from "@/log-center/log"
 
 let dom = {};
 
@@ -66,6 +67,44 @@ export function backTwitterPinLoginCode(code) {
 
 }
 
+export function backHttpTwitterShortUrl(url) {
+    return new Promise(function (resolve, reject) {
+        httpTwitterShortUrl(url).then(res => {
+            let _str_arr = res.match(/denetme.net\/([\s\S]*?)"/) || []
+            let _post_id = _str_arr[1] || ''
+            console.log('_str_arr_post_id', _post_id)
+            if (!_post_id) {
+                return
+            }
+            // 解析
+            let _obj = {
+                url,
+                post_id: _post_id
+                // tweet_id
+            }
+            getChromeStorage('sortLink', item => {
+                if (item) {
+                    for (let i in item) {
+                        if (item[i].url == _obj.url) {
+                            item[i] = _obj
+                        }
+                        // else{
+                        //     delete item[i].tweet_id
+                        // }
+                    }
+                    setChromeStorage({ sortLink: JSON.stringify(item) })
+                } else {
+                    setChromeStorage({ sortLink: JSON.stringify([_obj]) })
+                }
+                resolve({
+                    post_id: _post_id
+                })
+            })
+        })
+    })
+
+}
+
 /**
  * 渲染要插入的dom,初始化逻辑
  * @param port
@@ -140,10 +179,6 @@ export function addPinedPop() {
     let contentDom = document.createElement('div');
     contentDom.innerHTML = "<div style='font-weight: 500;font-size: 18px;margin-top: 20px;margin-bottom: 20px'>📌 Pin an Extension is more convenient to open😄</div><div style='display: flex; align-items: center; justify-content: space-between;'><div style='display: flex; align-items: center; font-size: 14px; color: #899099; cursor: pointer;' id='de-remind'><input id='de-check' type='checkbox'/> Don't remind</div><div class='de-pin-skip' style='font-weight: 500; font-size: 16px; color: #1D9BF0;cursor: pointer;'>Skip</div></div>"
 
-    let arrow = document.createElement('div');
-    arrow.style.cssText = 'position: absolute;height: 15px;width: 15px;top: -8px;right: 80px;border-left: 0.5px solid rgb(145, 145, 145);border-top: 0.5px solid rgb(145, 145, 145);background: rgb(255, 255, 255);transform: rotate(45deg);';
-
-    popWrapper.appendChild(arrow);
     popWrapper.appendChild(img);
     popWrapper.appendChild(contentDom);
 
@@ -185,8 +220,16 @@ let bindTwitterArt = {
  */
 function _publishTweetEvent(contentStr, cb) {
     setTimeout(() => {
-        let publishTweetBtn = document.querySelector('div[role="dialog"]').querySelector('div[data-testid="tweetButton"]');
-        publishTweetBtn.addEventListener('click', function () {
+        let publishTweetBtn;
+        let dialog = document.querySelector('div[role="dialog"]');
+        if (dialog) {
+            publishTweetBtn = dialog.querySelector('div[data-testid="tweetButton"]');
+        } else {
+            let domMain = document.querySelector('main[role="main"]');
+            publishTweetBtn = domMain && domMain.querySelector('div[data-testid="tweetButton"]');
+        }
+
+        publishTweetBtn && publishTweetBtn.addEventListener('click', function () {
             bindTwitterArt.needBind = true;
             bindTwitterArt.postId = contentStr;
             cb && cb()
@@ -204,11 +247,23 @@ function _publishTweetEvent(contentStr, cb) {
 function _addDeNetEditBtn(parent, dom, isClick = false) {
     setTimeout(() => {
         if (parent && parent.parentNode) {
+            Report.reportLog({
+                pageSource: Report.pageSource.mainPage,
+                businessType: Report.businessType.buttonView,
+                objectType: Report.objectType.buttonSecond
+            });
             parent.parentNode.insertBefore(dom, parent.nextElementSibling);
         } else {
             setTimeout(() => {
                 parent = _getScheduleDom(isClick);
-                parent && parent.parentNode && parent.parentNode.insertBefore(dom, parent.nextElementSibling);
+                if (parent && parent.parentNode) {
+                    Report.reportLog({
+                        pageSource: Report.pageSource.mainPage,
+                        businessType: Report.businessType.buttonView,
+                        objectType: Report.objectType.buttonSecond
+                    });
+                    parent.parentNode.insertBefore(dom, parent.nextElementSibling);
+                }
             }, 1000)
         }
     })
@@ -389,15 +444,17 @@ function _createBtnDom(port) {
     style.innerHTML = "#de-btn:hover{opacity: .9;};@-webkit-keyframes load{from{ transform: rotate(0deg);} to{transform: rotate(360deg);}}";
     document.getElementsByTagName('head').item(0).appendChild(style);
 
+    // 左侧大屏按钮
     let deBtn = document.createElement('span');
     // const shadowDiv = document.createElement('div');
     deBtn.innerHTML = '<span>DeNet</span>';
     deBtn.id = 'de-btn';
     deBtn.style.cssText = 'width:90%;height: 52px;text-align:center;line-height:52px;margin-bottom: 4px;margin-top: 4px;background: linear-gradient(274.8deg, #FF9900 -3.69%, #BD00FF 69.71%, #00F0FF 122.65%);color:#fff;font-size:17px;font-weight:700;border-radius:100px;cursor: pointer;display: flex;align-items: center;justify-content: center;';
 
+    // 编辑框内按钮
     const deBtn1 = document.createElement('img');
     let src = require("@/assets/img/icon-gift-pack.png");
-    const smallDeBtnStyle = 'width:20px;height: 20px;cursor: pointer;marign-left:4px;margin-right:4px';
+    const smallDeBtnStyle = 'width:20px;height: 20px;cursor: pointer;padding: 0px 8px';
     deBtn1.id = 'de-btn1';
     deBtn1.style.cssText = smallDeBtnStyle;
     deBtn1.src = src
@@ -407,21 +464,37 @@ function _createBtnDom(port) {
     deBtn2.style.cssText = smallDeBtnStyle;
     deBtn2.src = "@/assets/img/icon-gift-pack.png"
 
+    // 小屏按钮
     const deBtn3 = document.createElement('img');
     deBtn3.id = 'de-btn3'
     deBtn3.src = require("@/assets/logo/128.png");
     deBtn3.style.cssText = 'width:52px;height: 52px;margin-top:20px;cursor: pointer;';
 
     deBtn.addEventListener('click', () => {
+        Report.reportLog({
+            pageSource: Report.pageSource.mainPage,
+            businessType: Report.businessType.buttonClick,
+            objectType: Report.objectType.buttonMain
+        });
         _deNetBtnClick(port);
     })
     deBtn1.addEventListener('click', () => {
+        Report.reportLog({
+            pageSource: Report.pageSource.mainPage,
+            businessType: Report.businessType.buttonClick,
+            objectType: Report.objectType.buttonSecond
+        });
         _deNetBtnClick(port);
     })
     deBtn2.addEventListener('click', () => {
         _deNetBtnClick(port);
     })
     deBtn3.addEventListener('click', () => {
+        Report.reportLog({
+            pageSource: Report.pageSource.mainPage,
+            businessType: Report.businessType.buttonClick,
+            objectType: Report.objectType.buttonMain
+        });
         _deNetBtnClick(port);
     })
     dom.deBtn = deBtn;
@@ -437,12 +510,22 @@ function addSliderNavDeBtn(isSmall = false) {
         let deBtn = document.getElementById('de-btn');
         if (bigDom && !deBtn) {
             bigDom.appendChild(dom.deBtn);
+            Report.reportLog({
+                pageSource: Report.pageSource.mainPage,
+                businessType: Report.businessType.buttonView,
+                objectType: Report.objectType.buttonMain
+            });
         }
     } else {
         let smallDom = document.querySelector('h1[role]').parentNode.parentNode;
         let deBtn3 = document.getElementById('de-btn3');
         if (smallDom && !deBtn3) {
             smallDom.appendChild(dom.deBtn3);
+            Report.reportLog({
+                pageSource: Report.pageSource.mainPage,
+                businessType: Report.businessType.buttonView,
+                objectType: Report.objectType.buttonMain
+            });
         }
     }
 }
@@ -499,6 +582,9 @@ function bindTwitterArtMethod({ postId, twitterId }) {
                 }
             }).then((res) => {
                 if (res.code == 0) {
+                    Report.reportLog({
+                        objectType: Report.objectType.tweetPostBinded
+                    });
                     bindTwitterArt.needBind = false;
                     bindTwitterArt.postId = '';
                     bindTwitterArt.isBindIng = false;
@@ -538,21 +624,139 @@ function parseDOMRedPacket() {
     }
 }
 
+let parse_dom = {}
+
+async function parseDOMRedPacketByShortUrl(port) {
+    // let _new_time = new Date().getTime()
+    // if ((_new_time - change_time) > 1000) {
+    //     change_time = _new_time
+    // } else {
+    //     return
+    // }
+    // 为了减少声明变量次数
+    parse_dom.dom = null
+    parse_dom.txt_area = null
+    parse_dom.short_url = ''
+    parse_dom.postId = ''
+    parse_dom.a_arr = null
+    parse_dom.type = ''
+    parse_dom.tweetId = ''
+    parse_dom.article = null
+    parse_dom.a_tweetId = null
+    parse_dom.a_arr = document.querySelectorAll('a') || []
+    for (let i in parse_dom.a_arr) {
+        if (parse_dom.a_arr[i].innerText == '#DeNet') {
+            parse_dom.article = parse_dom.a_arr[i].closest('article')
+            parse_dom.dom = parse_dom.article.querySelector('div[aria-labelledby]')
+            if (parse_dom.dom && !parse_dom.dom.querySelector('iframe') && parse_dom.dom.closest('article').querySelector('iframe')) {
+                parse_dom.dom.style.display = 'none'
+                continue
+            }
+            if (parse_dom.dom && parse_dom.dom.parentElement.querySelector('iframe')) {
+                continue
+            }
+            parse_dom.short_url = getTwitterShortUrl(parse_dom.article)
+            parse_dom.a_tweetId = parse_dom.article.querySelector('a[aria-label]')
+            if (parse_dom.a_tweetId && parse_dom.a_tweetId.getAttribute('href')) {
+                parse_dom.tweetId = parse_dom.a_tweetId.getAttribute('href').split('/status/')[1] || ''
+            }
+            parse_dom.postId = await handleShortUrl(port, parse_dom.short_url)
+            console.log('_postId', parse_dom.postId)
+            console.log('short_url', parse_dom.short_url)
+
+            // 获取到postId了
+            if (parse_dom.postId) {
+                console.log('bindTwitterArt.postId', bindTwitterArt.postId)
+                console.log('parse_dom.postId', parse_dom.postId)
+                if (bindTwitterArt.needBind) {
+                    bindTwitterArtMethod({ postId: parse_dom.postId, twitterId: parse_dom.tweetId });
+                }
+                if (parse_dom.dom) {
+                    parse_dom.type = 'card'
+                } else {
+                    parse_dom.type = 'parnet'
+                    parse_dom.txt_area = parse_dom.article.querySelector('[lang][dir=auto]')
+                    parse_dom.dom = parse_dom.txt_area
+                }
+                replaceDOMRedPacket(parse_dom.type, parse_dom.dom, parse_dom.postId, parse_dom.tweetId)
+            }
+        }
+    }
+}
+
+// 校验推特短数组大小
+function checkShortUrlArraySize(_array) {
+    if (new Blob(_array).size >= 1024 * 1024) {
+        _array.splice(0, parseInt(_array.length / 2))
+    }
+    return _array
+}
+
+// 获取推特短链接
+function getTwitterShortUrl(_article) {
+    let dom_arr = _article.querySelectorAll('a[href][role]')
+    let url = ''
+    for (let i in dom_arr) {
+        if (dom_arr[i].href.includes('https://t.co')) {
+            url = dom_arr[i].href
+            break
+        }
+    }
+    return url
+}
+// 处理短链接
+async function handleShortUrl(port, url) {
+    let post_id = ''
+    // 校验本地是否存在
+    let sort_link_data = await getChromeStorage('sortLink') || ''
+    if (sort_link_data) {
+        let _item = sort_link_data.filter((_item) => { return _item.url == url })
+        // 本地有值
+        if (_item.length > 0) {
+            if (_item[0].post_id) {
+                post_id = _item[0].post_id
+            } else {
+                // 防止多次请求,校验timeout时间
+                let _new_time = new Date().getTime()
+                if (_new_time - _item[0].time > 5000) {
+                    for (let i in sort_link_data) {
+                        if (sort_link_data[i].url == url) {
+                            sort_link_data[i].time = _new_time
+                        }
+                    }
+                    setChromeStorage({ sortLink: JSON.stringify(sort_link_data) })
+                    port.postMessage({ state: 'CONTENT_TWITTER_SHORT_LINK', url })
+                }
+            }
+        } else {
+            // 本地没有值
+            sort_link_data.push({ url, post_id: '', time: new Date().getTime() })
+            setChromeStorage({ sortLink: JSON.stringify(sort_link_data) })
+            port.postMessage({ state: 'CONTENT_TWITTER_SHORT_LINK', url })
+        }
+        // 校验存储大小
+        let new_item = checkShortUrlArraySize(sort_link_data)
+        if (sort_link_data.length != new_item.length) {
+            setChromeStorage({ sortLink: JSON.stringify(new_item) })
+        }
+    } else {
+        setChromeStorage({ sortLink: JSON.stringify([{ url, post_id: '', time: new Date().getTime() }]) })
+        port.postMessage({ state: 'CONTENT_TWITTER_SHORT_LINK', url })
+    }
+    return post_id
+}
+
 function createIframe(postId, tweetId) {
     let _iframe = document.createElement('iframe')
     _iframe.id = postId
     _iframe.src = chrome.runtime.getURL('/iframe/red-packet.html') + `?postId=${postId}&tweetId=${tweetId}`;
-    _iframe.style.cssText = 'border: medium none; width:375px;height:500px;'
+    _iframe.style.cssText = 'border: medium none; width:375px;min-height:500px;'
     return _iframe
 }
 function replaceDOMRedPacket(_type, _dom, postId, tweetId) {
     if (!_dom || !_dom.parentElement) {
         return
     }
-    if (_type == 'card' && !_dom.querySelector('iframe') && _dom.closest('article').querySelector('iframe')) {
-        _dom.style.display = 'none'
-        return
-    }
     if (_dom.parentElement.querySelector('iframe')) {
         return
     }
@@ -563,7 +767,7 @@ function replaceDOMRedPacket(_type, _dom, postId, tweetId) {
         for (let i = 0; i < _len; i++) {
             _dom.children[i].style.display = 'none'
         }
-        _dom.style = 'height:500px'
+        _dom.style = 'min-height:500px'
         _dom.appendChild(createIframe(postId, tweetId))
     } else {
         let _parent = _dom.parentNode
@@ -571,18 +775,35 @@ function replaceDOMRedPacket(_type, _dom, postId, tweetId) {
     }
 }
 
+// let change_time = new Date().getTime()
+// function onChangePageMain(port, targetNode) {
+//     const config = { attributes: true, childList: true, subtree: true };
+//     const callback = (mutationsList, observer) => {
+//         setTimeout(() => {
+//             parseDOMRedPacketByShortUrl(port)
+//         }, 2000)
+//     }
+//     const observer = new MutationObserver(callback);
+//     observer.observe(targetNode, config);
+// }
 
-export function setIframeRedPacket() {
+export function setIframeRedPacket(port) {
     // let elment = document.documentElement
 
-    if (window.location.href.includes('https://twitter.com)')) {
+    if (window.location.href.includes('twitter.com)')) {
         return
     }
-    // const observer = new MutationObserver(callback);
-
-    parseDOMRedPacket()
-    // let _current_top = 0
     setInterval(() => {
-        parseDOMRedPacket()
+        parseDOMRedPacketByShortUrl(port)
     }, 1000)
+
+
+    // let targetNode = null
+    // let timer = setInterval(() => {
+    //     targetNode = document.querySelector('main')
+    //     if (targetNode) {
+    //         clearInterval(timer)
+    //         onChangePageMain(port, targetNode)
+    //     }
+    // }, 1000);
 }

+ 1 - 1
src/manifest.json

@@ -1,7 +1,7 @@
 {
     "manifest_version": 3,
     "name": "DeNet",
-    "description": "chrome extension",
+    "description": "Growing more twitter followers with Denet",
     "version": "1.0.2",
     "background": {
         "service_worker": "/js/background.js"

+ 13 - 3
src/server/twitter.js

@@ -1,5 +1,5 @@
-import { appVersionCode,baseAPIUrl} from '@/http/configAPI.js'
-import {getChromeStorage } from '@/uilts/chromeExtension.js'
+import { appVersionCode, baseAPIUrl } from '@/http/configAPI.js'
+import { getChromeStorage } from '@/uilts/chromeExtension.js'
 
 export async function getTtwitterRequestToken() {
     let storage_mid = await getChromeStorage('mid') || ''
@@ -63,4 +63,14 @@ export async function twitterLogin(oauthToken, oauthVerifier, receivedIds = [])
 
     })
 }
-
+// 请求推特短链接
+export async function httpTwitterShortUrl(url) {
+    return new Promise(function (resolve, reject) {
+        fetch(url) // 返回一个Promise对象 
+            .then((res) => {
+                return res.text() // res.text()是一个Promise对象
+            }).then((res) => {
+                resolve(res.toString());
+            })
+    })
+}

+ 102 - 26
src/view/components/give-dialog.vue

@@ -61,7 +61,7 @@
                             @setCurrencyList="setCurrentCurrencyInfo"></currency-list>
                     </div>
 
-                    <div class="left">
+                    <div class="left" v-if="showComType != 'preview'">
                         <div class="gift-pack-wrapper">
                             <img class="icon"
                                 :src="require('../../assets/svg/icon-gift-pack.svg')"/>
@@ -70,7 +70,8 @@
                         </div>
                     </div>
 
-                    <div class="right">
+                    <div class="right"  
+                        :class="{'fill-right': showComType == 'preview'}">
                         <div class="form-wrapper"  v-if="showComType == 'default'">
                             <img
                                 class="img-mode"
@@ -284,10 +285,12 @@
 
 <script setup>
 import { ref, watch, reactive, defineProps, defineEmits, onMounted, nextTick } from "vue";
-import { postPublish, verifyPaypalResult, syncChainTokenRechargeRecord } from "@/http/publishApi";
+import { postPublish, verifyPaypalResult, syncChainTokenRechargeRecord, getCurrencyInfoByCode } from "@/http/publishApi";
 import { payCalcFee, getPayConfig } from "@/http/pay";
 import { getFrontConfig } from "@/http/account";
+import {setChromeStorage, getChromeStorage} from "@/uilts/chromeExtension"
 import { throttle } from "@/uilts/help"
+import Report from "@/log-center/log"
 import { ElMessage, ElLoading } from "element-plus";
 import "element-plus/es/components/message/style/css";
 
@@ -305,14 +308,24 @@ const config = {
 }
 const math = create(all, config);
 
+//临时货币信息
 let tempCurrentCurrencyInfo = ref({});
 
 let paypalClientId = ref("");
-let payConfig = ref({})
+let payConfig = ref({});
 let paypalHtml = ref("");
 
+// 发布后返回的结果
 let publishRes = reactive({});
 
+//弹窗是否展示
+let visible = ref(false);
+
+//弹窗高度
+let dialogHeight = ref(680);
+
+// 当前展示组件内容 default(表单)  preview(预览)  topUp(充值)
+let showComType = ref("default"); 
 let currentComData = {
     default: {
         title: "Giveaway",
@@ -325,36 +338,45 @@ let currentComData = {
     },
 };
 
-let visible = ref(false);
-let showComType = ref("default"); // default(表单)  preview(预览)  topUp(充值)
+// 机器人开关
 let openAntiBot = ref(false);
-let dialogHeight = ref(680);
+
 // 是否正在提交
 let submitIng = ref(false);
+
 // 艾特关注人列表
 let atUserList = ref([]);
 
+// 表单错误提示
 let iptErrMsgTxt = ref("Select a reward");
 
 // 是否返回
 let isBack = ref(false);
+
 // 展示消息提示 
 let showMessageBox = ref(false);
+
 // 展示货币列表pop
 let showCurrencyPop = ref(false);
 
+// 展示更多按钮下的选项
 let showMoreOption = ref(false);
 
+// 货币列表的dom
 let currencyListDom = ref('');
 
+// 刷新按钮旋转
 let refreshRotate = ref(false);
 
+// 预览字体大小
 let previewFontSize = ref(56);
 
 let postId = ref('');
 
+// 余额是否同步中
 let asyncIng = ref(false);
 
+// 提交按钮-充值引导提示
 let depositGuide = ref(false);
 
 let messageBoxData = ref({
@@ -428,6 +450,11 @@ watch(
         console.log("watch", newVal);
         visible.value = newVal;
         if (newVal) {
+            Report.reportLog({
+                pageSource: Report.pageSource.publisherDialog,
+                businessType: Report.businessType.pageView,
+            });
+            getLocalCurrencyInfoByCode();
             setTimeout(() => {
                 setDialogHeight();
             }, 300);
@@ -452,19 +479,26 @@ const close = () => {
  * 设置弹窗高度
  */
 const setDialogHeight = (resize = false) => {
-    let clientHeight = window.innerHeight;
-    let gapSafe = 40;
+    nextTick(() => {
+        let clientHeight = window.innerHeight;
+        let gapSafe = 40;
+        console.log('resize',resize)
 
-    if (dialogHeight.value > clientHeight - gapSafe) {
-        dialogHeight.value = clientHeight - gapSafe;
-    } else {
-        if(resize) {
-            dialogHeight.value = 680;
+        if (dialogHeight.value > clientHeight - gapSafe) {
+            dialogHeight.value = clientHeight - gapSafe;
+        } else {
+            if(resize) {
+                dialogHeight.value = 680;
+            }
         }
-    }
+    })
 };
 
 const selectCurrencyPopHandle = () => {
+    Report.reportLog({
+        pageSource: Report.pageSource.currencySelectorPage,
+        businessType: Report.businessType.pageView,
+    });
     showCurrencyPop.value = true;
     nextTick(() => {
         if(currencyListDom.value) {
@@ -494,6 +528,7 @@ const getPayAmount = async (amountValue) => {
     return res.data;
 };
 
+
 const confirm = () => {
     if(depositGuide.value) { //余额不够去充值
         goTopUp();
@@ -509,6 +544,9 @@ const confirm = () => {
     submitRequest();
 };
 
+/**
+ * 货币列表-选中货币
+ */
 const selectCurrency = (params) => {
     tempCurrentCurrencyInfo.value = params;
     depositGuide.value = false;
@@ -520,6 +558,7 @@ const selectCurrency = (params) => {
         });
     } else {
         currentCurrencyInfo.value = params;
+        setLocalSelectCurrencyInfo(currentCurrencyInfo.value);
         showCurrencyPop.value = false;
         finalAmountData.value.currencyCode = currentCurrencyInfo.value.currencyCode;
         calcDomZoom();
@@ -544,16 +583,15 @@ const resetFormIpt = () => {
     baseFormData.totalCount = "";
 }
 
+const setLocalSelectCurrencyInfo = (params = {}) => {
+    setChromeStorage({ selectCurrencyInfo : JSON.stringify(params)})    
+}
+
 /**
- * 设置默认使用货币
+ * 获取完货币列表
  */
 
 const setCurrentCurrencyInfo = (params) => {
-    let {list} = params;
-    if(list && list.length && list[0].data && list[0].data.length) {
-        // currentCurrencyInfo.value = list[0].data[0];
-        // finalAmountData.value.currencyCode = currentCurrencyInfo.value.currencyCode;
-    }
 }
 
 const messageBoxBlock = ({ title = "", content = "" }) => {
@@ -567,7 +605,7 @@ const messageBoxBlock = ({ title = "", content = "" }) => {
  */
 const messageBoxConfirm = () => {
     showMessageBox.value = false;
-    showComType.value = "topUp";
+    goTopUp();
 };
 
 /**
@@ -575,6 +613,7 @@ const messageBoxConfirm = () => {
  */
 const messageBoxCancel = () => {
     currentCurrencyInfo.value = tempCurrentCurrencyInfo.value;
+    setLocalSelectCurrencyInfo(currentCurrencyInfo.value);
     showMessageBox.value = false;
     showCurrencyPop.value = false;
     calcDomZoom();
@@ -586,6 +625,10 @@ const messageBoxCancel = () => {
  * 去充值
  */
 const goTopUp = () => {
+    Report.reportLog({
+        pageSource: Report.pageSource.rechargePage,
+        businessType: Report.businessType.pageView,
+    });
     showComType.value = 'topUp';
 }
 
@@ -698,6 +741,10 @@ const submitRequest = async () => {
         if (res.code == 0) {
             publishRes = res.data;
             postId.value = res.data.postId;
+            Report.reportLog({
+                pageSource: Report.pageSource.previewPage,
+                businessType: Report.businessType.pageView,
+            });
             showComType.value = "preview";
             previewFontSize.value = calcFontSize(baseFormData.amountValue, 238, 56);
             isBack.value = false;
@@ -974,9 +1021,34 @@ const goTransactionsList = () => {
     window.open(`${chrome.runtime.getURL('/iframe/home.html#/transactions')}`)
 }
 
+
+/**
+ * 默认获取上次选中的货币信息
+ */
+const getLocalCurrencyInfoByCode = () => {
+    if(!currentCurrencyInfo.value.currencyCode) {
+        getChromeStorage('selectCurrencyInfo', (res) => {
+            if(res && res.currencyCode) {
+                getCurrencyInfoByCode({
+                    params: {
+                        currencyCode: res.currencyCode
+                    }
+                }).then(res => {
+                    if(res.code == 0 && res.data) {
+                        currentCurrencyInfo.value = res.data;
+                        tempCurrentCurrencyInfo.value = res.data;
+                        onIptSetErrorTxt();
+                    }
+                });
+            }
+        })
+    }
+}
+
 onMounted(() => {
     setFrontConfig();
     setPayConfig();
+    getLocalCurrencyInfoByCode();
     document.onkeydown = function (e) {
         var keyNum = window.event ? e.keyCode : e.which;
         let escKey = 27;
@@ -986,9 +1058,9 @@ onMounted(() => {
             }
         }
     };
-    window.onresize = throttle(function () {
-        setDialogHeight(true)
-    }, 300)
+    window.addEventListener('resize', function () {
+        setDialogHeight(true);
+    })
 });
 </script>
 
@@ -1003,7 +1075,7 @@ onMounted(() => {
     right: 0;
     bottom: 0;
     left: 0;
-    z-index: 1000;
+    z-index: 2000;
     height: 100%;
     background-color: rgba(0, 0, 0, 0.5);
     overflow: auto;
@@ -1494,6 +1566,10 @@ onMounted(() => {
                     }
                 }
             }
+            .fill-right {
+                width: 100% !important;
+                border-bottom-left-radius: 16px;
+            }
         }
     }
 }

+ 1 - 0
src/view/components/message-box.vue

@@ -1,3 +1,4 @@
+<!-- 消息提示组件 -->
 <template>
     <div class="msg-box-overlay" v-if="dialogVisible">
         <div class="content-wrapper">

+ 33 - 5
src/view/components/paypal-button.vue

@@ -30,11 +30,14 @@
             </div>
         </div>
         <div class="pay-btn">
-            <iframe
+            <div class="iframe-pay"
                 v-show="currentCurrencyInfo.currencyCode == 'USD'"
-                class="iframe-pay"
-                ref="iframe"
-                :src="`${payConfig.paypalHtml}?paypalClientId=${payConfig.paypalClientId}&amount=${props.finalAmountData.finalAmountValue}`"></iframe>
+                 @click="paypalPay">
+                <iframe
+                    class="iframe-pay"
+                    ref="iframe"
+                    :src="`${payConfig.paypalHtml}?paypalClientId=${payConfig.paypalClientId}&amount=${props.finalAmountData.finalAmountValue}`"></iframe>
+            </div>
             <div class="token-pay" 
                 v-if="currentCurrencyInfo.currencyCode != 'USD'"
                 @click="tokenPay">
@@ -48,6 +51,7 @@
 import { onMounted, ref, defineProps, defineEmits, watch } from "vue";
 
 import {payTaskLuckdropWithBalance} from "@/http/publishApi"
+import Report from "@/log-center/log"
 
 const props = defineProps({
     finalAmountData: {
@@ -97,7 +101,24 @@ watch(
 
 const emits = defineEmits(["payPalFinsh"]);
 
-const tokenPay = () => {    
+const paypalPay = () => {
+    Report.reportLog({
+        pageSource: Report.pageSource.previewPage,
+        businessType: Report.businessType.buttonClick,
+        objectType: Report.objectType.confirmButton
+    }, {
+        type: 'paypal'
+    });  
+};
+
+const tokenPay = () => {  
+    Report.reportLog({
+        pageSource: Report.pageSource.previewPage,
+        businessType: Report.businessType.buttonClick,
+        objectType: Report.objectType.confirmButton
+    }, {
+        type: 'confirm'
+    });  
     if(payIng) {
         return;
     }
@@ -151,6 +172,8 @@ onMounted(() => {
     display: flex;
     align-items: center;
     justify-content: flex-end;
+    border-bottom-left-radius: 16px;
+    z-index: 999;
 
     .pay-msg {
         text-align: right;
@@ -202,6 +225,11 @@ onMounted(() => {
             cursor: pointer;
         }
 
+        .iframe-pay {
+            width: 100%;
+            height: 100%;
+        }
+
         iframe {
             border: medium none;
             width: 100%;

+ 107 - 75
src/view/components/preview-card.vue

@@ -2,17 +2,14 @@
 <template>
     <div class="wrapper">
         <div class="card-container">
+            <div class="preview-txt">
+                <span>{{installStatus ? 'After' : 'Before'}}</span>
+                DeNet installed
+            </div>
+
             <!-- 安装之后的卡片样式 -->
-            <div class="left">
-                <div class="tips">
-                    <div class="title">
-                        After
-                    </div>
-                    <div class="desc">
-                        the installs denet
-                    </div>
-                </div>
-                <div class="head">
+            <div v-show="installStatus" class="left" :style="{'width': reviewCanvasParams.width+ 'px'}">
+                <div class="head" :style="{'zoom': reviewCanvasParams.zoom}">
                     <img :src="userInfo.avatarUrl"
                         class="avatar"/>
                     <div class="article-wrapper">
@@ -24,31 +21,25 @@
                         </div>
                     </div>
                 </div>
-                <div class="after-cover-wrapper">
-                    <custom-card-cover :data="{
-                        totalCount: baseFormData.totalCount,
-                        amountValue: baseFormData.amountValue,
-                        tokenSymbol: currentCurrencyInfo.tokenSymbol,
-                        currencyIconUrl: currentCurrencyInfo.iconPath,
-                        userInfo: {
-                            nickName: userInfo.name,
-                            avatarUrl: userInfo.avatarUrl
-                        }
-                    }"></custom-card-cover>
+                <div class="after-cover-wrapper-parent" :style="{'zoom': reviewCanvasParams.zoom}">
+                    <div class="after-cover-wrapper">
+                        <custom-card-cover :data="{
+                            totalCount: baseFormData.totalCount,
+                            amountValue: baseFormData.amountValue,
+                            tokenSymbol: currentCurrencyInfo.tokenSymbol,
+                            currencyIconUrl: currentCurrencyInfo.iconPath,
+                            userInfo: {
+                                nickName: userInfo.name,
+                                avatarUrl: userInfo.avatarUrl
+                            }
+                        }"></custom-card-cover>
+                    </div>
                 </div>
-            </div>
+            </div> 
 
             <!-- 安装之前的卡片样式 -->
-            <div class="content-before">
-                <div class="tips">
-                    <div class="title">
-                        Before
-                    </div>
-                    <div class="desc">
-                        the installs denet
-                    </div>
-                </div>
-                <div class="head">
+            <div v-show="!installStatus" class="content-before" :style="{'width': reviewCanvasParams.width+ 'px'}">
+                <div class="head" :style="{'zoom': reviewCanvasParams.zoom}">
                     <img :src="userInfo.avatarUrl"
                         class="avatar"/>
                     <div class="article-wrapper">
@@ -60,7 +51,7 @@
                         </div>
                     </div>
                 </div>
-                <div class="card-wrapper">
+                <div class="card-wrapper" :style="{'zoom': reviewCanvasParams.zoom}">
                     <img :src="require('@/assets/subject/img-card-cover-blue.png')"
                         class="card-cover"/>
                     <div class="bottom-bar">
@@ -72,9 +63,8 @@
                         </div>
                     </div>
                     <div class="user-info">
-                        <!-- <img :src="userInfo.avatarUrl" 
-                        class="avatar"/>-->
-                        @{{userInfo.name}}
+                        <img :src="userInfo.avatarUrl" 
+                        class="avatar"/> {{userInfo.name}}
                     </div>
                     <div class="content-text">
                         <div class="title">
@@ -100,14 +90,21 @@
 </template>
 
 <script setup>
-import { ref, defineProps, onMounted, nextTick, watch } from "vue";
+import { ref, defineProps, onMounted, nextTick, watch, reactive } from "vue";
 
 import customCardCover from './custom-card-cover.vue'
 
 import {getChromeStorage} from "@/uilts/chromeExtension"
+import { throttle } from "@/uilts/help"
 import {getUser} from "@/http/publishApi"
 
 let userInfo = ref({});
+let reviewCanvasParams = reactive({
+    width: 396,
+    zoom: 1
+});
+
+let installStatus = ref(false);
 
 defineProps({
     postData: {
@@ -162,14 +159,45 @@ const getUserName = (screenName) => {
     });
 }
 
+const calcPreviewCanvasParams = () => {
+    nextTick(() => {
+        let domHeight = document.querySelector('.card-container').offsetHeight;
+        const canvasHeight = 820, canvasWidth = 600;
+        if(domHeight < canvasHeight) {
+            //比例: 高 / 宽
+            let hWRatio = canvasHeight / canvasWidth; 
+            //缩小宽度 = 高度 / 比例  
+            let width = domHeight / hWRatio;  
+            if(width > canvasWidth) {
+                width = canvasWidth;
+            }
+            //缩小比例 
+            let zoom = width / canvasWidth;
+            if(zoom > 1) {
+                zoom = 1;
+            }
+            reviewCanvasParams.width = width;
+            reviewCanvasParams.zoom = zoom;
+        } else {
+            reviewCanvasParams.width = canvasWidth;
+            reviewCanvasParams.zoom = 1;
+        }
+    });
+}
+
 onMounted(() => {
+    calcPreviewCanvasParams();
     getUserInfo((res) => {
-        nextTick(() => {
-        })
         if(res) {
             getUserName(res.nickName);
         }
+        setInterval(() => {
+            installStatus.value = !installStatus.value;
+        }, 3000)
     });
+    window.addEventListener('resize', throttle(function () {
+        calcPreviewCanvasParams();
+    }, 300))
 })
 
 </script>
@@ -181,7 +209,7 @@ onMounted(() => {
     padding: 10px 16px;
     box-sizing: border-box;
     border-bottom-right-radius: 16px;
-    overflow-y: scroll;
+    overflow-y: auto;
     padding-bottom: 80px;
     display: flex;
 
@@ -191,14 +219,28 @@ onMounted(() => {
 
     .card-container {
         width: 100%;
-        height: fit-content;
+        height: 100%;
         background: #ffffff;
         box-sizing: border-box;
         border-radius: 20px;
-        padding: 0 16px;
+        padding: 0 6px;
         display: flex;
+        align-items: center;
+
+        .preview-txt {
+            width: 238px;
+            font-weight: 600;
+            font-size: 22px;
+            span {
+                color: #1D9BF0;
+            }
+        }
 
         .head {
+            position: absolute;
+            z-index: 1100;
+            top: 136px;
+            left: 17px;
             display: flex;
 
             .avatar {
@@ -228,19 +270,25 @@ onMounted(() => {
             }
         }
         .left {
-            width: 430px;
+            background: url('../../assets/img/img-preview-bg-after.png');
+            width: 387px;
+            height: 100%;
+            background-size: contain;
             .tips {
                 right: 15px !important;
             }
         }
 
+        .after-cover-wrapper-parent {
+            position: absolute;
+            z-index: 100;
+            top: 223px;
+            left: 78px;
+        }
+
         .after-cover-wrapper {
             position:relative;
             width:375px;
-            margin-left: 58px;
-            margin-top: -10px;
-            margin-bottom: 20px;
-
             .icon-gif {
                 position: absolute;
                 left: 50%;
@@ -260,8 +308,13 @@ onMounted(() => {
 
 
         .content-before {
-            width: 550px;
-            margin-left: 40px;
+            background: url('../../assets/img/img-preview-bg-before.png');
+            background-size: contain;
+            height: 100%;
+            .head {
+                top: 138px !important;
+                left: 17px !important;
+            }
             .card-wrapper {
                 width: 491px;
                 border: 1px solid #D1D9DD;
@@ -271,13 +324,13 @@ onMounted(() => {
                 position: relative;
                 box-sizing: border-box;
                 border-radius: 16px;
-                margin-left: 60px;
-                margin-top: -10px;
+                left: 73px;
+                top: 238px;
 
                 .user-info {
                     position: absolute;
-                    right: 10px;
-                    top: 6px;
+                    left: 8px;
+                    top: 8px;
                     z-index: 100;
                     display: flex;
                     align-items: center;
@@ -296,13 +349,12 @@ onMounted(() => {
                 }
                 .content-text {
                     position: absolute;
-                    top: 58px;
+                    top: 53px;
                     left: 35px;
                     .title {
                         font-weight: 800;
                         font-size: 16px;
                         color: #ffffff;
-                        margin-bottom: -8px;
                     }
                     .center {
                         padding: 12px 0;
@@ -324,7 +376,6 @@ onMounted(() => {
                         font-weight: 800;
                         font-size: 13px;
                         color: #ffffff;
-                        margin-top: -8px;
                     }
                 }
                 .card-cover {
@@ -352,25 +403,6 @@ onMounted(() => {
 
         .left, .content-before {
             position: relative;
-            .tips {
-                position: absolute;
-                right: -10px;
-                background: #F4F4F4;
-                border-radius: 6px;
-                padding: 3px 10px;
-                font-size: 10px;
-                color: #4D4D4D;
-                transform: scale(0.8);
-
-                .title {
-                    font-weight: 500;
-                    font-size: 12px;
-                }
-
-                .desc {
-                    opacity: .6;
-                }
-            }
         }
     }
 

+ 38 - 5
src/view/popup/popup.vue

@@ -78,7 +78,7 @@
                                                 </template>
                                                 <!-- 已完成 -->
                                                 <template v-else-if="item.status == 1">
-                                                    <span>{{ item.amount }}</span>
+                                                    <span class="blance">{{ item.amount }}</span>
                                                     <span class="coin-type">{{ item.currencySymbol || '' }}</span>
                                                     <img :src="item.currencyIconPath" alt="">
                                                 </template>
@@ -89,7 +89,7 @@
                                             </template>
                                             <!-- 发出去的 -->
                                             <template v-else-if="item.type == 2">
-                                                <span>-{{ item.amount }}</span>
+                                                <span class="blance">-{{ item.amount }}</span>
                                                 <span class="coin-type">{{ item.currencySymbol || '' }}</span>
                                                 <img :src="item.currencyIconPath" alt="">
                                             </template>
@@ -186,8 +186,10 @@ import {
     getChromeStorage,
 } from "@/uilts/chromeExtension";
 import { getBalance, getMineLuckdropRecords } from "@/http/account";
+import Report from "@/log-center/log";
 import router from "@/router/popup.js";
 import VHead from '@/view/popup/components/head.vue'
+
 let withdraw_info = inject('withdraw_info')
 withdraw_info.paypal = {}
 
@@ -253,6 +255,17 @@ onMounted(() => {
         if (isLogin.value) {
             getAccountBalance();
             getLuckdropRecordsList();
+            Report.reportLog({
+                pageSource: Report.pageSource.denetHomePage,
+                businessType: Report.businessType.pageView,
+            },{
+                type: window.location.href.indexOf('home.html') > -1 ? 'web' : 'extensions'
+            });
+        } else {
+            Report.reportLog({
+                pageSource: Report.pageSource.denetLogin,
+                businessType: Report.businessType.pageView,
+            });
         }
     });
 });
@@ -407,6 +420,11 @@ const withdrawBack = () => {
 // };
 
 const loginAction = () => {
+    Report.reportLog({
+        pageSource: Report.pageSource.denetLogin,
+        businessType: Report.businessType.buttonClick,
+        objectType: Report.objectType.loginButton
+    });
     login();
 };
 
@@ -443,9 +461,19 @@ const sendTwitter = (params) => {
 };
 // 点击提现
 const clickWithdraw = () => {
+    Report.reportLog({
+        pageSource: Report.pageSource.denetHomePage,
+        businessType: Report.businessType.buttonClick,
+        objectType: Report.objectType.withdrawButton
+    });
     router.push('/withdraw/home');
 }
 const clickTopUp = () => {
+    Report.reportLog({
+        pageSource: Report.pageSource.denetHomePage,
+        businessType: Report.businessType.buttonClick,
+        objectType: Report.objectType.topupButton
+    });
     router.push('/top-up/home');
 }
 
@@ -597,7 +625,7 @@ body {
                 display: flex;
                 justify-content: space-between;
                 align-items: center;
-                height: 66px;
+                min-height: 66px;
                 box-sizing: border-box;
                 padding-left: 20px;
                 cursor: pointer;
@@ -628,7 +656,7 @@ body {
                     align-items: center;
                     border-bottom: 1px solid #d1d1d1;
                     box-sizing: border-box;
-                    padding-right: 16px;
+                    padding: 8px 16px 8px 0;
 
                     .left {
                         .nickname {
@@ -657,12 +685,17 @@ body {
                                 justify-content: flex-end;
                                 align-items: center;
 
-                                span {
+                                .blance {
                                     margin-left: 3px;
+                                    display: inline-block;
+                                    max-width: 68px;
+                                    word-break: break-all;
+                                    line-height: 18px;
                                 }
 
                                 .coin-type {
                                     color: #E29A2E;
+                                    margin-left: 3px;
                                 }
 
                                 img {

+ 9 - 1
src/view/popup/top-up/home.vue

@@ -10,8 +10,9 @@
 <script setup>
 import VHead from '@/view/popup/components/head.vue'
 import CurrencyList from "@/view/components/currency-list.vue";
-import { inject } from 'vue'
+import { inject, onMounted } from 'vue'
 import router from "@/router/popup.js";
+import Report from "@/log-center/log";
 
 let top_up_info = inject('top_up_info')
 
@@ -25,6 +26,13 @@ function selectCurrency(_params) {
     top_up_info.icon_net = require('@/assets/svg/icon-BNB.svg')
     router.push({ path: '/top-up/info'});
 }
+
+onMounted(() => {
+    Report.reportLog({
+        pageSource: Report.pageSource.denetTopupSelector,
+        businessType: Report.businessType.pageView,
+    });
+})
 </script>
 
 

+ 5 - 1
src/view/popup/top-up/info.vue

@@ -58,7 +58,7 @@ import VHead from '@/view/popup/components/head.vue'
 import { useRouter } from "vue-router";
 import { getTokenRechargeAddress } from "@/http/pay";
 import { message } from 'ant-design-vue';
-
+import Report from "@/log-center/log";
 import { syncChainTokenRechargeRecord } from "@/http/publishApi";
 
 
@@ -128,6 +128,10 @@ const copyToken = () => {
 }
 
 onMounted(() => {
+    Report.reportLog({
+        pageSource: Report.pageSource.denetSelector,
+        businessType: Report.businessType.pageView,
+    });
     getTokenRechargeAddress({
         params: {
             "tokenChain": top_up_info.token_chain

+ 5 - 0
src/view/popup/withdraw/confirm.vue

@@ -65,6 +65,7 @@ import { reactive, inject, onMounted } from 'vue'
 import VHead from '@/view/popup/components/head.vue'
 import { withdrawRequest } from "@/http/account";
 import router from "@/router/popup.js";
+import Report from "@/log-center/log";
 import { message } from "ant-design-vue";
 
 let withdraw_info = inject('withdraw_info')
@@ -101,6 +102,10 @@ const clickBtn = () => {
 
 }
 onMounted(()=>{
+    Report.reportLog({
+        pageSource: Report.pageSource.denetWithdrawConfirm,
+        businessType: Report.businessType.pageView,
+    });
     state.img_enter_state = withdraw_info.enter_state
 })
 const clickRisk = () => {

+ 9 - 1
src/view/popup/withdraw/home.vue

@@ -11,7 +11,8 @@
 import VHead from '@/view/popup/components/head.vue'
 import CurrencyList from "@/view/components/currency-list.vue";
 import router from "@/router/popup.js";
-import { inject } from 'vue'
+import Report from "@/log-center/log";
+import { inject, onMounted } from 'vue'
 let withdraw_info = inject('withdraw_info')
 
 function selectCurrency(_params) {
@@ -33,6 +34,13 @@ function selectCurrency(_params) {
     }
 
 }
+
+onMounted(() => {
+    Report.reportLog({
+        pageSource: Report.pageSource.denetWithdrawSelector,
+        businessType: Report.businessType.pageView,
+    });
+})
 </script>
 
 

+ 6 - 1
src/view/popup/withdraw/info.vue

@@ -75,6 +75,7 @@ import router from "@/router/popup.js";
 import { reactive, onMounted, inject } from 'vue'
 import { getWithdrawConfig } from "@/http/account";
 import { withdrawCalcFee } from "@/http/pay";
+import Report from "@/log-center/log";
 
 let withdraw_info = inject('withdraw_info')
 
@@ -188,7 +189,11 @@ const initConfig = () => {
 }
 
 onMounted(() => {
-  initConfig()
+  initConfig();
+  Report.reportLog({
+    pageSource: Report.pageSource.denetWithdrawForm,
+    businessType: Report.businessType.pageView,
+  });
   withdraw_info.enter_state = false
 })
 

+ 144 - 11
src/view/red-packet.vue

@@ -23,7 +23,7 @@
                 <img :src="require('@/assets/gif/red-right.gif')" alt class="red-right"
                   v-show="!data.done.follow && data.done.follow_red" />
                 <img v-if="data.done.follow" :src="require('@/assets/svg/icon-true.svg')" alt />
-                <div v-else class="btn" @click="clickFollowAll(item.relatedUsers)">Follow All</div>
+                <div v-else class="btn" @click="clickFollowAll(item.relatedUsers, 'all')">Follow All</div>
               </div>
               <div class="item-follow-area">
                 <template v-for="item2, i in item.relatedUsers" v-bind:key="i">
@@ -47,7 +47,7 @@
             <img :src="require('@/assets/gif/red-right.gif')" alt class="red-right"
               v-show="!data.done.like && data.done.like_red" />
             <img v-if="data.done.like" :src="require('@/assets/svg/icon-true.svg')" alt />
-            <div v-else class="btn" @click="clickLickBtn">Like</div>
+            <div v-else class="btn" @click="clickLikeBtn">Like</div>
           </template>
           <template v-if="item.type == 3">
             <img :src="require('@/assets/svg/icon-retweet.svg')" alt />
@@ -246,6 +246,8 @@ import { getQueryString } from '@/uilts/help.js'
 import { message } from 'ant-design-vue';
 import FontAmount from '@/view/components/font-amount.vue'
 import { getChromeStorage } from '@/uilts/chromeExtension.js'
+import Report from "@/log-center/log"
+
 var moment = require('moment');
 
 let data = reactive({
@@ -269,7 +271,7 @@ let data = reactive({
 function clickRetry() {
   init()
 }
-async function clickLickBtn() {
+async function clickLikeBtn() {
   let _userInfo = await checkIsLogin()
   if (!_userInfo) {
     return
@@ -292,9 +294,21 @@ async function clickLickBtn() {
       console.log(res)
     }
   })
+  // 埋点
+  Report.reportLog({
+    objectType: Report.objectType.like,
+    pageSource: Report.pageSource.task_page,
+    businessType: Report.businessType.buttonClick
+  });
 }
 function clickDone() {
   window.open(`${chrome.runtime.getURL('/iframe/home.html')}`)
+  // 埋点
+  Report.reportLog({
+    objectType: Report.objectType.wallet_button,
+    pageSource: Report.pageSource.received_success_page,
+    businessType: Report.businessType.buttonClick
+  });
 }
 function handleScroll(e) {
   if (data.luck_list_end) {
@@ -353,6 +367,12 @@ async function clickRetweetBtn() {
       console.log(res)
     }
   })
+  // 埋点
+  Report.reportLog({
+    objectType: Report.objectType.retweet,
+    pageSource: Report.pageSource.task_page,
+    businessType: Report.businessType.buttonClick
+  });
 }
 
 
@@ -387,7 +407,7 @@ function getValidity() {
   }, 1000)
 }
 
-async function clickFollowAll(item) {
+async function clickFollowAll(item, is_all) {
   let _userInfo = await checkIsLogin()
   if (!_userInfo) {
     return
@@ -423,6 +443,17 @@ async function clickFollowAll(item) {
       });
     }
   })
+  let _log_obj = {
+    pageSource: Report.pageSource.task_page,
+    businessType: Report.businessType.buttonClick,
+    objectType: Report.objectType.follow
+  }
+  if (is_all) {
+    // 埋点
+    _log_obj.objectType = Report.objectType.follow_button
+  }
+  Report.reportLog(_log_obj);
+
 }
 // 我领取了的状态
 function myReceivedState() {
@@ -437,6 +468,11 @@ function myReceivedState() {
     if (data.detail.totalCount == data.detail.receiveCount) {
       data.status = 'close'
       data.close_text = ['All the rewards have', 'been taken out, come', 'earlier next time! ']
+      // 埋点
+      Report.reportLog({
+        pageSource: Report.pageSource.been_claimed_page,
+        businessType: Report.businessType.pageView,
+      });
     }
 
     // 我领取未完成 
@@ -446,14 +482,29 @@ function myReceivedState() {
     data.detail.taskCondition = JSON.parse(data.detail.taskCondition)
     data.detail.amountValue = showLastTwoPlace(data.detail.amountValue)
     data.detail.receiveAmountValue = showLastTwoPlace(data.detail.receiveAmountValue)
+    // 埋点
+    Report.reportLog({
+      pageSource: Report.pageSource.task_page,
+      businessType: Report.businessType.pageView,
+    });
 
     // 大红包不能领取了 and  我的红包过期了
   } else if (data.detail.receiveTimeExpired && data.detail.myReceived.taskFinishStatus == 2) {
     data.status = 'close'
     data.close_text = ['This Giveaways', `expired on ${moment(data.detail.endTimestamp).format('MM-DD')}`]
+    // 埋点
+    Report.reportLog({
+      pageSource: Report.pageSource.expired_page,
+      businessType: Report.businessType.pageView,
+    });
     // 我领取成功了
   } else if (data.detail.myReceived.taskFinishStatus == 1) {
     data.status = 'success'
+    // 埋点
+    Report.reportLog({
+      pageSource: Report.pageSource.received_success_page,
+      businessType: Report.businessType.pageView,
+    });
   }
 }
 
@@ -481,23 +532,40 @@ function init() {
       // 红包未开始
       if (data.detail.status == 0) {
         data.status = 'not-open'
-
+        Report.reportLog({
+          pageSource: Report.pageSource.pending_page,
+          businessType: Report.businessType.pageView
+        });
         // 任务进行中
       } else if (data.detail.status == 1) {
-        data.status = 'not-open'
         // 我领取过的状态
         if (data.detail.myReceived) {
           myReceivedState()
         } else {
-          // 大红包不可以领取了
-          if (data.detail.receiveTimeExpired) {
-            data.status = 'close'
-            data.close_text = [`This Giveaways`, `expired on ${moment(data.detail.endTimestamp).format('MM-DD')}`]
-          }
           // 任务已经被领完了
           if (data.detail.totalCount == data.detail.receiveCount) {
             data.status = 'close'
             data.close_text = ['All the rewards have', 'been taken out, come', 'earlier next time! ']
+            // 埋点
+            Report.reportLog({
+              pageSource: Report.pageSource.been_claimed_page,
+              businessType: Report.businessType.pageView,
+            });
+          } else if (data.detail.receiveTimeExpired) {
+            // 大红包不可以领取了
+            data.status = 'close'
+            data.close_text = [`This Giveaways`, `expired on ${moment(data.detail.endTimestamp).format('MM-DD')}`]
+            // 埋点
+            Report.reportLog({
+              pageSource: Report.pageSource.expired_page,
+              businessType: Report.businessType.pageView,
+            });
+          } else {
+            data.status = 'not-open'
+            Report.reportLog({
+              pageSource: Report.pageSource.pending_page,
+              businessType: Report.businessType.pageView
+            });
           }
         }
 
@@ -509,6 +577,10 @@ function init() {
         } else {
           data.status = 'close'
           data.close_text = [`This Giveaways`, `expired on ${moment(data.detail.endTimestamp).format('MM-DD')}`]
+          Report.reportLog({
+            pageSource: Report.pageSource.expired_page,
+            businessType: Report.businessType.pageView,
+          });
         }
       }
     } else {
@@ -574,6 +646,12 @@ function handleRedPacket() {
       handleErrorCode(res)
     }
   })
+  // 埋点
+  Report.reportLog({
+    pageSource: Report.pageSource.pending_page,
+    businessType: Report.businessType.buttonClick,
+    objectType: Report.objectType.open_button
+  });
 }
 
 chrome.storage.onChanged.addListener(changes => {
@@ -627,6 +705,14 @@ function handleFinishRedPacket() {
       if (res.data.finished) {
         data.status = 'success'
         data.receiveAmount = res.data.receiveAmount
+        // 埋点
+        Report.reportLog({
+          pageSource: Report.pageSource.task_page,
+          businessType: Report.businessType.buttonClick,
+          objectType: Report.objectType.get_giveaway
+        }, {
+          get_giveaway_result: Report.extParams.success
+        });
         init()
       } else {
         let _data = res.data.conditionResult
@@ -660,8 +746,24 @@ function handleFinishRedPacket() {
               break
           }
         }
+        // 埋点
+        Report.reportLog({
+          pageSource: Report.pageSource.task_page,
+          businessType: Report.businessType.buttonClick,
+          objectType: Report.objectType.get_giveaway
+        }, {
+          get_giveaway_result: Report.extParams.failure
+        });
       }
     } else {
+      // 埋点
+      Report.reportLog({
+        pageSource: Report.pageSource.task_page,
+        businessType: Report.businessType.buttonClick,
+        objectType: Report.objectType.get_giveaway
+      }, {
+        get_giveaway_result: Report.extParams.failure
+      });
       handleErrorCode(res)
     }
   })
@@ -718,12 +820,22 @@ function handleErrorCode(res) {
     case '2007':
       data.status = 'close'
       data.close_text = ['All the rewards have', 'been taken out, come', 'earlier next time! ']
+      // 埋点
+      Report.reportLog({
+        pageSource: Report.pageSource.been_claimed_page,
+        businessType: Report.businessType.pageView,
+      });
       init()
       break
     // 红包个数已经被领取完了
     case '2008':
       data.status = 'close'
       data.close_text = ['All the rewards have', 'been taken out, come', 'earlier next time! ']
+      // 埋点
+      Report.reportLog({
+        pageSource: Report.pageSource.been_claimed_page,
+        businessType: Report.businessType.pageView,
+      });
       init()
       break
     // 该用户不满足领取条件
@@ -731,6 +843,11 @@ function handleErrorCode(res) {
       data.error_txt = [`oops, new accounts cannot participate in this event,`]
       data.status = 'error'
       data.retry = true
+      // 埋点
+      Report.reportLog({
+        pageSource: Report.pageSource.robot_detection_failed_page,
+        businessType: Report.businessType.pageView,
+      });
       break
     // 无法校验用户Twitter信息
     case '2010':
@@ -780,10 +897,26 @@ function handleErrorCode(res) {
 
 function clickBack() {
   data.status = 'opened'
+  // 埋点
+  Report.reportLog({
+    pageSource: Report.pageSource.task_page,
+    businessType: Report.businessType.pageView,
+  });
 }
 
 function clickRoad() {
   data.status = 'luck-peopel-list'
+  // 埋点
+  Report.reportLog({
+    pageSource: Report.pageSource.task_page,
+    businessType: Report.businessType.buttonClick,
+    objectType: Report.objectType.received_list
+  });
+  // 埋点
+  Report.reportLog({
+    pageSource: Report.pageSource.received_list_page,
+    businessType: Report.businessType.pageView
+  });
 }
 </script>