Jelajahi Sumber

[edit] style

wenliming 2 tahun lalu
induk
melakukan
7e3ea8838e

TEMPAT SAMPAH
src/assets/img/icon-tool-box-01.png


TEMPAT SAMPAH
src/assets/img/img-tool-box-preview-after.png


TEMPAT SAMPAH
src/assets/img/img-tool-box-preview-before.png


+ 5 - 0
src/assets/svg/icon-tool-box-02.svg

@@ -0,0 +1,5 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M10.8737 13.4889L1.59961 8.13477V17.5585C1.59979 17.7925 1.66091 18.0225 1.77696 18.2258C1.89301 18.4291 2.05999 18.5986 2.26147 18.7177L11.1851 23.9991V13.6143C11.0759 13.5873 10.9711 13.5451 10.8737 13.4889Z" fill="#1D9BF0"/>
+<path d="M22.5015 7.99219V17.5588C22.5014 17.7927 22.4405 18.0226 22.3247 18.2259C22.2089 18.4291 22.0422 18.5987 21.841 18.718L12.916 23.9994V13.5243C12.9379 13.5133 12.9595 13.5016 12.9807 13.4892L22.5015 7.99219Z" fill="#24D37F"/>
+<path d="M1.59961 5.93698C1.71483 5.79133 1.85894 5.67109 2.02287 5.58381L11.4587 0.558553C11.6537 0.454705 11.8713 0.400391 12.0923 0.400391C12.3132 0.400391 12.5308 0.454705 12.7258 0.558553L22.1617 5.58381C22.2897 5.65121 22.4043 5.74018 22.5027 5.84128L12.157 11.8142C12.0899 11.8529 12.0267 11.8981 11.9683 11.949C11.9103 11.8981 11.8475 11.853 11.7809 11.8142L1.59961 5.93698Z" fill="#FFBB56"/>
+</svg>

File diff ditekan karena terlalu besar
+ 7 - 0
src/assets/svg/img-select-giveaway.svg


+ 6 - 0
src/assets/svg/img-select-tool-box.svg

@@ -0,0 +1,6 @@
+<svg width="150" height="150" viewBox="0 0 150 150" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="150" height="150" rx="75" fill="#F9F9F9"/>
+<path d="M71.2466 79.9644L40.333 62.1172V93.5296C40.3336 94.3098 40.5374 95.0764 40.9242 95.7539C41.311 96.4315 41.8676 96.9966 42.5392 97.3938L72.2846 114.998V80.3823C71.9207 80.2923 71.5713 80.1517 71.2466 79.9644Z" fill="#1D9BF0"/>
+<path d="M110.006 61.6406V93.5293C110.006 94.309 109.803 95.0754 109.417 95.7529C109.031 96.4304 108.475 96.9958 107.805 97.3935L78.0547 114.998V80.081C78.1277 80.0442 78.1997 80.0052 78.2704 79.9641L110.006 61.6406Z" fill="#24D37F"/>
+<path d="M40.333 54.7912C40.7171 54.3057 41.1975 53.9049 41.7439 53.614L73.1967 36.8631C73.8468 36.517 74.572 36.3359 75.3085 36.3359C76.045 36.3359 76.7703 36.517 77.4204 36.8631L108.873 53.614C109.3 53.8387 109.682 54.1352 110.01 54.4722L75.5242 74.3818C75.3005 74.511 75.0899 74.6615 74.8951 74.8312C74.7018 74.6617 74.4927 74.5113 74.2706 74.3818L40.333 54.7912Z" fill="#FFBB56"/>
+</svg>

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

@@ -5,7 +5,6 @@ import { reportSrcPublishEvent } from '@/http/publishApi'
 import Report from "@/log-center/log"
 import { fetchAddFinishEvent } from '@/logic/background/fetch/facebook';
 import { showNFTGroupIcon, hideNFTGroupList, checkUserJoinGroup, elemAddEventListener, addJoinedGroupList } from '@/logic/content/nft';
-import { getTwitterNftGroupInfo } from '@/http/nft'
 import { jumpTwitterDetailByAlert, showEditTweet } from '@/logic/content/help/twitter.js'
 import { clearPostContent, setGroupIconStatus } from '@/logic/content/nft.js'
 import axios from 'axios';
@@ -73,14 +72,14 @@ function renderDom() {
 /**
  * 展示give弹窗
  */
-export function showGiveDialogHandler(userInfo) {
+export function showGiveDialogHandler(params) {
     let iframe = document.getElementById('iframe-content');
     if (iframe) {
-        iframe.contentWindow.postMessage({ actionType: 'CONTENT_SHOW_GIVE_DIALOG', userInfo }, '*');
+        iframe.contentWindow.postMessage({ actionType: 'CONTENT_SHOW_GIVE_DIALOG', data: params }, '*');
     } else {
         _addIframe();
         let iframe = document.getElementById('iframe-content');
-        iframe.contentWindow.postMessage({ actionType: 'CONTENT_SHOW_GIVE_DIALOG', userInfo }, '*');
+        iframe.contentWindow.postMessage({ actionType: 'CONTENT_SHOW_GIVE_DIALOG', data: params }, '*');
     }
 }
 
@@ -273,9 +272,10 @@ function checkIsShowReSend(dom, params) {
  * @param isClick
  * @private
  */
-function _addDeNetEditBtn(parent, dom, isClick = false) {
+function _addDeNetEditBtn(params = {}) {
     setTimeout(() => {
-        if (parent && parent.parentNode) {
+        let toolElem = document.querySelector('div[data-testid="toolBar"]');
+        if (toolElem) {
             Report.reportLog({
                 pageSource: Report.pageSource.mainPage,
                 businessType: Report.businessType.buttonView,
@@ -283,12 +283,17 @@ function _addDeNetEditBtn(parent, dom, isClick = false) {
             });
             let innerDeIcon = document.getElementById('de-btn1');
             if (!innerDeIcon) {
-                parent.parentNode.insertBefore(dom, parent.nextElementSibling);
+                toolElem.firstChild.appendChild(createTweetToolbarDenet())
+            }
+
+            let innerToolBoxIcon = document.getElementById('de-tool-box-btn-01');
+            if (!innerToolBoxIcon) {
+                toolElem.firstChild.appendChild(createTweetToolbarToolBox())
             }
         } else {
             setTimeout(() => {
-                parent = _getScheduleDom(isClick);
-                if (parent && parent.parentNode) {
+                let toolElem = document.querySelector('div[data-testid="toolBar"]');
+                if (toolElem) {
                     Report.reportLog({
                         pageSource: Report.pageSource.mainPage,
                         businessType: Report.businessType.buttonView,
@@ -296,7 +301,12 @@ function _addDeNetEditBtn(parent, dom, isClick = false) {
                     });
                     let innerDeIcon = document.getElementById('de-btn1');
                     if (!innerDeIcon) {
-                        parent.parentNode.insertBefore(dom, parent.nextElementSibling);
+                        toolElem.firstChild.appendChild(createTweetToolbarDenet())
+                    }
+        
+                    let innerToolBoxIcon = document.getElementById('de-tool-box-btn-01');
+                    if (!innerToolBoxIcon) {
+                        toolElem.firstChild.appendChild(createTweetToolbarToolBox())
                     }
                 }
             }, 1000)
@@ -335,9 +345,9 @@ function _addDeNetBtn() {
         let navWidth = document.querySelector('nav[role="navigation"]').offsetWidth;
         addSliderNavDeBtn(navWidth < 245);
         let innerDeIcon = document.getElementById('de-btn1');
-        if (!innerDeIcon) {
-            let dialogScheduleBtn = _getScheduleDom(false);
-            dom && dom.deBtn1 && _addDeNetEditBtn(dialogScheduleBtn, dom.deBtn1);
+        let innerToolBoxIcon = document.getElementById('de-tool-box-btn-01');
+        if (!innerDeIcon || !innerToolBoxIcon) {
+            _addDeNetEditBtn();
         }
     }, 800)
 }
@@ -430,7 +440,7 @@ export function hideNoticeBindTweet() {
  * 点击deNet按钮处理
  * @private
  */
-function _deNetBtnClick() {
+function _deNetBtnClick(params = {}) {
     getUserInfo((res) => {
         if (res) {
             if (window.location.pathname != '/home') {
@@ -439,7 +449,7 @@ function _deNetBtnClick() {
                 }
                 dom.homeBtn.click();
             }
-            showGiveDialogHandler(res);
+            showGiveDialogHandler(params);
         } else {
             let loadIcon = document.getElementById('de-btn-loading');
             if (loadIcon) {
@@ -526,17 +536,13 @@ function _createBtnDom() {
     deBtn.style.cssText = 'width:90%;height: 52px;text-align:center;line-height:52px;margin-bottom: 4px;margin-top: 4px;background: linear-gradient(274.8deg, #FF9900 -3.69%, #BD00FF 69.71%, #00F0FF 122.65%);color:#fff;font-size:17px;font-weight:700;border-radius:100px;cursor: pointer;display: flex;align-items: center;justify-content: center;';
 
     // 编辑框内按钮
-    const deBtn1 = document.createElement('img');
     let src = require("@/assets/img/icon-gift-pack.png");
     const smallDeBtnStyle = 'width:20px;height: 20px;cursor: pointer;padding: 0px 8px';
-    deBtn1.id = 'de-btn1';
-    deBtn1.style.cssText = smallDeBtnStyle;
-    deBtn1.src = src
 
     const deBtn2 = document.createElement('div');
     deBtn2.id = 'de-btn2';
     deBtn2.style.cssText = smallDeBtnStyle;
-    deBtn2.src = "@/assets/img/icon-gift-pack.png"
+    deBtn2.src = src
 
     // 小屏按钮
     const deBtn3 = document.createElement('img');
@@ -545,29 +551,14 @@ function _createBtnDom() {
     deBtn3.style.cssText = 'width:52px;height: 52px;margin-top:20px;cursor: pointer;';
 
     deBtn.addEventListener('click', () => {
-        // chrome.runtime.sendMessage({
-        //     actionType: 'CONTENT_SET_BADGE',
-        //     data: {
-        //         text: '2'
-        //     }
-        // }, res => {
-        //     console.log(res);
-        // })
-
         Report.reportLog({
             pageSource: Report.pageSource.mainPage,
             businessType: Report.businessType.buttonClick,
             objectType: Report.objectType.buttonMain
         });
-        _deNetBtnClick();
-    })
-    deBtn1.addEventListener('click', () => {
-        Report.reportLog({
-            pageSource: Report.pageSource.mainPage,
-            businessType: Report.businessType.buttonClick,
-            objectType: Report.objectType.buttonSecond
+        _deNetBtnClick({
+            type: 'SHOW_SELECT'
         });
-        _deNetBtnClick();
     })
     deBtn2.addEventListener('click', () => {
         _deNetBtnClick();
@@ -578,15 +569,55 @@ function _createBtnDom() {
             businessType: Report.businessType.buttonClick,
             objectType: Report.objectType.buttonMain
         });
-        _deNetBtnClick();
+        _deNetBtnClick({
+            type: 'SHOW_SELECT'
+        });
     })
     dom.deBtn = deBtn;
-    dom.deBtn1 = deBtn1;
     dom.deBtn2 = deBtn2;
     dom.deBtn3 = deBtn3;
     dom.loadingImg = loadingImg;
 }
 
+function createTweetToolbarDenet() {
+    let src = require("@/assets/img/icon-gift-pack.png");
+    const smallDeBtnStyle = 'width:20px;height: 20px;cursor: pointer;padding: 0px 8px';
+
+    const deBtn1 = document.createElement('img');
+    deBtn1.id = 'de-btn1';
+    deBtn1.style.cssText = smallDeBtnStyle;
+    deBtn1.src = src;
+
+    deBtn1.addEventListener('click', () => {
+        Report.reportLog({
+            pageSource: Report.pageSource.mainPage,
+            businessType: Report.businessType.buttonClick,
+            objectType: Report.objectType.buttonSecond
+        });
+        _deNetBtnClick();
+    })
+
+    return deBtn1;
+}
+
+function createTweetToolbarToolBox() {
+    let src = require("@/assets/img/icon-tool-box-01.png");
+    const smallDeBtnStyle = 'width:20px;height: 20px;cursor: pointer;padding: 0px 8px';
+
+    const deToolBoxBtn = document.createElement('img');
+    deToolBoxBtn.id = 'de-tool-box-btn-01';
+    deToolBoxBtn.style.cssText = smallDeBtnStyle;
+    deToolBoxBtn.src = src;
+
+    deToolBoxBtn.addEventListener('click', () => {
+        _deNetBtnClick({
+            type: 'TOOL_BOX'
+        })
+    })
+
+    return deToolBoxBtn;
+}
+
 function addSliderNavDeBtn(isSmall = false) {
     if (!isSmall) {
         let bigDom = document.querySelector('a[href="/compose/tweet"]').parentNode.parentNode;
@@ -655,8 +686,7 @@ function checkHasDeBtn() {
         let toolBar = document.querySelector('div[data-testid="toolBar"]');
         let innerDeIcon = document.getElementById('de-btn1');
         if (toolBar && !innerDeIcon) {
-            let dialogScheduleBtn = _getScheduleDom(false);
-            dom && dom.deBtn1 && _addDeNetEditBtn(dialogScheduleBtn, dom.deBtn1);
+            _addDeNetEditBtn();
         }
     } catch (e) {
         console.log(e)
@@ -887,11 +917,11 @@ export function init() {
     }
 
     if (window.location.host.includes('twitter.com')) {
+        renderDom();
         showNFTCard()
         showNFTGroupIcon()
         addEventAction();
         checkUserJoinGroup();
-        renderDom();
         checkTwitterTaskState();
         initBuyNFT();
         addJoinedGroupList();

+ 1 - 1
src/view/components/global-tip.vue

@@ -33,7 +33,7 @@ onMounted(() => {
 <style lang="scss" scoped>
 .global-tip {
     position: absolute;
-    z-index: 999;
+    z-index: 3000;
     display: flex;
     height: 40px;
     background: #000000;

+ 141 - 0
src/view/iframe/publish/components/select-publish-content.vue

@@ -0,0 +1,141 @@
+<template>
+    <div class="overlay" v-if="visible">
+        <div class="content">
+            <!-- 头部 -->
+            <div class="head">
+                <div class="left">
+                    <!-- 关闭按钮 -->
+                    <div class="close-btn" @click="close">
+                        <img  class="icon-close"
+                            :src="require('@/assets/svg/icon-close.svg')"/>
+                    </div>
+                    <!-- 标题 -->
+                    <div class="title">
+                        DeNet
+                    </div>
+                </div>
+            </div>
+            <div class="body">
+                <div v-for="(item, index) in list"
+                    :key="index"
+                    class="item"
+                    @click="clickItem(item, index)">
+                    <img :src="item.icon" alt="">
+                    {{item.txt}}
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { ref, watch, reactive, defineProps, onMounted } from "vue";
+let list = reactive([
+    {
+        icon: require('@/assets/svg/img-select-giveaway.svg'),
+        type: 'REDPACKET',
+        txt: 'Giveaway'
+    },
+    {
+        icon: require('@/assets/svg/img-select-tool-box.svg'),
+        type: 'TOOL_BOX',
+        txt: 'Tool Box'
+    }
+])
+
+const props = defineProps({
+    visible: {
+        type: Boolean,
+        default: false
+    },
+});
+
+
+const emits = defineEmits(["close", "select"]);
+
+const close = () => {
+    emits('close', {});
+}
+
+const clickItem = (params, index) => {
+    emits('select', params);
+}
+
+</script>
+
+<style lang="scss" scoped>
+.overlay {
+    position: fixed;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+    z-index: 1000;
+    width: 100%;
+    height: 100%;
+    background-color: rgba(0, 0, 0, 0.5);
+    overflow: auto;
+
+    .content {
+        width: 580px;
+        height: 400px;
+        background: #ffffff;
+        border-radius: 20px;
+        position: absolute;
+        left: 50%;
+        top: 50%;
+        transform: translate(-50%, -50%);
+        box-sizing: border-box;
+        z-index: 2000;
+
+        .head {
+            border-bottom: 1px solid #ececec;
+            height: 48px;
+            box-sizing: border-box;
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            padding: 0 14px;
+
+            .left {
+                display: flex;
+                align-items: center;
+                .title {
+                    font-size: 16px;
+                    font-weight: 500;
+                }
+
+                .close-btn {
+                    display: flex;
+                    align-items: center;
+                    width: max-content;
+                    margin-right: 12px;
+                    cursor: pointer;
+                }
+            }
+        }
+
+        .body {
+            display: flex;
+            justify-content: space-between;
+            height: calc(100% - 48px);
+            width: 350px;
+            margin: 0 auto;
+
+            .item {
+                display: flex;
+                flex-direction: column;
+                align-items: center;
+                font-weight: 500;
+                font-size: 18px;
+                margin-top: 70px;
+                cursor: pointer;
+
+                img {
+                    margin-bottom: 20px;
+                }
+            }
+        }
+    }
+}
+</style>

+ 298 - 249
src/view/iframe/publish/give-dialog.vue

@@ -71,288 +71,298 @@
                     </div>
 
                     <div class="left" v-if="showComType != 'preview'">
-                        <div class="gift-pack-wrapper">
-                            <img class="icon" :src="require('@/assets/svg/icon-gift-pack.svg')"/>
-                        </div>
-                        <div class="bottom">
+                        <div class="tab-item" 
+                            :class="{'active-tab': item.type == publishType}"
+                            v-for="(item, index) in leftTabList" 
+                            :key="index"
+                            @click="clickLeftTab(item, index)"
+                            >
+                            <img class="icon" :src="item.icon"/>
                         </div>
                     </div>
 
                     <div class="right"  
                         :class="{'fill-right': showComType == 'preview'}">
                         <global-tip :type="'2'"></global-tip>
-                        <div class="form-wrapper"  v-if="showComType == 'default'">
-                            <div class="form-cell-item base-form-wrapper">
-                                <div class="title">
-                                    <img class="icon" :src="require('@/assets/svg/icon-reward-v2.svg')"/>
-                                    Reward
-                                </div>
-                                <div class="form-cell-content">
-                                    <div class="select-mode-ele">
-                                        <img v-for="(item, index) in publishModeList" 
-                                            :key="index" 
-                                            :src="selectModeInfo.index == index ? item.imgActive : item.imgInActive"
-                                            @click="selectPublishMode(item, index)">
+
+                        
+                        <template v-if="publishType == 'TOOL_BOX'">
+                            <tool-box></tool-box>
+                        </template>
+                        <template v-else>
+                            <div class="form-wrapper"  v-if="showComType == 'default'">
+                                <div class="form-cell-item base-form-wrapper">
+                                    <div class="title">
+                                        <img class="icon" :src="require('@/assets/svg/icon-reward-v2.svg')"/>
+                                        Reward
                                     </div>
-                                    <!-- 金额、数量 -->
-                                    <div class="form-base">
-                                        <div class="item currency-select-wrapper">
-                                            <div>
-                                                <div class="label currency-select"
-                                                    :class="{'selected': currentCurrencyInfo.currencyCode}"
-                                                    @click="selectCurrencyPopHandle">
-                                                    <img class="icon"
-                                                        v-if="currentCurrencyInfo.iconPath"
-                                                        :src="currentCurrencyInfo.iconPath"/>
-                                                    <div class="text">
-                                                        {{currentCurrencyInfo.currencyCode == 'USD' ? 'USD' : currentCurrencyInfo.tokenSymbol || 'Select a reward'}}
+                                    <div class="form-cell-content">
+                                        <div class="select-mode-ele">
+                                            <img v-for="(item, index) in publishModeList" 
+                                                :key="index" 
+                                                :src="selectModeInfo.index == index ? item.imgActive : item.imgInActive"
+                                                @click="selectPublishMode(item, index)">
+                                        </div>
+                                        <!-- 金额、数量 -->
+                                        <div class="form-base">
+                                            <div class="item currency-select-wrapper">
+                                                <div>
+                                                    <div class="label currency-select"
+                                                        :class="{'selected': currentCurrencyInfo.currencyCode}"
+                                                        @click="selectCurrencyPopHandle">
+                                                        <img class="icon"
+                                                            v-if="currentCurrencyInfo.iconPath"
+                                                            :src="currentCurrencyInfo.iconPath"/>
+                                                        <div class="text">
+                                                            {{currentCurrencyInfo.currencyCode == 'USD' ? 'USD' : currentCurrencyInfo.tokenSymbol || 'Select a reward'}}
+                                                        </div>
+                                                        <img class="arrow"
+                                                            :src="currentCurrencyInfo.currencyCode ?
+                                                                require('@/assets/svg/icon-form-arrow-down.svg') :  require('@/assets/svg/icon-form-white-arrow-down.svg')"/>
                                                     </div>
-                                                    <img class="arrow"
-                                                        :src="currentCurrencyInfo.currencyCode ?
-                                                            require('@/assets/svg/icon-form-arrow-down.svg') :  require('@/assets/svg/icon-form-white-arrow-down.svg')"/>
-                                                </div>
 
-                                                <!-- 刷新按钮、充值 -->
-                                                <div class="currency-operation"
-                                                    v-if="currentCurrencyInfo.currencyCode">
-                                                    <div class="amount">
-                                                        Balance:
-                                                        <a-tooltip :title="currentCurrencyInfo.balance">
-                                                            {{ getBit(currentCurrencyInfo.balance) }}
-                                                        </a-tooltip>
-                                                        <img :class="{ 'icon-refresh-rotate': refreshRotate }"
-                                                            :src="require('@/assets/svg/icon-form-refresh.svg')"
-                                                            @click="updateCurrencyBanlce"/>
+                                                    <!-- 刷新按钮、充值 -->
+                                                    <div class="currency-operation"
+                                                        v-if="currentCurrencyInfo.currencyCode">
+                                                        <div class="amount">
+                                                            Balance:
+                                                            <a-tooltip :title="currentCurrencyInfo.balance">
+                                                                {{ getBit(currentCurrencyInfo.balance) }}
+                                                            </a-tooltip>
+                                                            <img :class="{ 'icon-refresh-rotate': refreshRotate }"
+                                                                :src="require('@/assets/svg/icon-form-refresh.svg')"
+                                                                @click="updateCurrencyBanlce"/>
+                                                        </div>
+                                                        <div v-if="currentCurrencyInfo.currencyCode != 'USD'" 
+                                                            class="top-up" 
+                                                            @click="goTopUp">Deposit</div>
                                                     </div>
-                                                    <div v-if="currentCurrencyInfo.currencyCode != 'USD'" 
-                                                        class="top-up" 
-                                                        @click="goTopUp">Deposit</div>
                                                 </div>
-                                            </div>
 
-                                            <input v-model="baseFormData.amountValue"
+                                                <input v-model="baseFormData.amountValue"
+                                                        placeholder="0"
+                                                        autofocus
+                                                        @input="onAmountInput"
+                                                        @blur="onAmountBlur"/>
+                                            </div>
+                                            <div class="item winners-count-input">
+                                                <div>
+                                                    <div class="label">
+                                                        <img class="icon"
+                                                            :src="require('@/assets/svg/icon-winner-v2.svg')"/>
+                                                        Winner Count
+                                                    </div>
+                                                    <div class="msg" v-show="selectModeInfo.type == 1">Recommend Winners 100~10000</div>
+                                                </div>
+                                                <input v-model="baseFormData.totalCount"
                                                     placeholder="0"
-                                                    autofocus
-                                                    @input="onAmountInput"
-                                                    @blur="onAmountBlur"/>
-                                        </div>
-                                        <div class="item winners-count-input">
-                                            <div>
+                                                    @input="onCountInput"
+                                                    @blur="onCountBlur"/>
+                                            </div>
+                                            <div class="item automatically-input" v-if="selectModeInfo.type == 2">
                                                 <div class="label">
                                                     <img class="icon"
-                                                        :src="require('@/assets/svg/icon-winner-v2.svg')"/>
-                                                    Winner Count
+                                                        :src="require('@/assets/svg/icon-automatically.svg')"/>
+                                                    Automatically Draw in
+                                                </div>
+                                                <div class="input-wrapper">
+                                                    <input v-model="baseFormData.validityDuration"
+                                                    placeholder="0"
+                                                    @input="onValidityDurationInput"
+                                                    @blur="onValidityDurationBlur"/>
+                                                    <span class="unit">h</span>
                                                 </div>
-                                                <div class="msg" v-show="selectModeInfo.type == 1">Recommend Winners 100~10000</div>
-                                            </div>
-                                            <input v-model="baseFormData.totalCount"
-                                                placeholder="0"
-                                                @input="onCountInput"
-                                                @blur="onCountBlur"/>
-                                        </div>
-                                        <div class="item automatically-input" v-if="selectModeInfo.type == 2">
-                                            <div class="label">
-                                                <img class="icon"
-                                                    :src="require('@/assets/svg/icon-automatically.svg')"/>
-                                                Automatically Draw in
-                                            </div>
-                                            <div class="input-wrapper">
-                                                <input v-model="baseFormData.validityDuration"
-                                                placeholder="0"
-                                                @input="onValidityDurationInput"
-                                                @blur="onValidityDurationBlur"/>
-                                                <span class="unit">h</span>
                                             </div>
                                         </div>
-                                    </div>
-                                    <!--  提示 -->
-                                    <ul class="tips-wrapper">
-                                        <li class="row">
-                                            Rewards can only be claimed after the target user completes all tasks you set. 
-                                        </li>
-                                        <li class="row">
-                                            Each user can only receive a reward once per task.
-                                        </li>
-                                        <li class="row"  v-show="selectModeInfo.type == 1">
-                                            The reward will expire in 7 days once issued. Please promote it as much as possible within this period. After the experiment, the remaining rewards will be returned to your DeNet Wallet.
-                                        </li>
-                                    </ul>
-                                </div> 
-                            </div>
-
-                            <div class="form-cell-item task-wrapper">
-                                <div class="title">
-                                    <img class="icon" :src="require('@/assets/svg/icon-tasks-v2.svg')"/>
-                                    Tasks
+                                        <!--  提示 -->
+                                        <ul class="tips-wrapper">
+                                            <li class="row">
+                                                Rewards can only be claimed after the target user completes all tasks you set. 
+                                            </li>
+                                            <li class="row">
+                                                Each user can only receive a reward once per task.
+                                            </li>
+                                            <li class="row"  v-show="selectModeInfo.type == 1">
+                                                The reward will expire in 7 days once issued. Please promote it as much as possible within this period. After the experiment, the remaining rewards will be returned to your DeNet Wallet.
+                                            </li>
+                                        </ul>
+                                    </div> 
                                 </div>
-                                <div class="form-cell-content form-require">
-                                    <!-- 转推、like、关注 -->
-                                    <div v-for="(item, index) in formList"
-                                        :key="index">
-                                        <div v-if="item.show"  class="form-item"    
-                                            :class="{ 'border-hide': formList.length - 1 == index }">
-                                            <div class="item-left">
-                                                <div class="label">
-                                                    <img class="icon" :src="item.icon"/>
-                                                    {{ item.label }}
-                                                </div>
-                                                <div class="control"
-                                                    v-if="item.nodeType == 'textarea'">
-                                                    <follow-input
-                                                        :isAddSelf="!isBack"
-                                                        :atUserList="atUserList"
-                                                        @addUser="addFollowUser"
-                                                        @setUser="setFollowUser"
-                                                        @delUser="delFollowUser"></follow-input>
-                                                </div>
-                                                <div class="control"
-                                                    v-if="item.nodeType == 'input'">
-                                                    <div v-if="showDiscordInvitePop" 
-                                                        class="discord-invite-info"
-                                                        @click="showDiscordInvitePop = false">
-                                                        <img class="icon" :src="discordInviteInfo.icon || require('@/assets/svg/icon-discord-mini.svg')" />
-                                                        <span class="name">{{discordInviteInfo.name}}</span>
+
+                                <div class="form-cell-item task-wrapper">
+                                    <div class="title">
+                                        <img class="icon" :src="require('@/assets/svg/icon-tasks-v2.svg')"/>
+                                        Tasks
+                                    </div>
+                                    <div class="form-cell-content form-require">
+                                        <!-- 转推、like、关注 -->
+                                        <div v-for="(item, index) in formList"
+                                            :key="index">
+                                            <div v-if="item.show"  class="form-item"    
+                                                :class="{ 'border-hide': formList.length - 1 == index }">
+                                                <div class="item-left">
+                                                    <div class="label">
+                                                        <img class="icon" :src="item.icon"/>
+                                                        {{ item.label }}
+                                                    </div>
+                                                    <div class="control"
+                                                        v-if="item.nodeType == 'textarea'">
+                                                        <follow-input
+                                                            :isAddSelf="!isBack"
+                                                            :atUserList="atUserList"
+                                                            @addUser="addFollowUser"
+                                                            @setUser="setFollowUser"
+                                                            @delUser="delFollowUser"></follow-input>
+                                                    </div>
+                                                    <div class="control"
+                                                        v-if="item.nodeType == 'input'">
+                                                        <div v-if="showDiscordInvitePop" 
+                                                            class="discord-invite-info"
+                                                            @click="showDiscordInvitePop = false">
+                                                            <img class="icon" :src="discordInviteInfo.icon || require('@/assets/svg/icon-discord-mini.svg')" />
+                                                            <span class="name">{{discordInviteInfo.name}}</span>
+                                                        </div>
+                                                        <input v-model="item.text" 
+                                                            placeholder="Enter discord invite link"
+                                                            class="discord-address" 
+                                                            @input="onIptDiscordAddress($event, index)"
+                                                            @blur="onBlurDiscordAddress($event, index)" />
                                                     </div>
-                                                    <input v-model="item.text" 
-                                                        placeholder="Enter discord invite link"
-                                                        class="discord-address" 
-                                                        @input="onIptDiscordAddress($event, index)"
-                                                        @blur="onBlurDiscordAddress($event, index)" />
                                                 </div>
-                                            </div>
-                                            
-                                            <div>
-                                                <a-switch
-                                                    v-if="item.type > 3"
-                                                    v-model:checked="item.checked"
-                                                    @change="formSwitchChange($event, item, index)"/>
+                                                
+                                                <div>
+                                                    <a-switch
+                                                        v-if="item.type > 3"
+                                                        v-model:checked="item.checked"
+                                                        @change="formSwitchChange($event, item, index)"/>
+                                                </div>
                                             </div>
                                         </div>
                                     </div>
                                 </div>
-                            </div>
 
-                            <div class="submit-btn-wrapper">
-                                <div class="submit-btn"
-                                    :class="{ 'disabled-submit': iptErrMsgTxt != ''}"
-                                    @click="confirm">
-                                    <img  class="icon-loading"
-                                        v-if="submitIng"
-                                        :src="require('@/assets/svg/icon-btn-loading.svg')"
-                                    />
-                                    {{iptErrMsgTxt ? iptErrMsgTxt : 'NEXT'}}
+                                <div class="submit-btn-wrapper">
+                                    <div class="submit-btn"
+                                        :class="{ 'disabled-submit': iptErrMsgTxt != ''}"
+                                        @click="confirm">
+                                        <img  class="icon-loading"
+                                            v-if="submitIng"
+                                            :src="require('@/assets/svg/icon-btn-loading.svg')"
+                                        />
+                                        {{iptErrMsgTxt ? iptErrMsgTxt : 'NEXT'}}
+                                    </div>
                                 </div>
                             </div>
-                        </div>
 
-                        <!-- 预览 -->
-                        <template v-else-if="showComType == 'preview'">
-                            <div class="preview">
-                                <div class="card"
-                                    :class="{ center: Number(baseFormData.amountValue) <= Number(currentCurrencyInfo.balance) }">
-                                    <div class="card-title">
-                                        <img class="img"
-                                            v-if="Number(baseFormData.amountValue) > Number(currentCurrencyInfo.balance)"
-                                            :src=" require('@/assets/subject/top-01.svg') " />
-                                        <div class="font">
-                                            Preview: <span>{{installStatus ? 'After' : 'Before' }}</span> DeNet Installed
-                                        </div>
-                                    </div>
-                                    <div class="flash">
-                                        <preview-card
-                                            :currentCurrencyInfo="currentCurrencyInfo"
-                                            :postData="publishRes"
-                                            :baseFormData="baseFormData"
-                                            :amountFontSize="previewFontSize"
-                                        ></preview-card>
-                                    </div>
-                                </div>
-                                <!-- 需充值 -->
-                                <div class="card-content" v-if="Number(baseFormData.amountValue) > Number(currentCurrencyInfo.balance)">
-                                    <template v-if="currentCurrencyInfo.currencyCode === 'USD'">
+                            <!-- 预览 -->
+                            <template v-else-if="showComType == 'preview'">
+                                <div class="preview">
+                                    <div class="card"
+                                        :class="{ center: Number(baseFormData.amountValue) <= Number(currentCurrencyInfo.balance) }">
                                         <div class="card-title">
-                                            <img class="img" :src=" require('@/assets/subject/top-02.svg') " />
-                                            <div class="font">Deposit to Send Giveaway</div>
+                                            <img class="img"
+                                                v-if="Number(baseFormData.amountValue) > Number(currentCurrencyInfo.balance)"
+                                                :src=" require('@/assets/subject/top-01.svg') " />
+                                            <div class="font">
+                                                Preview: <span>{{installStatus ? 'After' : 'Before' }}</span> DeNet Installed
+                                            </div>
+                                        </div>
+                                        <div class="flash">
+                                            <preview-card
+                                                :currentCurrencyInfo="currentCurrencyInfo"
+                                                :postData="publishRes"
+                                                :baseFormData="baseFormData"
+                                                :amountFontSize="previewFontSize"
+                                            ></preview-card>
                                         </div>
-                                        <div class="card-list">
-                                            <div class="item">
-                                                <div class="l">Giveaway Amount</div>
-                                                <div class="r"></div>
+                                    </div>
+                                    <!-- 需充值 -->
+                                    <div class="card-content" v-if="Number(baseFormData.amountValue) > Number(currentCurrencyInfo.balance)">
+                                        <template v-if="currentCurrencyInfo.currencyCode === 'USD'">
+                                            <div class="card-title">
+                                                <img class="img" :src=" require('@/assets/subject/top-02.svg') " />
+                                                <div class="font">Deposit to Send Giveaway</div>
                                             </div>
-                                            <div class="item">
-                                                <div class="l">Balance</div>
-                                                <div class="r"></div>
+                                            <div class="card-list">
+                                                <div class="item">
+                                                    <div class="l">Giveaway Amount</div>
+                                                    <div class="r"></div>
+                                                </div>
+                                                <div class="item">
+                                                    <div class="l">Balance</div>
+                                                    <div class="r"></div>
+                                                </div>
+                                                <div class="item">
+                                                    <div class="l">Paypal charges fee ()</div>
+                                                    <div class="r"></div>
+                                                </div>
+                                                <div class="item">
+                                                    <div class="l">Deposit Amount</div>
+                                                    <div class="r"></div>
+                                                </div>
                                             </div>
-                                            <div class="item">
-                                                <div class="l">Paypal charges fee ()</div>
-                                                <div class="r"></div>
+                                        </template>
+                                        <template v-else>
+                                            <div class="card-title">
+                                                <img class="img" :src=" require('@/assets/subject/top-02.svg') " />
+                                                <div class="font">Deposit to Send Giveaway</div>
                                             </div>
-                                            <div class="item">
-                                                <div class="l">Deposit Amount</div>
-                                                <div class="r"></div>
+                                            <top-up2
+                                                :asyncIng="asyncIng"
+                                                :currentCurrencyInfo="tempCurrentCurrencyInfo"
+                                                @topUpDone="topUpDone">
+                                            </top-up2>
+                                            <div class="card-title">
+                                                <img class="img" :src=" require('@/assets/subject/top-03.svg') " />
+                                                <div class="font">Wait for the amount to arrive</div>
                                             </div>
-                                        </div>
-                                    </template>
-                                    <template v-else>
-                                        <div class="card-title">
-                                            <img class="img" :src=" require('@/assets/subject/top-02.svg') " />
-                                            <div class="font">Deposit to Send Giveaway</div>
-                                        </div>
-                                        <top-up2
-                                            :asyncIng="asyncIng"
-                                            :currentCurrencyInfo="tempCurrentCurrencyInfo"
-                                            @topUpDone="topUpDone">
-                                        </top-up2>
-                                        <div class="card-title">
-                                            <img class="img" :src=" require('@/assets/subject/top-03.svg') " />
-                                            <div class="font">Wait for the amount to arrive</div>
-                                        </div>
-                                        <div class="card-amount">
+                                            <div class="card-amount">
+                                                <img class="icon" src="@/assets/subject/icon-balance.png" />
+                                                <div class="con">
+                                                    <div class="desc">Balance</div>
+                                                    <div class="price">{{currentCurrencyInfo.balance}} {{currentCurrencyInfo.tokenSymbol}}</div>
+                                                </div>
+                                                <img
+                                                    class="refresh"
+                                                    :class="{ 'icon-refresh-rotate': refreshRotate }"
+                                                    @click="updateCurrencyBanlce"
+                                                    :src=" require('@/assets/svg/icon-form-refresh-blue.svg') "
+                                                />
+                                            </div>
+                                        </template>
+                                    </div>
+                                </div>
+                            </template>
+
+                            <!-- paypal支付按钮 -->
+                            <div class="payment" v-show="showComType == 'preview'">
+                                <paypal-button
+                                    :finalAmountData="finalAmountData"
+                                    :payConfig="{
+                                        paypalClientId,
+                                        feeDesc: payConfig.feeDesc,
+                                        paypalHtml,
+                                        amount: baseFormData.amountValue,
+                                        postId
+                                    }"
+                                    :currentCurrencyInfo="currentCurrencyInfo"
+                                    @payPalFinsh="payPalFinsh">
+                                    <template v-slot:balance>
+                                        <div class="balance" v-if="Number(baseFormData.amountValue) <= Number(currentCurrencyInfo.balance)">
                                             <img class="icon" src="@/assets/subject/icon-balance.png" />
                                             <div class="con">
                                                 <div class="desc">Balance</div>
                                                 <div class="price">{{currentCurrencyInfo.balance}} {{currentCurrencyInfo.tokenSymbol}}</div>
                                             </div>
-                                            <img
-                                                class="refresh"
+                                            <img class="refresh"
                                                 :class="{ 'icon-refresh-rotate': refreshRotate }"
-                                                @click="updateCurrencyBanlce"
-                                                :src=" require('@/assets/svg/icon-form-refresh-blue.svg') "
-                                            />
+                                                :src=" require('@/assets/svg/icon-form-refresh.svg')"
+                                                @click="updateCurrencyBanlce"/>
                                         </div>
                                     </template>
-                                </div>
+                                </paypal-button>
                             </div>
                         </template>
-
-                        <!-- paypal支付按钮 -->
-                        <div class="payment" v-show="showComType == 'preview'">
-                            <paypal-button
-                                :finalAmountData="finalAmountData"
-                                :payConfig="{
-                                    paypalClientId,
-                                    feeDesc: payConfig.feeDesc,
-                                    paypalHtml,
-                                    amount: baseFormData.amountValue,
-                                    postId
-                                }"
-                                :currentCurrencyInfo="currentCurrencyInfo"
-                                @payPalFinsh="payPalFinsh">
-                                <template v-slot:balance>
-                                    <div class="balance" v-if="Number(baseFormData.amountValue) <= Number(currentCurrencyInfo.balance)">
-                                        <img class="icon" src="@/assets/subject/icon-balance.png" />
-                                        <div class="con">
-                                            <div class="desc">Balance</div>
-                                            <div class="price">{{currentCurrencyInfo.balance}} {{currentCurrencyInfo.tokenSymbol}}</div>
-                                        </div>
-                                        <img class="refresh"
-                                            :class="{ 'icon-refresh-rotate': refreshRotate }"
-                                            :src=" require('@/assets/svg/icon-form-refresh.svg')"
-                                            @click="updateCurrencyBanlce"/>
-                                    </div>
-                                </template>
-                            </paypal-button>
-                        </div>
                     </div>
                 </div>
             </div>
@@ -384,6 +394,7 @@ import "element-plus/es/components/loading/style/css";
 
 import {create, all} from "mathjs";
 
+import GlobalTip  from '@/view/components/global-tip.vue';
 import messageBox from "@/view/components/message-box.vue";
 import currencyList from "@/view/components/currency-list.vue";
 import currencySelect from "@/view/components/currency-select.vue";
@@ -392,7 +403,9 @@ import followInput from "@/view/iframe/publish/components/follow-input";
 import paypalButton from "@/view/iframe/publish/components/paypal-button";
 import topUp from "@/view/iframe/publish/components/top-up.vue";
 import topUp2 from "@/view/iframe/publish/components/top-up2.vue";
-import  GlobalTip  from '@/view/components/global-tip.vue'
+import toolBox from '@/view/iframe/publish/tool-box/index.vue'
+
+import axios from 'axios';
 
 const config = {
     number: 'BigNumber',
@@ -414,7 +427,9 @@ provide('installStatus', installStatus)
 let publishRes = reactive({});
 
 //弹窗是否展示
-let visible = ref(false);
+let visible = ref(true);
+let publishType = ref('TOOL_BOX');
+
 
 //弹窗高度
 let dialogStyle = reactive({
@@ -592,19 +607,37 @@ let showDiscordInvitePop = ref(false);
 
 let lotteryMaxHourDuration = 168;
 
+let leftTabList = reactive([
+    {
+        icon: require('@/assets/svg/icon-gift-pack.svg'),
+        type: 'REDPACKET'
+    },
+    {
+        icon: require('@/assets/svg/icon-tool-box-02.svg'),
+        type: 'TOOL_BOX'
+    }
+])
+
+
 const props = defineProps({
-    dialogVisible: {
-        type: Boolean,
-        default: false,
+    dialogData: {
+        type: Object,
+        default: () => {
+            return {
+                visible: false,
+                type: 'REDPACKET'
+            }
+        },
     },
 });
 
 watch(
-    () => props.dialogVisible,
+    () => props.dialogData,
     (newVal) => {
-        console.log("watch", newVal);
-        visible.value = newVal;
-        if (newVal) {
+        visible.value = newVal.visible;
+
+        if (newVal.visible) {
+            publishType.value = newVal.type;
             Report.reportLog({
                 pageSource: Report.pageSource.publisherDialog,
                 businessType: Report.businessType.pageView,
@@ -622,6 +655,9 @@ watch(
         } else {
             clearInterval(timer.value);
         }
+    },
+    {
+        deep: true
     }
 );
 
@@ -1004,6 +1040,8 @@ const initParams = () => {
     tempCurrentCurrencyInfo.value = {};
     currentCurrencyInfo.value = {};
 
+    publishType.value = 'REDPACKET';
+
     // clear discord value
     setDiscordIptTxt({text: ''});
 
@@ -1589,6 +1627,10 @@ const selectPublishMode = (params, index) => {
     setInputErrorMsg();
 }
 
+const clickLeftTab = (params, index) => {
+    publishType.value = params.type;
+}
+
 onMounted(() => {
     setFrontConfig();
     setPayConfig();
@@ -1596,6 +1638,10 @@ onMounted(() => {
     window.addEventListener('resize', function () {
         setDialogStyle(true);
     })
+
+    axios.get('https://www.baidu.com/s?wd=%E5%BA%86%E7%A5%9D%E9%A6%99%E6%B8%AF%E5%9B%9E%E5%BD%9225%E5%91%A8%E5%B9%B4%E5%A4%A7%E4%BC%9A&sa=fyb_n_homepage&rsv_dl=fyb_n_homepage&from=super&cl=3&tn=baidutop10&fr=top1000&rsv_idx=2&hisfilter=1').then(res => {
+        console.log(res);
+    })
 });
 </script>
 
@@ -1783,16 +1829,19 @@ onMounted(() => {
                 width: 50px;
                 display: flex;
                 flex-direction: column;
-                justify-content: space-between;
                 align-items: center;
 
-                .gift-pack-wrapper {
+                .tab-item {
                     width: 100%;
                     height: 55px;
-                    background: #f5f5f5;
                     display: flex;
                     align-items: center;
                     justify-content: center;
+                    cursor: pointer;
+                }
+
+                .active-tab {
+                    background-color: #D2EAFC;
                 }
 
                 .bottom {

+ 35 - 9
src/view/iframe/publish/publish.vue

@@ -2,21 +2,30 @@
 <template>
     <div class="main_app">
         <give-dialog
-            :dialogVisible="dialogVisible"
+            :dialogData="dialogData"
             @close="close"
-            @payPalFinsh="payPalFinsh"
-        ></give-dialog>
+            @payPalFinsh="payPalFinsh" ></give-dialog>
+        <select-publish-content 
+            :visible="selectVisible" 
+            @close="hideSelectDialog"
+            @select="selectPublishType"></select-publish-content>
     </div>
 </template>
 
 <script setup>
-import { ref } from "vue";
+import { ref, reactive } from "vue";
 import giveDialog from "@/view/iframe/publish/give-dialog.vue";
+import selectPublishContent from "@/view/iframe/publish/components/select-publish-content.vue";
 
-let dialogVisible = ref(false);
+let dialogData = reactive({
+    visible: false,
+    type: 'REDPACKET'
+});
+
+let selectVisible = ref(false);
 
 const close = () => {
-    dialogVisible.value = false;
+    dialogData.visible = false;
     hideIframe();
 };
 
@@ -29,11 +38,28 @@ const hideIframe = () => {
     window.parent.postMessage({ actionType: "IFRAME_HIDE_IFREME" }, "*");
 };
 
+const hideSelectDialog = () => {
+    selectVisible.value = false;
+}
+
+const selectPublishType = (params) => {
+    hideSelectDialog();
+    dialogData.visible = true;
+    dialogData.type = params.type;
+}
+
 window.addEventListener("message", function (event) {
-    console.log("addEventListener", event);
-    if (event.data && event.data.actionType == "CONTENT_SHOW_GIVE_DIALOG") {
+    let eventData = event.data;
+    if (eventData && eventData.actionType == "CONTENT_SHOW_GIVE_DIALOG") {
         window.parent.postMessage({ actionType: "IFRAME_SHOW_IFREME" }, "*");
-        dialogVisible.value = true;
+
+        let {type = 'REDPACKET'} = eventData.data || {};
+        if(type != 'SHOW_SELECT') {
+            dialogData.visible = true;
+            dialogData.type = type;
+        } else {
+            selectVisible.value = true;
+        }
     }
 });
 </script>

+ 408 - 0
src/view/iframe/publish/tool-box/child/editor.vue

@@ -0,0 +1,408 @@
+<template>
+    <div class="editor-wrapper">
+        <div class="top">
+            <div class="title">
+                Enter Link to Embed in Tweet
+            </div>
+            <div class="search-wrapper">
+                <input class="input" type="text" placeholder="Enter link ">
+                <div class="btn">></div>
+            </div>
+            <div class="desc">
+                desc
+            </div>
+        </div>
+        <div class="bottom">
+            <div class="content">
+                <div class="cate-item history-wrapper" v-for="(item) in historyList" :key="item.cateId">
+                    <div class="cate">
+                        <img :src="item.iconPath">
+                    </div>
+                    <div class="app-list">
+                        <div class="app" v-for="(app, idx) in item.apps" :key="idx">
+                            <img :src="app.iconPath" alt="">
+                            {{app.name}}
+                        </div>
+                    </div>
+                </div>
+                <div class="cate-item" v-for="(item) in appList" :key="item.cateId">
+                    <div class="cate">
+                        <img :src="item.iconPath">
+                    </div>
+                    <div class="app-list">
+                        <div class="app" v-for="(app, idx) in item.apps" :key="idx">
+                            <img :src="app.iconPath" alt="">
+                            {{app.name}}
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { ref, watch, reactive, defineProps, defineEmits, onMounted, nextTick } from "vue";
+
+let historyList = reactive([
+     {
+      "apps": [
+        {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "history 1"
+        },
+         {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string2"
+        },
+         {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string1"
+        },
+      ],
+      "cateId": 0,
+      "iconPath": "https://www.baidu.com/favicon.ico",
+      "name": "history"
+    },
+])
+
+let appList = reactive([
+    {
+      "apps": [
+        {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string1"
+        },
+         {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string2"
+        },
+         {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string1"
+        },
+         {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string2"
+        },
+         {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string1"
+        },
+         {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string2"
+        },
+         {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string1"
+        },
+         {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string2"
+        },
+         {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string1"
+        },
+         {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string2"
+        },
+         {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string1"
+        },
+         {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string2"
+        }
+      ],
+      "cateId": 0,
+      "iconPath": "https://www.baidu.com/favicon.ico",
+      "name": "string"
+    },
+     {
+      "apps": [
+        {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "s1"
+        },
+         {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "s2"
+        }
+      ],
+      "cateId": 0,
+      "iconPath": "https://www.baidu.com/favicon.ico",
+      "name": "s0"
+    },
+     {
+      "apps": [
+        {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string1"
+        },
+         {
+          "appId": 0,
+          "cateId": 0,
+          "createType": 0,
+          "defaultUrl": "string",
+          "guideData": "string",
+          "iconPath": "https://www.baidu.com/favicon.ico",
+          "interactType": 0,
+          "linkImagePath": "string",
+          "name": "string2"
+        }
+      ],
+      "cateId": 0,
+      "iconPath": "https://www.baidu.com/favicon.ico",
+      "name": "string"
+    },
+]);
+
+</script>
+
+<style lang="scss" scoped>
+    .editor-wrapper {
+        width: 100%;
+        height: 100%;
+        .top {
+            padding: 25px 40px 30px 40px;
+            border-bottom: 0.5px solid #D1D9DD;
+            box-sizing: border-box;
+            
+            .title {
+                font-weight: 500;
+                font-size: 20px;
+            }
+
+            .search-wrapper {
+                margin: 20px 0;
+                border-radius: 8px;
+                width: 100%;
+                height: 49px;
+                display: flex;
+                align-items: center;
+
+                .input {
+                    background: #F1F3F4;
+                    border: none;
+                    outline: none;
+                    font-weight: 400;
+                    font-size: 16px;
+                    color: #636363;
+                    height: 100%;
+                    width: calc(100% - 49px);
+                    padding-left: 20px;
+                    border-bottom-left-radius: 8px;
+                    border-top-left-radius: 8px;
+                }
+
+                .btn {
+                    width: 49px;
+                    height: 49px;
+                    background: #1D9BF0;
+                    border-bottom-right-radius: 8px;
+                    border-top-right-radius: 8px;
+                    display: flex;
+                    align-items: center;
+                    justify-content: center;
+                    cursor: pointer;
+                }
+            }
+        }
+        .bottom {
+            width: 100%;
+            height: calc(100% - 185px);
+            overflow-y: auto;
+
+            .content {
+                width: 100%;
+                padding: 36px 30px 20px 50px;
+                box-sizing: border-box;
+
+                .history-wrapper {
+                    height: 110px !important;
+                    overflow: hidden;
+
+                    .app-list {
+                        flex-wrap: nowrap !important;
+                    }
+                }
+
+                .cate-item {
+                    min-height: 110px;
+                    display: flex;
+                    margin-bottom: 12px;
+
+                    .cate {
+                        width: 20px;
+                        height: 110px;
+                        margin-right: 26px;
+                        display: flex;
+                        align-items: center;
+                        margin-top: -10px;
+
+                        img {
+                            width: 20px;
+                            height: 20px;
+                        }
+                    }
+
+                    .app-list {
+                        display: flex;
+                        align-content: center;
+                        flex-wrap: wrap;
+                        
+                        .app {
+                            display: flex;
+                            flex-direction: column;
+                            justify-content: center;
+                            align-items: center;
+                            width: 100px;
+                            height: 110px;
+                            font-weight: 500;
+                            font-size: 12px;
+                            color: #636363;
+                            cursor: pointer;
+
+                            img {
+                                width: 60px;
+                                height: 60px;
+                                border-radius: 10px;
+                                margin-bottom: 10px;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+</style>

+ 264 - 0
src/view/iframe/publish/tool-box/child/preview.vue

@@ -0,0 +1,264 @@
+<template>
+    <div class="preview-wrapper">
+        <div class="top">
+            <div class="card-container">
+                <!-- 安装之后的卡片样式 -->
+                <div v-show="installStatus" class="content-after" :style="{ 'width': reviewCanvasParams.width + 'px' }">
+                    <div class="head" :style="{ 'zoom': reviewCanvasParams.zoom }">
+                        <img :src="userInfo.avatarUrl" class="avatar" />
+                        <div class="article-wrapper">
+                            <div class="nickname">
+                                {{ userInfo.name }}
+                            </div>
+                            <div class="name">
+                                @{{ userInfo.nickName }}
+                            </div>
+                        </div>
+                    </div>
+                    <div class="after-cover-wrapper-parent" :style="{ 'zoom': reviewCanvasParams.zoom }">
+                        <div class="after-cover-wrapper"
+                            style="width: 425px;height: 458px;border: 1px solid;border-radius: 10px">
+
+                        </div>
+                    </div>
+                </div>
+
+                <!-- 安装之前的卡片样式 -->
+                <div class="content-before" v-show="!installStatus"
+                    :style="{ 'width': reviewCanvasParams.width + 'px' }">
+                    <div class="head" :style="{ 'zoom': reviewCanvasParams.zoom }">
+                        <img :src="userInfo.avatarUrl" class="avatar" />
+                        <div class="article-wrapper">
+                            <div class="nickname">
+                                {{ userInfo.name }}
+                            </div>
+                            <div class="name">
+                                @{{ userInfo.nickName }}
+                            </div>
+                        </div>
+                    </div>
+                    <div class="card-wrapper" :style="{ 'zoom': reviewCanvasParams.zoom }" style="height: 284px">
+
+                    </div>
+                </div>
+            </div>
+            <div class="font">
+                Preview: <span>{{ installStatus ? 'After' : 'Before' }}</span> DeNet Installed
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { ref, watch, reactive, defineProps, onMounted, nextTick, onUnmounted } from "vue";
+
+import { getChromeStorage } from "@/uilts/chromeExtension"
+import { getUser } from "@/http/publishApi"
+
+let installStatus = ref(true);
+
+let userInfo = ref({});
+
+let reviewCanvasParams = reactive({
+    width: 620,
+    zoom: 1
+});
+let timer = ref(null);
+
+defineProps({
+    amountFontSize: {
+        type: Number,
+        default: '56'
+    }
+})
+
+const getUserInfo = (cb) => {
+    getChromeStorage('userInfo', (res) => {
+        if (res) {
+            userInfo.value = res;
+        }
+        cb && cb(res);
+    })
+}
+
+const getUserName = (screenName) => {
+    getUser({
+        params: {
+            screenName
+        }
+    }).then(res => {
+        console.log(res);
+        if (res.code == 0) {
+            userInfo.value.name = res.data.name || ''
+        }
+    });
+}
+
+const calcPreviewCanvasParams = () => {
+    nextTick(() => {
+        let containerDom = document.querySelector('.card-container');
+        let domHeight = containerDom && containerDom.offsetHeight || 500;
+        const canvasHeight = 780, canvasWidth = 620;
+        if (domHeight < canvasHeight) {
+            //比例: 高 / 宽
+            let hWRatio = canvasHeight / canvasWidth;
+            //缩小宽度 = 高度 / 比例  
+            let width = domHeight / hWRatio;
+            if (width > canvasWidth) {
+                width = canvasWidth;
+            }
+            //缩小比例 
+            let zoom = width / canvasWidth;
+            if (zoom > 1) {
+                zoom = 1;
+            }
+            reviewCanvasParams.width = width;
+            reviewCanvasParams.zoom = zoom;
+        } else {
+            reviewCanvasParams.width = canvasWidth;
+            reviewCanvasParams.zoom = 1;
+        }
+    });
+}
+
+onMounted(() => {
+    calcPreviewCanvasParams();
+    getUserInfo((res) => {
+        if (res) {
+            getUserName(res.nickName);
+        }
+        clearInterval(timer.value);
+        timer.value = setInterval(() => {
+            installStatus.value = !installStatus.value;
+        }, 3000)
+    });
+    window.addEventListener('resize', function () {
+        calcPreviewCanvasParams();
+    })
+})
+
+onUnmounted(() => {
+    clearInterval(timer.value);
+})
+
+</script>
+
+<style lang="scss" scoped>
+.preview-wrapper {
+    width: 100%;
+    height: 100%;
+
+    .top {
+        width: 100%;
+        height: calc(100% - 80px);
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        overflow-y: auto;
+        padding: 20px 0;
+        box-sizing: border-box;
+
+        .card-container {
+            height: 100%;
+            margin-right: 50px;
+
+            .content-after,
+            .content-before {
+                position: relative;
+            }
+
+            .head {
+                position: absolute;
+                z-index: 1100;
+                top: 20px;
+                left: 17px;
+                display: flex;
+
+                .avatar {
+                    width: 47px;
+                    height: 47px;
+                    border-radius: 50%;
+                    object-fit: cover;
+                    margin-right: 13px;
+                }
+
+                .article-wrapper {
+                    display: flex;
+
+                    .nickname {
+                        font-weight: 500;
+                    }
+
+                    .nickname,
+                    .name {
+                        font-size: 15px;
+                    }
+                    .name {
+                        color: #566370;
+                        margin-left: 7px;
+                    }
+                }
+            }
+
+            .content-after {
+                background: url('@/assets/img/img-tool-box-preview-after.png');
+                width: 387px;
+                height: 100%;
+                background-size: contain;
+                background-repeat: no-repeat;
+                border: 1px solid #D1D9DD;
+                border-radius: 13px;
+                box-sizing: border-box;
+
+                .after-cover-wrapper-parent {
+                    position: absolute;
+                    z-index: 100;
+                    top: 108px;
+                    left: 78px;
+
+                    .after-cover-wrapper {
+                        position: relative;
+                        width: 375px;
+                    }
+                }
+
+            }
+
+            .content-before {
+                background: url('@/assets/img/img-tool-box-preview-before.png');
+                background-size: contain;
+                background-repeat: no-repeat;
+                height: 100%;
+                border: 1px solid #D1D9DD;
+                border-radius: 13px;
+                box-sizing: border-box;
+
+                .card-wrapper {
+                    width: 491px;
+                    border: 1px solid #D1D9DD;
+                    background: #ffffff;
+                    box-sizing: border-box;
+                    overflow: hidden;
+                    position: relative;
+                    box-sizing: border-box;
+                    border-radius: 16px;
+                    left: 73px;
+                    top: 100px;
+                }
+            }
+
+        }
+
+        .font {
+            width: 300px;
+            font-weight: 600;
+            font-size: 20px;
+
+            span {
+                color: #1D9BF0;
+            }
+        }
+    }
+
+}
+</style>

+ 23 - 0
src/view/iframe/publish/tool-box/index.vue

@@ -0,0 +1,23 @@
+<template>
+    <div class="page-wrapper">
+        <editor v-if="showCom == 'EDITOR'" />  
+        <preview v-else />
+    </div>
+</template>
+
+<script setup>
+import { ref, watch, reactive, defineProps, defineEmits, onMounted, nextTick, provide } from "vue";
+
+let showCom = ref('PERVIEW'); //PERVIEW
+
+import editor from '@/view/iframe/publish/tool-box/child/editor.vue'
+import preview from '@/view/iframe/publish/tool-box/child/preview.vue'
+
+</script>
+
+<style lang="scss" scoped>
+    .page-wrapper {
+        width: 100%;
+        height: 100%;
+    }
+</style>

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini