Browse Source

[add][buy]

zhangwei 2 years ago
parent
commit
e4a1f915ff

+ 6 - 0
src/assets/svg/icon-loading-while.svg

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="margin: auto; background: rgb(255, 255, 255,0); display: block; shape-rendering: auto;" width="200px" height="200px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
+<circle cx="50" cy="50" fill="none" stroke="#fff" stroke-width="12" r="35" stroke-dasharray="164.93361431346415 56.97787143782138">
+  <animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="1s" values="0 50 50;360 50 50" keyTimes="0;1"></animateTransform>
+</circle>
+<!-- [ldio] generated by https://loading.io/ --></svg>

+ 2 - 2
src/http/nft.js

@@ -2,9 +2,9 @@
 
 import { service } from "./request";
 
-export function getNftProjectInfo(params) {
+export function getNftMysteryBoxSaleInfo(params) {
     return service({
-        url: `/nft/project/getNftProjectInfo`,
+        url: `/nft/project/getNftMysteryBoxSaleInfo`,
         method: 'post',
         data: params
     })

+ 7 - 0
src/http/pay.js

@@ -33,5 +33,12 @@ export function getTokenRechargeAddress(params) {
     });
 }
 
+export function payNftMysteryBoxWithBalance(params) {
+    return service({
+        url: `/wallet/pay/payNftMysteryBoxWithBalance`,
+        method: "post",
+        data: params,
+    });
+}
 
 // ---- 提现 ----

+ 42 - 10
src/view/components/preview-balance.vue

@@ -3,22 +3,34 @@
         <img class="icon" src="@/assets/subject/icon-balance.png" />
         <div class="con">
             <div class="desc">Balance</div>
-            <div class="price">{{ currentCurrencyInfo.balance }} {{ currentCurrencyInfo.tokenSymbol }}</div>
+            <div class="price">{{ currentCurrencyInfo.balance }} {{ props.tokenSymbol }}</div>
         </div>
-        <img class="refresh" :class="{ 'icon-refresh-rotate': false }" @click="updateCurrencyBanlce"
+        <img class="refresh" :class="{ 'icon-refresh-rotate': refreshRotate }" @click="updateCurrencyBanlce"
             :src="require('@/assets/svg/icon-form-refresh.svg')" />
     </div>
 </template>
 <script setup>
-import { ref } from "vue";
+import { ref, onMounted, reactive, defineProps } from "vue";
 import { syncChainTokenRechargeRecord } from "@/http/publishApi";
+
+const props = defineProps({
+    dialogVisible: {
+        type: Object,
+        default: {},
+    },
+    currencyCode: {
+        type: String,
+        default: ''
+    }
+});
+
 /**
  * 同步链上交易
  */
 const asyncTokenRechRecord = (cb) => {
     syncChainTokenRechargeRecord({
         params: {
-            currencyCode: ''
+            currencyCode: props.currencyCode
         }
     }).then(res => {
         if (res.code == 0) {
@@ -30,7 +42,7 @@ const asyncTokenRechRecord = (cb) => {
 let refreshRotate = ref(false);
 
 // 当前选择的货币信息
-let currentCurrencyInfo = ref({
+let currentCurrencyInfo = reactive({
     currencyCode: "",
     currencyName: "",
     balance: "",
@@ -53,15 +65,28 @@ const updateCurrencyBanlce = () => {
         }, 1000)
     }
     asyncTokenRechRecord((res) => {
-        if (res.code == 0 && res.data && res.data.length) {
-            let currencyInfo = res.data[0];
-            if (currencyInfo.currencyCode == currentCurrencyInfo.value.currencyCode) {
-                currentCurrencyInfo.value.balance = currencyInfo.balance;
-            }
+        let currencyInfo = res[0];
+        if (currencyInfo.currencyCode == props.currencyCode) {
+            currentCurrencyInfo.balance = currencyInfo.balance;
         }
     })
 }
 
+
+onMounted(() => {
+    console.log(props.currencyCode)
+    if(!props.currencyCode){
+        return
+    }
+    asyncTokenRechRecord((res) => {
+        let currencyInfo = res[0];
+        if (currencyInfo.currencyCode == props.currencyCode) {
+            currentCurrencyInfo.balance = currencyInfo.balance;
+        }
+    })
+})
+
+
 </script>
 
 <style lang="scss" scoped>
@@ -100,5 +125,12 @@ const updateCurrencyBanlce = () => {
         height: 50px;
         margin-top: -5px;
     }
+
+
+}
+
+.icon-refresh-rotate {
+    transform: rotate(360deg);
+    transition-duration: 1s;
 }
 </style>

+ 162 - 34
src/view/iframe/buy-nft/buy/home.vue

@@ -7,46 +7,132 @@
         </div>
         <!-- 内容 -->
         <div class="area-content">
-            <img :src="require('@/assets/svg/icon-default.svg')" class="box" />
+            <img :src="state.data.mysteryBoxImagePath" class="box" v-show="state.data.mysteryBoxImagePath" />
+            <img :src="require('@/assets/svg/icon-default.svg')" class="box" v-show="!state.data.mysteryBoxImagePath" />
         </div>
 
         <!-- 底部 -->
         <div class="footer">
             <!-- 首页 -->
-            <div class="sold">SOLD: 107/10000 </div>
-            <div class="limit">Buy Limit: 0/5</div>
-            <!-- <btn-loading></btn-loading> -->
-            
-            <div class="buy5">
-                <div class="right">Buy 5</div>
-                <div class="left">
-                    <div class="off">20% OFF</div>
-                    <div class="usdt">40 USDT</div>
+            <div class="mark">
+                <div class="sold">SOLD: {{ state.data.itemSoldCount || 0 }}/{{ state.data.itemTotalCount || 0 }} </div>
+                <div class="limit">Buy Limit: {{ state.data.userBuyCount || 0 }}/{{ state.data.perUserBuyLimit || 0 }}
                 </div>
             </div>
-            <!-- <btn-loading></btn-loading> -->
-            <div class="buy1" @click="clickJump">
-                <div class="right">Buy 1</div>
-                <div class="left">10 USDT</div>
-            </div>
+            <!-- <div class="buy1">
+                <btn-loading :color="'while'"></btn-loading>
+            </div> -->
+            <template v-for="item in state.data.salePlans.splice(0, 2)">
+                <div class="buy5"
+                    v-show="item.itemCount == 5 && (state.data.perUserBuyLimit - state.data.userBuyCount) >= 5"
+                    @click="clickJump(item)">
+                    <div class="left">Buy {{ item.itemCount }}</div>
+                    <div class="right" v-if="(item.price.length + item.currencyCode) > 10">
+                        <div class="usdt">{{ item.price }} {{ item.currencyCode }}</div>
+                        <div class="off">{{ item.discount }} OFF</div>
+                    </div>
+                    <div class="right" v-else>
+                        <div class="usdt">
+                            <p>{{ item.price }}</p>
+                            <p>{{ item.currencyCode }}</p>
+                        </div>
+                        <div class="off">
+                            <p>{{ item.discount }} OFF</p>
+                        </div>
+                    </div>
+
+                </div>
+
+                <!-- <btn-loading></btn-loading> -->
+                <div class="buy1" @click="clickJump(item)"
+                    v-show="item.itemCount == 1 && (state.data.perUserBuyLimit - state.data.userBuyCount) >= 1">
+                    <template v-if="(item.price.length + item.currencyCode) > 30">
+                        <div class="left">Buy 1</div>
+                        <div class="right">
+                            <p>{{ item.price }}</p>
+                            <p>{{ item.currencyCode }}</p>
+                        </div>
+                    </template>
+                    <template v-else>
+                        <div class="left">Buy 1</div>
+                        <div class="right">
+                            {{ item.price }}
+                            {{ item.currencyCode }}
+                        </div>
+                    </template>
+                </div>
+                <div class="buy1 grey"
+                    v-show="item.itemCount == 1 && (state.data.perUserBuyLimit - state.data.userBuyCount) <= 0">
+                    <template v-if="(item.price.length + item.currencyCode) > 30">
+                        <div class="left">Buy 1</div>
+                        <div class="right">
+                            <p>{{ item.price }}</p>
+                            <p>{{ item.currencyCode }}</p>
+                        </div>
+                    </template>
+                    <template v-else>
+                        <div class="left">Buy 1</div>
+                        <div class="right">
+                            {{ item.price }}
+                            {{ item.currencyCode }}
+                        </div>
+                    </template>
+                </div>
+            </template>
         </div>
     </div>
 </template>
 <script setup>
 import router from "@/router/buy-nft.js";
-import { onMounted  } from "vue";
-import { getNftProjectInfo} from "@/http/nft";
+import { onMounted, reactive, inject } from "vue";
+import { getNftMysteryBoxSaleInfo } from "@/http/nft";
 import BtnLoading from '../components/btn-loading.vue'
+import { getQueryString } from "@/uilts/help";
+let pay_info = inject('pay_info');
 
-
+let state = reactive({
+    data: {
+        salePlans: [
+            {
+                currencyCode: 'BSC_TESTNET_BF_6X',
+                discount: '20$',
+                itemCount: 5,
+                price: 23,
+                salePlanId: '2'
+            },
+            {
+                currencyCode: 'BSC_TESTNET_BF_6X',
+                discount: '20$',
+                itemCount: 1,
+                price: 123,
+                salePlanId: '123'
+            }
+        ]
+    }
+})
 const clickClose = () => {
 
 }
-const clickJump = () => {
+const clickJump = (item) => {
+    pay_info.home.sale_plan = item
     router.push({ path: '/pay' });
 }
-onMounted(()=>{
-    
+onMounted(() => {
+    let nft_project_Id = getQueryString('nftProjectId') || '9b491fe0fa51499ca0fc3a78abdf0eb0'
+    getNftMysteryBoxSaleInfo({
+        params: {
+            nftProjectId: nft_project_Id
+        }
+    }).then((res) => {
+        if (res.code == 0) {
+            state.data = res.data
+            pay_info.home = res.data
+        } else {
+
+        }
+    }).catch(() => {
+
+    })
 })
 </script>
 
@@ -56,7 +142,8 @@ onMounted(()=>{
     border-radius: 25px;
     max-width: 90%;
     min-width: 800px;
-    height: 90%;
+    max-height: 90%;
+    min-height: 90%;
     z-index: 23;
     display: flex;
     flex-direction: column;
@@ -64,7 +151,7 @@ onMounted(()=>{
 
     .area-title {
         width: 100%;
-        height: 48px;
+        min-height: 48px;
         display: flex;
         align-items: center;
         border-bottom: 1px solid #D9D9D9;
@@ -85,6 +172,7 @@ onMounted(()=>{
 
     .area-content {
         flex: 1;
+        overflow-y: auto;
 
         img {
             width: 100%;
@@ -94,24 +182,29 @@ onMounted(()=>{
 
     .footer {
         border-top: 1px solid #D9D9D9;
-        height: 80px;
+        min-height: 80px;
+        padding: 15px 0;
         width: 100%;
         display: flex;
         align-items: center;
         justify-content: flex-end;
         position: relative;
-        .loading{
+
+        .loading {
             width: 24px;
         }
 
-        .sold {
+        .mark {
             position: absolute;
             left: 20px;
-        }
+            .sold {
+                
+            }
 
-        .limit {
-            color: #AF934E;
-            margin-right: 25px;
+            .limit {
+                color: #AF934E;
+                margin-right: 25px;
+            }
         }
 
         .buy5 {
@@ -119,17 +212,32 @@ onMounted(()=>{
             background: rgba(29, 155, 240, 0.01);
             border-radius: 100px;
             color: #1D9BF0;
-            width: 217px;
+            min-width: 217px;
             height: 50px;
             display: flex;
             justify-content: space-between;
             align-items: center;
             padding: 0 15px 0 20px;
             font-weight: 700;
-            font-size: 18px;
+            font-size: 14px;
             cursor: pointer;
             margin-right: 12px;
 
+            .left {
+                margin-right: 20px;
+            }
+
+            .right {
+                text-align: right;
+
+                p {
+                    margin: 0;
+                    padding: 0;
+                    line-height: 17px;
+                }
+            }
+
+
             .off {
                 color: #AF934E;
                 font-weight: 700;
@@ -151,15 +259,35 @@ onMounted(()=>{
             background: #1D9BF0;
             color: #fff;
             border-radius: 100px;
-            width: 217px;
+            min-width: 217px;
             height: 50px;
             display: flex;
             align-items: center;
-            font-size: 18px;
+            font-size: 14px;
             font-weight: 700;
             justify-content: space-between;
             padding: 0 15px 0 20px;
             margin-right: 25px;
+
+            .left {
+                margin-right: 20px;
+            }
+
+            .right {
+                text-align: right;
+
+                p {
+                    margin: 0;
+                    padding: 0;
+                    line-height: 17px;
+                }
+            }
+
+        }
+
+        .grey {
+            background: #CDCDCD;
+            cursor: auto;
         }
     }
 }

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

@@ -4,27 +4,21 @@
         <img :src="require('@/assets/gif/box.gif')" class="box" v-show="state.box.show" />
         <div class="nft" v-for="item in state.nft.data" v-show="item.show">
             <div class="detail">
-                <img :src="require('@/assets/img/img-box5.png')" alt="" />
+                <img :src="item.imagePath" alt="" />
             </div>
-            <p>Azuki #6346</p>
+            <p>{{item.nftItemName}}</p>
         </div>
     </div>
 </template>
 <script setup>
-import { reactive, onMounted } from 'vue'
+import { reactive, onMounted, inject } from 'vue'
+let pay_info = inject('pay_info');
 let state = reactive({
     box: {
         show: true
     },
     nft: {
-        data: [
-            {
-                show: false
-            },
-            {
-                show: false
-            }
-        ]
+        data: []
     }
 })
 
@@ -55,11 +49,11 @@ const showNFTs = () => {
 }
 
 onMounted(() => {
+    state.nft.data = pay_info.buy_items || []
     setTimeout(() => {
         state.box.show = false
         showNFTs()
     }, 2000)
-
 })
 </script>
 <style lang="scss" scoped>

+ 88 - 29
src/view/iframe/buy-nft/buy/pay.vue

@@ -8,12 +8,15 @@
         <!-- 内容 -->
         <div class="area-content">
             <div class="left">
-                <img :src="require('@/assets/img/img-box5.png')" alt="">
+                <img :src="require('@/assets/img/img-box5.png')" v-show="pay_info.home.sale_plan.itemCount == 5"
+                    alt="" />
+                <img :src="require('@/assets/img/img-box1.png')" v-show="pay_info.home.sale_plan.itemCount == 1"
+                    alt="" />
                 <div class="tip">
-                    <span>Mystery box*1</span>
+                    <span>Mystery box*{{ pay_info.home.sale_plan.itemCount }}</span>
                     <span>
-                        <img src="" alt="">
-                        10
+                        <img :src="pay_info.home.sale_plan.currencyInfo.iconPath" alt="">
+                        {{ pay_info.home.sale_plan.price }}
                     </span>
                 </div>
             </div>
@@ -23,66 +26,113 @@
                         <img class="img" :src="require('@/assets/subject/top-01.svg')" />
                         <div class="font">Deposit to Send Giveaway</div>
                     </div>
-                    <top-up2 :asyncIng="false" :currentCurrencyInfo="{}" @topUpDone="topUpDone">
+                    <top-up2 v-if="tempCurrentCurrencyInfo.currencyCode" :asyncIng="asyncIng"
+                        :currentCurrencyInfo="tempCurrentCurrencyInfo" @topUpDone="topUpDone">
                     </top-up2>
 
                     <div class="card-title">
                         <img class="img" :src="require('@/assets/subject/top-02.svg')" />
                         <div class="font">Wait for the amount to arrive</div>
                     </div>
-                    <preview-balance></preview-balance>
+                    <preview-balance v-if="tempCurrentCurrencyInfo.currencyCode"
+                        :currencyCode="tempCurrentCurrencyInfo.currencyCode"></preview-balance>
                 </div>
             </div>
         </div>
 
         <!-- 底部 -->
         <div class="footer">
-            <!-- <btn-loading></btn-loading> -->
-            <div class="pay" @click="clickPlay">Pay 10 USDT</div>
+            <div class="pay" v-show="state.loading.show">
+                <btn-loading :color="'while'"></btn-loading>
+            </div>
+            <div class="pay" v-show="!state.loading.show" @click="clickPlay">Pay {{ pay_info.home.sale_plan.price }}
+                {{ pay_info.home.sale_plan.currencyCode }}</div>
         </div>
     </div>
 </template>
 <script setup >
 import router from "@/router/buy-nft.js";
-import { ref } from 'vue'
+import { ref, onMounted, inject, reactive } from 'vue'
 import topUp2 from "@/view/iframe/publish/components/top-up2.vue";
+import { getCurrencyInfoByCode } from "@/http/publishApi";
 import PreviewBalance from "@/view/components/preview-balance.vue";
 import BtnLoading from '../components/btn-loading.vue'
-let currentCurrencyInfo = ref({
+import { payNftMysteryBoxWithBalance } from "@/http/pay";
+import { getChromeStorage } from "@/uilts/chromeExtension"
+let pay_info = inject('pay_info');
+let state = reactive({
+    loading: {
+        show: false
+    }
+})
+
+let currentCurrencyInfo = reactive({
     currencyCode: "",
     currencyName: "",
     balance: "",
-    currencyType: "",
-    iconPath: "",
-    minAmount: "",
-    tokenChain: "",
-    tokenSymbol: "",
-    usdEstimateBalance: ""
 });
 
 const clickBack = () => {
     router.back()
 }
 const clickPlay = () => {
-    router.push({ path: '/open_box' });
+    state.loading.show = true
+    payNftMysteryBoxWithBalance({
+        params: {
+            nftProjectId: pay_info.home.nftProjectId,
+            salePlanId: pay_info.home.sale_plan.salePlanId
+        }
+    }).then((res) => {
+        state.loading.show = false
+        if (res.code == 0) {
+            pay_info.buy_items = res.data.buyItems
+            router.push({ path: '/open_box' });
+        } else {
+
+        }
+    }).catch(() => {
+        state.loading.show = false
+
+    })
 }
+// 余额是否同步中
+let asyncIng = ref(false);
 
 // 刷新按钮旋转
 let refreshRotate = ref(false);
 
-/**
- * 同步链上交易
- */
-const asyncTokenRechRecord = (cb) => {
-    syncChainTokenRechargeRecord({
-        params: {
-            currencyCode: currentCurrencyInfo.value.currencyCode
-        }
-    }).then(res => {
-        cb && cb(res)
-    })
+//临时货币信息
+let tempCurrentCurrencyInfo = ref({});
+
+
+const getLocalCurrencyInfoByCode = () => {
+    if (!currentCurrencyInfo.currencyCode) {
+        getCurrencyInfo();
+    }
 }
+const getCurrencyInfo = async () => {
+    let { accessToken = '' } = await getChromeStorage('userInfo') || {};
+    if (accessToken) {
+        getCurrencyInfoByCode({
+            params: {
+                currencyCode: currentCurrencyInfo.currencyCode
+            }
+        }).then(res => {
+            if (res.code == 0 && res.data) {
+                currentCurrencyInfo = res.data;
+                tempCurrentCurrencyInfo.value = res.data;
+            }
+        });
 
+    }
+}
+
+
+onMounted(() => {
+    currentCurrencyInfo.currencyCode = pay_info.home.sale_plan.currencyCode
+    console.log(pay_info.home)
+    getCurrencyInfo()
+})
 
 
 </script>
@@ -122,6 +172,7 @@ const asyncTokenRechRecord = (cb) => {
     .area-content {
         display: flex;
         overflow-y: auto;
+        flex:1;
 
         .left {
             width: 400px;
@@ -130,9 +181,13 @@ const asyncTokenRechRecord = (cb) => {
             img {
                 max-width: 400px;
                 max-height: 400px;
-                width:100%;
+                width: 100%;
                 height: auto;
             }
+            p{
+                margin: 0;
+                padding:0;
+            }
 
             .tip {
                 margin-top: 15px;
@@ -207,6 +262,10 @@ const asyncTokenRechRecord = (cb) => {
         text-align: center;
         line-height: 50px;
         cursor: pointer;
+        p{
+                margin: 0;
+                padding:0;
+            }
     }
 
     .footer {

+ 3 - 2
src/view/iframe/buy-nft/components/btn-loading.vue

@@ -1,12 +1,13 @@
 <template>
     <div class="btn-loading">
-        <img :src="require('@/assets/svg/icon-loading.svg')" class="loading" />        
+        <img :src="require('@/assets/svg/icon-loading.svg')" class="loading" v-if="props.color == 'blue'"/>
+        <img :src="require('@/assets/svg/icon-loading-while.svg')" class="loading" v-else-if="props.color == 'while'"/>
     </div>
 </template>
 <script setup>
 import {  defineProps } from 'vue'
 const props = defineProps({
-    border_color: {
+    color: {
         type: String,
         default: 'blue',
     },

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

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