浏览代码

Merge branch 'feature_220602_popup_nft' into dev_1.1.0

wenliming 2 年之前
父节点
当前提交
c35481360e

+ 1 - 1
src/assets/svg/icon-telegram.svg

@@ -1,3 +1,3 @@
 <svg width="42" height="42" viewBox="0 0 42 42" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M32.2165 13.8207L28.5516 30.7927C28.2752 31.9905 27.5541 32.2887 26.5295 31.7244L20.9454 27.6837L18.251 30.2284C17.9528 30.5212 17.7034 30.7661 17.1288 30.7661L17.5299 25.1815L27.8794 15.9981C28.3294 15.6042 27.7818 15.3859 27.18 15.7799L14.3855 23.6909L8.87738 21.998C7.67925 21.6306 7.65757 20.8214 9.12677 20.2571L30.6714 12.1065C31.669 11.7392 32.5418 12.3248 32.2165 13.8207V13.8207Z" fill="#259EDA"/>
+<path d="M32.2165 13.8207L28.5516 30.7927C28.2752 31.9905 27.5541 32.2887 26.5295 31.7244L20.9454 27.6837L18.251 30.2284C17.9528 30.5212 17.7034 30.7661 17.1288 30.7661L17.5299 25.1815L27.8794 15.9981C28.3294 15.6042 27.7818 15.3859 27.18 15.7799L14.3855 23.6909L8.87738 21.998C7.67925 21.6306 7.65757 20.8214 9.12677 20.2571L30.6714 12.1065C31.669 11.7392 32.5418 12.3248 32.2165 13.8207Z" fill="#1D9BF0"/>
 </svg>

文件差异内容过多而无法显示
+ 6 - 0
src/assets/svg/icon-wallter-list-blind-box.svg


+ 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>

+ 24 - 7
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-wallter-list-blind-box.svg')
+                            " />
+                        </template>
                     </div>
                     <div class="info-wrapper">
                         <div class="left">
@@ -77,14 +83,16 @@
                                 <template v-else-if="item.bizType == -2">
                                     Giveaways
                                 </template>
+                                <template v-else-if="item.bizType == -3">
+                                    Mystery box*{{item.bizData.nftItemCount}}  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"
@@ -152,16 +160,25 @@
                                         </div>
                                     </template>
                                 </template>
-                                <!-- 收入 -->
+
                                 <template v-else>
                                     <div class="balance"
                                         :class="{'balance-direction': item.trxAmountCurrencyInfo.tokenSymbol.length + ('' + item.trxAmountValue).length > 12}">
-                                        <span class="amount">
-                                            <template v-if="item.bizType == -2">-</template>
-                                            <a-tooltip :title="item.bizType == -2 ? '-' + item.trxAmountValue : item.trxAmountValue">
+
+                                        <!--支出—— -2:零钱余额支付 、-3: NFT盲盒余额支付 -->
+                                        <span class="amount" v-if="item.bizType == -2 || item.bizType == -3">
+                                            -
+                                            <a-tooltip :title="'-' + item.trxAmountValue">
                                                 {{ getBit(item.trxAmountValue) || 0 }}
                                             </a-tooltip>
                                         </span>
+                                        <!-- 收入—— bizType:1、2、3、4 -->
+                                        <span class="amount" v-else>
+                                            <a-tooltip :title="item.trxAmountValue">
+                                                {{ getBit(item.trxAmountValue) || 0 }}
+                                            </a-tooltip>
+                                        </span>
+
                                         <div class="trx-amount-currency-info">
                                             <span class="name">{{ item.trxAmountCurrencyInfo.tokenSymbol }}</span>
                                             <img :src="item.trxAmountCurrencyInfo.iconPath" alt="">
@@ -197,7 +214,7 @@ let listContent = ref(null);
 let listReqParams = {
     params: {
         pageNum: 1,
-        pageSize: 10,
+        pageSize: 20,
     },
     loadMore: false,
 };

+ 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>
 

+ 39 - 30
src/view/popup/currency-detail.vue

@@ -10,8 +10,8 @@
         class="icon-currency"
         :src="currencyInfo.iconPath"/>
       <div class="amount">
-        {{currencyInfo.totalBalance}} {{currencyInfo.currencyName}}
-        <div class="final">${{currencyInfo.totalUsdEstimateBalance}}</div>
+        {{currencyInfo.balance}} {{currencyInfo.currencyName}}
+        <div class="final">${{currencyInfo.usdEstimateBalance}}</div>
       </div>
     </div>
     <div class="bottom">
@@ -29,7 +29,7 @@
                 @selectCurrency="selectCurrency">
             </currency-select>
         </div>
-        <div class="selectBg" @click="showCurrencySelect = false"></div>
+        <div class="selectBg"></div>
     </template>
   </div>
 </template>
@@ -40,6 +40,8 @@ import router from "@/router/popup.js";
 import Report from "@/log-center/log";
 import { getStorage } from "@/uilts/help";
 
+import { syncChainTokenRechargeRecord } from "@/http/publishApi";
+
 import VHead from '@/view/popup/components/head.vue'
 import currencySelect from "@/view/components/currency-select.vue";
 
@@ -48,20 +50,17 @@ let currenciesData = ref([]);
 let currencyInfo = ref({});
 let showCurrencySelect = ref(false);
 
-let currencyOpertionType = '';
-
-
-
 const selectCurrency = (params) => {
     showCurrencySelect.value = false;
-    if(currencyOpertionType == 'WITHDRAW') {
-      withdrawHandle(params);
-    } else if(currencyOpertionType == 'DEPOSIT') {
-      depositHandle(params);
+
+    currencyInfo.value = {
+      ...params,
+      totalBalance: currencyInfo.value.totalBalance,
+      totalUsdEstimateBalance: currencyInfo.value.totalUsdEstimateBalance
     }
+    console.log(currencyInfo.value)
 }
 
-let withdraw_info = inject('withdraw_info')
 // 点击提现
 const clickWithdraw = () => {
     Report.reportLog({
@@ -69,15 +68,10 @@ const clickWithdraw = () => {
         businessType: Report.businessType.buttonClick,
         objectType: Report.objectType.withdrawButton
     });
-
-    if(currenciesData.value.length > 1) {
-      showCurrencySelect.value = true;
-      currencyOpertionType = "WITHDRAW";
-    } else if(currenciesData.value.length == 1){
-      withdrawHandle(currenciesData.value[0]);
-    }
+    withdrawHandle(currencyInfo.value);
 }
 
+let withdraw_info = inject('withdraw_info')
 const withdrawHandle = (_params) => {
   withdraw_info.chainInfo = _params.chainInfo;
   if (_params.currencyCode == 'USD') {
@@ -97,10 +91,6 @@ const withdrawHandle = (_params) => {
   }
 }
 
-
-
-let top_up_info = inject('top_up_info');
-
 const clickDeposit = () => {
     Report.reportLog({
         pageSource: Report.pageSource.denetHomePage,
@@ -108,14 +98,10 @@ const clickDeposit = () => {
         objectType: Report.objectType.topupButton
     });
 
-    if(currenciesData.value.length > 1) {
-      showCurrencySelect.value = true;
-      currencyOpertionType = "DEPOSIT";
-    } else if(currenciesData.value.length == 1){
-      depositHandle(currenciesData.value[0]);
-    }
+    depositHandle(currencyInfo.value);
 }
 
+let top_up_info = inject('top_up_info');
 const depositHandle = (_params) => {
   top_up_info.token = _params.currencyName || ''
   top_up_info.token_chain = _params.tokenChain 
@@ -131,9 +117,28 @@ const depositHandle = (_params) => {
 };
 
 const onRefresh = () => {
-
+  // 刷新余额接口
+  asyncTokenRechRecord(currencyInfo.value, (res) => {
+    if(res.code == 0 && res.data && res.data.length) {
+        let currencyData = res.data[0];
+        if(currencyData.currencyCode == currencyInfo.value.currencyCode) {
+          currencyInfo.value.balance = currencyData.balance;
+          currencyInfo.value.usdEstimateBalance = currencyData.usdEstimateBalance;
+        }
+    }
+  })
 };
 
+const asyncTokenRechRecord = (_params, cb) => {
+    syncChainTokenRechargeRecord({
+        params: {
+            currencyCode: _params.currencyCode
+        }
+    }).then(res => {
+        cb && cb(res)
+    })
+}
+
 onMounted(() => {
     let {params = '{}'} = router.currentRoute.value.query;
 
@@ -148,6 +153,10 @@ onMounted(() => {
         totalUsdEstimateBalance
       };
     }
+
+    if(currenciesData.value.length > 1) {
+      showCurrencySelect.value = true;
+    }
 })
 </script>
 

+ 5 - 1
src/view/popup/tabbar-page/index.vue

@@ -2,7 +2,7 @@
   <div class="tabbar-page-wrapper">
     <global-tip :type="'3'"></global-tip>
     <!-- login -->
-    <popup-login v-if="!userInfo.accessToken" @loginAction="loginAction" />
+    <popup-login v-if="!loginStatus" @loginAction="loginAction" />
     <template v-else>
       <top-bar  :userInfo="userInfo" 
                 :bgColor="bgColor"
@@ -32,11 +32,15 @@ let bgColor = ref('#1b92e2');
 let color =  ref('#fff');
 let boxShadow = ref('none');
 
+let loginStatus = ref('default'); 
+
 const getUserInfo = (cb) => {
   getChromeStorage("userInfo", (res) => {
     if (res && res.accessToken) {
       userInfo.value = res;
+      loginStatus.value = res;
     } else {
+      loginStatus.value = '';
       userInfo.value = {};
     }
     cb && cb(res);

+ 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 {

+ 6 - 6
src/view/popup/tabbar-page/more/index.vue

@@ -30,7 +30,7 @@ import { ref } from "vue";
 let moreTabList = ref([
   {
     icon: require("@/assets/svg/icon-website.svg"),
-    label: "Website",
+    label: "Official Website",
     href: "https://denet.me",
   },
   {
@@ -43,11 +43,11 @@ let moreTabList = ref([
     label: "Discord",
     href: "https://discord.gg/wZSz9p8ddG",
   },
-  // , {
-  //     icon: require("@/assets/svg/icon-telegram.svg"),
-  //     label: "Telegram",
-  //     href: 'https://t.me/denetpro'
-  // }
+  {
+      icon: require("@/assets/svg/icon-telegram.svg"),
+      label: "Telegram",
+      href: 'https://t.me/denetpro'
+  }
 ]);
 
 const moreItemHandle = (params) => {

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

@@ -1,379 +1,424 @@
 <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 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 class="content">
+            <div class="nft-img">
+                <img
+                    class="img"
+                    :src="NFTInfo.imagePath"
+                    @click="clickNFTImg"
+                />
+            </div>
+            <div class="desc item" v-if="nftMetaData.description">
+                <div class="title">Description</div>
+                <div class="desc-content" v-html="nftMetaData.description"></div>
+            </div>
+            <div class="prop item" v-if="nftMetaData.properties && nftMetaData.properties.length">
+                <div class="title">Properties</div>
+                <div class="prop-content">
+                    <div
+                        class="prop-item"
+                        v-for="(filedValueItem, filedValueIndex) in nftMetaData.properties"
+                        :key="filedValueIndex"
+                    >
+                        {{ filedValueItem.name }}
+                        <div class="prop-name">
+                            {{ filedValueItem.value }}
+                        </div>
+                        {{ filedValueItem.description }}
+                    </div>
                 </div>
-                {{item.c}}
             </div>
-        </div>
-      </div>
-
-      <div class="about item">
-        <div class="title">About</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>
+            <div class="about item" v-if="nftMetaData.about">
+                <div class="title">About</div>
+                <div class="about-content" v-html="nftMetaData.about"></div>
             </div>
-        </div>
-      </div>
+            <div class="detail item"  v-if="nftDetailData.details">
+                    <div class="title">Details</div>
+                    <div class="detail-content">
+                        <div class="detail-item">
+                            <div class="left">Contract Address</div>
+                            <div class="right address"  
+                                @click="clickAddress">
+                                    <span>{{nftDetailData.details.contractAddress}}</span>
+                                    <span>{{nftDetailData.details.contractAddress}}</span>
+                            </div>
+                        </div>
+                        <div class="detail-item">
+                            <div class="left">Token ID</div>
+                            <div class="right token"
+                                @click="clickToken">
+                                {{nftDetailData.details.tokenId}}
+                            </div>
+                        </div>
+                        <div class="detail-item">
+                            <div class="left">Token Standard</div>
+                            <div class="right" >
+                                {{nftDetailData.details.tokenStandard}}
+                            </div>
+                        </div>
+                        <div class="detail-item">
+                            <div class="left">Blockchain</div>
+                            <div class="right" >
+                                {{nftDetailData.details.blockChain}}
+                            </div>
+                        </div>
+                        <div class="detail-item">
+                            <div class="left">Creator Fees</div>
+                            <div class="right" >
+                                {{nftDetailData.details.creatorFees}}
+                            </div>
+                        </div>
+                        <div class="detail-item">
+                            <div class="left">Transaction Royalties</div>
+                            <div class="right" >
+                                {{nftDetailData.details.transactionRoyalties}}
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="date item"  v-if="nftDetailData.dateOfPossession">
+                    <div class="title">Date of possession</div>
+                    <div class="date-content">{{nftDetailData.dateOfPossession}}</div>
+                </div>
 
-      <div class="date item">
-        <div class="title">Date of possession</div>
-        <div class="date-content">
-            2022-05-27
+                <div class="price item"  v-if="nftDetailData.purchasePrice">
+                    <div class="title">Purchase price</div>
+                    <div class="price-content">{{nftDetailData.purchasePrice}}</div>
+                </div>
         </div>
-      </div>
-
-      <div class="price item">
-        <div class="title">Purchase price</div>
-        <div class="price-content">
-            100 USDT
+        <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>
-    <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>
 </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 nftMetaData = ref({});
+let nftDetailData = ref({});
+
+let NFTInfo = ref({
+    imagePath: '',
+    nftItemName: ''
+});
 
 const back = () => {
     router.back();
+};
+
+const clickAddress = () => {
+    let {contractAddressUrl = ''} = nftDetailData.value.details;
+    if(contractAddressUrl) {
+        window.open(contractAddressUrl);
+    }
+}
+
+const clickToken = () => {
+    let {tokenIdUrl = ''} = nftDetailData.value.details;
+    if(tokenIdUrl) {
+        window.open(tokenIdUrl);
+    }
 }
 
 const clickNFTImg = () => {
+    window.open(NFTInfo.value.imagePath);
+};
 
+const getDetail = () => {
+    getNFTDetail({
+        params: {
+            nftItemId: NFTInfo.value.nftItemId
+        }
+    }).then(res => {
+        if(res.code == 0) {
+            console.log(res)
+            let { metadata = '{}'} = res.data || {};
+            nftDetailData.value = res.data;
+            nftMetaData.value = JSON.parse(metadata);
+        }
+    }).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;
+            .detail-item {
+                display: flex;
+                align-items: center;
+                justify-content: space-between;
+                height: 24px;
+                font-weight: 400;
+                font-size: 14px;
 
-            .right {
-                color: #929292;
-            }
+                .right {
+                    color: #929292;
+                }
 
-            .blue {
-                color: #1D9BF0 !important;
-            }
+                .token {
+                    color: #1d9bf0 !important;
+                    cursor: pointer;
+                }
 
-            .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>

+ 66 - 28
src/view/popup/tabbar-page/nft/index.vue

@@ -1,46 +1,83 @@
 <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";
 
-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'
+import {nftListMine} from "@/http/nft.js";
+
+let listData = ref([]);
+
+let NFTReqParams = {
+  params: {
+    pageNum: 1,
+    pageSize: 30,
   },
-])
+  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 +111,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;
                 }
             }
         }

部分文件因为文件数量过多而无法显示