335 lines
8.7 KiB
Vue
335 lines
8.7 KiB
Vue
<template>
|
|
<div class="cards">
|
|
<div class="card-top" v-if="nftData">
|
|
<div class="card-img" @click="toDetail">
|
|
<ImgCard :nftData="nftData" />
|
|
<!-- <LazyLoadImg :src="nftData.image" :src-placeholder="placeholderImg" alt="图片"/> -->
|
|
</div>
|
|
<div class="card-name">
|
|
<div>
|
|
<span v-if="nftData.type == 1">GENESIS HERO</span>
|
|
</div>
|
|
<div class="no-sell" v-show="nftData.on_sale == 1" @click="cancelNft(nftData)">
|
|
<img src="@/assets/img/marketplace/On_SeLL.png" alt="">
|
|
</div>
|
|
</div>
|
|
<div class="card-price">
|
|
<div class="sell-price">
|
|
<div v-show="nftData.on_sale == 1">
|
|
<span>
|
|
{{ nftPrice }}
|
|
<!-- {{cardPrice(nftData)}} -->
|
|
</span>
|
|
<img :src="icon" alt="">
|
|
</div>
|
|
</div>
|
|
<div v-if="nftData.type == 11 && nftData.on_sale == 0" class="enabled" @click="lockToGame('redeem')">
|
|
Redeem
|
|
</div>
|
|
<div v-if="nftData.type == 1 && nftData.on_sale == 0" class="link-below" @click="lockToGame('convert')">
|
|
Convert
|
|
</div>
|
|
<!-- <div>{{ nftData.owner_address.substr(0,6) }}...{{ nftData.owner_address.substr(-6) }}</div> -->
|
|
</div>
|
|
</div>
|
|
<div class="card-btn">
|
|
<div class="card-sell" v-if="nftData.on_sale == 0" @click="sellNft(nftData)">List</div>
|
|
<div class="card-cancel" v-if="nftData.on_sale == 1" @click="cancelNft(nftData)">Cancel listing</div>
|
|
</div>
|
|
<SellDialog :sellDialogVisible="sellDialogVisible" :floorPrice="floorPrice" :sellDataArr="sellDataArr" @handleClose="sellHandleClose" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, toRaw, onMounted, getCurrentInstance, inject } from "vue"
|
|
const message = inject('$message')
|
|
import SellDialog from "@/components/Dialogs/sellDialog.vue"
|
|
import { apiGetPrice, nftDetail } from "@/utils/marketplace"
|
|
import ImgCard from "@/components/common/imgCard.vue"
|
|
import { priceCalculated } from "@/configs/priceCalculate"
|
|
import LazyLoadImg from "@/components/lazyloadimg"
|
|
import placeholderImg from '@/assets/img/marketplace/GenesisHeroes_NFT.png'
|
|
import {createModal} from "@/utils/model.util";
|
|
import ConfirmDialog from "@/components/Dialogs/confirmDialog.vue"
|
|
import { timeFormat } from "@/configs/priceCalculate"
|
|
const emit = defineEmits(['renewMyNft'])
|
|
import {formatPrice} from "@/components/chain/utils"
|
|
|
|
import { useRouter } from "vue-router";
|
|
import { BlockChain } from "@/components/chain/BlockChain"
|
|
const router = useRouter();
|
|
const { proxy } = getCurrentInstance();
|
|
const props = defineProps({
|
|
nftData: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
});
|
|
|
|
// 获取地板价
|
|
const floorPrice = ref('0')
|
|
const getFloorPrice = async (val) => {
|
|
const data = {
|
|
net_id: val.net_id,
|
|
contract_address: val.contract_address,
|
|
item_id: val.item_id,
|
|
quality: val.detail.quality,
|
|
}
|
|
let res = await apiGetPrice(data)
|
|
if(res.lowest_price_goods) {
|
|
floorPrice.value = res.lowest_price_goods.event.data.buy[0].amount
|
|
} else {
|
|
floorPrice.value = '0'
|
|
}
|
|
return floorPrice.value
|
|
}
|
|
|
|
// 获取nft信息
|
|
const getNftData = async (val) => {
|
|
let nftDetailData = {}
|
|
const { errcode, errmsg, data } = await nftDetail(toRaw(val).contract_address,toRaw(val).token_id)
|
|
if(errcode == 0) {
|
|
nftDetailData = data
|
|
} else {
|
|
// alert('0000')
|
|
}
|
|
return nftDetailData
|
|
}
|
|
|
|
const sellDialogVisible = ref(false)
|
|
const sellDataArr = ref([])
|
|
// 出售NFT
|
|
const sellNft = async (val) => {
|
|
sellDataArr.value = val
|
|
floorPrice.value = await getFloorPrice(val)
|
|
sellDialogVisible.value = true
|
|
}
|
|
|
|
// 取消出售
|
|
const cancelNft = async (val) => {
|
|
let orderIds = await getNftData(val)
|
|
try {
|
|
const bc = new BlockChain()
|
|
let res = await bc.market.cancelOrder([orderIds.event.data.id])
|
|
if(res.result) {
|
|
let timer = setTimeout(() => {
|
|
message.success('Your item has been unlisted.')
|
|
emit('renewMyNft')
|
|
clearTimeout(timer);
|
|
}, 2000);
|
|
}
|
|
} catch (e) {
|
|
message.error('Your item has failed to be unlisted.')
|
|
}
|
|
}
|
|
|
|
// 下链使用
|
|
const lockToGame = async(type) => {
|
|
if(type == 'redeem') {
|
|
const confirmResult = await createModal(ConfirmDialog, {
|
|
title: '',
|
|
message: `Redeem ${props.nftData.detail.gold_coins} Gold to your game account. Do you wish to proceed?`
|
|
}).show()
|
|
if (confirmResult.errcode == 0) {
|
|
lockToGameConfirm()
|
|
}
|
|
} else if(type == 'convert') {
|
|
const confirmResult = await createModal(ConfirmDialog, {
|
|
title: '',
|
|
message: 'After converting, you will be able to use the hero in the game. At the end of Season 1, the hero will automatically be returned to your wallet or Immutable Passport. Do you want to proceed?'
|
|
}).show()
|
|
if (confirmResult.errcode == 0) {
|
|
lockToGameConfirm()
|
|
}
|
|
}
|
|
}
|
|
const lockToGameConfirm = async () => {
|
|
try {
|
|
const bc = new BlockChain()
|
|
let res = await bc.locker.lock(toRaw(props.nftData).contract_address, [toRaw(props.nftData).token_id])
|
|
// console.log('lockToGame success', res)
|
|
message.success('lockToGame success')
|
|
// router.go(-1)
|
|
emit('renewMyNft')
|
|
// router.push('/assets')
|
|
} catch (e) {
|
|
message.error('lockToGame fail.')
|
|
}
|
|
}
|
|
|
|
|
|
// 获取出售中价格价格
|
|
const nftPrice = ref('-')
|
|
const icon = ref('')
|
|
const cardPrice = async (val) => {
|
|
let nftData = await getNftData(toRaw(val))
|
|
// console.log(nftData)
|
|
if (nftData?.event?.data) {
|
|
const data = formatPrice(nftData?.event?.data)
|
|
icon.value = data.icon
|
|
nftPrice.value = data.tokenAmount
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// 去详情页面
|
|
const toDetail = () => {
|
|
router.push(`/detail/${props.nftData.contract_address}/${props.nftData.token_id}`)
|
|
}
|
|
|
|
// 关闭弹窗
|
|
const sellHandleClose = (val) => {
|
|
sellDialogVisible.value = false
|
|
sellDataArr.value = []
|
|
if(val) {
|
|
let timer = setTimeout(() => {
|
|
emit('renewMyNft')
|
|
clearTimeout(timer);
|
|
}, 2000);
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
cardPrice(toRaw(props.nftData))
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.cards {
|
|
background: #2d2738;
|
|
border-radius: 20px;
|
|
color: #fff;
|
|
// padding: 20px;
|
|
overflow: hidden;
|
|
.card-top {
|
|
padding: 30px 30px 20px 30px;
|
|
box-sizing: border-box;
|
|
.card-img {
|
|
width: 240px;
|
|
height: 360px;
|
|
margin: 0 auto;
|
|
:deep(.card-img-common) {
|
|
li {
|
|
width: 100%;
|
|
height: 100%;
|
|
.img-top {
|
|
width: 100px;
|
|
height: 30px;
|
|
top: 20px;
|
|
left: 20px;
|
|
}
|
|
.img-btm {
|
|
bottom: 12px;
|
|
left: 20px;
|
|
>div {
|
|
width: 80px;
|
|
height: 30px;
|
|
}
|
|
div:nth-child(1) {
|
|
}
|
|
div:nth-child(2) {
|
|
margin-left: 8px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.card-name {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
height: 46px;
|
|
margin: 20px 0;
|
|
font-family: 'Poppins';
|
|
font-weight: 600;
|
|
font-size: 20px;
|
|
box-sizing: border-box;
|
|
color: #F3F0FF;
|
|
.no-sell {
|
|
width: 138px;
|
|
height: 46px;
|
|
img {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
}
|
|
}
|
|
.card-price {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
>div {
|
|
display: flex;
|
|
// justify-content: center;
|
|
align-items: center;
|
|
width: 94px;
|
|
height: 44px;
|
|
font-family: 'Poppins';
|
|
font-weight: 400;
|
|
font-size: 14px;
|
|
border-radius: 10px;
|
|
}
|
|
.sell-price {
|
|
div {
|
|
display: flex;
|
|
text-align: left;
|
|
}
|
|
img {
|
|
width: 25px;
|
|
height: 25px;
|
|
margin-left: 10px;
|
|
}
|
|
}
|
|
.enabled {
|
|
justify-content: center;
|
|
border: 2px solid #ffd45f;
|
|
color: #FEC25D;
|
|
}
|
|
.link-below {
|
|
justify-content: center;
|
|
color: #FF6271;
|
|
border: 2px solid #ff6978;
|
|
}
|
|
}
|
|
}
|
|
.card-btn {
|
|
width: 95%;
|
|
height: 50px;
|
|
margin: 0 auto;
|
|
margin-bottom: 5px;
|
|
border-radius: 10px;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
padding-bottom: 8px;
|
|
>div {
|
|
height: 57px;
|
|
background: #1778f1;
|
|
border-radius: 12px;
|
|
text-align: center;
|
|
}
|
|
.card-sell, .card-cancel {
|
|
width: 100%;
|
|
line-height: 57px;
|
|
color: #fff;
|
|
font-weight: 700;
|
|
font-size: 28px;
|
|
}
|
|
.card-cancel {
|
|
background: #ff6271;
|
|
}
|
|
.card-cat {
|
|
width: 71px;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
margin-left: 3px;
|
|
img {
|
|
width: 43px;
|
|
height: 39px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style> |