nieyuge 2 år sedan
förälder
incheckning
f58e1047d0

+ 8 - 0
src/http/nft.js

@@ -71,4 +71,12 @@ export function getTwitterNftGroupInfo(params) {
         method: 'post',
         data: params
     })
+}
+
+export function transferRequest(params) {
+    return service({
+        url: `/nft/transfer/request`,
+        method: 'post',
+        data: params
+    })
 }

+ 6 - 1
src/router/popup.js

@@ -7,7 +7,7 @@ import Message from '@/view/popup/tabbar-page/message/index.vue'
 import More from '@/view/popup/tabbar-page/more/index.vue'
 
 import NFTDetail  from '@/view/popup/tabbar-page/nft/detail.vue'
-
+import NFTTransfer from '@/view/popup/tabbar-page/nft/transfer.vue'
 import Withdraw from '@/view/popup/withdraw/index.vue'
 import WithdrawInfo from '@/view/popup/withdraw/info.vue'
 import WithdrawConfirm from '@/view/popup/withdraw/confirm.vue'
@@ -120,6 +120,11 @@ const routes = [
         name: 'NFTDetail',
         component: NFTDetail
     },
+    {
+        path: '/NFTTransfer',
+        name: 'NFTTransfer',
+        component: NFTTransfer
+    },
     {
         path: '/currencyDetail',
         name: 'currencyDetail',

+ 37 - 79
src/view/popup/tabbar-page/nft/detail.vue

@@ -96,23 +96,9 @@
                 </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 class="sale" @click="transfer">
+                <span>Transfer</span>
+            </div>
         </div>
     </div>
 </template>
@@ -123,6 +109,7 @@ import router from "@/router/popup.js";
 
 import {getNFTDetail} from "@/http/nft.js";
 
+let timer = ref(null);
 let nftMetaData = ref({});
 let nftDetailData = ref({});
 
@@ -170,6 +157,28 @@ const getDetail = () => {
     })
 }
 
+const transfer = () => {
+    if (Object.keys(nftDetailData.value).length) {
+        clearTimeout(timer.value);
+        router.push({
+            name: 'NFTTransfer',
+            query: {
+                params: JSON.stringify({
+                    nftItemId: nftDetailData.value?.nftItemId,
+                    chainInfo: nftDetailData.value?.chainInfo,
+                    transferFeeCurrencyInfo: nftDetailData.value?.transferFeeCurrencyInfo,
+                    transferFeeAmountValue: nftDetailData.value?.transferFeeAmountValue,
+                })
+            }
+        })
+    } else {
+        clearTimeout(timer.value);
+        timer.value = setTimeout(() => {
+            transfer()
+        }, 300)
+    }
+}
+
 onMounted(() => {
     let {params = '{}'} = router.currentRoute.value.query;
     NFTInfo.value = JSON.parse(params);
@@ -352,73 +361,22 @@ onMounted(() => {
         background: #ffffff;
         box-shadow: inset 0px 1px 0px #ececec;
         height: 70px;
-        padding: 15px 16px;
+        padding: 0 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;
-                font-weight: 500;
-                font-size: 16px;
-                color: #1d9bf0;
-                display: flex;
-                align-items: center;
-                justify-content: center;
-                position: absolute;
-                right: 16px;
-                cursor: pointer;
-            }
-        }
-
-        .cancel-sale {
-            width: 100%;
-            height: 100%;
+        justify-content: right;
+        .sale {
             display: flex;
             align-items: center;
-            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;
-            }
+            justify-content: center;
+            cursor: pointer;
+            width: 97px;
+            height: 37px;
+            font-size: 14px;
+            color: #1D9BF0;
+            border-radius: 20px;
+            border: 1px solid #1D9BF0;
         }
     }
 }

+ 275 - 0
src/view/popup/tabbar-page/nft/transfer.vue

@@ -0,0 +1,275 @@
+<template>
+    <div class="info">
+        <v-head
+            :title="'Transfer'"
+            :show_more="true"
+            :transactionsRouterParams="{
+                backUrl: 'back'
+            }">
+        </v-head>
+        <template v-if="!isSuccess">
+            <div class="content">
+                <div class="token">
+                    <div class="title">Network</div>
+                    <div class="box">
+                        <img :src="transChainInfo?.iconPath" alt="" />
+                        <span>{{ transChainInfo?.chainName }}</span>
+                    </div>
+                </div>
+                <div class="token">
+                    <div class="title">Address</div>
+                    <div class="box">
+                        <input type="text" v-model="address" placeholder="Click to enter" />
+                    </div>
+                </div>
+            </div>
+            <div class="footer">
+                <div class="left">
+                    <div class="txt">Network fee</div>
+                    <zoom fontSize="15" width="160" v-if="feeCurrencyInfo?.currencyCode"><span class="money">{{feeAmountValue || 0}} {{ feeCurrencyInfo?.tokenSymbol }}</span></zoom>
+                    <div class="tips" v-if="showTips">Insufficient balance</div>
+                </div>
+                <div class="right">
+                    <div class="btn enter" @click="next" v-if="isNext">Confirm</div>
+                    <div class="btn" v-else>Confirm</div>
+                </div>
+            </div>
+        </template>
+        <template v-else>
+            <div class="withdraw-status">
+                <img :src="require('@/assets/svg/icon-withdraw-status.svg')" alt="" />
+                <div>
+                    <div class="title">Submitted successfully</div>
+                    <div class="desc">
+                        Please check the status at the Transfer exit
+                    </div>
+                </div>
+            </div>
+            <div class="confirm-btn" @click="doneHandle">Done</div>
+        </template>
+    </div>
+</template>
+
+<script setup>
+import { ref, onMounted, watchEffect } from 'vue'
+import { message } from 'ant-design-vue';
+import { getCurrencyInfoByCode } from '@/http/publishApi'
+import { transferRequest } from '@/http/nft'
+import router from "@/router/popup.js";
+import VHead from '@/view/popup/components/head.vue'
+import Zoom from '@/view/components/component-zoom.vue'
+
+const isNext = ref(false)
+const isSuccess = ref(false)
+const isPayment = ref(false)
+const showTips = ref(false)
+const transChainInfo = ref({})
+const feeAmountValue = ref(0)
+const feeCurrencyInfo = ref({})
+const address = ref('')
+const nftId = ref('')
+
+const getCurrentyInfo = (data) => {
+    getCurrencyInfoByCode({
+        params: {
+            currencyCode: data?.currencyCode
+        }
+    }).then(res => {
+        let { code, data } = res;
+        if (code === 0) {
+            isPayment.value = data?.balance >= feeAmountValue.value
+            showTips.value = data?.balance < feeAmountValue.value
+        }
+    })
+}
+
+const next = () => {
+    transferRequest({
+        params: {
+            nftItemId: nftId.value,
+            receiveAddress: address.value
+        }
+    }).then(res => {
+        let { code } = res;
+        if (code === 0) {
+            isSuccess.value = true;
+        } else {
+            message.error(`try again later`);
+        }
+    })
+}
+
+const doneHandle = () => {
+    router.push({ name: 'NFT' })
+}
+
+watchEffect(() => {
+    isNext.value = address.value !== '' && isPayment.value
+})
+
+onMounted(() => {
+    let { params = '{}' } = router.currentRoute.value.query;
+    let { chainInfo, nftItemId, transferFeeAmountValue, transferFeeCurrencyInfo } = JSON.parse(params);
+    // set
+    nftId.value = nftItemId;
+    transChainInfo.value = chainInfo
+    feeAmountValue.value = transferFeeAmountValue
+    feeCurrencyInfo.value = transferFeeCurrencyInfo
+
+    getCurrentyInfo(feeCurrencyInfo.value)
+})
+</script>
+
+<style lang="scss" scoped>
+.info {
+    position: relative;
+    height: 100%;
+    .content {
+        height: calc(100% - 48px - 80px);
+        overflow: auto;
+        padding: 13px 16px 0 13px;
+        .token {
+            margin-bottom: 20px;
+            .title {
+                font-weight: 500;
+                font-size: 12px;
+                margin-bottom: 6px;
+                color: #8B8B8B;
+            }
+            .box {
+                border: 1px solid #DBDBDB;
+                border-radius: 8px;
+                height: 44px;
+                display: flex;
+                align-items: center;
+                padding: 0 15px 0 10px;
+                display: flex;
+                flex-wrap: nowrap;
+                justify-content: space-between;
+                img {
+                    width: 20px;
+                    height: 20px;
+                }
+                .up {
+                    width: 13px;
+                    height: 12px;
+                    cursor: pointer;
+                }
+                input {
+                    outline: none;
+                    border: 0;
+                    flex: 1;
+                    height: 18px;
+                    padding: 0 6px;
+                    font-weight: 500;
+                    font-size: 15px;
+                    &::placeholder {
+                        color: #B8B8B8;
+                    }
+                }
+                input::-webkit-outer-spin-button,
+                input::-webkit-inner-spin-button {
+                    -webkit-appearance: none;
+                }
+                input[type='number'] {
+                    -moz-appearance: textfield;
+                }
+                span {
+                    flex: 1;
+                    margin-left: 6px;
+                    font-size: 14px;
+                    font-weight: 500;
+                }
+            }
+        }
+    }
+    .footer {
+        z-index: 11;
+        background: #fff;
+        border-top: 1px solid #DBDBDB;
+        bottom: 0;
+        height: 80px;
+        display: flex;
+        position: absolute;
+        justify-content: space-between;
+        width: 100%;
+        bottom: 0;
+        align-items: center;
+        .left {
+            margin-left: 16px;
+
+            .txt {
+                color: #9D9D9D;
+                font-weight: 400;
+                font-size: 12px;
+            }
+
+            .money {
+                color: #000000;
+            }
+
+            .tips {
+                color: #FF0000;
+                font-weight: 500;
+                font-size: 12px;
+            }
+        }
+
+        .right {
+            margin-right: 16px;
+            .btn {
+                cursor: pointer;
+                width: 140px;
+                height: 46px;
+                line-height: 46px;
+                text-align: center;
+                font-weight: 600;
+                font-size: 18px;
+                color: #FFFFFF;
+                background: #D2D2D2;
+                border-radius: 100px;
+            }
+            .enter {
+                background: #1D9BF0;
+            }
+        }
+    }
+}
+
+.withdraw-status {
+    text-align: center;
+    img {
+        margin-top: 40px;
+        margin-bottom: 34px;
+    }
+    .title {
+        font-weight: 500;
+        font-size: 20px;
+        margin-bottom: 10px;
+    }
+    .desc {
+        font-size: 15px;
+        color: rgba($color: #000000, $alpha: 0.5);
+    }
+}
+
+.confirm-btn {
+    width: 335px;
+    height: 60px;
+    text-align: center;
+    line-height: 60px;
+    border-radius: 100px;
+    background: #1D9BF0;
+    font-weight: 600;
+    font-size: 18px;
+    color: #fff;
+    position: absolute;
+    left: 50%;
+    bottom: 35px;
+    transform: translateX(-50%);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    cursor: pointer;
+}
+</style>