瀏覽代碼

[edit] nft 主体

wenliming 2 年之前
父節點
當前提交
308022bb0e

+ 16 - 0
src/http/nft.js

@@ -7,3 +7,19 @@ export function getTwitterSaleNftProjectInfo(params) {
         data: params
     })
 }
+
+export function nftListMine(params) {
+    return service({
+        url: `/nft/item/listMine`,
+        method: 'post',
+        data: params
+    })
+}
+
+export function getNFTDetail(params) {
+    return service({
+        url: `/nft/item/getDetail`,
+        method: 'post',
+        data: params
+    })
+}

+ 2 - 2
src/view/components/currency-list.vue

@@ -56,7 +56,7 @@
                     </template>
                 </div>
                 <div class="no-data" v-if="show_empty">
-                    {{page != 'top-up' ? 'Not found' : 'No balance'}}
+                    Not found
                 </div>
 
             </div>
@@ -84,7 +84,7 @@
                     </div>
                 </div>
                 <div class="no-data" v-if="!searchList.length">
-                    {{page != 'top-up' ? 'Not found' : 'No balance'}}
+                    Not found
                 </div>
             </div>
         </div>

+ 12 - 2
src/view/components/popup-transactions.vue

@@ -55,6 +55,12 @@
                                         require('@/assets/svg/icon-big-give.svg')
                             " />
                         </template>
+                        <!-- 支出-买盲盒 -->
+                        <template v-else-if="item.bizType == -3">
+                            <img style="margin-left:-4px" :src="
+                                        require('@/assets/svg/icon-big-give.svg')
+                            " />
+                        </template>
                     </div>
                     <div class="info-wrapper">
                         <div class="left">
@@ -77,14 +83,17 @@
                                 <template v-else-if="item.bizType == -2">
                                     Giveaways
                                 </template>
+                                <template v-else-if="item.bizType == -3">
+                                    Mystery box*1  Sold
+                                </template>
                             </div>
                             <div class="time">{{ moment(item.createTimestamp).format('MM-DD HH:mm:ss') }}</div>
                         </div>
                         <div class="right">
                             <div class="msg">
-                                <!-- 支出--提现 -->
+                                <!-- 支出- -->
                                 <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">
                                         <div>
                                             <div class="balance"
@@ -137,6 +146,7 @@
                                             </div>
                                         </div>
                                     </template>
+                                    <!-- 非提现支出 -->
                                     <template v-else>
                                         <div class="balance"
                                             :class="{'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12}">

+ 111 - 41
src/view/popup/components/tabbar.vue

@@ -1,13 +1,29 @@
 <template>
     <div class="tab-bar-wrappeer">
-        <div class="tab-bar-item"
-            v-for="(item,index) in tabbarData" 
+        <div
+            class="tab-bar-item"
+            v-for="(item, index) in tabbarData"
             :key="index"
-            @click="tabbarHandler(item, index)">
-            <img :src="index == currentTab.index ? item.iconActive : item.iconInActive">
-            <div class="text"  :class="{'active-tab': index == currentTab.index}">
-                {{item.name}}
-            </div>
+            @click="tabbarHandler(item, index)"
+        >
+            <template v-if="item.path != '/NFT' || item.path == '/NFT' && showNFTTab">
+                <red-dot class="red-dots"
+                    v-if="unReadCountTask > 0 && item.path == '/message' && currentTab.path != '/message'"
+                    ></red-dot>
+                <img
+                    :src="
+                        index == currentTab.index
+                            ? item.iconActive
+                            : item.iconInActive
+                    "
+                />
+                <div
+                    class="text"
+                    :class="{ 'active-tab': index == currentTab.index }"
+                >
+                    {{ item.name }}
+                </div>
+            </template>
         </div>
     </div>
 </template>
@@ -15,70 +31,117 @@
 <script setup>
 import { ref, onMounted, defineEmits, nextTick } from "vue";
 
+import redDot from "@/view/components/red-dot.vue";
 import router from "@/router/popup.js";
+import { setBadgeInfo, hideBadge } from "@/logic/background/twitter";
+
+
+import { nftListMine } from "@/http/nft.js";
+import { getAllMessageInfo } from "@/http/messageApi"
 
 let currentTab = ref({
-    index: 0
-})
+    index: 0,
+    path: '/'
+});
+
+let unReadCountTask = ref(0);
+let showNFTTab = ref(true);
 
 let tabbarData = ref([
     {
-        name:  'Wallet',
-        path: '/',
-        iconActive: require('@/assets/svg/icon-tab-wallet-active.svg'),
-        iconInActive: require('@/assets/svg/icon-tab-wallet.svg')
+        name: "Wallet",
+        path: "/",
+        iconActive: require("@/assets/svg/icon-tab-wallet-active.svg"),
+        iconInActive: require("@/assets/svg/icon-tab-wallet.svg"),
     },
     {
-        name:  'NFTs',
-        path: '/NFT',
-        iconActive: require('@/assets/svg/icon-tab-NFT-active.svg'),
-        iconInActive: require('@/assets/svg/icon-tab-NFT.svg')
+        name: "NFTs",
+        path: "/NFT",
+        iconActive: require("@/assets/svg/icon-tab-NFT-active.svg"),
+        iconInActive: require("@/assets/svg/icon-tab-NFT.svg"),
     },
     {
-        name:  'Message',
-        path: '/message',
-        iconActive: require('@/assets/svg/icon-tab-message-active.svg'),
-        iconInActive: require('@/assets/svg/icon-tab-message.svg')
+        name: "Message",
+        path: "/message",
+        iconActive: require("@/assets/svg/icon-tab-message-active.svg"),
+        iconInActive: require("@/assets/svg/icon-tab-message.svg"),
     },
     {
-        name:  'More',
-        path: '/more',
-        iconActive: require('@/assets/svg/icon-tab-more-active.svg'),
-        iconInActive: require('@/assets/svg/icon-tab-more.svg')
-    }
-])
+        name: "More",
+        path: "/more",
+        iconActive: require("@/assets/svg/icon-tab-more-active.svg"),
+        iconInActive: require("@/assets/svg/icon-tab-more.svg"),
+    },
+]);
 
-const emits = defineEmits(['tabbarClick']);
+let NFTReqParams = {
+    params: {
+        pageNum: 1,
+        pageSize: 20,
+    },
+};
 
+const emits = defineEmits(["tabbarClick"]);
 
-const tabbarHandler  = (params, index)  => {
+const tabbarHandler = (params, index) => {
     currentTab.value.index = index;
+    currentTab.value.path = params.path;
+
     router.push(params.path);
     emits("tabbarClick", params);
-}
+};
 
 const setActiveTab = (path) => {
     let list = tabbarData.value;
-    for(let i = 0; i < list.length; i++) {
-        if(path == list[i].path) {
+    for (let i = 0; i < list.length; i++) {
+        if (path == list[i].path) {
             currentTab.value.index = i;
+            currentTab.value.path = path;
             break;
         }
     }
+};
+
+const getNFTListMine = () => {
+    nftListMine({
+        params: NFTReqParams.params,
+    }).then((res) => {
+        if (res.data && res.data.length) {
+            showNFTTab.value = true;
+        } else {
+            showNFTTab.value = false;
+        }
+    });
+};
+
+
+const setMessageCount = () => {
+    getAllMessageInfo({params: {
+    }}).then(res => {
+        if(res.code == 0) {
+            let {unReadCountTotal = 0, unReadCountWalletDetail = 0, unReadCountTaskLuckdrop = 0} = res.data;
+            unReadCountTask.value = unReadCountTaskLuckdrop;
+            if(unReadCountTotal > 0) {
+                let text = unReadCountTotal > 99 ? '99+' : unReadCountTotal+'';
+                setBadgeInfo({data: {text}});
+            } else {
+                hideBadge();
+            }
+        }
+    });
 }
 
 onMounted(() => {
     let path = router.currentRoute.value.path;
     setActiveTab(path);
-})
-
+    // getNFTListMine();
+});
 </script>
 
-
 <style scoped lang="scss">
 .tab-bar-wrappeer {
-    background: #FFFFFF;
-    box-shadow: inset 0px 1px 0px #ECECEC;
+    background: #ffffff;
+    box-shadow: inset 0px 1px 0px #ececec;
     width: 100%;
     height: 70px;
     display: flex;
@@ -92,18 +155,25 @@ onMounted(() => {
     cursor: pointer;
 
     .tab-bar-item {
-        flex: 1;    
+        flex: 1;
         text-align: center;
+        position: relative;
 
         .text {
             font-weight: 500;
             font-size: 12px;
-            color: #C0C0C0;
+            color: #c0c0c0;
         }
 
         .active-tab {
-            color: #1D9BF0 !important;
+            color: #1d9bf0 !important;
+        }
+
+        .red-dots {
+            position: absolute;
+            right: 32%;
+            top: 0px;
         }
     }
 }
-</style>
+</style>

+ 2 - 2
src/view/popup/components/top-bar.vue

@@ -4,9 +4,9 @@
             <img :src="userInfo.avatarUrl" class="icon-avatar">
             <span class="nick-name" :style="{color: color}">{{userInfo.nickName}}</span>
         </div>
-        <div>
+        <!-- <div>
             <img :src="require('@/assets/svg/icon-denet-logo.svg')" />
-        </div>
+        </div> -->
     </div>
 </template>
 

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

@@ -236,8 +236,7 @@ let giveReqParams = {
   loadMore: false,
 };
 
-// 钱包未读数
-let unReadCountWallet = ref(0);
+
 let isReadMsg = ref(true);
 
 const clickTab = (params, index) => {
@@ -379,7 +378,6 @@ const setMessageCount = () => {
     }}).then(res => {
         if(res.code == 0) {
             let {unReadCountTotal = 0, unReadCountWalletDetail = 0, unReadCountTaskLuckdrop = 0} = res.data;
-            unReadCountWallet.value = unReadCountWalletDetail;
             if(unReadCountTotal > 0) {
                 let text = unReadCountTotal > 99 ? '99+' : unReadCountTotal+'';
                 setBadgeInfo({data: {text}});
@@ -474,7 +472,7 @@ onMounted(() => {
             .icon-give {
               position: absolute;
               right: -4px;
-              bottom: 2px;
+              bottom: -1px;
             }
 
             .icon-big-give {

+ 314 - 304
src/view/popup/tabbar-page/nft/detail.vue

@@ -1,379 +1,389 @@
 <template>
-  <div class="nft-detail-wrapper">
-    <div class="back-bar">
-        <img :src="require('@/assets/svg/icon-nft-back-arrow.svg')" 
-            class="icon-arrow"
-            @click="back"
-            >
-        Azuki #6436
-    </div>
-    <div class="content">
-      <div class="nft-img">
-        <img
-          class="img"
-          src="https://img0.baidu.com/it/u=901606327,1176126707&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500"
-          @click="clickNFTImg"
-        />
-      </div>
-
-      <div class="desc item">
-        <div class="title">Description</div>
-        <div class="desc-content" v-html="''"></div>
-      </div>
-
-      <div class="prop item">
-        <div class="title">Properties</div>
-        <div class="prop-content">
-            <div class="prop-item" v-for="(item, index) in propList" :key="index">
-                {{item.a}}
-                <div class="prop-name">
-                    {{item.b}}
-                </div>
-                {{item.c}}
-            </div>
+    <div class="nft-detail-wrapper">
+        <div class="back-bar">
+            <img
+                :src="require('@/assets/svg/icon-nft-back-arrow.svg')"
+                class="icon-arrow"
+                @click="back"
+            />
+            {{NFTInfo.nftItemName}}
         </div>
-      </div>
+        <div class="content">
+            <div class="nft-img">
+                <img
+                    class="img"
+                    :src="NFTInfo.imagePath"
+                    @click="clickNFTImg"
+                />
+            </div>
+            <div v-for="(item, index) in listData" :key="index">
+                <div class="desc item" v-if="item.filedName == 'Description'">
+                    <div class="title">{{item.filedName}}</div>
+                    <div class="desc-content" v-html="item.filedValue"></div>
+                </div>
+                <div class="prop item" v-if="item.filedName == 'Properties'">
+                    <div class="title">{{item.filedName}}</div>
+                    <div class="prop-content">
+                        <div
+                            class="prop-item"
+                            v-for="(filedValueItem, filedValueIndex) in item.filedValue"
+                            :key="filedValueIndex"
+                        >
+                            {{ filedValueItem.name }}
+                            <div class="prop-name">
+                                {{ filedValueItem.value }}
+                            </div>
+                            {{ filedValueItem.description }}
+                        </div>
+                    </div>
+                </div>
 
-      <div class="about item">
-        <div class="title">About</div>
+                <div class="about item" v-if="item.filedName == 'About'">
+                    <div class="title">{{item.filedName}}</div>
+                    <div class="about-content" v-html="item.filedValue"></div>
+                </div>
 
-        <div class="about-content" v-html="testHtml">
-        </div>
-      </div>
-
-      <div class="detail item">
-        <div class="title">Details</div>
-        <div class="detail-content">
-            <div class="detail-item" v-for="(item, index) in detailList" :key="index">
-                <div class="left">{{item.label}}</div>
-                <div class="right address" :class="{'blue': index < 2}">
-                    {{item.value}}
-                    <!-- <template>
-                        <span>{{item.value}}</span>
-                        <span>{{item.value}}</span>
-                    </template> -->
+                <div class="detail item"  v-if="item.filedName == 'Details'">
+                    <div class="title">{{item.filedName}}</div>
+                    <div class="detail-content">
+                        <div
+                            class="detail-item"
+                            v-for="(filedValueItem, filedValueIndex) in item.filedValue"
+                            :key="filedValueIndex"
+                        >
+                            <div class="left">{{ filedValueItem.name }}</div>
+                            <div class="right" :class="{'address': filedValueItem.name == 'Contract Address'}"  
+                                v-if="filedValueItem.name != 'Token ID'"
+                                @click="clickAddress(filedValueItem)">
+                                <template v-if="filedValueItem.name != 'Contract Address'">
+                                    {{ filedValueItem.value }}
+                                </template>
+                                <template v-else>
+                                    <span>{{filedValueItem.value}}</span>
+                                    <span>{{filedValueItem.value}}</span>
+                                </template>
+                            </div>
+                            <div v-else v-html='filedValueItem.value'></div>
+                        </div>
+                    </div>
                 </div>
-            </div>
-        </div>
-      </div>
 
-      <div class="date item">
-        <div class="title">Date of possession</div>
-        <div class="date-content">
-            2022-05-27
-        </div>
-      </div>
+                <div class="date item"  v-if="item.filedName == 'Date of possession'">
+                    <div class="title">{{item.filedName}}</div>
+                    <div class="date-content">{{item.filedValue}}</div>
+                </div>
 
-      <div class="price item">
-        <div class="title">Purchase price</div>
-        <div class="price-content">
-            100 USDT
-        </div>
-      </div>
-    </div>
-    <div class="bottom-bar">
-        <div class="default">
-            NFT Sale function, coming soon
-        </div> 
-        <!-- <div class="sell">
-            <div class="sell-btn">
-                Sell
-            </div>
-        </div> 
-        <div class="cancel-sale">
-            <div class="left">
-                233 USDT
-                <div class="final">
-                    (Final 203.5 USDT)
+                <div class="price item"  v-if="item.filedName == 'Purchase price'">
+                    <div class="title">{{item.filedName}}</div>
+                    <div class="price-content">{{item.filedValue}}</div>
                 </div>
             </div>
-            <div class="cancel-btn">
-                Cancel sale
-            </div>
-        </div> -->
+        </div>
+        <div class="bottom-bar">
+            <div class="default">NFT Sale function, coming soon</div>
+            <!-- <div class="sell">
+                    <div class="sell-btn">
+                        Sell
+                    </div>
+                </div> 
+                <div class="cancel-sale">
+                    <div class="left">
+                        233 USDT
+                        <div class="final">
+                            (Final 203.5 USDT)
+                        </div>
+                    </div>
+                    <div class="cancel-btn">
+                        Cancel sale
+                    </div>
+                </div> -->
+        </div>
     </div>
-  </div>
 </template>
 
 <script setup>
-import { ref } from "vue";
+import { ref, onMounted } from "vue";
 import router from "@/router/popup.js";
 
-let propList = ref([
-    {
-        a: 'BACKGROUND',
-        b: 'Cool Blue',
-        c: '5% have this trait'
-    },
-    {
-        a: 'BACKGROUND',
-        b: 'Cool Blue',
-        c: '5% have this trait'
-    }
-]);
-
-let a = ''
-let testHtml = ref('<div class="section" style="margin-bottom: 20px">Take the red bean to join the garden. View the collection at <a style="text-decoration:none;color: #1D9BF0;" href="https://azuki.com/gallery" target="_blank">azuki.com/gallery</a></div><div class="section" style="margin-bottom: 20px">Azuki starts with a collection of 10,000 avatars that give you membership access to The Garden: a corner of the internet where artists, builders, and web3 enthusiasts meet to create a decentralized future. Azuki holders receive access to exclusive drops, experiences, and more. Visit azuki.com for more details.</div><div class="section" style="margin-bottom: 20px">We rise together. We build together. We grow together. </div>')
-
-let detailList = ref([
-    {
-        label: 'Contract Address',
-        value: '0xed5a889898989c5442752'
-    },
-    {
-        label: 'Contract Address',
-        value: '0xed5a...c5442752'
-    },
-        {
-        label: 'Contract Address',
-        value: '0xed5a...c5442752'
-    }
-])
+import {getNFTDetail} from "@/http/nft.js";
+
+let listData = ref([{"filedName":"Description","filedValue":"Created by <font color=\"#1D9BF0\">Azuki<font>"},{"filedName":"Properties","filedValue":[{"description":"5% have this trait","name":"BACKGROUND","value":"Cool Blue"},{"description":"1% have this trait","name":"CLOTHING","value":"Hoodie"},{"description":"16% have this trait","name":"EAR","value":"Pearl"},{"description":"0.35% have this trait","name":"EYES","value":"Closed"},{"description":"4% have this trait","name":"MOUTH","value":"Lipstick"},{"description":"90% have this trait","name":"TYPE","value":"Human"}]},{"filedName":"About","filedValue":"<div class=\"section\" style=\"margin-bottom: 20px\">Take the red bean to join the garden. View the collection at <a style=\"text-decoration:none;color: #1D9BF0;\" href=\"https://azuki.com/gallery\" target=\"_blank\">azuki.com/gallery</a></div><div class=\"section\" style=\"margin-bottom: 20px\">Azuki starts with a collection of 10,000 avatars that give you membership access to The Garden: a corner of the internet where artists, builders, and web3 enthusiasts meet to create a decentralized future. Azuki holders receive access to exclusive drops, experiences, and more. Visit <a style=\"text-decoration:none;color: #1D9BF0;\" href=\"https://www.azuki.com\" target=\"_blank\">azuki.com</a> for more details.</div><div class=\"section\" style=\"margin-bottom: 20px\">We rise together. We build together. We grow together. </div>"},{"filedName":"Details","filedValue":[{"name":"Contract Address","url":"https://bscscan.com/token/0x2Fb9376cFf6fb7f5fe99665aE1Ec2FdDD5099134","value":"0xECa41281c24451168a37211F0bc2b8645AF45092"},{"name":"Token ID","value":"2752"},{"name":"Token Standard","value":"Ethereum"},{"name":"Blockchain","value":"Ethereum"},{"name":"Creator Fees","value":"4%"},{"name":"Transaction Royalties","value":"9%"}]},{"filedName":"Date of possession","filedValue":"2022-05-27"},{"filedName":"Purchase price","filedValue":"100 USDT"}]);
+
+let NFTInfo = ref({
+    imagePath: '',
+    nftItemName: ''
+});
 
 const back = () => {
     router.back();
+};
+
+const clickAddress = (params) => {
+    window.open(params.url);
 }
 
 const clickNFTImg = () => {
+    window.open(NFTInfo.value.imagePath);
+};
 
+const getDetail = () => {
+    getNFTDetail({
+        params: {
+            nftItemId: NFTInfo.value.nftItemId
+        }
+    }).then(res => {
+        if(res.code == 0) {
+
+        }
+    }).catch((err)=>{
 
+    })
 }
-</script>
 
+onMounted(() => {
+    let {params = '{}'} = router.currentRoute.value.query;
+    NFTInfo.value = JSON.parse(params);
+    getDetail();
+})
+
+
+</script>
 
 <style scoped lang="scss">
 .nft-detail-wrapper {
-  width: 100%;
-  height: 100%;
-
-  .back-bar {
-    height: 48px;
-    background: #ffffff;
-    box-shadow: 0px 0.5px 0px #d1d9dd;
-    box-sizing: border-box;
-    padding: 14px;
-    font-weight: 500;
-    font-size: 16px;
-    display: flex;
-    align-items: center;
-
-    .icon-arrow {
-        width: 24px;
-        margin-right: 12px;
-        cursor: pointer;
-    }
-  }
-
-  .content {
     width: 100%;
-    height: calc(100% - 120px);
-    padding: 0 16px;
-    box-sizing: border-box;
-    overflow-y: auto;
-
-    .nft-img {
-        margin-top: 23px;
-        margin-bottom: 20px;
-        text-align: center;
-        .img {
-            width: 280px;
-            border-radius: 26px;
+    height: 100%;
+
+    .back-bar {
+        height: 48px;
+        background: #ffffff;
+        box-shadow: 0px 0.5px 0px #d1d9dd;
+        box-sizing: border-box;
+        padding: 14px;
+        font-weight: 500;
+        font-size: 16px;
+        display: flex;
+        align-items: center;
+
+        .icon-arrow {
+            width: 24px;
+            margin-right: 12px;
+            cursor: pointer;
         }
     }
 
-    .item {
-      border: 1px solid #e3e3e3;
-      border-radius: 10px;
-      padding: 14px;
-      box-sizing: border-box;
-      margin-bottom: 12px;
-
-      .title {
-        font-weight: 600;
-        font-size: 14px;
-      }
-    }
+    .content {
+        width: 100%;
+        height: calc(100% - 120px);
+        padding: 0 16px;
+        box-sizing: border-box;
+        overflow-y: auto;
+
+        .nft-img {
+            margin-top: 23px;
+            margin-bottom: 20px;
+            text-align: center;
+            cursor: pointer;            
+
+            .img {
+                width: 280px;
+                border-radius: 26px;
+            }
+        }
 
-    .desc {
-        margin-top: 10px;
-        .desc-content {
-            font-weight: 500;
-            font-size: 14px;
-            color: #929292;
+        .item {
+            border: 1px solid #e3e3e3;
+            border-radius: 10px;
+            padding: 14px;
+            box-sizing: border-box;
+            margin-bottom: 12px;
 
-            span {
-                color: #1D9BF0;
+            .title {
+                font-weight: 600;
+                font-size: 14px;
             }
         }
-    }
 
-    .prop {
-        .prop-content {
-            display: flex;
-            flex-wrap: wrap;
-            margin-top: 12px;
-
-            .prop-item {
-                width: 48%;
-                height: 88px;
-                background: #F8F8F8;
-                border-radius: 10px;
-                display: flex;
-                flex-direction: column;
-                justify-content: center;
-                padding: 8px;
-                box-sizing: border-box;
-                align-items: center;
+        .desc {
+            margin-top: 10px;
+            .desc-content {
                 font-weight: 500;
-                font-size: 12px;
+                font-size: 14px;
                 color: #929292;
 
-                .prop-name {
-                    font-weight: 700;
-                    font-size: 17px;
-                    margin-top: 6px;
-                    margin-bottom: 8px;
-                    color: #000;
+                span {
+                    color: #1d9bf0;
                 }
             }
-            .prop-item:nth-child(odd) {
-                margin-right: 8px;
+        }
+
+        .prop {
+            .prop-content {
+                display: flex;
+                flex-wrap: wrap;
+                margin-top: 12px;
+
+                .prop-item {
+                    width: 48%;
+                    height: 88px;
+                    background: #f8f8f8;
+                    border-radius: 10px;
+                    display: flex;
+                    flex-direction: column;
+                    justify-content: center;
+                    padding: 8px;
+                    box-sizing: border-box;
+                    align-items: center;
+                    font-weight: 500;
+                    font-size: 12px;
+                    color: #929292;
+                    margin-bottom: 10px;
+
+                    .prop-name {
+                        font-weight: 700;
+                        font-size: 17px;
+                        margin-top: 6px;
+                        margin-bottom: 8px;
+                        color: #000;
+                    }
+                }
+                .prop-item:nth-child(odd) {
+                    margin-right: 8px;
+                }
             }
         }
-    }
 
-    .about-content {
-        margin-top: 22px;
-  .section {
-            font-weight: 400;
-            font-size: 14px;
-            margin-bottom:  20px;
+        .about-content {
+            margin-top: 22px;
+            .section {
+                font-weight: 400;
+                font-size: 14px;
+                margin-bottom: 20px;
+            }
         }
-      
-    }
-  .section {
+        .section {
             font-weight: 400;
             font-size: 14px;
-            margin-bottom:  10px;
+            margin-bottom: 10px;
         }
 
-    .detail-content {
-        margin-top: 15px;
+        .detail-content {
+            margin-top: 15px;
 
-        .detail-item {
-            display: flex;
-            align-items: center;
-            justify-content: space-between;
-            height: 24px;
-            font-weight: 400;
-            font-size: 14px;
-
-            .right {
-                color: #929292;
-            }
+            .detail-item {
+                display: flex;
+                align-items: center;
+                justify-content: space-between;
+                height: 24px;
+                font-weight: 400;
+                font-size: 14px;
 
-            .blue {
-                color: #1D9BF0 !important;
-            }
+                .right {
+                    color: #929292;
+                }
 
-            .address {
-                width: 100px;
-                white-space: nowrap;
-                > span {
-                    display: inline-block;
-                    overflow: hidden;
-                    text-overflow: ellipsis;
-                    width: 50%;
-                    + span {
-                        width: calc(50% + 10px);
-                        direction: rtl;
-                        margin-left: -13px;
+                .address {
+                    width: 100px;
+                    white-space: nowrap;
+                    color: #1d9bf0 !important;
+                    cursor: pointer;
+
+                    > span {
+                        display: inline-block;
+                        overflow: hidden;
+                        text-overflow: ellipsis;
+                        width: 50%;
+                        + span {
+                            width: calc(50% + 10px);
+                            direction: rtl;
+                            margin-left: -11px;
+                        }
                     }
                 }
             }
         }
-    }
-
-    .date-content, .price-content {
-        margin-top: 10px;
-        font-weight: 500;
-        font-size: 14px;
-        color: #929292;
-    }
-  }
-
-  .bottom-bar {
-    background: #ffffff;
-    box-shadow: inset 0px 1px 0px #ececec;
-    height: 70px;
-    padding: 15px 16px;
-    box-sizing: border-box;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-
-    .default {
-        font-weight: 500;
-        font-size: 16px;
-        color: #a8a8a8;
-        text-align: center;
-    }
 
-    .sell {
-        width: 100%;
-        height: 100%;
-
-        .sell-btn {
-            width: 120px;
-            height: 40px;
-            box-sizing: border-box;
-            border: 1px solid #E9E9E9;
-            border-radius: 100px;
+        .date-content,
+        .price-content {
+            margin-top: 10px;
             font-weight: 500;
-            font-size: 16px;
-            color: #1D9BF0;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            position: absolute;
-            right: 16px;
-            cursor: pointer;
+            font-size: 14px;
+            color: #929292;
         }
     }
 
-    .cancel-sale {
-        width: 100%;
-        height: 100%;
+    .bottom-bar {
+        background: #ffffff;
+        box-shadow: inset 0px 1px 0px #ececec;
+        height: 70px;
+        padding: 15px 16px;
+        box-sizing: border-box;
         display: flex;
         align-items: center;
-        justify-content: space-between;
+        justify-content: center;
 
-        .left {
+        .default {
             font-weight: 500;
-            font-size: 15px;
-            .final {
+            font-size: 16px;
+            color: #a8a8a8;
+            text-align: center;
+        }
+
+        .sell {
+            width: 100%;
+            height: 100%;
+
+            .sell-btn {
+                width: 120px;
+                height: 40px;
+                box-sizing: border-box;
+                border: 1px solid #e9e9e9;
+                border-radius: 100px;
                 font-weight: 500;
-                font-size: 12px;
-                color: #929292;
-                margin-top: 6px;
+                font-size: 16px;
+                color: #1d9bf0;
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                position: absolute;
+                right: 16px;
+                cursor: pointer;
             }
         }
 
-        .cancel-btn {
-            width: 120px;
-            height: 40px;
-            box-sizing: border-box;
-            border: 1px solid #E9E9E9;
-            border-radius: 100px;
-            font-weight: 500;
-            font-size: 16px;
-            color: #FF0000;
+        .cancel-sale {
+            width: 100%;
+            height: 100%;
             display: flex;
             align-items: center;
-            justify-content: center;
-            cursor: pointer;
+            justify-content: space-between;
+
+            .left {
+                font-weight: 500;
+                font-size: 15px;
+                .final {
+                    font-weight: 500;
+                    font-size: 12px;
+                    color: #929292;
+                    margin-top: 6px;
+                }
+            }
+
+            .cancel-btn {
+                width: 120px;
+                height: 40px;
+                box-sizing: border-box;
+                border: 1px solid #e9e9e9;
+                border-radius: 100px;
+                font-weight: 500;
+                font-size: 16px;
+                color: #ff0000;
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                cursor: pointer;
+            }
         }
     }
-  }
 }
-</style>
+</style>

+ 68 - 25
src/view/popup/tabbar-page/nft/index.vue

@@ -1,46 +1,88 @@
 <template>
-  <div class="nft-page-wrapper">
-    <div class="content">
-      <div class="item" v-for="(item, index) in listData" :key="index" @click="clickNFT(item)">
-        <img :src="item.src" class="img">
-        <div class="name">{{item.name}}</div>
+  <div class="nft-page-wrapper"
+    ref="pageWrapperDom"
+    @scroll="pageScroll" >
+    <div class="content" ref="pageListDom">
+      <div class="item" 
+          v-for="(item, index) in listData" 
+          :key="index" 
+          @click="clickNFT(item)">
+        <img :src="item.imagePath" class="img">
+        <div class="name">{{item.nftItemName}}</div>
       </div>
     </div>
   </div>
 </template>
 
 <script setup>
-import { ref } from "vue";
+import { ref, onMounted } from "vue";
 import router from "@/router/popup.js";
 
+import {nftListMine} from "@/http/nft.js";
+
 let listData = ref([
   {
-    src: 'https://img0.baidu.com/it/u=901606327,1176126707&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
-    name: 'test Name'
-  },
-  {
-    src: 'https://img0.baidu.com/it/u=901606327,1176126707&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
-    name: 'test Name'
-  },
-  {
-    src: 'https://img0.baidu.com/it/u=901606327,1176126707&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
-    name: 'test Name'
-  },
-   {
-    src: 'https://img0.baidu.com/it/u=901606327,1176126707&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
-    name: 'test Name'
-  },
-  {
-    src: 'https://img0.baidu.com/it/u=901606327,1176126707&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
-    name: 'test Name'
+    imagePath: 'https://img0.baidu.com/it/u=901606327,1176126707&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500',
+    nftItemName: 'test Name'
   },
 ])
 
+let NFTReqParams = {
+  params: {
+    pageNum: 1,
+    pageSize: 20,
+  },
+  loadMore: false,
+};
+
+let pageWrapperDom = ref(null);
+let pageListDom = ref(null);
+
 const clickNFT = (params) => {
   router.push({
-    path: '/NFTDetail'
+    path: '/NFTDetail',
+    query: {
+      params: JSON.stringify(params)
+    }
   })
 }
+
+const getNFTListMine = () => {
+  nftListMine({
+    params: NFTReqParams.params,
+  }).then((res) => {
+    if (res.data && res.data.length) {
+      if (NFTReqParams.params.pageNum < 2) {
+        listData.value = res.data;
+      } else {
+        let data = listData.value;
+        data = data.concat(res.data);
+        listData.value = data;
+      }
+      NFTReqParams.loadMore = false;
+    }
+  });
+}
+
+
+
+const pageScroll = (e) => {
+  let wrapperHeight = pageWrapperDom.value.offsetHeight;
+  let pageListHeight = pageListDom.value.offsetHeight;
+  let scrollTop = e.target.scrollTop || 0;
+  if (
+    NFTReqParams.loadMore === false &&
+    wrapperHeight + scrollTop >= pageListHeight - 60
+  ) {
+    NFTReqParams.loadMore = true;
+    NFTReqParams.params.pageNum++;
+    getNFTListMine();
+  }
+};
+
+onMounted(() => {
+  // getNFTListMine();
+})
 </script>
 
 
@@ -74,6 +116,7 @@ const clickNFT = (params) => {
           .name {
             font-weight: 400;
             font-size: 12px;
+            margin-top: 6px;
           }
         }
       }

+ 19 - 11
src/view/popup/tabbar-page/wallter/popup.vue

@@ -19,6 +19,7 @@
 
                     <img :src="require('@/assets/svg/icon-home-refresh.svg')" 
                         class="icon"
+                        :class="{ transform_rotate: iconRotate }"
                         @click="refreshList"  />
                 </div>
             </div>
@@ -43,7 +44,7 @@ import {
     getChromeStorage,
 } from "@/uilts/chromeExtension";
 import { getBalance } from "@/http/account";
-import { readAllMsgByType, getAllMessageInfo } from "@/http/messageApi"
+import { getAllMessageInfo } from "@/http/messageApi"
 import { setBadgeInfo, hideBadge } from "@/logic/background/twitter";
 import Report from "@/log-center/log";
 import router from "@/router/popup.js";
@@ -62,6 +63,10 @@ withdraw_info.balance = 0
 let isRequestWithdrawBalance = ref(false);
 
 let currencyListDom = ref('');
+let iconRotate = ref(false)
+
+// 钱包未读数
+let unReadCountWallet = ref(0);
 
 let walletWithdrawConfig = ref({
     withdrawUSDPaypalFee: 0,
@@ -101,21 +106,12 @@ onMounted(() => {
     });
 });
 
-const readAllMsg = ({msgType}, cb) => {
-    readAllMsgByType({
-        params: {
-            msgType
-        }
-    }).then(res => {
-        cb && cb();
-    })
-};
-
 const setMessageCount = () => {
     getAllMessageInfo({params: {
     }}).then(res => {
         if(res.code == 0) {
             let {unReadCountTotal = 0, unReadCountWalletDetail = 0, unReadCountTaskLuckdrop = 0} = res.data;
+            unReadCountWallet.value = unReadCountWalletDetail;
             if(unReadCountTotal > 0) {
                 let text = unReadCountTotal > 99 ? '99+' : unReadCountTotal+'';
                 setBadgeInfo({data: {text}});
@@ -187,6 +183,13 @@ const clickTopUp = () => {
 }
 
 const refreshList = () => {
+    if (iconRotate.value) {
+        return
+    }
+    iconRotate.value = true
+    setTimeout(() => {
+        iconRotate.value = false
+    }, 1000)
     if(currencyListDom.value) {
         currencyListDom.value.getCurrencyInfoList && currencyListDom.value.getCurrencyInfoList();
     }
@@ -296,6 +299,11 @@ body {
 
                 .icon {
                     margin-left: 22px;
+                    cursor: pointer;
+                }
+                .transform_rotate {
+                    transform: rotate(360deg);
+                    transition-duration: 1s;
                 }
             }
         }