修改nft详情页面

This commit is contained in:
cebgcontract 2022-04-12 14:53:28 +08:00
parent 252d66e482
commit 1e05eb5e86
3 changed files with 157 additions and 89 deletions

View File

@ -7,13 +7,13 @@
<span>Back</span>
</div>
<div class="base-info">
<div class="nft-id-mobile">#{{data.id}}</div>
<div class="nft-id-mobile">#{{nftData.id}}</div>
<div class="class-info">
<img v-if="data.class" :src="require('@/assets/main/card/class_'+data.class+'.png')" alt="">
<span class="name-label">{{data.name}}</span>
<img v-if="nftData.job" :src="require('@/assets/main/card/class_'+nftData.job+'.png')" alt="">
<span class="name-label">{{nftData.name}}</span>
</div>
<div class="level-comp">
LV.{{data.info.level}}
LV.{{nftData.level}}
</div>
<level-star :level="nftQuality"></level-star>
<div class="owner-container">
@ -33,7 +33,7 @@
</div>
</div>
<div class="right-part">
<div class="nft-id-desktop">#{{data.id}}</div>
<div class="nft-id-desktop">#{{nftData.id}}</div>
<div class="card-container">
<div class="card-border"></div>
<div class="border">
@ -44,27 +44,27 @@
<div class="two-col-info">
<div class="one-info">
<div class="info-title">HP</div>
<div class="info-val">{{data.info.hp}}</div>
<div class="info-val">{{nftData.attrMap.get('hp')}}</div>
</div>
<div class="one-info">
<div class="info-title">Speed</div>
<div class="info-val">{{data.info.speed}}</div>
<div class="info-val">{{nftData.attrMap.get('speed')}}</div>
</div>
</div>
<div class="two-col-info">
<div class="one-info">
<div class="info-title">Attack</div>
<div class="info-val">{{data.info.atk}}</div>
<div class="info-val">{{nftData.attrMap.get('atk')}}</div>
</div>
<div class="one-info">
<div class="info-title">Defence</div>
<div class="info-val">{{data.info.def}}</div>
<div class="info-val">{{nftData.attrMap.get('def')}}</div>
</div>
</div>
<div class="one-col-info">
<div class="one-info">
<div class="info-title">Advanced Count</div>
<div class="info-val">{{data.info.advancedCount}}</div>
<div class="info-val">{{nftData.attrMap.get('advanced_count')}}</div>
</div>
</div>
</div>
@ -83,11 +83,11 @@
<div class="two-col-info">
<div class="one-info">
<div class="info-title">Lucky</div>
<div class="info-val">{{data.info.lucky}}</div>
<div class="info-val">{{nftData.attrMap.get('lucky')}}</div>
</div>
<div class="one-info">
<div class="info-title font14">Success Rate</div>
<div class="info-val">{{data.info.successRate}}</div>
<div class="info-val">{{nftData.attrMap.get('success_rate')}}</div>
</div>
</div>
</div>
@ -96,7 +96,24 @@
<div class="top-right"></div>
</div>
<div class="card-container" v-if="data.priceDiscount">
<div class="card-container" v-if="nftData.extAttrList.length>0">
<div class="card-border"></div>
<div class="border special-data">
<div class="title">
More Data
</div>
<div class="ext-info">
<div class="one-info" v-for="(data, index) in nftData.extAttrList" :key="data.key+index">
<div class="info-title">{{data.key}}</div>
<div class="info-val">{{data.value}}</div>
</div>
</div>
</div>
<div class="top-left"></div>
<div class="top-right"></div>
</div>
<div class="card-container" v-if="nftData.priceInfo">
<div class="card-border"></div>
<div class="border price-data">
<div class="title">
@ -105,8 +122,8 @@
<div class="info">
<div class="one-col-info">
<div class="one-info">
<div class="info-title price">{{data.currency}}</div>
<div class="info-val price">{{data.priceDiscount}}</div>
<div class="info-title price">{{nftData.priceInfo.currency}}</div>
<div class="info-val price">{{nftData.priceInfo.priceDiscount}}</div>
</div>
</div>
</div>
@ -115,7 +132,7 @@
<div class="top-right"></div>
</div>
<div class="btn-div" v-if="data.priceDiscount">
<div class="btn-div" v-if="nftData.priceInfo">
<div class="buy-btn">
<img v-if="canBuy" src="@/assets/main/detail/btn_buy.png" alt="btn-buy">
<img v-if="!canBuy" src="@/assets/main/detail/btn_buy_d.png" alt="btn-buy">
@ -125,34 +142,29 @@
</div>
</div>
<div class="center-part">
<img v-if="data.skelName" class="main-img" :src="require(`@/assets/main/card/${data.skelName}.png`)" alt="">
<img v-if="nftData.image" class="main-img" :src="nftData.image" alt="">
</div>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import { Component, Prop, Vue } from 'vue-property-decorator'
import LevelStar from '@/components/market/LevelStar.vue'
import { ISpineData } from '@/utils/SpineRender'
import { INftData } from '@/types/Nft'
declare module 'vue/types/vue' {
interface Vue {
data: ISpineData
}
}
@Component({
name: 'NftDetail',
components: { LevelStar },
props: ['data']
components: { LevelStar }
})
export default class extends Vue {
@Prop() private nftData:INftData
canBuy = true
get nftQuality() {
return this.data?.info?.quality || 0
return this.nftData.quality
}
get mintTime() {
const time = this.data?.info?.mintTime || 0
const time = this.nftData.mintTime || 0
if (!time) {
return '-'
}
@ -161,7 +173,7 @@ export default class extends Vue {
}
get addressShow() {
const address = this.data?.info?.owner || ''
const address = this.nftData.owner || ''
if (address.length >= 10) {
return address.substring(0, 8) + '...' + address.substring(address.length - 8)
} else if (address.length > 0 && address.length < 10) {
@ -377,6 +389,14 @@ export default class extends Vue {
width: 40%;
}
}
.ext-info{
display: flex;
flex-wrap: wrap;
padding: 20px;
.one-info{
width: 50%;
}
}
}
.basic-data {
}

103
src/types/Nft.ts Normal file
View File

@ -0,0 +1,103 @@
export enum NftType{
HERO = 1,
WEAPON = 2,
CHIP = 3
}
/**
* 0:正常状态 1:出售中 2:出租中
*/
export enum NftState {
NORMAL = 0,
SELL = 1,
RENT = 2
}
interface KeyValuePair {
key: string
value: string
}
export interface IPriceData{
discount: number
price: number
priceDiscount?: number
currency: string
coinAddress: string
}
export interface INftData{
id: string
tokenId: string
name: string
image: string
type: NftType
level: number
job?: string
quality: number
// 所有者地址
owner?: string
state: NftState
mintTime: number
priceInfo?: IPriceData
attrMap: Map<string, string>
extAttrList: KeyValuePair[]
}
export const defaultINftData = () => {
return {
id: '',
tokenId: '',
name: '',
image: '',
type: NftType.HERO,
level: 0,
quality: 0,
state: NftState.NORMAL,
mintTime: 0,
attrMap: new Map<string, string>(),
extAttrList: []
}
}
export function parseNftData(data: any) {
const info = data.info
const attrMap: Map<string, string> = new Map()
for (const key in info) {
if (key === 'attr') {
continue
}
attrMap.set(key, info[key])
}
const extAttrList = []
if (info.attr) {
for (const sub of info.attr) {
const val = sub.type ? `${sub.val}%` : sub.val
extAttrList.push({ key: sub.name, value: val })
}
}
const nft: INftData = {
id: data.token_id,
tokenId: data.token_id,
name: info?.name || '',
image: data.image,
type: data.type,
level: info?.level || 0,
quality: info?.quality || 0,
owner: data.owner_address,
state: data.state,
mintTime: data.mint_time,
job: data.job,
attrMap,
extAttrList
}
const price: any = {}
if (data.currency_list && data.currency_list.length > 0) {
const priceData: any = data.currency_list[0]
price.discount = priceData.discount_rate
price.price = priceData.original_price
price.priceDiscount = priceData.discount_price
price.currency = priceData.name
price.coinAddress = priceData.contract_address
nft.priceInfo = priceData
}
return nft
}

View File

@ -2,7 +2,7 @@
<div>
<top-menu class="desk-top"></top-menu>
<div class="root">
<nft-detail :data="nftData"></nft-detail>
<nft-detail :nft-data="nftData"></nft-detail>
</div>
<base-footer></base-footer>
</div>
@ -13,10 +13,10 @@ import { Component, Vue, Watch } from 'vue-property-decorator'
import ItemDetail from '@/components/market/ItemDetail.vue'
import TopMenu from '@/components/market/TopMenu.vue'
import NftDetail from '@/components/market/NftDetail.vue'
import { INftAttr, ISpineData } from '@/utils/SpineRender'
import { defaultINftAttr, getNftDetail } from '@/api/Mall'
import { getNftDetail } from '@/api/Mall'
import { AppModule } from '@/store/modules/app'
import BaseFooter from '@/components/layout/BaseFooter.vue'
import { defaultINftData, INftData, parseNftData } from '@/types/Nft'
@Component({
components: {
@ -28,7 +28,7 @@ import BaseFooter from '@/components/layout/BaseFooter.vue'
})
export default class Item extends Vue {
nftId = ''
nftData: ISpineData = { info: defaultINftAttr() }
nftData: INftData = defaultINftData()
created() {
this.nftId = this.$route.params.id
if (this.accountId) {
@ -54,62 +54,7 @@ export default class Item extends Vue {
token_id: this.nftId
}
const res: any = await getNftDetail(reqData)
const data = res.info
// const data = {
// id: '100000000001',
// token_id: 100000000001,
// type: 0,
// skelName: 'n_aoi',
// name: 'miffy',
// price: 10,
// priceDiscount: 10,
// decimals: 0,
// currency: 'BNB',
// class: 0,
// repeat: false,
// showBuy: false,
// mint_time: 1647652513621,
// owner_address: '',
// currency_list: [
// {
// discount_rate: 1,
// original_price: 1,
// discount_price: 1,
// contract_address: '0x111',
// name: 'cec'
// }
// ],
// info: {
// level: 1,
// advanced_count: 1,
// success_rate: 2,
// name: 'astral',
// job: '1'
// }
// }
const nftInfo: INftAttr = data.info
nftInfo.mintTime = data.mint_time
nftInfo.owner = data.owner_address
nftInfo.advancedCount = data.info?.advanced_count || 0
nftInfo.successRate = data.info?.success_rate || 0
const nftData: any = {
name: data.info.name,
class: ((data.info?.job || '') + '').toLowerCase(),
recordId: data.token_id,
id: data.token_id,
skelName: `n_${(data.info?.name || '').toLowerCase()}`,
directBuy: false,
showBuy: false
}
if (data.currency_list && data.currency_list.length > 0) {
const priceData: any = data.currency_list[0]
nftData.discount = priceData.discount_rate
nftData.price = priceData.original_price
nftData.priceDiscount = priceData.discount_price
nftData.currency = priceData.name
nftData.coinAddress = priceData.contract_address
}
nftData.info = nftInfo
const nftData = parseNftData(res.info)
this.nftData = nftData
// this.$forceUpdate()
console.log(this.nftData)