CounterFireGames/src/views/DetailView.vue
CounterFire2023 715ec01110 bug fix
2024-06-25 13:07:40 +08:00

428 lines
12 KiB
Vue

<template>
<div class="detail">
<div class="detail-bg"></div>
<div v-if="detailData" class="detail-content">
<div class="content">
<div class="top-left">
<div class="top-left-img">
<img src="@/assets/img/marketplace/GenesisHeroes_NFT.png" alt="">
</div>
</div>
<div class="top-right">
<h2>Item name</h2>
<div class="top-right-owner">
<div>Owner:</div>
<div class="address">{{ sliceAddress(detailData.owner_address) }}</div>
</div>
<div class="top-right-price" v-if="detailData.event">
<li>
<div>Price</div>
<div class="time">
<img src="@/assets/img/marketplace/time.png" alt="图片">
<div>Time remaining: &nbsp;<StarTimer :getAddress="detailData.event.data.end_at" /></div>
</div>
</li>
<li>
<div class="price">
<span class="bold">{{ priceWei(detailData.event.data.buy[0].amount) }}&nbsp;</span>
<img src="@/assets/img/marketplace/ETHicon.png" alt="ICON">
<span>( $ 37.64 )</span>
</div>
</li>
</div>
<div class="top-right-btns">
<!--
1、添加购物车
2、移除购物车
3、购买
4、
-->
<div v-if="myAddress != detailData.owner_address && detailData.event">
<div class="buy" @click="buyNow">Buy Now</div>
<div class="add">
<span>Add to cart </span>
<div>
<img src="@/assets/img/marketplace/Add shopping cart.png" alt="">
</div>
</div>
<div class="remove" v-if="!myAddress">
<span>Remove from cart</span>
<div>
<img src="@/assets/img/marketplace/Move out.png" alt="">
</div>
</div>
</div>
<!--
1、上架
2、下架
3、使用
-->
<div v-else>
<div class="sell" v-if="!detailData.event">上架</div>
<div class="cancel" v-if="detailData.event">下架</div>
<div class="redeem" @click="lockToGame">使用</div>
</div>
</div>
<div class="info">
<h2>Info</h2>
<li>
<div>Contract address</div>
<div>{{ sliceAddress(detailData.contract_address) }}</div>
</li>
<li>
<div>Token ID</div>
<div>{{ detailData.token_id }}</div>
</li>
<li>
<div>Blockchain</div>
<div>Arbitrum</div>
</li>
<li>
<div>Metadata</div>
<div><a :href="detailData.meta_url" target="_blank">{{ sliceAddress(detailData.meta_url) }}</a></div>
</li>
<li>
<div>Royalties</div>
<div>2%</div>
</li>
</div>
</div>
</div>
<div class="content">
<div class="btm-left">
<h2>Property</h2>
<div class="btm-detail">
<li v-for="(item, val, index) in nftAbilities" :key="index">
<div v-show="val == 'quality'">
<h5>Tier</h5>
<p>{{ item }}</p>
</div>
<div v-show="val == 'max_mining_days'">
<h5>Active Days</h5>
<p>{{ item }}</p>
</div>
<div v-show="val == 'wealth'">
<h5>Wealth Value</h5>
<p>{{ parseInt(item) }}</p>
</div>
<div v-show="val == 'lucky'">
<h5>Luck Value</h5>
<p>{{ parseInt(item) }}</p>
</div>
<div v-show="val == 'hp'">
<h5>HP</h5>
<p>{{ parseInt(item) }}</p>
</div>
<div v-show="val == 'atk'">
<h5>Attack</h5>
<p>{{ parseInt(item) }}</p>
</div>
<div v-show="val == 'def'">
<h5>Defense</h5>
<p>{{ Number(item).toFixed(2) }}%</p>
</div>
<div v-show="val == 'block'">
<h5>Block Rate</h5>
<p>{{ Number(item).toFixed(2) }}%</p>
</div>
<div v-show="val == 'crit'">
<h5>Crit Rate</h5>
<p>{{ Number(item).toFixed(2) }}%</p>
</div>
</li>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, toRaw, onMounted } from "vue"
import { useRouter } from "vue-router";
import StarTimer from "@/components/common/starTimer.vue"
import { apiDetail } from "@/utils/marketplace"
import { BlockChain } from "@/components/chain/BlockChain"
import {walletStore} from "@/store/wallet";
const router = useRouter();
const localWalletStore = walletStore()
const detailData = window.history.state.nftData
console.log(detailData)
const myAddress = localWalletStore.address
const nftAbilities = ref(detailData.detail)
// 购买
const buyNow = async () => {
let tokenIds = [detailData.event.data.id]
try {
await new BlockChain().market.batchBuy(tokenIds)
console.log('buy success')
} catch (e) {
console.log('buy fail', e.message)
}
}
const lockToGame = async() => {
try {
await new BlockChain().locker.lock(detailData.contract_address, [detailData.token_id])
console.log('lockToGame success')
router.go(-1)
} catch (e) {
console.log('lockToGame fail', e.message)
}
}
// 处理地址
const sliceAddress = (address) => {
if (!address) return "-";
if (address.length >= 10) {
return `${address.substring(0, 6)}......${address.slice(-4)}`;
}
return address;
}
// 处理货币
const priceWei = (price) => {
let toPrice = parseInt(BigInt(price))/1e18
return priceFixed(toPrice)
}
const priceFixed = (num) => {
if(isNaN(num)){return num};
//处理不需要转换的数字
var str = ''+num;
if(!/e/i.test(str)){return num;};
//先获取到精确的小数位
var fixed = (''+num).match(/\d+$/)[0];
//拿到保留指定的小数
return new Number(num).toFixed(fixed);
}
const getDetail = async () => {
let address = localStorage.getItem('address')
let res = await apiDetail(address)
console.log('getDetail',toRaw(res))
nftData.value = res.rows
}
onMounted(() => {
// getDetail()
})
</script>
<style lang="scss" scoped>
.detail {
width: 100%;
box-sizing: border-box;
background: url('@/assets/img/marketplace/BG01.jpg') no-repeat;
background-size: 100% 100%;
.detail-bg {
width: 100%;
height: 84px;
}
.detail-content {
width: 100%;
height: 100%;
.content {
width: 1266px;
margin: 0 auto;
padding-top: 76px;
display: flex;
justify-content: space-between;
color: #fff;
.top-left {
width: 453px;
.top-left-img {
height: 678px;
img {
width: 100%;
height: 100%;
}
}
}
.top-right {
width: 719px;
h2 {
font-size: 42px;
font-family: 'Poppins';
font-weight: bold;
}
.top-right-owner {
display: flex;
font-family: 'Poppins';
font-weight: bold;
font-size: 30px;
.address {
margin-left: 20px;
}
}
.top-right-price {
width: 719px;
height: 133px;
display: flex;
flex-direction: column;
justify-content: space-between;
background: #2d2738;
border-radius: 20px;
margin-top: 10px;
color: #BB7FFF;
padding: 15px 20px;
box-sizing: border-box;
li {
display: flex;
justify-content: space-between;
>div {
display: flex;
font-size: 28px;
color: #9950FD;
}
.time {
display: flex;
align-items: center;
justify-content: end;
font-size: 18px;
img {
width: 25px;
height: 28px;
margin-right: 5px;
}
div {
display: flex;
align-items: center;
}
}
.price {
display: flex;
align-items: center;
span {
font-family: 'Poppins';
font-weight: 400;
font-size: 24px;
color: #BB7FFF;
}
.bold {
font-weight: bold;
font-size: 48px;
}
img {
width: 30px;
height: 30px;
margin-right: 20px;
}
}
}
}
.top-right-btns {
div {
display: flex;
justify-content: space-between;
align-items: center;
margin: 10px 0;
>div {
height: 57px;
display: flex;
justify-content: center;
align-items: center;
font-family: 'Poppins';
font-weight: bold;
font-size: 28px;
color: #FFFFFF;
border-radius: 12px;
cursor: pointer;
}
.buy {
background: #6336d7;
width: 348px;
}
.add {
span {
width: 269px;
height: 100%;
line-height: 57px;
border-radius: 12px;
text-align: center;
display: inline-block;
background: #1778f1;
}
div {
width: 76px;
height: 100%;
background: #1778f1;
margin-left: 2px;
img {
width: 43px;
height: 44px;
}
}
}
}
}
.info {
color: #B3B5DA;
margin-top: 40px;
h2 {
font-family: 'Poppins';
font-weight: bold;
font-size: 30px;
color: #fff;
border-bottom: 2px solid #3A3B57;
}
li {
display: flex;
justify-content: space-between;
margin-top: 10px;
div {
width: 300px;
font-size: 22px;
text-align: left;
margin-top: 10px;
a {
color: #B3B5DA;
}
}
}
}
}
.btm-left {
padding-bottom: 90px;
h2 {
font-size: 30px;
font-family: 'Poppins';
font-weight: bold;
margin-bottom: 10px;
}
.btm-detail {
display: flex;
flex-wrap: wrap;
clear: both;
width: 489px;
li {
width: 154px;
height: 84px;
background: #2d2738;
border-radius: 20px;
margin-right: 9px;
margin-bottom: 10px;
div {
text-align: center;
font-size: 22px;
color: #B3B5DA;
font-family: "Poppins";
h5 {
font-weight: bold;
}
p {
font-weight: 400;
color: #fff;
}
}
}
}
}
&:nth-child(2) {
padding-top: 20px;
}
}
}
}
</style>