nieyuge 2 年之前
父节点
当前提交
f4764d86e5

+ 3 - 0
src/assets/svg/icon-post-edit-luck.svg

@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M5.05497 9.83636V7.82727C5.05497 6.12727 6.29133 4.89091 7.99133 4.89091H9.2277C10.7732 4.89091 12.1641 6.12727 12.1641 7.82727V9.83636H13.555V7.82727C13.555 5.35455 11.5459 3.5 9.2277 3.5H7.99133C5.51861 3.5 3.66406 5.50909 3.66406 7.82727V9.83636H5.05497ZM14.3273 20.5003H2.89091C2.11818 20.5003 1.5 19.8821 1.5 19.1094V12.0003C1.5 11.2276 2.27273 10.6094 2.89091 10.6094H14.1727C15.1 10.6094 15.5636 11.2276 15.5636 12.0003V19.1094C15.7182 19.8821 15.1 20.5003 14.3273 20.5003ZM20.1177 20.5458L21.8908 18.7097L21.7607 11.2568C22.0825 11.0797 22.381 10.8534 22.6513 10.5734C23.3567 9.84292 23.743 8.86219 23.7253 7.84692C23.7076 6.83165 23.2873 5.865 22.5569 5.15962C21.8264 4.45425 20.8457 4.06793 19.8304 4.08565C18.8151 4.10337 17.8485 4.52368 17.1431 5.25412C16.4377 5.98455 16.0514 6.96528 16.0691 7.98056C16.0869 8.99583 16.5072 9.96248 17.2376 10.6679C17.5176 10.9382 17.8237 11.154 18.1516 11.3198L18.1871 13.359L19.5642 14.6888L18.2344 16.0658L19.6115 17.3957L18.2816 18.7727L20.1177 20.5458ZM19.8592 5.73542C20.1976 5.72951 20.5245 5.85828 20.768 6.09341C21.0115 6.32853 21.1516 6.65075 21.1575 6.98917C21.1634 7.3276 21.0346 7.65451 20.7995 7.89799C20.5644 8.14147 20.2422 8.28157 19.9038 8.28748C19.5653 8.29339 19.2384 8.16461 18.9949 7.92949C18.7515 7.69436 18.6114 7.37215 18.6055 7.03372C18.5995 6.6953 18.7283 6.36839 18.9634 6.12491C19.1986 5.88143 19.5208 5.74132 19.8592 5.73542Z" fill="#424B51"/>
+</svg>

+ 3 - 0
src/assets/svg/icon-post-edit-open.svg

@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M11.5957 5.58382C12.4466 5.58382 13.2627 5.92184 13.8643 6.52352C14.466 7.1252 14.804 7.94125 14.804 8.79215C14.804 9.64306 14.466 10.4591 13.8643 11.0608C13.2627 11.6625 12.4466 12.0005 11.5957 12.0005C10.7448 12.0005 9.92875 11.6625 9.32707 11.0608C8.72539 10.4591 8.38737 9.64306 8.38737 8.79215C8.38737 7.94125 8.72539 7.1252 9.32707 6.52352C9.92875 5.92184 10.7448 5.58382 11.5957 5.58382ZM5.17904 8.00049C5.69237 8.00049 6.16904 8.13799 6.58154 8.38549C6.44404 9.69632 6.82904 10.998 7.61737 12.0155C7.15904 12.8955 6.24237 13.5005 5.17904 13.5005C4.44969 13.5005 3.75022 13.2108 3.23449 12.695C2.71877 12.1793 2.42904 11.4798 2.42904 10.7505C2.42904 10.0211 2.71877 9.32167 3.23449 8.80594C3.75022 8.29022 4.44969 8.00049 5.17904 8.00049ZM18.0124 7.85352C18.7417 7.85352 19.4412 8.14325 19.9569 8.65897C20.4726 9.1747 20.7624 9.87417 20.7624 10.6035C20.7624 11.3329 20.4726 12.0323 19.9569 12.5481C19.4412 13.0638 18.7417 13.3535 18.0124 13.3535C16.949 13.3535 16.0324 12.7485 15.574 11.8685C16.3624 10.851 16.7474 9.54935 16.6099 8.23852C17.0224 7.99102 17.499 7.85352 18.0124 7.85352ZM5.63737 16.791C5.63737 14.8935 8.30487 13.3535 11.5957 13.3535C14.8865 13.3535 17.554 14.8935 17.554 16.791V18.3952H5.63737V16.791ZM0.595703 18.3952V17.0202C0.595703 15.746 2.3282 14.6735 4.67487 14.3619C4.13404 14.9852 3.80404 15.8468 3.80404 16.791V18.3952H0.595703ZM22.5957 18.3952H19.3874V16.791C19.3874 15.8468 19.0574 14.9852 18.5165 14.3619C20.8632 14.6735 22.5957 15.746 22.5957 17.0202V18.3952Z" fill="#424B51"/>
+</svg>

+ 4 - 0
src/assets/svg/icon-post-lock.svg

@@ -0,0 +1,4 @@
+<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M72.0799 86.2749H27.4304C24.4135 86.2749 22 83.6649 22 80.4025V50.388C22 47.1256 25.0169 44.5156 27.4304 44.5156H71.4766C75.0968 44.5156 76.9069 47.1256 76.9069 50.388V80.4025C77.5103 83.6649 75.0968 86.2749 72.0799 86.2749Z" fill="#F3B14D"/>
+<path d="M35.1867 40.4444V33.8186C35.1867 26.8184 40.1651 21.7274 47.0105 21.7274H51.989C58.212 21.7274 63.8128 26.8184 63.8128 33.8186V40.4444H69.4135V33.8186C69.4135 23.6366 61.3236 16 51.989 16H47.0105C37.0536 16 29.5859 24.2729 29.5859 33.8186V40.4444H35.1867Z" fill="#AEB9C2"/>
+</svg>

+ 6 - 0
src/entry/content.js

@@ -219,5 +219,11 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
         case 'Set_ToolBox_Fixed':
         case 'Set_ToolBox_Fixed':
             toolBox.switchStatus(req)
             toolBox.switchStatus(req)
             break
             break
+        case 'Set_ToolBox_By_Nft':
+            toolBox.buyNft(req)
+            break;
+        case 'Hide_ToolBox_By_Nft':
+            toolBox.hideBuyNft(req)
+            break;
     }
     }
 })
 })

+ 8 - 0
src/http/nft.js

@@ -87,4 +87,12 @@ export function redeemNft(params) {
         method: 'post',
         method: 'post',
         data: params
         data: params
     })
     })
+}
+
+export function listPossessNftProject(params) {
+    return service({
+        url: `/nft/possess/listPossessNftProject`,
+        method: 'post',
+        data: params
+    })
 }
 }

+ 9 - 1
src/http/toolBoxApi.js

@@ -30,4 +30,12 @@ export function checkInputUrlInBlacklist(params) {
         method: 'post',
         method: 'post',
         data: params
         data: params
     })
     })
-}
+}
+
+export function getPostEditorNftCertInfo(params) {
+    return service({
+        url: `/post/editor/getPostEditorNftCertInfo`,
+        method: 'post',
+        data: params
+    })
+}

+ 5 - 1
src/iframe/nft-card.js

@@ -1,7 +1,11 @@
 import { createApp } from 'vue'
 import { createApp } from 'vue'
 import App from '@/view/iframe/nft/card.vue'
 import App from '@/view/iframe/nft/card.vue'
+import CoutomSentry from "@/uilts/sentry.js"
+import AutoLog from '@/log-center/autoLog';
 
 
 const app = createApp(App);
 const app = createApp(App);
-import CoutomSentry from "@/uilts/sentry.js"
+
 CoutomSentry.initVue(app)
 CoutomSentry.initVue(app)
+
+app.use(AutoLog);
 app.mount('#app');
 app.mount('#app');

+ 3 - 1
src/iframe/publish.js

@@ -3,7 +3,7 @@ import App from '@/view/iframe/publish/publish.vue'
 
 
 import "ant-design-vue/dist/antd.css"; // or 'ant-design-vue/dist/antd.less'
 import "ant-design-vue/dist/antd.css"; // or 'ant-design-vue/dist/antd.less'
 
 
-import { Button, message, Tooltip, Switch } from "ant-design-vue";
+import { Button, message, Tooltip, Switch, Radio, RadioGroup } from "ant-design-vue";
 
 
 import AutoLog from '@/log-center/autoLog';
 import AutoLog from '@/log-center/autoLog';
 
 
@@ -20,6 +20,8 @@ app.use(Tooltip);
 app.use(message);
 app.use(message);
 app.use(Switch);
 app.use(Switch);
 app.use(AutoLog);
 app.use(AutoLog);
+app.use(Radio);
+app.use(RadioGroup);
 
 
 
 
 import CoutomSentry from "@/uilts/sentry.js"
 import CoutomSentry from "@/uilts/sentry.js"

+ 8 - 0
src/iframe/tool-box-buy-nft.js

@@ -0,0 +1,8 @@
+import { createApp } from 'vue'
+import App from '@/view/iframe/tool-box/buy-nft.vue'
+import AutoLog from '@/log-center/autoLog';
+
+const app = createApp(App);
+
+app.use(AutoLog);
+app.mount('#app');

+ 25 - 1
src/log-center/logEnum.js

@@ -4,6 +4,13 @@ export const logType = {
     'denet': '150',//denet-event-log
     'denet': '150',//denet-event-log
 }
 }
 
 
+export const redPacketType = {
+    nftSale: 2,
+    nftGroupSale: 3,
+    treasure: 4,
+    postEditor: 5,
+}
+
 export const businessType = {
 export const businessType = {
     buttonView: "buttonView",
     buttonView: "buttonView",
     buttonClick: "buttonClick",
     buttonClick: "buttonClick",
@@ -58,6 +65,15 @@ export const objectType = {
     create_nfts_button: 'create-nfts-button',
     create_nfts_button: 'create-nfts-button',
     confirm_transfer_button: 'confirm-transfer-button',
     confirm_transfer_button: 'confirm-transfer-button',
     redeem_button: 'redeem-button',
     redeem_button: 'redeem-button',
+    buy_button: 'buy-button',
+    buy_nft_button: 'buy-nft-button',
+    custom_link_button: 'custom-link-button',
+    history_button: 'history-button',
+    app_button: 'app-button',
+    enter_url_button: 'enter-url-button',
+    top_right_button: 'top-right-button',
+    fullscreen_button: 'fullscreen-button',
+    encrypte_nft_button: 'encrypte-nft-button',
 }
 }
 
 
 export const pageSource = {
 export const pageSource = {
@@ -75,6 +91,7 @@ export const pageSource = {
     denetMorePage: "denet-more-page",
     denetMorePage: "denet-more-page",
     denetSelector: "denet-selector",
     denetSelector: "denet-selector",
     nftShopPage: "nft-shop-page",
     nftShopPage: "nft-shop-page",
+    nftPreviewPage: "nft-preview-page",
     denetNftTransferPage: "denet-nft-transfer-page",
     denetNftTransferPage: "denet-nft-transfer-page",
     // 待开红包页
     // 待开红包页
     pending_page: 'pending-page',
     pending_page: 'pending-page',
@@ -91,7 +108,14 @@ export const pageSource = {
     // 成功领取到钱包
     // 成功领取到钱包
     received_success_page: 'received-success-page',
     received_success_page: 'received-success-page',
     received_empty_rewards_page: 'received-empty-rewards-page',
     received_empty_rewards_page: 'received-empty-rewards-page',
-
+    pe_loading_page: 'pe-loading-page',
+    pe_display_page: 'pe-display-page',
+    nft_sales_window: 'nft-sales-window',
+    nft_post_page: 'nft-post-page',
+    main_page_dashboard: 'main-page-dashboard',
+    post_editor_guide_page_left: 'post-editor-guide-page-left',
+    post_editor_guide_page_right: 'post-editor-guide-page-right',
+    buy_posteditor_nft_dialog: 'buy-posteditor-nft-dialog',
 }
 }
 
 
 export const extParams = {
 export const extParams = {

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

@@ -9,6 +9,13 @@ let mid = '';
  * @extParams 最终上报到阿里云以json字符串存储的参数,如果extparams传入的不是obj会转换成obj
  * @extParams 最终上报到阿里云以json字符串存储的参数,如果extparams传入的不是obj会转换成obj
  */
  */
 export async function reportLog(eventData = {}, extParams = {}) {
 export async function reportLog(eventData = {}, extParams = {}) {
+    // 过滤空值
+    let dataKey = Object.keys(eventData);
+    dataKey.forEach(key => {
+        if (eventData[key] === '') {
+            delete eventData[key]
+        }
+    })
     // 2.reportLog 异常 存储到本地,再上报
     // 2.reportLog 异常 存储到本地,再上报
     try {
     try {
         if (!userInfo) {
         if (!userInfo) {

+ 75 - 39
src/logic/background/twitter.js

@@ -244,21 +244,23 @@ export function onInstalledUserSet() {
         chrome.action.getUserSettings().then(res => {
         chrome.action.getUserSettings().then(res => {
             setChromeStorage({ userSettings: JSON.stringify({ res }) })
             setChromeStorage({ userSettings: JSON.stringify({ res }) })
             // 无刷新插入js
             // 无刷新插入js
-            chrome.tabs.query({}, (tab) => {
-                for (let i in tab) {
-                    chrome.scripting.executeScript({
-                        target: { tabId: tab[i].id },
-                        files: ['js/content_help.js']
-                    }, () => { })
-                    if (tab[i].url.indexOf('twitter.com') >= 0 || tab[i].url.indexOf('facebook.com') >= 0) {
+            chrome.tabs.query({}, (tabs) => {
+                for (let i in tabs) {
+                    if (tabs[i].url && tabs[i].url.substr(0, 4).includes('http')) {
                         chrome.scripting.executeScript({
                         chrome.scripting.executeScript({
-                            target: { tabId: tab[i].id },
-                            files: ['js/content.js'],
-                        }, () => {
-                            setTimeout(() => {
-                                setChromeStorage({ executeScript: JSON.stringify({ executeScript: 1 }) })
-                            }, 2000);
-                        })
+                            target: { tabId: tabs[i].id },
+                            files: ['js/content_help.js']
+                        }, () => { })
+                        if (tabs[i].url.indexOf('twitter.com') >= 0 || tabs[i].url.indexOf('facebook.com') >= 0) {
+                            chrome.scripting.executeScript({
+                                target: { tabId: tabs[i].id },
+                                files: ['js/content.js'],
+                            }, () => {
+                                setTimeout(() => {
+                                    setChromeStorage({ executeScript: JSON.stringify({ executeScript: 1 }) })
+                                }, 2000);
+                            })
+                        }
                     }
                     }
                 }
                 }
             })
             })
@@ -276,14 +278,22 @@ export function onInstalledUserSet() {
  * 检查是否pined 显示tips
  * 检查是否pined 显示tips
  */
  */
 export function checkPined() {
 export function checkPined() {
-    chrome.action.getUserSettings(res => {
-        let { isOnToolbar } = res;
-        if (!isOnToolbar) {
-            sendActivetabMessage({
-                actionType: 'BG_SHOW_PIN_TIPS'
-            });
-        }
-    })
+    try {
+        chrome.action.getUserSettings(res => {
+            let { isOnToolbar } = res;
+            if (!isOnToolbar) {
+                sendActivetabMessage({
+                    actionType: 'BG_SHOW_PIN_TIPS'
+                });
+            }
+        })
+    } catch (error) {
+        Report.reportLog({
+            objectType: Report.objectType.background_function_catch,
+            funcName: 'checkPined',
+            errMsg: error.message
+        })
+    }
 }
 }
 
 
 function sendActivetabMessage(message = {}) {
 function sendActivetabMessage(message = {}) {
@@ -292,9 +302,11 @@ function sendActivetabMessage(message = {}) {
             active: true,
             active: true,
             currentWindow: true
             currentWindow: true
         }, (tabs) => {
         }, (tabs) => {
-            chrome.tabs.sendMessage(tabs[0].id, message, res => {
-                console.log(res)
-            })
+            if(tabs && tabs.length) {
+                chrome.tabs.sendMessage(tabs[0].id, message, res => {
+                    console.log(res)
+                })
+            }
         })
         })
     } catch (error) {
     } catch (error) {
         Report.reportLog({
         Report.reportLog({
@@ -427,26 +439,50 @@ export function onInstalledCreateTab() {
  * @param {*} req 
  * @param {*} req 
  */
  */
 export function popupRePublish(req) {
 export function popupRePublish(req) {
-    setChromeStorage({
-        popupShowPublishDialog: JSON.stringify({
-            ...req.data,
-            show: true
-        }),
-    });
-    chrome.tabs.create({
-        url: "https://twitter.com",
-    });
+    try {
+        setChromeStorage({
+            popupShowPublishDialog: JSON.stringify({
+                ...req.data,
+                show: true
+            }),
+        });
+        chrome.tabs.create({
+            url: "https://twitter.com",
+        });
+    } catch (error) {
+        Report.reportLog({
+            objectType: Report.objectType.background_function_catch,
+            funcName: 'popupRePublish',
+            errMsg: error.message
+        })
+    }
 }
 }
 
 
 export function setBadgeInfo(params) {
 export function setBadgeInfo(params) {
-    let { text = '', color = '#DF3535' } = params.data || {};
-    chrome.action.setBadgeText({ text: text });
-    chrome.action.setBadgeBackgroundColor({ color: color });
+    try {
+        let { text = '', color = '#DF3535' } = params.data || {};
+        chrome.action.setBadgeText({ text: text });
+        chrome.action.setBadgeBackgroundColor({ color: color });
+    } catch (error) {
+        Report.reportLog({
+            objectType: Report.objectType.background_function_catch,
+            funcName: 'setBadgeInfo',
+            errMsg: error.message
+        })
+    }
 }
 }
 
 
 export function hideBadge() {
 export function hideBadge() {
-    chrome.action.setBadgeText({ text: '' });
-    chrome.action.setBadgeBackgroundColor({ color: [0, 0, 0, 0] });
+    try {
+        chrome.action.setBadgeText({ text: '' });
+        chrome.action.setBadgeBackgroundColor({ color: [0, 0, 0, 0] });
+    } catch (error) {
+        Report.reportLog({
+            objectType: Report.objectType.background_function_catch,
+            funcName: 'hideBadge',
+            errMsg: error.message
+        })
+    }
 }
 }
 
 
 export async function setMessageCount() {
 export async function setMessageCount() {

+ 24 - 0
src/logic/content/ToolBox.js

@@ -19,6 +19,7 @@ export const toolBox = new class ToolBox {
             border:medium none;  filter: drop-shadow(rgba(0, 0, 0, 0.2) 0px 4px 20px);
             border:medium none;  filter: drop-shadow(rgba(0, 0, 0, 0.2) 0px 4px 20px);
             `
             `
         iframe.src = chrome.runtime.getURL('/iframe/tool-box.html') + `?page_type=${'full'}`;
         iframe.src = chrome.runtime.getURL('/iframe/tool-box.html') + `?page_type=${'full'}`;
+        iframe.allow = "camera *;microphone *"
         document.body.append(iframe)
         document.body.append(iframe)
     }
     }
     // 切换状态
     // 切换状态
@@ -55,4 +56,27 @@ export const toolBox = new class ToolBox {
                 break
                 break
         }
         }
     }
     }
+    // 购买NFT
+    buyNft(req) {
+        let iframe = document.createElement('iframe')
+            iframe.src = chrome.runtime.getURL('/iframe/tool-box-buy-nft.html') + `?postId=${req.data.postId}`;
+        let ifAppend = document.querySelector('#denet-tool-box-buy-nft')
+        if (ifAppend) return;
+        let div = document.createElement(`div`);
+            div.id = 'denet-tool-box-buy-nft';
+            div.innerHTML = `
+                ${iframe.outerHTML}
+                <div class="mask_bg"></div>
+                <style>
+                    #denet-tool-box-buy-nft { position:fixed; width:100%; height:100%; top:0; left:0; }
+                    #denet-tool-box-buy-nft iframe { position:absolute; z-index:33; top:0; left:0; width:100%; height:100%; border:medium none; }
+                    #denet-tool-box-buy-nft .mask_bg{  position:absolute; z-index:32; width:100%; height:100%; top:0; left:0; background-color:rgba(0,0,0,.5); }
+                </style>
+            `
+        document.body.append(div)
+    }
+    hideBuyNft() {
+        let node = document.querySelector('#denet-tool-box-buy-nft')
+        node && node.remove()
+    }
 }
 }

+ 17 - 0
src/logic/content/nft.js

@@ -3,6 +3,7 @@ import { listJoinNftGroup } from '@/http/nft';
 import { getChromeStorage } from '@/uilts/chromeExtension.js'
 import { getChromeStorage } from '@/uilts/chromeExtension.js'
 import { _setPublishContent, publishNFTTweetPost, bindTwitterArt, bindTwitterArtMethod } from './twitter';
 import { _setPublishContent, publishNFTTweetPost, bindTwitterArt, bindTwitterArtMethod } from './twitter';
 import { jumpTwitterDetailByAlert } from '@/logic/content/help/twitter.js'
 import { jumpTwitterDetailByAlert } from '@/logic/content/help/twitter.js'
+import Report from "@/log-center/log"
 
 
 var ifShowNftGroup = false;
 var ifShowNftGroup = false;
 var tempNftGroupPost = null;
 var tempNftGroupPost = null;
@@ -31,8 +32,24 @@ export const showNFTGroupIcon = () => {
             oDiv.addEventListener('click', (e) => {
             oDiv.addEventListener('click', (e) => {
                 showNFTGroupList(e);
                 showNFTGroupList(e);
                 e.stopPropagation();
                 e.stopPropagation();
+                // report
+                Report.reportLog({
+                    pageSource: Report.pageSource.mainPage,
+                    businessType: Report.businessType.buttonClick,
+                    objectType: Report.objectType.buttonSecond
+                }, {
+                    type: 2
+                });
             })
             })
         toolElem.firstChild.appendChild(oDiv)
         toolElem.firstChild.appendChild(oDiv)
+        // report
+        Report.reportLog({
+            pageSource: Report.pageSource.mainPage,
+            businessType: Report.businessType.buttonView,
+            objectType: Report.objectType.buttonSecond
+        }, {
+            type: 2
+        });
     }
     }
 }
 }
 
 

+ 42 - 14
src/logic/content/twitter.js

@@ -31,11 +31,11 @@ function twitterPinLogin() {
     if (pin_login) {
     if (pin_login) {
         return
         return
     }
     }
-    pin_login = true
     if (window.location.href == 'https://api.twitter.com/oauth/authorize') {
     if (window.location.href == 'https://api.twitter.com/oauth/authorize') {
         let code = document.querySelector('code')
         let code = document.querySelector('code')
 
 
         if (code) {
         if (code) {
+            pin_login = true
             chrome.runtime.sendMessage({ actionType: "CONTENT_SEND_CODE", code: code.innerText }, () => { })
             chrome.runtime.sendMessage({ actionType: "CONTENT_SEND_CODE", code: code.innerText }, () => { })
             // port.postMessage({ state: 'CONTENT_SEND_CODE', code: code.innerText })
             // port.postMessage({ state: 'CONTENT_SEND_CODE', code: code.innerText })
         }
         }
@@ -276,42 +276,60 @@ function checkIsShowReSend(dom, params) {
  * @param isClick
  * @param isClick
  * @private
  * @private
  */
  */
-function _addDeNetEditBtn(params = {}) {
+ function _addDeNetEditBtn(params = {}) {
     let toolElem = document.querySelector('div[data-testid="toolBar"]');
     let toolElem = document.querySelector('div[data-testid="toolBar"]');
     if (toolElem) {
     if (toolElem) {
-        Report.reportLog({
-            pageSource: Report.pageSource.mainPage,
-            businessType: Report.businessType.buttonView,
-            objectType: Report.objectType.buttonSecond
-        });
         let innerDeIcon = toolElem.querySelector('#de-btn1');
         let innerDeIcon = toolElem.querySelector('#de-btn1');
         if (!innerDeIcon) {
         if (!innerDeIcon) {
             toolElem.firstChild.appendChild(createTweetToolbarDenet());
             toolElem.firstChild.appendChild(createTweetToolbarDenet());
             popupShowGiveawayDialog();
             popupShowGiveawayDialog();
+            Report.reportLog({
+                pageSource: Report.pageSource.mainPage,
+                businessType: Report.businessType.buttonView,
+                objectType: Report.objectType.buttonSecond
+            }, {
+                type: 0
+            });
         }
         }
 
 
         let innerToolBoxIcon = toolElem.querySelector('#de-tool-box-btn-01');
         let innerToolBoxIcon = toolElem.querySelector('#de-tool-box-btn-01');
         if (!innerToolBoxIcon) {
         if (!innerToolBoxIcon) {
             toolElem.firstChild.appendChild(createTweetToolbarToolBox())
             toolElem.firstChild.appendChild(createTweetToolbarToolBox())
+            Report.reportLog({
+                pageSource: Report.pageSource.mainPage,
+                businessType: Report.businessType.buttonView,
+                objectType: Report.objectType.buttonSecond
+            }, {
+                type: 1
+            });
         }
         }
     } else {
     } else {
         setTimeout(() => {
         setTimeout(() => {
             let toolElem = document.querySelector('div[data-testid="toolBar"]');
             let toolElem = document.querySelector('div[data-testid="toolBar"]');
             if (toolElem) {
             if (toolElem) {
-                Report.reportLog({
-                    pageSource: Report.pageSource.mainPage,
-                    businessType: Report.businessType.buttonView,
-                    objectType: Report.objectType.buttonSecond
-                });
                 let innerDeIcon = toolElem.querySelector('#de-btn1');
                 let innerDeIcon = toolElem.querySelector('#de-btn1');
                 if (!innerDeIcon) {
                 if (!innerDeIcon) {
                     toolElem.firstChild.appendChild(createTweetToolbarDenet());
                     toolElem.firstChild.appendChild(createTweetToolbarDenet());
                     popupShowGiveawayDialog();
                     popupShowGiveawayDialog();
+                    Report.reportLog({
+                        pageSource: Report.pageSource.mainPage,
+                        businessType: Report.businessType.buttonView,
+                        objectType: Report.objectType.buttonSecond
+                    }, {
+                        type: 0
+                    });
                 }
                 }
 
 
                 let innerToolBoxIcon = toolElem.querySelector('#de-tool-box-btn-01');
                 let innerToolBoxIcon = toolElem.querySelector('#de-tool-box-btn-01');
                 if (!innerToolBoxIcon) {
                 if (!innerToolBoxIcon) {
                     toolElem.firstChild.appendChild(createTweetToolbarToolBox())
                     toolElem.firstChild.appendChild(createTweetToolbarToolBox())
+                    Report.reportLog({
+                        pageSource: Report.pageSource.mainPage,
+                        businessType: Report.businessType.buttonView,
+                        objectType: Report.objectType.buttonSecond
+                    }, {
+                        type: 1
+                    });
                 }
                 }
             }
             }
         }, 1000)
         }, 1000)
@@ -594,6 +612,8 @@ function createTweetToolbarDenet() {
             pageSource: Report.pageSource.mainPage,
             pageSource: Report.pageSource.mainPage,
             businessType: Report.businessType.buttonClick,
             businessType: Report.businessType.buttonClick,
             objectType: Report.objectType.buttonSecond
             objectType: Report.objectType.buttonSecond
+        }, {
+            type: 0
         });
         });
         _deNetBtnClick();
         _deNetBtnClick();
     })
     })
@@ -614,6 +634,14 @@ function createTweetToolbarToolBox() {
         _deNetBtnClick({
         _deNetBtnClick({
             type: 'TOOL_BOX'
             type: 'TOOL_BOX'
         })
         })
+        // report
+        Report.reportLog({
+            pageSource: Report.pageSource.mainPage,
+            businessType: Report.businessType.buttonClick,
+            objectType: Report.objectType.buttonSecond
+        }, {
+            type: 1
+        });
     })
     })
 
 
     return deToolBoxBtn;
     return deToolBoxBtn;
@@ -1716,13 +1744,13 @@ export const hideBuyNFT = () => {
     iframe.src = ''
     iframe.src = ''
 }
 }
 
 
-export const showBuyNFT = ({ nft_project_Id }) => {
+export const showBuyNFT = ({ nft_project_Id, post_Id = '' }) => {
     if (!nft_project_Id) {
     if (!nft_project_Id) {
         return
         return
     }
     }
     let iframe = document.querySelector('#nftProjectId')
     let iframe = document.querySelector('#nftProjectId')
     iframe.style.display = 'block'
     iframe.style.display = 'block'
-    iframe.src = chrome.runtime.getURL(`/iframe/buy-nft.html#/?nftProjectId=${nft_project_Id}`)
+    iframe.src = chrome.runtime.getURL(`/iframe/buy-nft.html#/?nftProjectId=${nft_project_Id}&postId=${post_Id}`)
 }
 }
 
 
 const initBuyNFT = () => {
 const initBuyNFT = () => {

+ 3 - 2
src/manifest.json

@@ -2,8 +2,8 @@
     "manifest_version": 3,
     "manifest_version": 3,
     "name": "DeNet",
     "name": "DeNet",
     "description": "Growing more twitter followers with Denet",
     "description": "Growing more twitter followers with Denet",
-    "version": "1.1.6.1",
-    "denet_app_version_code": "18",
+    "version": "1.1.6.2",
+    "denet_app_version_code": "19",
     "background": {
     "background": {
         "service_worker": "/js/background.js"
         "service_worker": "/js/background.js"
     },
     },
@@ -95,6 +95,7 @@
                 "/iframe/joined-group-list.html",
                 "/iframe/joined-group-list.html",
                 "/iframe/tool-box-guide.html",
                 "/iframe/tool-box-guide.html",
                 "/iframe/tool-box.html",
                 "/iframe/tool-box.html",
+                "/iframe/tool-box-buy-nft.html",
                 "/iframe/test.html",
                 "/iframe/test.html",
                 "/iframe/ach-cashier.html",
                 "/iframe/ach-cashier.html",
                 "/img/icon-denet-logo.svg",
                 "/img/icon-denet-logo.svg",

+ 13 - 9
src/uilts/chromeExtension.js

@@ -141,15 +141,19 @@ export function checkIsLogin(callback) {
 
 
 let callback_arr = []
 let callback_arr = []
 export function httpContentToBack(data, callback) {
 export function httpContentToBack(data, callback) {
-    let callback_id = guid()
-    chrome.runtime.sendMessage({ actionType: "HTTP_CONTENT_TO_BACK", data, callback_id }, (res) => {
-        if (res && callback) {
-            callback_arr.push({
-                callback_id,
-                callback,
-            })
-        }
-    })
+    try {
+        let callback_id = guid()
+        chrome.runtime.sendMessage({ actionType: "HTTP_CONTENT_TO_BACK", data, callback_id }, (res) => {
+            if (res && callback) {
+                callback_arr.push({
+                    callback_id,
+                    callback,
+                })
+            }
+        })
+    } catch (error) {
+
+    }
 }
 }
 
 
 // 再找到它执行
 // 再找到它执行

+ 44 - 34
src/view/components/popup-transactions.vue

@@ -1,5 +1,5 @@
 <template>
 <template>
-    <div class="com-wrapper" ref="listWrapper"  @scroll="listScroll">
+    <div class="com-wrapper" ref="listWrapper" @scroll="listScroll">
         <!-- <div class="com-nav-bar">
         <!-- <div class="com-nav-bar">
             <img
             <img
                 :src="require('@/assets/svg/icon-bar-arrow-left.svg')"
                 :src="require('@/assets/svg/icon-bar-arrow-left.svg')"
@@ -9,14 +9,13 @@
             Transactions
             Transactions
         </div> -->
         </div> -->
 
 
-            <template v-if="!dataList.length">
-                <img class="icon-empty" :src="require('@/assets/svg/icon-empty-list.svg')" />
-            </template>
+        <template v-if="!dataList.length">
+            <img class="icon-empty" :src="require('@/assets/svg/icon-empty-list.svg')" />
+        </template>
         <div class="list-wrapper" ref="listContent">
         <div class="list-wrapper" ref="listContent">
             <div>
             <div>
                 <div class="cell" v-for="(item, index) in dataList" :key="index">
                 <div class="cell" v-for="(item, index) in dataList" :key="index">
-                    <red-dot class="red-dots"
-                        v-if="item.unReadMsgCount > 0 && isReadMsg"></red-dot>
+                    <red-dot class="red-dots" v-if="item.unReadMsgCount > 0 && isReadMsg"></red-dot>
                     <div class="img-wrapper">
                     <div class="img-wrapper">
                         <!-- 收入- 任务红包领取 -->
                         <!-- 收入- 任务红包领取 -->
                         <template v-if="item.bizType == 1 || item.bizType == 5 || item.bizType == 10 || item.bizType == 11 || item.bizType == 12">
                         <template v-if="item.bizType == 1 || item.bizType == 5 || item.bizType == 10 || item.bizType == 11 || item.bizType == 12">
@@ -44,14 +43,18 @@
                         </template>
                         </template>
                         <!-- 收入 - 盲盒 -->
                         <!-- 收入 - 盲盒 -->
                         <template v-else-if="item.bizType == 7">
                         <template v-else-if="item.bizType == 7">
-                            <img class="icon-avatar" style="margin-left:-4px" :src="item.bizData.imagePath" v-if="item.bizData && item.bizData.imagePath" />
-                            <img class="icon-avatar" style="margin-left:-4px" :src="require('@/assets/svg/icon-wallter-list-blind-box.svg')" v-else />
+                            <img class="icon-avatar" style="margin-left:-4px" :src="item.bizData.imagePath"
+                                v-if="item.bizData && item.bizData.imagePath" />
+                            <img class="icon-avatar" style="margin-left:-4px"
+                                :src="require('@/assets/svg/icon-wallter-list-blind-box.svg')" v-else />
                             <img class="icon-give" :src="require('@/assets/svg/icon-list-withdraw-s.svg')" />
                             <img class="icon-give" :src="require('@/assets/svg/icon-list-withdraw-s.svg')" />
                         </template>
                         </template>
                         <!-- 收入 - 盲盒 -->
                         <!-- 收入 - 盲盒 -->
                         <template v-else-if="item.bizType == 8">
                         <template v-else-if="item.bizType == 8">
-                            <img class="icon-avatar" style="margin-left:-4px" :src="item.bizData.imagePath" v-if="item.bizData && item.bizData.imagePath" />
-                            <img class="icon-avatar" style="margin-left:-4px" :src="require('@/assets/svg/icon-wallter-list-blind-box.svg')" v-else />
+                            <img class="icon-avatar" style="margin-left:-4px" :src="item.bizData.imagePath"
+                                v-if="item.bizData && item.bizData.imagePath" />
+                            <img class="icon-avatar" style="margin-left:-4px"
+                                :src="require('@/assets/svg/icon-wallter-list-blind-box.svg')" v-else />
                             <img class="icon-give" :src="require('@/assets/svg/icon-get-giveaways-s.svg')" />
                             <img class="icon-give" :src="require('@/assets/svg/icon-get-giveaways-s.svg')" />
                         </template>
                         </template>
                         <!-- 支出 - 提现 -->
                         <!-- 支出 - 提现 -->
@@ -72,12 +75,12 @@
                         <!-- 支出-买盲盒 -->
                         <!-- 支出-买盲盒 -->
                         <template v-else-if="item.bizType == -3">
                         <template v-else-if="item.bizType == -3">
                             <img style="margin-left:-4px" :src="
                             <img style="margin-left:-4px" :src="
-                                        require('@/assets/svg/icon-wallter-list-blind-box.svg')
+                                require('@/assets/svg/icon-wallter-list-blind-box.svg')
                             " />
                             " />
                         </template>
                         </template>
                         <template v-else-if="item.bizType == -4">
                         <template v-else-if="item.bizType == -4">
                             <img class="icon-avatar" style="margin-left:-4px" :src="
                             <img class="icon-avatar" style="margin-left:-4px" :src="
-                                        require('@/assets/svg/icon-big-give.svg')
+                                require('@/assets/svg/icon-big-give.svg')
                             " />
                             " />
                             <img class="icon-give" :src="
                             <img class="icon-give" :src="
                                 require('@/assets/svg/icon-list-withdraw-s.svg')
                                 require('@/assets/svg/icon-list-withdraw-s.svg')
@@ -85,8 +88,10 @@
                         </template>
                         </template>
                         <!-- 交易链手续费 -->
                         <!-- 交易链手续费 -->
                         <template v-else-if="item.bizType == -5">
                         <template v-else-if="item.bizType == -5">
-                            <img class="icon-avatar" style="margin-left:-4px" :src="item.bizData.imagePath" v-if="item.bizData && item.bizData.imagePath" />
-                            <img class="icon-avatar" style="margin-left:-4px" :src="require('@/assets/img/icon-box2.png')" v-else />
+                            <img class="icon-avatar" style="margin-left:-4px" :src="item.bizData.imagePath"
+                                v-if="item.bizData && item.bizData.imagePath" />
+                            <img class="icon-avatar" style="margin-left:-4px"
+                                :src="require('@/assets/img/icon-box2.png')" v-else />
                             <img class="icon-give" :src="require('@/assets/svg/icon-transaction-s.svg')" />
                             <img class="icon-give" :src="require('@/assets/svg/icon-transaction-s.svg')" />
                         </template>
                         </template>
                         <!-- 支出-夺宝 -->
                         <!-- 支出-夺宝 -->
@@ -121,7 +126,7 @@
                                     Lottery Refund
                                     Lottery Refund
                                 </template>
                                 </template>
                                 <template v-else-if="item.bizType == 7">
                                 <template v-else-if="item.bizType == 7">
-                                    Sell NFT Mystery box*{{(item.bizData && item.bizData.nftItemCount || '')}}
+                                    Sell NFT Mystery box*{{ (item.bizData && item.bizData.nftItemCount || '') }}
                                 </template>
                                 </template>
                                 <template v-else-if="item.bizType == 8">
                                 <template v-else-if="item.bizType == 8">
                                     NFT Refund
                                     NFT Refund
@@ -139,7 +144,7 @@
                                     Giveaways
                                     Giveaways
                                 </template>
                                 </template>
                                 <template v-else-if="item.bizType == -3">
                                 <template v-else-if="item.bizType == -3">
-                                    Buy NFT Mystery box*{{(item.bizData && item.bizData.nftItemCount || '')}}
+                                    Buy NFT Mystery box*{{ (item.bizData && item.bizData.nftItemCount || '') }}
                                 </template>
                                 </template>
                                 <template v-else-if="item.bizType == -4">
                                 <template v-else-if="item.bizType == -4">
                                     Lottery Giveaway
                                     Lottery Giveaway
@@ -157,17 +162,19 @@
                             <div class="msg">
                             <div class="msg">
                                 <template v-if="item.bizType == -1">
                                 <template v-if="item.bizType == -1">
                                     <!-- 提现支出-状态(0:已申请,1:支付中,2:提现成功,3:提现失败) -->
                                     <!-- 提现支出-状态(0:已申请,1:支付中,2:提现成功,3:提现失败) -->
-                                    <template v-if="item.bizData.withdrawStatus == 0 || item.bizData.withdrawStatus == 1">
+                                    <template
+                                        v-if="item.bizData.withdrawStatus == 0 || item.bizData.withdrawStatus == 1">
                                         <div>
                                         <div>
                                             <div class="balance"
                                             <div class="balance"
-                                                :class="{'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12}">
+                                                :class="{ 'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12 }">
                                                 <span class="amount">
                                                 <span class="amount">
-                                                    <a-tooltip :title="'-'+item.trxAmountValue">
+                                                    <a-tooltip :title="'-' + item.trxAmountValue">
                                                         -{{ getBit(item.trxAmountValue) || 0 }}
                                                         -{{ getBit(item.trxAmountValue) || 0 }}
                                                     </a-tooltip>
                                                     </a-tooltip>
                                                 </span>
                                                 </span>
                                                 <div class="trx-amount-currency-info">
                                                 <div class="trx-amount-currency-info">
-                                                    <span class="name">{{ item.trxAmountCurrencyInfo.tokenSymbol }}</span>
+                                                    <span class="name">{{ item.trxAmountCurrencyInfo.tokenSymbol
+                                                    }}</span>
                                                     <img :src="item.trxAmountCurrencyInfo.iconPath" alt="">
                                                     <img :src="item.trxAmountCurrencyInfo.iconPath" alt="">
                                                 </div>
                                                 </div>
                                             </div>
                                             </div>
@@ -178,9 +185,9 @@
                                     </template>
                                     </template>
                                     <template v-else-if="item.bizData.withdrawStatus == 2">
                                     <template v-else-if="item.bizData.withdrawStatus == 2">
                                         <div class="balance"
                                         <div class="balance"
-                                            :class="{'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12}">
+                                            :class="{ 'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12 }">
                                             <span class="amount">
                                             <span class="amount">
-                                                <a-tooltip :title="'-'+item.trxAmountValue">
+                                                <a-tooltip :title="'-' + item.trxAmountValue">
                                                     -{{ getBit(item.trxAmountValue) || 0 }}
                                                     -{{ getBit(item.trxAmountValue) || 0 }}
                                                 </a-tooltip>
                                                 </a-tooltip>
                                             </span>
                                             </span>
@@ -200,7 +207,8 @@
                                                     </a-tooltip>
                                                     </a-tooltip>
                                                 </span>
                                                 </span>
                                                 <div class="trx-amount-currency-info">
                                                 <div class="trx-amount-currency-info">
-                                                    <span class="name">{{ item.trxAmountCurrencyInfo.tokenSymbol }}</span>
+                                                    <span class="name">{{ item.trxAmountCurrencyInfo.tokenSymbol
+                                                    }}</span>
                                                     <img :src="item.trxAmountCurrencyInfo.iconPath" alt="">
                                                     <img :src="item.trxAmountCurrencyInfo.iconPath" alt="">
                                                 </div>
                                                 </div>
                                             </div>
                                             </div>
@@ -211,9 +219,9 @@
                                     </template>
                                     </template>
                                     <template v-else>
                                     <template v-else>
                                         <div class="balance"
                                         <div class="balance"
-                                            :class="{'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12}">
+                                            :class="{ 'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12 }">
                                             <span class="amount">
                                             <span class="amount">
-                                                <a-tooltip :title="'-'+item.trxAmountValue">
+                                                <a-tooltip :title="'-' + item.trxAmountValue">
                                                     -{{ getBit(item.trxAmountValue) || 0 }}
                                                     -{{ getBit(item.trxAmountValue) || 0 }}
                                                 </a-tooltip>
                                                 </a-tooltip>
                                             </span>
                                             </span>
@@ -227,7 +235,7 @@
 
 
                                 <template v-else>
                                 <template v-else>
                                     <div class="balance"
                                     <div class="balance"
-                                        :class="{'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12}">
+                                        :class="{ 'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12 }">
 
 
                                         <!--支出—— -2:零钱余额支付 、-3: NFT盲盒余额支付 -->
                                         <!--支出—— -2:零钱余额支付 、-3: NFT盲盒余额支付 -->
                                         <span class="amount" v-if="item.bizType == -2 || item.bizType == -3 || item.bizType == -4 || item.bizType == -5 || item.bizType == -6">
                                         <span class="amount" v-if="item.bizType == -2 || item.bizType == -3 || item.bizType == -4 || item.bizType == -5 || item.bizType == -6">
@@ -237,7 +245,7 @@
                                         </span>
                                         </span>
                                         <!-- 收入—— bizType:1、2、3、4 -->
                                         <!-- 收入—— bizType:1、2、3、4 -->
                                         <span class="amount" v-else>
                                         <span class="amount" v-else>
-                                            <a-tooltip :title="'+'+item.trxAmountValue">
+                                            <a-tooltip :title="'+' + item.trxAmountValue">
                                                 +{{ getBit(item.trxAmountValue) || 0 }}
                                                 +{{ getBit(item.trxAmountValue) || 0 }}
                                             </a-tooltip>
                                             </a-tooltip>
                                         </span>
                                         </span>
@@ -325,13 +333,15 @@ onMounted(() => {
 });
 });
 
 
 const setMessageCount = () => {
 const setMessageCount = () => {
-    getAllMessageInfo({params: {
-    }}).then(res => {
-        if(res.code == 0) {
-            let {unReadCountTotal = 0 } = res.data;
-            if(unReadCountTotal > 0) {
-                let text = unReadCountTotal > 99 ? '99+' : unReadCountTotal+'';
-                setBadgeInfo({data: {text}});
+    getAllMessageInfo({
+        params: {
+        }
+    }).then(res => {
+        if (res.code == 0) {
+            let { unReadCountTotal = 0 } = res.data;
+            if (unReadCountTotal > 0) {
+                let text = unReadCountTotal > 99 ? '99+' : unReadCountTotal + '';
+                setBadgeInfo({ data: { text } });
             } else {
             } else {
                 hideBadge();
                 hideBadge();
             }
             }

+ 19 - 1
src/view/iframe/buy-nft/buy/home.vue

@@ -113,6 +113,7 @@ import BtnLoading from '../components/btn-loading.vue'
 import Report from "@/log-center/log"
 import Report from "@/log-center/log"
 import { getQueryString } from "@/uilts/help";
 import { getQueryString } from "@/uilts/help";
 import { sendChromeTabMessage } from '@/uilts/chromeExtension.js';
 import { sendChromeTabMessage } from '@/uilts/chromeExtension.js';
+let postId = inject('post_Id');
 let pay_info = inject('pay_info');
 let pay_info = inject('pay_info');
 let router = useRouter()
 let router = useRouter()
 let showDesc = ref(true)
 let showDesc = ref(true)
@@ -155,6 +156,16 @@ const clickClose = () => {
 const clickJump = (item) => {
 const clickJump = (item) => {
     pay_info.home.sale_plan = item
     pay_info.home.sale_plan = item
     router.push({ path: '/pay' });
     router.push({ path: '/pay' });
+    // report
+    Report.reportLog({
+        pageSource: Report.pageSource.nftShopPage,
+        businessType: Report.businessType.buttonClick,
+        objectType: Report.objectType.buy_button,
+        nftProjectId: projectId.value,
+        postEditorPostId: postId.value,
+    }, {
+        'buy-number': item.itemCount
+    })
 }
 }
 
 
 const setDialogStyle = () => {
 const setDialogStyle = () => {
@@ -192,6 +203,7 @@ const redeemPost = () => {
                 businessType: Report.businessType.buttonClick,
                 businessType: Report.businessType.buttonClick,
                 objectType: Report.objectType.redeem_button,
                 objectType: Report.objectType.redeem_button,
                 nftProjectId: projectId.value,
                 nftProjectId: projectId.value,
+                postEditorPostId: postId.value,
             }, {
             }, {
                 result: 'success'
                 result: 'success'
             })
             })
@@ -233,6 +245,7 @@ const redeemPost = () => {
                 businessType: Report.businessType.buttonClick,
                 businessType: Report.businessType.buttonClick,
                 objectType: Report.objectType.redeem_button,
                 objectType: Report.objectType.redeem_button,
                 nftProjectId: projectId.value,
                 nftProjectId: projectId.value,
+                postEditorPostId: postId.value,
             }, {
             }, {
                 result: 'fail'
                 result: 'fail'
             })
             })
@@ -257,6 +270,7 @@ const showRedeemLayer = () => {
         businessType: Report.businessType.buttonClick,
         businessType: Report.businessType.buttonClick,
         objectType: Report.objectType.redeem_button,
         objectType: Report.objectType.redeem_button,
         nftProjectId: projectId.value,
         nftProjectId: projectId.value,
+        postEditorPostId: postId.value,
     })
     })
 }
 }
 
 
@@ -280,6 +294,7 @@ onMounted(() => {
 
 
     let nft_project_Id = router.currentRoute.value.query.nftProjectId
     let nft_project_Id = router.currentRoute.value.query.nftProjectId
     let nft_group_Id = router.currentRoute.value.query.nft_group_Id
     let nft_group_Id = router.currentRoute.value.query.nft_group_Id
+    let post_id = router.currentRoute.value.query.postId
     if(nft_group_Id){
     if(nft_group_Id){
         pay_info.nft_group_Id = nft_group_Id
         pay_info.nft_group_Id = nft_group_Id
     }
     }
@@ -290,6 +305,7 @@ onMounted(() => {
     // 作用域外用
     // 作用域外用
     groupId.value = nft_group_Id
     groupId.value = nft_group_Id
     projectId.value = nft_project_Id
     projectId.value = nft_project_Id
+    postId.value = post_id
 
 
     getNftMysteryBoxSaleInfo({
     getNftMysteryBoxSaleInfo({
         params: {
         params: {
@@ -315,7 +331,8 @@ onMounted(() => {
     Report.reportLog({
     Report.reportLog({
         pageSource: Report.pageSource.nftShopPage,
         pageSource: Report.pageSource.nftShopPage,
         businessType: Report.businessType.pageView,
         businessType: Report.businessType.pageView,
-        nftProjectId: nft_project_Id
+        nftProjectId: nft_project_Id,
+        postEditorPostId: postId.value,
     })
     })
 })
 })
 </script>
 </script>
@@ -487,6 +504,7 @@ onMounted(() => {
                 border-radius: 100px;
                 border-radius: 100px;
                 color: #1D9BF0;
                 color: #1D9BF0;
                 min-width: 110px;
                 min-width: 110px;
+                min-height: 50px;
                 display: flex;
                 display: flex;
                 justify-content: center;
                 justify-content: center;
                 align-items: center;
                 align-items: center;

+ 12 - 0
src/view/iframe/buy-nft/buy/open-box.vue

@@ -25,6 +25,7 @@
 import { reactive, onMounted, inject } from 'vue'
 import { reactive, onMounted, inject } from 'vue'
 import nftCard from "@/view/components/nft-card.vue"
 import nftCard from "@/view/components/nft-card.vue"
 import router from "@/router/buy-nft.js";
 import router from "@/router/buy-nft.js";
+let postId = inject('post_Id')
 let pay_info = inject('pay_info');
 let pay_info = inject('pay_info');
 let state = reactive({
 let state = reactive({
     box: {
     box: {
@@ -68,6 +69,17 @@ const showNFTs = () => {
                         showJoinGroupFinish: state.showJoinGroupFinish
                         showJoinGroupFinish: state.showJoinGroupFinish
                     }
                     }
                 }, (res) => { });
                 }, (res) => { });
+                // postId
+                if (postId.value) {
+                    chrome.tabs.getCurrent((tab) => {
+                        chrome.tabs.sendMessage(tab.id, {
+                            actionType: "FINISH_ToolBox_By_Nft",
+                            data: {
+                                post_Id: postId.value,
+                            }
+                        }, (res) => { });
+                    })
+                }
                 router.replace('/')
                 router.replace('/')
             })
             })
         }
         }

+ 37 - 0
src/view/iframe/buy-nft/buy/pay.vue

@@ -85,6 +85,7 @@
     </div>
     </div>
 </template>
 </template>
 <script setup >
 <script setup >
+import Report from "@/log-center/log"
 import router from "@/router/buy-nft.js";
 import router from "@/router/buy-nft.js";
 import { ref, onMounted, inject, reactive } from 'vue'
 import { ref, onMounted, inject, reactive } from 'vue'
 import topUp2 from "@/view/iframe/publish/components/top-up2.vue";
 import topUp2 from "@/view/iframe/publish/components/top-up2.vue";
@@ -98,6 +99,7 @@ import "element-plus/es/components/message/style/css";
 import { sendChromeTabMessage } from '@/uilts/chromeExtension.js';
 import { sendChromeTabMessage } from '@/uilts/chromeExtension.js';
 
 
 let pay_info = inject('pay_info');
 let pay_info = inject('pay_info');
+let postId = inject('post_Id');
 let state = reactive({
 let state = reactive({
     loading: {
     loading: {
         show: false
         show: false
@@ -138,6 +140,16 @@ const clickPlay = () => {
             pay_info.buy_items = res.data.buyItems
             pay_info.buy_items = res.data.buyItems
             sendChromeTabMessage({ actionType: "FINISH_GROUP_BANNNER" }, () => { })
             sendChromeTabMessage({ actionType: "FINISH_GROUP_BANNNER" }, () => { })
             router.push({ path: '/open_box' });
             router.push({ path: '/open_box' });
+            Report.reportLog({
+                pageSource: Report.pageSource.nftShopPage,
+                businessType: Report.businessType.buttonClick,
+                objectType: Report.objectType.buy_button,
+                nftProjectId: pay_info.home.nftProjectId,
+                postEditorPostId: postId.value,
+            }, {
+                'buy-number': pay_info.home?.sale_plan?.itemCount,
+                result: 'success'
+            })
         } else {
         } else {
             let msg = ''
             let msg = ''
             switch (res.code.toString()) {
             switch (res.code.toString()) {
@@ -166,10 +178,28 @@ const clickPlay = () => {
                 offset: -16,
                 offset: -16,
                 appendTo: document.body
                 appendTo: document.body
             })
             })
+            Report.reportLog({
+                pageSource: Report.pageSource.nftShopPage,
+                businessType: Report.businessType.buttonClick,
+                objectType: Report.objectType.buy_button,
+                nftProjectId: pay_info.home.nftProjectId,
+                postEditorPostId: postId.value,
+            }, {
+                'buy-number': pay_info.home?.sale_plan?.itemCount,
+                result: 'fail'
+            })
         }
         }
     }).catch(() => {
     }).catch(() => {
         state.loading.show = false
         state.loading.show = false
     })
     })
+    // report
+    Report.reportLog({
+        pageSource: Report.pageSource.nftPreviewPage,
+        businessType: Report.businessType.buttonClick,
+        objectType: Report.objectType.confirmButton,
+        nftProjectId: pay_info.home.nftProjectId,
+        postEditorPostId: postId.value,
+    })
 }
 }
 // 余额是否同步中
 // 余额是否同步中
 let asyncIng = ref(false);
 let asyncIng = ref(false);
@@ -213,6 +243,13 @@ onMounted(() => {
     currentCurrencyInfo.currencyCode = pay_info.home.sale_plan.currencyCode
     currentCurrencyInfo.currencyCode = pay_info.home.sale_plan.currencyCode
     getLocalCurrencyInfoByCode();
     getLocalCurrencyInfoByCode();
     setDialogStyle()
     setDialogStyle()
+    // report
+    Report.reportLog({
+        pageSource: Report.pageSource.nftPreviewPage,
+        businessType: Report.businessType.pageView,
+        nftProjectId: pay_info.home.nftProjectId,
+        postEditorPostId: postId.value,
+    })
 })
 })
 
 
 
 

+ 3 - 1
src/view/iframe/buy-nft/index.vue

@@ -4,9 +4,11 @@
     </div>
     </div>
 </template>
 </template>
 <script setup>
 <script setup>
-import { reactive, provide } from 'vue'
+import { ref, reactive, provide } from 'vue'
 let pay_info = reactive({})
 let pay_info = reactive({})
+let post_Id = ref('')
 provide('pay_info', pay_info)
 provide('pay_info', pay_info)
+provide('post_Id', post_Id)
 let state = reactive({
 let state = reactive({
     // 
     // 
     show: 'dialog-home'
     show: 'dialog-home'

+ 17 - 2
src/view/iframe/nft/card.vue

@@ -11,7 +11,13 @@
                     <img :src=" require('@/assets/img/icon-ntf-share.png') " />
                     <img :src=" require('@/assets/img/icon-ntf-share.png') " />
                 </div>
                 </div>
             </div>
             </div>
-            <div class="content">
+            <div
+                class="content"
+                v-show-log="{
+                    pageSource: isShare ? Report.pageSource.nft_post_page : Report.pageSource.nft_sales_window,
+                    nftProjectId: nftProjectId,
+                    redPacketType: Report.redPacketType.nftSale,
+                }">
                 <img :src="saleData.windowImagePath" />
                 <img :src="saleData.windowImagePath" />
             </div>
             </div>
             <div
             <div
@@ -23,7 +29,13 @@
             <div
             <div
                 v-else
                 v-else
                 class="buy"
                 class="buy"
-                @click="buy">
+                @click="buy"
+                v-click-log="{
+                    pageSource: isShare ? Report.pageSource.nft_post_page : Report.pageSource.nft_sales_window,
+                    objectType: Report.objectType.buy_nft_button,
+                    nftProjectId: nftProjectId,
+                    redPacketType: Report.redPacketType.nftSale,
+                }">
                 <img class="guide" v-if="isShowGuide" :src=" require('@/assets/img/icon-arrow.png') " />
                 <img class="guide" v-if="isShowGuide" :src=" require('@/assets/img/icon-arrow.png') " />
                 <button>Buy NFT</button>
                 <button>Buy NFT</button>
             </div>
             </div>
@@ -32,6 +44,7 @@
 </template>
 </template>
 
 
 <script setup>
 <script setup>
+import Report from "@/log-center/log"
 import { onBeforeMount, ref, onMounted, onBeforeUnmount } from 'vue'
 import { onBeforeMount, ref, onMounted, onBeforeUnmount } from 'vue'
 import { getTwitterSaleNftProjectInfo, getNftProjectInfo } from '@/http/nft'
 import { getTwitterSaleNftProjectInfo, getNftProjectInfo } from '@/http/nft'
 import { pageUrl } from "@/http/configAPI.js"
 import { pageUrl } from "@/http/configAPI.js"
@@ -40,6 +53,7 @@ const saleData = ref({});
 const isShare = ref(false);
 const isShare = ref(false);
 const isLoading = ref(true);
 const isLoading = ref(true);
 const isShowGuide = ref(false);
 const isShowGuide = ref(false);
+const nftProjectId = ref('');
 
 
 const getSaleInfo = () => {
 const getSaleInfo = () => {
     chrome.tabs.getCurrent((tab) => {
     chrome.tabs.getCurrent((tab) => {
@@ -152,6 +166,7 @@ onBeforeMount(() => {
     let projectId = searchParmas.get('projectId') || '';
     let projectId = searchParmas.get('projectId') || '';
     if (projectId) {
     if (projectId) {
         isShare.value = true;
         isShare.value = true;
+        nftProjectId.value = projectId;
         getSaleData(projectId)
         getSaleData(projectId)
     } else {
     } else {
         getSaleInfo()
         getSaleInfo()

+ 182 - 0
src/view/iframe/publish/components/nft-setting.vue

@@ -0,0 +1,182 @@
+<template>
+    <div class="setting">
+        <a-radio-group v-model:value="type" name="radioType" @change="changeType">
+            <label class="item">
+                <div class="sel"><a-radio value="public"></a-radio></div>
+                <div class="inp">
+                    <img :src=" require('@/assets/svg/icon-post-edit-open.svg') " />
+                    <span>Publick</span>
+                </div>
+            </label>
+            <label class="item">
+                <div class="sel"><a-radio value="nft"></a-radio></div>
+                <div class="inp">
+                    <img :src=" require('@/assets/svg/icon-post-edit-luck.svg') " />
+                    <span>NFT holders only</span>
+                </div>
+            </label>
+        </a-radio-group>
+        <div
+            v-if="showList"
+            ref="nftScroll"
+            class="scroll"
+            @scroll="getMore">
+            <div ref="nftGroupList">
+                <a-radio-group v-model:value="nftSelectId" name="radioList" @change="changeList">
+                    <label
+                        class="item"
+                        :key="index"
+                        v-for="(item, index) in nftList">
+                        <div class="sel2"></div>
+                        <div class="sel2"><a-radio :value="item.nftProjectId"></a-radio></div>
+                        <div class="inp">
+                            <img :src=" item.icon " />
+                            <span>{{ item.nftProjectName }}</span>
+                        </div>
+                    </label>
+                </a-radio-group>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { ref, onBeforeMount, onMounted, defineEmits } from "vue";
+import { ElMessage } from 'element-plus'
+import { listPossessNftProject } from "@/http/nft.js";
+import { throttle } from "@/uilts/help";
+
+let type = ref('public');
+let showList = ref(false);
+let nftSelectId = ref('');
+let nftList = ref([]);
+let pageSize = 100;
+let pageNum  = ref(1);
+let nftScroll = ref();
+let nftGroupList = ref();
+let getMoreStatus = ref(true);
+let emits = defineEmits(['change']);
+
+const changeType = (e) => {
+    if (e.target.value === 'nft' && nftList.value.length === 0) {
+        type.value = 'public';
+        showList.value = false;
+        ElMessage({
+            message: `Oops,only NFT holders can choose`,
+            type: 'warning',
+        })
+        emits('change', '');
+    } else if (e.target.value === 'nft' && nftList.value.length > 0) {
+        showList.value = true;
+        emits('change', nftSelectId.value);
+    } else if (e.target.value === 'public') {
+        showList.value = false;
+        emits('change', '');
+    }
+}
+const changeList = (e) => {
+    emits('change', e.target.value);
+}
+const getNftList = () => {
+    listPossessNftProject({
+        params: {
+            pageNum: pageNum.value,
+            pageSize: pageSize
+        }
+    }).then(res => {
+        let { code, data } = res;
+        if ( code === 0 && data.length > 0 ) {
+            if (pageNum.value === 1) {
+                nftList.value = data;
+                nftSelectId.value = data[0]['nftProjectId'];
+            } else {
+                nftList.value = [...nftList.value, ...data];
+            }
+        }
+
+        if (data.length < pageSize) {
+            getMoreStatus.value = false
+        } else {
+            getMoreStatus.value = true
+        }
+    })
+}
+const getMore = throttle((e) => {
+    let oT = e.target.scrollTop;
+    let oH = nftGroupList.value.offsetHeight;
+    let sH = nftScroll.value.offsetHeight;
+
+    if ((oT + sH  >= oH - 20) && getMoreStatus.value) {
+        pageNum.value++
+        getNftList()
+    }
+}, 700)
+
+onBeforeMount(() => {
+    // get list
+    getNftList()
+})
+
+onMounted(() => {
+    emits('change', '');
+})
+</script>
+
+<style scoped lang="scss">
+.setting {
+    overflow: hidden;
+    clear: both;
+    height: calc(100% - 30px);
+    max-height: 600px;
+    border-radius: 12px;
+    background: #FFFFFF;
+    border: 1px solid #E6E6E6;
+    .item {
+        display: flex;
+        height: 52px;
+        cursor: pointer;
+        align-items: center;
+        .sel {
+            width: 52px;
+            text-align: center;
+            .ant-radio-wrapper {
+                margin-right: 0;
+            }
+        }
+        .sel2 {
+            width: 40px;
+            text-align: center;
+            .ant-radio-wrapper {
+                margin-right: 0;
+            }
+        }
+        .inp {
+            flex: 1;
+            display: flex;
+            align-items: center;
+            height: 52px;
+            background: #FFFFFF;
+            box-shadow: inset 0px -1px 0px #EFEFEF;
+            img {
+                width: 24px;
+                height: 24px;
+                margin-right: 12px;
+                border-radius: 2px;
+            }
+        }
+        &:last-child {
+            .inp {
+                box-shadow: unset;
+            }
+        }
+    }
+    .scroll {
+        overflow-y: auto;
+        height: calc(100% - 105px);
+    }
+}
+
+.ant-radio-group {
+    display: block;
+}
+</style>

+ 17 - 4
src/view/iframe/publish/components/select-publish-content.vue

@@ -1,6 +1,11 @@
 <template>
 <template>
     <div class="overlay" v-if="visible">
     <div class="overlay" v-if="visible">
-        <div class="content">
+        <div
+            class="content"
+            v-show-log="{
+                businessType: Report.businessType.pageView,
+                pageSource: Report.pageSource.main_page_dashboard,
+            }">
             <!-- 头部 -->
             <!-- 头部 -->
             <div class="head">
             <div class="head">
                 <div class="left">
                 <div class="left">
@@ -19,7 +24,12 @@
                 <div v-for="(item, index) in list"
                 <div v-for="(item, index) in list"
                     :key="index"
                     :key="index"
                     class="item"
                     class="item"
-                    @click="clickItem(item, index)">
+                    @click="clickItem(item, index)"
+                    v-click-log="{
+                        businessType: Report.businessType.buttonClick,
+                        pageSource: Report.pageSource.main_page_dashboard,
+                        objectType: item.btnType
+                    }">
                     <img :src="item.icon" alt="">
                     <img :src="item.icon" alt="">
                     {{item.txt}}
                     {{item.txt}}
                 </div>
                 </div>
@@ -29,17 +39,20 @@
 </template>
 </template>
 
 
 <script setup>
 <script setup>
+import Report from "@/log-center/log"
 import { ref, watch, reactive, defineProps, onMounted } from "vue";
 import { ref, watch, reactive, defineProps, onMounted } from "vue";
 let list = reactive([
 let list = reactive([
     {
     {
         icon: require('@/assets/svg/img-select-giveaway.svg'),
         icon: require('@/assets/svg/img-select-giveaway.svg'),
         type: 'REDPACKET',
         type: 'REDPACKET',
-        txt: 'Giveaway'
+        txt: 'Giveaway',
+        btnType: 'giveaway-button',
     },
     },
     {
     {
         icon: require('@/assets/svg/img-select-tool-box.svg'),
         icon: require('@/assets/svg/img-select-tool-box.svg'),
         type: 'TOOL_BOX',
         type: 'TOOL_BOX',
-        txt: 'Tool Box'
+        txt: 'Tool Box',
+        btnType: 'toolbox-button',
     }
     }
 ])
 ])
 
 

+ 43 - 3
src/view/iframe/publish/tool-box/child/editor.vue

@@ -52,6 +52,7 @@
 <script setup>
 <script setup>
 import { ref, defineProps, defineEmits, onMounted } from "vue";
 import { ref, defineProps, defineEmits, onMounted } from "vue";
 import axios from 'axios';
 import axios from 'axios';
+import Report from "@/log-center/log"
 import { message } from "ant-design-vue";
 import { message } from "ant-design-vue";
 import { convertUrl, getAllPostEditorAppData, checkInputUrlInBlacklist } from "@/http/toolBoxApi";
 import { convertUrl, getAllPostEditorAppData, checkInputUrlInBlacklist } from "@/http/toolBoxApi";
 import { setChromeStorage, getChromeStorage } from "@/uilts/chromeExtension"
 import { setChromeStorage, getChromeStorage } from "@/uilts/chromeExtension"
@@ -80,6 +81,14 @@ const searchHandler = async (_params) => {
   let siteTitle = '', favicon = '';
   let siteTitle = '', favicon = '';
   let timer = null;
   let timer = null;
 
 
+  // report
+  Report.reportLog({
+    pageSource: Report.pageSource.publisherDialog,
+    businessType: Report.businessType.buttonClick,
+    objectType: Report.objectType.custom_link_button,
+  }, {
+    type: 3
+  });
 
 
   if (!siteUrl.value) {
   if (!siteUrl.value) {
     return;
     return;
@@ -184,14 +193,23 @@ const getTitleByHtmlStr = (str = '') => {
 
 
 const clickHistoryAppHandler =  debounce(function(params) {
 const clickHistoryAppHandler =  debounce(function(params) {
   if (params.appId) {
   if (params.appId) {
-    clickAppHandler(params);
+    clickAppHandler(params, false);
   } else {
   } else {
     siteUrl.value = params.defaultUrl;
     siteUrl.value = params.defaultUrl;
     searchHandler(params);
     searchHandler(params);
   }
   }
+
+  Report.reportLog({
+    pageSource: Report.pageSource.publisherDialog,
+    businessType: Report.businessType.buttonClick,
+    objectType: Report.objectType.history_button,
+  }, {
+    appId: params && params.appId || '',
+    type: 3
+  });
 }, 800);
 }, 800);
 
 
-const clickAppHandler =  debounce(function(params) {
+const clickAppHandler =  debounce(function(params, isReport = true) {
   let { createType, defaultUrl, appId, linkImagePath } = params;
   let { createType, defaultUrl, appId, linkImagePath } = params;
   switch (createType) {
   switch (createType) {
     case 1:
     case 1:
@@ -201,6 +219,17 @@ const clickAppHandler =  debounce(function(params) {
       openWindow(params);
       openWindow(params);
       break;
       break;
   }
   }
+
+  if (isReport) {
+    Report.reportLog({
+      pageSource: Report.pageSource.publisherDialog,
+      businessType: Report.businessType.buttonClick,
+      objectType: Report.objectType.app_button,
+    }, {
+      appId: appId || '',
+      type: 3
+    });
+  }
 }, 800);
 }, 800);
 
 
 const openWindow = (params) => {
 const openWindow = (params) => {
@@ -246,7 +275,18 @@ const createGuideWindow = (params, isUpdate = false) => {
     openWindowList.push(window2);
     openWindowList.push(window2);
 
 
     setChromeStorage({ guideAppWindowList: JSON.stringify({list: openWindowList})});
     setChromeStorage({ guideAppWindowList: JSON.stringify({list: openWindowList})});
-  })  
+
+    // report
+    Report.reportLog({
+      pageSource: Report.pageSource.post_editor_guide_page_left,
+      businessType: Report.businessType.pageView,
+    });
+
+    Report.reportLog({
+      pageSource: Report.pageSource.post_editor_guide_page_right,
+      businessType: Report.businessType.pageView,
+    });
+  })
 }
 }
 
 
 const getAppList = () => {
 const getAppList = () => {

+ 8 - 0
src/view/iframe/publish/tool-box/child/guide.vue

@@ -27,6 +27,7 @@
 <script setup>
 <script setup>
 import { ref, reactive, onMounted } from "vue";
 import { ref, reactive, onMounted } from "vue";
 import { checkURL } from "@/uilts/help"
 import { checkURL } from "@/uilts/help"
+import Report from "@/log-center/log"
 import { setChromeStorage, getChromeStorage } from "@/uilts/chromeExtension"
 import { setChromeStorage, getChromeStorage } from "@/uilts/chromeExtension"
 import { message } from "ant-design-vue";
 import { message } from "ant-design-vue";
 
 
@@ -42,6 +43,13 @@ let pageData = reactive({
 const confirm = async () => {
 const confirm = async () => {
     siteUrl.value = siteUrl.value.trim();
     siteUrl.value = siteUrl.value.trim();
 
 
+    // report
+    Report.reportLog({
+      pageSource: Report.pageSource.post_editor_guide_page_right,
+      businessType: Report.businessType.buttonClick,
+      objectType: Report.objectType.enter_url_button,
+    });
+
     if (!checkURL(siteUrl.value)) {
     if (!checkURL(siteUrl.value)) {
         message.info('Incorrect URL entered');
         message.info('Incorrect URL entered');
         return;
         return;

+ 37 - 23
src/view/iframe/publish/tool-box/child/preview.vue

@@ -2,6 +2,9 @@
     <div class="editor-preview-wrapper">
     <div class="editor-preview-wrapper">
         <div class="top">
         <div class="top">
             <div class="card-container">
             <div class="card-container">
+                <div class="font">
+                    Preview: <span>{{ installStatus ? 'After' : 'Before' }}</span> DeNet Installed
+                </div>
                 <!-- 安装之后的卡片样式 -->
                 <!-- 安装之后的卡片样式 -->
                 <div class="content-after" v-show="installStatus" :style="{ 'width': reviewCanvasParams.width + 'px' }">
                 <div class="content-after" v-show="installStatus" :style="{ 'width': reviewCanvasParams.width + 'px' }">
                     <div class="head" :style="{ 'zoom': reviewCanvasParams.zoom }">
                     <div class="head" :style="{ 'zoom': reviewCanvasParams.zoom }">
@@ -37,7 +40,7 @@
                     <div class="card-wrapper" :style="{ 'zoom': reviewCanvasParams.zoom }">
                     <div class="card-wrapper" :style="{ 'zoom': reviewCanvasParams.zoom }">
                         <img class="cover" v-if="previewData.linkImagePath && previewData.appId"
                         <img class="cover" v-if="previewData.linkImagePath && previewData.appId"
                             :src="previewData.linkImagePath" />
                             :src="previewData.linkImagePath" />
-                        <iframe class="iframe" sandbox :src="previewData.convertUrl" scrolling="no" v-else></iframe>
+                        <iframe class="iframe" :src="previewData.convertUrl" scrolling="no" v-else></iframe>
 
 
                         <div class="bottom-bar">
                         <div class="bottom-bar">
                             <div class="site-url">DeNet.me</div>
                             <div class="site-url">DeNet.me</div>
@@ -55,8 +58,9 @@
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
-            <div class="font">
-                Preview: <span>{{ installStatus ? 'After' : 'Before' }}</span> DeNet Installed
+            <div class="setting">
+                <div class="font">Settings</div>
+                <slot></slot>
             </div>
             </div>
         </div>
         </div>
         <div class="bottom">
         <div class="bottom">
@@ -115,13 +119,17 @@ const props = defineProps({
     showCom: {
     showCom: {
         type: String,
         type: String,
         default: 'EDITOR'
         default: 'EDITOR'
+    },
+    certNftProjectId: {
+        type: String,
+        default: ''
     }
     }
 })
 })
 
 
 watch(() => props.screenshotWebsiteData,
 watch(() => props.screenshotWebsiteData,
     (newVal) => {
     (newVal) => {
         let { appId } = props.previewData;
         let { appId } = props.previewData;
-        if (loadingHide && (!appId || appId && !props.previewData.linkImagePath ) && (newVal.url || newVal.status)) {
+        if (loadingHide && (!appId || appId && !props.previewData.linkImagePath) && (newVal.url || newVal.status)) {
             loadingHide();
             loadingHide();
             loadingHide = null;
             loadingHide = null;
             submitPublish();
             submitPublish();
@@ -169,13 +177,13 @@ const getUserName = (screenName) => {
 const calcPreviewCanvasParams = () => {
 const calcPreviewCanvasParams = () => {
     nextTick(() => {
     nextTick(() => {
         let containerDom = document.querySelector('.card-container');
         let containerDom = document.querySelector('.card-container');
-        let domHeight = containerDom && containerDom.offsetHeight || 500;
+        let domHeight = containerDom && containerDom.offsetHeight || 490;
         const canvasHeight = 780, canvasWidth = 620;
         const canvasHeight = 780, canvasWidth = 620;
         if (domHeight < canvasHeight) {
         if (domHeight < canvasHeight) {
             //比例: 高 / 宽
             //比例: 高 / 宽
             let hWRatio = canvasHeight / canvasWidth;
             let hWRatio = canvasHeight / canvasWidth;
             //缩小宽度 = 高度 / 比例
             //缩小宽度 = 高度 / 比例
-            let width = domHeight / hWRatio;
+            let width = canvasWidth / hWRatio;
             if (width > canvasWidth) {
             if (width > canvasWidth) {
                 width = canvasWidth;
                 width = canvasWidth;
             }
             }
@@ -198,7 +206,6 @@ const publishHandler = () => {
     if (loadingHide) {
     if (loadingHide) {
         return;
         return;
     }
     }
-
     if ((!appId || appId && !props.previewData.linkImagePath) && (!props.screenshotWebsiteData.url && !props.screenshotWebsiteData.status)) {
     if ((!appId || appId && !props.previewData.linkImagePath) && (!props.screenshotWebsiteData.url && !props.screenshotWebsiteData.status)) {
         loadingHide = message.loading('loading...', 0);
         loadingHide = message.loading('loading...', 0);
         return;
         return;
@@ -225,6 +232,9 @@ const submitPublish = () => {
         linkTitle: !appId ? linkTitle : '',
         linkTitle: !appId ? linkTitle : '',
         linkImagePath: props.screenshotWebsiteData.url
         linkImagePath: props.screenshotWebsiteData.url
     };
     };
+    if (props.certNftProjectId !== '') {
+        postBizData['certNftProjectId'] = props.certNftProjectId;
+    }
     let data = {
     let data = {
         params: {
         params: {
             postBizData: JSON.stringify(postBizData),
             postBizData: JSON.stringify(postBizData),
@@ -314,15 +324,13 @@ onUnmounted(() => {
         width: 100%;
         width: 100%;
         height: calc(100% - 80px);
         height: calc(100% - 80px);
         display: flex;
         display: flex;
-        align-items: center;
-        justify-content: center;
-        overflow-y: auto;
-        padding: 20px 0;
+        justify-content: space-between;
+        padding: 20px 40px;
         box-sizing: border-box;
         box-sizing: border-box;
 
 
         .card-container {
         .card-container {
             height: 100%;
             height: 100%;
-            margin-right: 50px;
+            margin-right: 32px;
 
 
             .content-after,
             .content-after,
             .content-before {
             .content-before {
@@ -366,10 +374,11 @@ onUnmounted(() => {
             .content-after {
             .content-after {
                 background: url('@/assets/img/img-tool-box-preview-after.png');
                 background: url('@/assets/img/img-tool-box-preview-after.png');
                 width: 387px;
                 width: 387px;
-                height: 100%;
-                background-size: contain;
+                height: calc(100% - 30px);
+                overflow: hidden;
+                background-size: cover;
                 background-repeat: no-repeat;
                 background-repeat: no-repeat;
-                border: 1px solid #D1D9DD;
+                border: 1px solid #E6E6E6;
                 border-radius: 13px;
                 border-radius: 13px;
                 box-sizing: border-box;
                 box-sizing: border-box;
 
 
@@ -388,24 +397,25 @@ onUnmounted(() => {
 
 
             .content-before {
             .content-before {
                 background: url('@/assets/img/img-tool-box-preview-before.png');
                 background: url('@/assets/img/img-tool-box-preview-before.png');
-                background-size: contain;
+                background-size: cover;
                 background-repeat: no-repeat;
                 background-repeat: no-repeat;
-                height: 100%;
-                border: 1px solid #D1D9DD;
+                height: calc(100% - 30px);
+                overflow: hidden;
+                border: 1px solid #E6E6E6;
                 border-radius: 13px;
                 border-radius: 13px;
                 box-sizing: border-box;
                 box-sizing: border-box;
 
 
                 .card-wrapper {
                 .card-wrapper {
-                    width: 505px;
-                    height: 338px;
-                    border: 1px solid #D1D9DD;
+                    width: 448px;
+                    height: 300px;
+                    border: 1px solid #E6E6E6;
                     background: #ffffff;
                     background: #ffffff;
                     box-sizing: border-box;
                     box-sizing: border-box;
                     overflow: hidden;
                     overflow: hidden;
                     position: relative;
                     position: relative;
                     box-sizing: border-box;
                     box-sizing: border-box;
                     border-radius: 16px;
                     border-radius: 16px;
-                    left: 73px;
+                    left: 70px;
                     top: 90px;
                     top: 90px;
 
 
                     .iframe {
                     .iframe {
@@ -446,7 +456,7 @@ onUnmounted(() => {
         }
         }
 
 
         .font {
         .font {
-            width: 300px;
+            height: 30px;
             font-weight: 600;
             font-weight: 600;
             font-size: 20px;
             font-size: 20px;
 
 
@@ -454,6 +464,10 @@ onUnmounted(() => {
                 color: #1D9BF0;
                 color: #1D9BF0;
             }
             }
         }
         }
+
+        .setting {
+            flex: 1;
+        }
     }
     }
 
 
     .bottom {
     .bottom {

+ 10 - 1
src/view/iframe/publish/tool-box/index.vue

@@ -6,7 +6,10 @@
             :screenshotWebsiteData="screenshotWebsiteData"
             :screenshotWebsiteData="screenshotWebsiteData"
             :showCom="showCom"
             :showCom="showCom"
             :defaultLinkTitle="pageData.defaultLinkTitle"
             :defaultLinkTitle="pageData.defaultLinkTitle"
-            @publishFinish="publishFinish" />
+            :certNftProjectId="certNftProjectId"
+            @publishFinish="publishFinish">
+            <nft-setting @change="changeSetting"></nft-setting>
+        </preview>
     </div>
     </div>
 </template>
 </template>
 
 
@@ -17,6 +20,7 @@ import { screenshotWebsite } from "@/http/toolBoxApi";
 import editor from '@/view/iframe/publish/tool-box/child/editor.vue'
 import editor from '@/view/iframe/publish/tool-box/child/editor.vue'
 import preview from '@/view/iframe/publish/tool-box/child/preview.vue'
 import preview from '@/view/iframe/publish/tool-box/child/preview.vue'
 import Report from "@/log-center/log"
 import Report from "@/log-center/log"
+import nftSetting from '@/view/iframe/publish/components/nft-setting.vue'
 
 
 const props = defineProps({
 const props = defineProps({
     pageData: {
     pageData: {
@@ -60,6 +64,7 @@ let previewData = reactive({
     appId: '',
     appId: '',
     currentApp: {}
     currentApp: {}
 })
 })
+let certNftProjectId = ref('')
 
 
 let screenshotWebsiteData = reactive({
 let screenshotWebsiteData = reactive({
     url: '',
     url: '',
@@ -106,6 +111,10 @@ const publishFinish = (params) => {
     emits("toolBoxPublishFinish", params);
     emits("toolBoxPublishFinish", params);
 }
 }
 
 
+const changeSetting = (id = '') => {
+    certNftProjectId.value = id;
+}
+
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>

+ 198 - 0
src/view/iframe/tool-box/buy-nft.vue

@@ -0,0 +1,198 @@
+<template>
+    <div
+        class="nft-layer"
+        v-show-log="{
+            pageSource: Report.pageSource.buy_posteditor_nft_dialog,
+        }">
+        <div class="title">
+            <img @click="close" :src=" require('@/assets/svg/icon-close.svg') " />
+            <span class="text">Unlock by Ruomeng NFT</span>
+        </div>
+        <div class="content">
+            <div class="img">
+                <img v-if="nftAuthINfo && nftAuthINfo.icon" :src="nftAuthINfo.icon" />
+            </div>
+            <div class="tips">
+                <span>only Ruomeng NFT holder can view the content</span>
+            </div>
+            <div
+                class="btn"
+                v-if="btnStatus"
+                @click="buy"
+                v-click-log="{
+                    pageSource: Report.pageSource.buy_posteditor_nft_dialog,
+                    objectType: Report.objectType.buy_button,
+                }">
+                <span>Buy NFT to Participate</span>
+            </div>
+            <div class="btn disabled" v-else>
+                <span>Buy NFT to Participate</span>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import Report from "@/log-center/log"
+import { ref, onBeforeMount } from 'vue';
+import { ElMessage } from 'element-plus';
+import { getQueryString } from '@/uilts/help';
+import { getPostEditorNftCertInfo } from '@/http/toolBoxApi';
+import { getChromeStorage, sendChromeTabMessage } from "@/uilts/chromeExtension";
+import "element-plus/es/components/message/style/css";
+
+const postId = ref('')
+const btnStatus = ref(false)
+const nftAuthINfo = ref(null)
+
+const close = () => {
+    sendChromeTabMessage({
+        actionType: 'Hide_ToolBox_By_Nft'
+    })
+}
+
+const buy = () => {
+    getChromeStorage('userInfo', (_userInfo) => {
+        if (!_userInfo) {
+            chrome.runtime.sendMessage(
+                { actionType: "POPUP_LOGIN", data: "" },
+                (response) => {
+                    console.log("res", response);
+                }
+            )
+        } else {
+            if (nftAuthINfo.value && nftAuthINfo.value?.publishStatus === 1) {
+                chrome.tabs.getCurrent((tab) => {
+                    chrome.tabs.sendMessage(tab.id, {
+                        actionType: "IFRAME_TWITTER_SHOW_BUY_NFT",
+                        data: {
+                            nft_project_Id: nftAuthINfo.value.certNftProjectId,
+                            post_Id: postId.value,
+                        }
+                    }, (res) => { });
+                })
+                // close buy
+                close();
+            } else {
+                ElMessage({
+                    message: `NFT project not published!`,
+                    type: 'error',
+                })
+            }
+        }
+    })
+}
+
+onBeforeMount(() => {
+    postId.value = getQueryString('postId')
+    getPostEditorNftCertInfo({
+        params: {
+            postId: postId.value
+        }
+    }).then(res => {
+        let { code, data } = res;
+        if ( code === 0 ) {
+            btnStatus.value = true;
+            nftAuthINfo.value = data;
+        }
+    })
+})
+
+</script>
+
+<style lang="scss">
+body {
+    margin: 0;
+    padding: 0;
+}
+.nft-layer {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    width: 500px;
+    height: 420px;
+    transform: translate(-50%, -50%);
+    border-radius: 20px;
+    background: #FFFFFF;
+    .title {
+        height: 48px;
+        display: flex;
+        align-items: center;
+        box-shadow: 0px 0.5px 0px #D1D9DD;
+        img {
+            width: 24px;
+            height: 24px;
+            margin-left: 14px;
+            margin-right: 12px;
+            cursor: pointer;
+        }
+        .text {
+            font-size: 16px;
+            font-weight: 500;
+            line-height: 19px;
+        }
+    }
+    .content {
+        .img {
+            display: flex;
+            height: 250px;
+            align-items: center;
+            justify-content: center;
+            img {
+                width: 150px;
+                height: 150px;
+                border-radius: 5px;
+            }
+        }
+        .tips {
+            position: relative;
+            font-size: 14px;
+            font-weight: 400;
+            text-align: center;
+            line-height: 33px;
+            margin: auto;
+            margin-bottom: 28px;
+            width: calc(100% - 30px);
+            &::before {
+                position: absolute;
+                top: 50%;
+                left: 0;
+                content: '';
+                display: block;
+                width: 14%;
+                height: 1px;
+                background-color: rgba($color: #000000, $alpha: .2);
+            }
+            &::after {
+                position: absolute;
+                top: 50%;
+                right: 0;
+                content: '';
+                display: block;
+                width: 14%;
+                height: 1px;
+                background-color: rgba($color: #000000, $alpha: .2);
+            }
+        }
+        .btn {
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            margin: auto;
+            width: calc(100% - 30px);
+            height: 46px;
+            color: #FFFFFF;
+            cursor: pointer;
+            font-size: 16px;
+            font-weight: 600;
+            border-radius: 100px;
+            background: #1D9BF0;
+            &.disabled {
+                background: #CDCDCD;
+                cursor: not-allowed;
+                color: #fff;
+            }
+        }
+    }
+}
+</style>

+ 325 - 20
src/view/iframe/tool-box/card.vue

@@ -11,6 +11,16 @@
             <iframe :src="iframe_url" frameborder="0" sandbox></iframe>
             <iframe :src="iframe_url" frameborder="0" sandbox></iframe>
         </div>
         </div>
         <div class="content" v-else>
         <div class="content" v-else>
+            <template v-if="state.showMask && state.status != '固定右上角'">
+                <div class="mask" @click="confirmStatus">
+                    <img class="luck" :src=" require('@/assets/svg/icon-post-lock.svg') " />
+                    <div class="btn">
+                        <img class="img" v-if="state.detail && state.detail.nftProjectIcon" :src=" state.detail.nftProjectIcon " />
+                        <div class="font">Available for holders of {{state.detail.nftProjectName}} NFT</div>
+                    </div>
+                </div>
+                <img class="mask_bg" v-if="state.detail.linkImagePath" :src=" state.detail.linkImagePath " />
+            </template>
             <iframe :src="state.iframe_url" v-show="state.status == 'iframe'" ref="dom_iframe" frameborder="0"
             <iframe :src="state.iframe_url" v-show="state.status == 'iframe'" ref="dom_iframe" frameborder="0"
                 scrolling="yes" allow="camera *;microphone *"></iframe>
                 scrolling="yes" allow="camera *;microphone *"></iframe>
             <!-- sandbox="allow-same-origin allow-scripts allow-popups allow-top-navigation allow-forms allow-modals allow-popups-to-escape-sandbox" -->
             <!-- sandbox="allow-same-origin allow-scripts allow-popups allow-top-navigation allow-forms allow-modals allow-popups-to-escape-sandbox" -->
@@ -64,9 +74,13 @@
 <script setup>
 <script setup>
 import { getChromeStorage, setChromeStorage, defineProps, sendChromeTabMessage } from "@/uilts/chromeExtension";
 import { getChromeStorage, setChromeStorage, defineProps, sendChromeTabMessage } from "@/uilts/chromeExtension";
 import { getPostDetail } from '@/http/redPacket.js'
 import { getPostDetail } from '@/http/redPacket.js'
+import { getPostEditorNftCertInfo } from '@/http/toolBoxApi'
 import { guid, getQueryString } from "@/uilts/help";
 import { guid, getQueryString } from "@/uilts/help";
-import { onMounted, reactive, ref } from "vue";
+import { onMounted, reactive, ref, onBeforeUnmount } from "vue";
+import { ElMessage } from 'element-plus'
 import { reSetBindTwtterId } from '@/http/help.js'
 import { reSetBindTwtterId } from '@/http/help.js'
+import Report from "@/log-center/log"
+import "element-plus/es/components/message/style/css";
 let dom_iframe = ref(null)
 let dom_iframe = ref(null)
 let state = reactive({
 let state = reactive({
     status: '', //
     status: '', //
@@ -79,10 +93,13 @@ let state = reactive({
     tweetId: '',
     tweetId: '',
     detail: {},
     detail: {},
     handle_type: '',
     handle_type: '',
+    showMask: false,
     cover_url: require('@/assets/img/back-loading.png')
     cover_url: require('@/assets/img/back-loading.png')
 })
 })
 
 
 let dom = {}
 let dom = {}
+let nftAuthINfo = ref(null)
+let loadTime = (new Date).getTime()
 
 
 let props = defineProps({
 let props = defineProps({
     pre_view: {
     pre_view: {
@@ -103,6 +120,10 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
                 state.show_btn = true
                 state.show_btn = true
                 state.status = 'iframe'
                 state.status = 'iframe'
                 state.iframe_url = req.data.iframe_url
                 state.iframe_url = req.data.iframe_url
+                nftAuthINfo.value = req.data.nftAuthINfo
+                state.showMask = req.data.showMask
+                state.detail = req.data.detail
+                state.postId = req.data.postId
             }
             }
             break
             break
     }
     }
@@ -139,6 +160,19 @@ onMounted(() => {
         }
         }
     })
     })
 
 
+    chrome.runtime.onMessage.addListener(msgListener)
+
+    // 页面返回重试状态
+    document.addEventListener('visibilitychange', function () {
+        let isHidden = document.hidden;
+        if (!isHidden && !nftAuthINfo.value) {
+            getDetail();
+        }
+    });
+})
+
+onBeforeUnmount(() => {
+    chrome.runtime.onMessage.removeListener(msgListener);
 })
 })
 
 
 // detail函数
 // detail函数
@@ -148,6 +182,7 @@ const getDetail = () => {
         state.status = '网页错误'
         state.status = '网页错误'
     }
     }
     // iframe.onload = () => {
     // iframe.onload = () => {
+    //     alert(123)
     //     if (state.status == '加载' || state.status == 'iframe') {
     //     if (state.status == '加载' || state.status == 'iframe') {
     //         state.show_btn = true
     //         state.show_btn = true
     //         state.status = 'iframe'
     //         state.status = 'iframe'
@@ -172,29 +207,199 @@ const getDetail = () => {
             if (state.detail.viewBgImagePath) {
             if (state.detail.viewBgImagePath) {
                 state.cover_url = state.detail.viewBgImagePath
                 state.cover_url = state.detail.viewBgImagePath
             }
             }
+            state.iframe_url = state.detail.convertUrl
             state.show_btn = true
             state.show_btn = true
             state.status = 'iframe'
             state.status = 'iframe'
-            state.iframe_url = state.detail.convertUrl
+            // 蒙层
+            if (state.detail && state.detail.certNftProjectId) {
+                state.showMask = true;
+                // 确权
+                getChromeStorage('userInfo', (_userInfo) => {
+                    if (_userInfo) {
+                        getNftInfoStatus()
+                    }
+                })
+            } else {
+                reportSucc(false)
+            }
+            // report
+            Report.reportLog({
+                redPacketType: Report.redPacketType.postEditor,
+                businessType: Report.businessType.pageView,
+                pageSource: Report.pageSource.pe_loading_page,
+                postId: state.postId || '',
+                postEditorUrl: state.detail.convertUrl
+            });
         } else {
         } else {
             state.status = '网页错误'
             state.status = '网页错误'
         }
         }
     })
     })
 }
 }
 
 
+const getNftInfoStatus = () => {
+    getPostEditorNftCertInfo({
+        params: {
+            postId: state.postId,
+        }
+    }).then(res => {
+        let { code, data } = res;
+        if ( code === 0 ) {
+            nftAuthINfo.value = data;
+            // checkMask
+            getChromeStorage('post_id_list', (list) => {
+                if (list && list.indexOf(state.postId) !== -1 && nftAuthINfo.value?.certStatus === 1) {
+                    state.showMask = false;
+                    // report
+                    reportSucc()
+                } else {
+                    // report
+                    reportFail()
+                }
+            })
+        }
+    })
+}
+
+const reportSucc = (isEncrypted = true) => {
+    let params = {}
+    if (isEncrypted) {
+        params['nft-encrypted-status'] = 1;
+    }
+    // report
+    Report.reportLog({
+        redPacketType: Report.redPacketType.postEditor,
+        businessType: Report.businessType.pageView,
+        pageSource: Report.pageSource.pe_display_page,
+        postId: state.postId || '',
+        postEditorUrl: state.detail.convertUrl,
+        ...params,
+    }, {
+        'loading-time': (new Date).getTime() - loadTime,
+    });
+}
+
+const reportFail = () => {
+    Report.reportLog({
+        redPacketType: Report.redPacketType.postEditor,
+        businessType: Report.businessType.pageView,
+        pageSource: Report.pageSource.pe_display_page,
+        postId: state.postId || '',
+        postEditorUrl: state.detail.convertUrl,
+        'nft-encrypted-status': 0,
+    }, {
+        'loading-time': (new Date).getTime() - loadTime,
+    });
+}
+
+const confirmStatus = () => {
+    getChromeStorage('userInfo', (_userInfo) => {
+        if (!_userInfo) {
+            chrome.runtime.sendMessage(
+                { actionType: "POPUP_LOGIN", data: "" },
+                (response) => {
+                    console.log("res", response);
+                }
+            )
+        } else {
+            if (nftAuthINfo.value && nftAuthINfo.value?.certStatus === 1) {
+                succBack()
+            } else {
+                sendChromeTabMessage({
+                    actionType: 'Set_ToolBox_By_Nft',
+                    data: {
+                        postId: state.postId,
+                    }
+                })
+            }
+        }
+    })
+
+    // report
+    let params = {}
+    if (nftAuthINfo.value?.certStatus === 1) {
+        if (state.showMask) {
+            params['nft-encrypted-status'] = 0
+        } else {
+            params['nft-encrypted-status'] = 1
+        }
+    }
+    Report.reportLog({
+        redPacketType: Report.redPacketType.postEditor,
+        businessType: Report.businessType.buttonClick,
+        pageSource: Report.pageSource.pe_display_page,
+        objectType: Report.objectType.encrypte_nft_button,
+        postId: state.postId || '',
+        postEditorUrl: state.detail.convertUrl,
+        ...params,
+    });
+}
+
+const succBack = () => {
+    ElMessage({
+        message: `NFT validated!`,
+        type: 'success'
+    })
+    state.showMask = false;
+    // 记录解锁
+    getChromeStorage('post_id_list', (list) => {
+        let originList = list ? list : [];
+        if (originList.indexOf(state.postId) === -1) {
+            originList.push(state.postId)
+            setChromeStorage({ post_id_list: JSON.stringify(originList) })
+        }
+    })
+}
+
+const hideMask = (data) => {
+    if (data && data.post_Id && data.post_Id === state.postId) {
+        succBack()
+    }
+}
+
 const clickCancel = () => {
 const clickCancel = () => {
     state.show_alert = false
     state.show_alert = false
 }
 }
 
 
 const clickFixed = () => {
 const clickFixed = () => {
-    state.handle_type = '固定右上角'
-    getChromeStorage('fullCheck', (res) => {
-        if (res && res.fullCheck) {
-            // 固定
-            handleFixed()
+    getChromeStorage('userInfo', (_userInfo) => {
+        if (!_userInfo) {
+            chrome.runtime.sendMessage(
+                { actionType: "POPUP_LOGIN", data: "" },
+                (response) => {
+                    console.log("res", response);
+                }
+            )
         } else {
         } else {
-            state.show_alert = true
+            state.handle_type = '固定右上角'
+            getChromeStorage('fullCheck', (res) => {
+                if (res && res.fullCheck) {
+                    // 固定
+                    handleFixed()
+                } else {
+                    state.show_alert = true
+                }
+            })
         }
         }
     })
     })
+
+    // report
+    let params = {}
+    if (nftAuthINfo.value?.certStatus === 1) {
+        if (state.showMask) {
+            params['nft-encrypted-status'] = 0
+        } else {
+            params['nft-encrypted-status'] = 1
+        }
+    }
+    Report.reportLog({
+        redPacketType: Report.redPacketType.postEditor,
+        businessType: Report.businessType.buttonClick,
+        pageSource: Report.pageSource.pe_display_page,
+        objectType: Report.objectType.top_right_button,
+        postId: state.postId || '',
+        postEditorUrl: state.detail.convertUrl,
+        ...params,
+    });
 }
 }
 
 
 // 固定
 // 固定
@@ -202,19 +407,34 @@ const handleFull = () => {
     if (state.status != 'iframe' || !state.iframe_url) {
     if (state.status != 'iframe' || !state.iframe_url) {
         return
         return
     }
     }
-    // 切换状态
-    state.status = '固定右上角'
-    state.show_btn = false
-    sendChromeTabMessage({
-        actionType: 'Set_ToolBox_Fixed',
-        data: {
-            type: '全屏',
-            iframe_url: state.iframe_url,
-            tweetId: state.tweetId,
+    getChromeStorage('userInfo', (_userInfo) => {
+        if (!_userInfo) {
+            chrome.runtime.sendMessage(
+                { actionType: "POPUP_LOGIN", data: "" },
+                (response) => {
+                    console.log("res", response);
+                }
+            )
+        } else {
+            // 切换状态
+            state.status = '固定右上角'
+            state.show_btn = false
+            sendChromeTabMessage({
+                actionType: 'Set_ToolBox_Fixed',
+                data: {
+                    type: '全屏',
+                    iframe_url: state.iframe_url,
+                    tweetId: state.tweetId,
+                    nftAuthINfo: nftAuthINfo.value,
+                    showMask: state.showMask,
+                    detail: state.detail,
+                    postId: state.postId,
+                }
+            })
+            // 清除当前iframe src
+            state.iframe_url = ''
         }
         }
     })
     })
-    // 清除当前iframe src
-    state.iframe_url = ''
 }
 }
 
 
 // 全屏
 // 全屏
@@ -227,7 +447,11 @@ const handleFixed = () => {
         data: {
         data: {
             type: '固定右上角',
             type: '固定右上角',
             iframe_url: state.iframe_url,
             iframe_url: state.iframe_url,
-            tweetId: state.tweetId
+            tweetId: state.tweetId,
+            nftAuthINfo: nftAuthINfo.value,
+            showMask: state.showMask,
+            detail: state.detail,
+            postId: state.postId,
         }
         }
     })
     })
     // 清除当前iframe src
     // 清除当前iframe src
@@ -244,6 +468,35 @@ const clickFull = () => {
             state.show_alert = true
             state.show_alert = true
         }
         }
     })
     })
+    // report
+    let params = {}
+    if (nftAuthINfo.value?.certStatus === 1) {
+        if (state.showMask) {
+            params['nft-encrypted-status'] = 0
+        } else {
+            params['nft-encrypted-status'] = 1
+        }
+    }
+    Report.reportLog({
+        redPacketType: Report.redPacketType.postEditor,
+        businessType: Report.businessType.buttonClick,
+        pageSource: Report.pageSource.pe_display_page,
+        objectType: Report.objectType.fullscreen_button,
+        postId: state.postId || '',
+        postEditorUrl: state.detail.convertUrl,
+        ...params,
+    });
+}
+
+const msgListener = (req, sender, sendResponse) => {
+    switch (req.actionType) {
+        case 'BG_LOGIN_SET_USERINFO_CB':
+            getDetail()
+            break;
+        case 'FINISH_ToolBox_By_Nft':
+            hideMask(req.data)
+            break;
+    }
 }
 }
 
 
 </script>
 </script>
@@ -266,6 +519,7 @@ const clickFull = () => {
     .alert {
     .alert {
         text-align: center;
         text-align: center;
         position: absolute;
         position: absolute;
+        z-index: 3;
         top: 0;
         top: 0;
         left: 0;
         left: 0;
         width: 100%;
         width: 100%;
@@ -390,6 +644,7 @@ const clickFull = () => {
     }
     }
 
 
     .content {
     .content {
+        position: relative;
         width: 100%;
         width: 100%;
         height: calc(100% - 40px);
         height: calc(100% - 40px);
         background: #686868;
         background: #686868;
@@ -397,6 +652,56 @@ const clickFull = () => {
         align-items: center;
         align-items: center;
         justify-content: center;
         justify-content: center;
 
 
+        .mask {
+            position: absolute;
+            z-index: 2;
+            display: flex;
+            cursor: pointer;
+            align-items: center;
+            justify-content: center;
+            flex-direction: column;
+            width: 100%;
+            height: 100%;
+            background-color: rgba($color: #000000, $alpha: .8);
+            .luck {
+                width: 100px;
+                height: 100px;
+            }
+            .btn {
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                width: 345px;
+                height: 70px;
+                margin-top: 12px;
+                border-radius: 100px;
+                background: #1D9BF0;
+                .img {
+                    overflow: hidden;
+                    width: 35px;
+                    height: 35px;
+                    margin-right: 16px;
+                    border-radius: 4px;
+                }
+                .font {
+                    width: 188px;
+                    color: #fff;
+                    font-weight: 700;
+                    font-size: 16px;
+                    line-height: 19px;
+                    letter-spacing: 0.3px;
+                }
+            }
+        }
+        .mask_bg {
+            position: absolute;
+            z-index: 1;
+            width: 100%;
+            height: 100%;
+            object-fit: contain;
+            background-color: #000000;
+        }
+
         iframe {
         iframe {
             background: #fff;
             background: #fff;
             width: 100%;
             width: 100%;

+ 133 - 5
src/view/iframe/tool-box/full.vue

@@ -12,13 +12,25 @@
             </div>
             </div>
         </div>
         </div>
         <div class="content">
         <div class="content">
+            <template v-if="showMask">
+                <div class="mask" @click="confirmStatus">
+                    <img class="luck" :src=" require('@/assets/svg/icon-post-lock.svg') " />
+                    <div class="btn">
+                        <img class="img" v-if="detail.nftProjectIcon" :src=" detail.nftProjectIcon " />
+                        <div class="font">Available for holders of {{detail.nftProjectName}} NFT</div>
+                    </div>
+                </div>
+                <img class="mask_bg" v-if="detail.linkImagePath" :src=" detail.linkImagePath " />
+            </template>
             <iframe :src="state.iframe_url" frameborder="0" allow="camera *;microphone *"></iframe>
             <iframe :src="state.iframe_url" frameborder="0" allow="camera *;microphone *"></iframe>
         </div>
         </div>
     </div>
     </div>
 </template>
 </template>
 <script setup>
 <script setup>
-import { reactive } from "vue";
-import { sendChromeTabMessage } from "@/uilts/chromeExtension";
+import { reactive, ref } from "vue";
+import { ElMessage } from 'element-plus'
+import { getChromeStorage, setChromeStorage, sendChromeTabMessage } from "@/uilts/chromeExtension";
+import "element-plus/es/components/message/style/css";
 
 
 let state = reactive({
 let state = reactive({
     status: '固定右上角', // 全屏
     status: '固定右上角', // 全屏
@@ -26,13 +38,21 @@ let state = reactive({
     tweetId: ''
     tweetId: ''
 })
 })
 
 
-chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
+let detail = ref(null)
+let nftAuthINfo = ref(null)
+let showMask = ref(false)
+let postId = ref('')
 
 
+chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
     switch (req.actionType) {
     switch (req.actionType) {
         // 事件传输
         // 事件传输
         case 'Set_ToolBox_Fixed':
         case 'Set_ToolBox_Fixed':
             if (req.data.type == '全屏' || req.data.type == '固定右上角') {
             if (req.data.type == '全屏' || req.data.type == '固定右上角') {
                 state.status = req.data.type
                 state.status = req.data.type
+                nftAuthINfo.value = req.data.nftAuthINfo;
+                showMask.value = req.data.showMask;
+                detail.value = req.data.detail;
+                postId.value = req.data.postId;
                 if (state.tweetId != req.data.tweetId) {
                 if (state.tweetId != req.data.tweetId) {
                     state.tweetId = req.data.tweetId
                     state.tweetId = req.data.tweetId
                 }
                 }
@@ -40,8 +60,10 @@ chrome.runtime.onMessage.addListener((req, sender, sendResponse) => {
                     state.iframe_url = req.data.iframe_url
                     state.iframe_url = req.data.iframe_url
                 }
                 }
             }
             }
-
             break
             break
+        case 'FINISH_ToolBox_By_Nft':
+            hideMask(req.data)
+            break;
     }
     }
 })
 })
 
 
@@ -74,14 +96,18 @@ const changeFixed = () => {
             type: '固定右上角',
             type: '固定右上角',
             iframe_url: state.iframe_url,
             iframe_url: state.iframe_url,
             tweetId: state.tweetId,
             tweetId: state.tweetId,
+            nftAuthINfo: nftAuthINfo.value,
+            showMask: showMask.value,
+            detail: detail.value,
+            postId: postId.value,
         }
         }
     })
     })
 }
 }
 
 
 const clickClose = () => {
 const clickClose = () => {
     sendClose()
     sendClose()
-
 }
 }
+
 const sendClose = () => {
 const sendClose = () => {
     sendChromeTabMessage({
     sendChromeTabMessage({
         actionType: 'Set_ToolBox_Fixed',
         actionType: 'Set_ToolBox_Fixed',
@@ -89,12 +115,61 @@ const sendClose = () => {
             type: '关闭',
             type: '关闭',
             iframe_url: state.iframe_url,
             iframe_url: state.iframe_url,
             tweetId: state.tweetId,
             tweetId: state.tweetId,
+            nftAuthINfo: nftAuthINfo.value,
+            showMask: showMask.value,
+            detail: detail.value,
+            postId: postId.value,
         }
         }
     })
     })
     state.iframe_url = ''
     state.iframe_url = ''
     state.tweetId = ''
     state.tweetId = ''
 }
 }
 
 
+const confirmStatus = () => {
+    getChromeStorage('userInfo', (_userInfo) => {
+        if (!_userInfo) {
+            chrome.runtime.sendMessage(
+                { actionType: "POPUP_LOGIN", data: "" },
+                (response) => {
+                    console.log("res", response);
+                }
+            )
+        } else {
+            if (nftAuthINfo.value && nftAuthINfo.value?.certStatus === 1) {
+                succBack()
+            } else {
+                sendChromeTabMessage({
+                    actionType: 'Set_ToolBox_By_Nft',
+                    data: {
+                        postId: postId.value,
+                    }
+                })
+            }
+        }
+    })
+}
+
+const succBack = () => {
+    ElMessage({
+        message: `NFT validated!`,
+        type: 'success'
+    })
+    showMask.value = false;
+    // 记录解锁
+    getChromeStorage('post_id_list', (list) => {
+        let originList = list ? list : [];
+        if (originList.indexOf(postId.value) === -1) {
+            originList.push(postId.value)
+            setChromeStorage({ post_id_list: JSON.stringify(originList) })
+        }
+    })
+}
+
+const hideMask = (data) => {
+    if (data && data.post_Id && data.post_Id === postId.value) {
+        succBack()
+    }
+}
 
 
 </script>
 </script>
 
 
@@ -144,6 +219,7 @@ const sendClose = () => {
     }
     }
 
 
     .content {
     .content {
+        position: relative;
         width: 100%;
         width: 100%;
         height: calc(100% - 40px);
         height: calc(100% - 40px);
         background: #686868;
         background: #686868;
@@ -151,6 +227,58 @@ const sendClose = () => {
         align-items: center;
         align-items: center;
         justify-content: center;
         justify-content: center;
 
 
+        .mask {
+            position: absolute;
+            z-index: 2;
+            display: flex;
+            cursor: pointer;
+            align-items: center;
+            justify-content: center;
+            flex-direction: column;
+            width: 100%;
+            height: 100%;
+            background-color: rgba($color: #000000, $alpha: .8);
+            .luck {
+                width: 100px;
+                height: 100px;
+            }
+            .btn {
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                width: 345px;
+                height: 70px;
+                cursor: pointer;
+                margin-top: 12px;
+                border-radius: 100px;
+                background: #1D9BF0;
+                .img {
+                    overflow: hidden;
+                    width: 35px;
+                    height: 35px;
+                    margin-right: 16px;
+                    border-radius: 4px;
+                }
+                .font {
+                    width: 188px;
+                    color: #fff;
+                    font-weight: 700;
+                    font-size: 16px;
+                    line-height: 19px;
+                    letter-spacing: 0.3px;
+                }
+            }
+        }
+
+        .mask_bg {
+            position: absolute;
+            z-index: 1;
+            width: 100%;
+            height: 100%;
+            object-fit: contain;
+            background-color: #000000;
+        }
+
         iframe {
         iframe {
             width: 100%;
             width: 100%;
             height: 100%;
             height: 100%;

+ 4 - 9
src/view/popup/tabbar-page/message/index.vue

@@ -28,15 +28,9 @@
                 </template>
                 </template>
                 <!-- 转出NFT记录 -->
                 <!-- 转出NFT记录 -->
                 <template v-else-if="item.type == 4">
                 <template v-else-if="item.type == 4">
-                  <img
-                    v-if="item.nftItemVO?.imagePath"
-                    class="icon-big-give"
-                    :src="item.nftItemVO?.imagePath" />
+                  <img v-if="item.nftItemVO?.imagePath" class="icon-big-give" :src="item.nftItemVO?.imagePath" />
                   <div v-else style="margin-top: 12px;">
                   <div v-else style="margin-top: 12px;">
-                    <nft-card
-                      :nftItemId="item.nftItemId"
-                      :item="item.nftItemVO.createImageInfo"
-                      :width="34">
+                    <nft-card :nftItemId="item.nftItemId" :item="item.nftItemVO.createImageInfo" :width="34">
                     </nft-card>
                     </nft-card>
                   </div>
                   </div>
                 </template>
                 </template>
@@ -275,7 +269,8 @@
                     </div>
                     </div>
                   </div>
                   </div>
                   <!-- 发红包—— 未发出、进行中 隐藏 -->
                   <!-- 发红包—— 未发出、进行中 隐藏 -->
-                  <img v-if="item.type != 2 && item.type != 4" class="icon" :src="require('@/assets/svg/icon-cell-arrow-right.svg')" />
+                  <img v-if="item.type != 2 && item.type != 4" class="icon"
+                    :src="require('@/assets/svg/icon-cell-arrow-right.svg')" />
                 </div>
                 </div>
               </div>
               </div>
             </div>
             </div>