新增功能完成

This commit is contained in:
yuyongdong 2024-07-19 16:57:05 +08:00
parent e3488bf9e0
commit 639f5e0a9e
18 changed files with 599 additions and 149 deletions

View File

@ -6,8 +6,8 @@
</li>
</div>
<div class="content">
<Founder v-if="navIndex == 0" />
<Collectibles v-if="navIndex == 1" />
<Founder v-if="navIndex == 1" />
<Collectibles v-if="navIndex == 0" />
<!-- <Hanging v-else-if="navIndex == 1" />
<Trading v-else-if="navIndex == 2" />
<Activity v-else-if="navIndex == 3" /> -->
@ -37,10 +37,10 @@ const marketplaceList = useMarketplaceStore()
const navList = ref([
{
name: "Founder's Tag"
name: "NFTs"
},
{
name: "NFTs"
name: "Founder's Tag"
},
{
name: "Centralized Assets"

View File

@ -9,11 +9,12 @@
<div>{{ localWalletStore.showAddress ? localWalletStore.showAddress : 'User Address' }}</div>
<div class="total">
<img src="@/assets/img/marketplace/totalContribution.png" alt="">
<span>Total contribution:&nbsp; 999999999</span>
<p>Total Contribution Credits:&nbsp; {{ contributionPointTotal }}</p>
</div>
<div class="day">
<span>Contribution are expected daily:&nbsp;&nbsp; +150000/d</span>
<img @click="rulesDialogVisible = true" src="@/assets/img/marketplace/Description.png" alt="">
<p>Daily Expected:&nbsp;&nbsp; <span>+{{ contributionPoint }}/d</span></p>
<img src="@/assets/img/marketplace/totalContribution.png" alt="">
<img class="icon" @click="rulesDialogVisible = true" src="@/assets/img/marketplace/Description.png" alt="">
</div>
</div>
<div>
@ -49,7 +50,7 @@
<span class="no" v-else @click="confirmCec">Collection</span>
</div>
<div ref="logModal">
<a-modal :class="'logModal'" :getContainer="() => $refs.logModal" v-model:open="logDialogVisible" :footer="null" :maskClosable="false">
<a-modal :class="'logModal'" :getContainer="() => $refs.logModal" v-model:open="logDialogVisible" :closable="false" :footer="null" :maskClosable="false">
<div class="log-title">CEC Incentives Record</div>
<div class="closable" @click="logDialogVisible = false">
<img src="@/assets/img/marketplace/Close_counter.png" alt="">
@ -175,8 +176,84 @@
</a-modal>
</div>
<div ref="rulesModel">
<a-modal :class="'rulesModal'" :getContainer="() => $refs.rulesModel" v-model:open="rulesDialogVisible" :footer="null" :maskClosable="false">
<div>1212121</div>
<a-modal :class="'rulesModal'" :getContainer="() => $refs.rulesModel" v-model:open="rulesDialogVisible" :closable="false" :footer="null" :maskClosable="false">
<div class="log-title">Staking Rules</div>
<div class="closable" @click="rulesDialogVisible = false">
<img src="@/assets/img/marketplace/Close_counter.png" alt="">
</div>
<h3>1. Staking Rules</h3>
<div class="text">
<p>*Contributions only count if staked for a minimum of 24 hours.</p>
<p>*If unstaked before 24 hours, no Credits will be awarded.</p>
<p>*Contribution Credits are calculated daily at 00:00 UTC.</p>
</div>
<h3>2. Staking Rewards</h3>
<div class="staking-content">
<li>
<h4>hero</h4>
<div class="hero-title">
<span>Tier</span>
<span>Daily contribution points</span>
</div>
<div class="hero-body">
<div>
<span>Tier 1</span>
<span>10</span>
</div>
<div>
<span>Tier 2</span>
<span>20</span>
</div>
<div>
<span>Tier 3</span>
<span>40</span>
</div>
<div>
<span>Tier 4</span>
<span>80</span>
</div>
<div>
<span>Tier 5</span>
<span>160</span>
</div>
</div>
</li>
<li>
<h4>Founders Tag</h4>
<div class="hero-title">
<span>Tier</span>
<span>Daily contribution points</span>
</div>
<div class="hero-body">
<div>
<span>Tier 1</span>
<span>20</span>
</div>
<div>
<span>Tier 2</span>
<span>40</span>
</div>
<div>
<span>Tier 3</span>
<span>100</span>
</div>
<div>
<span>&nbsp;</span>
<span></span>
</div>
<div>
<span>&nbsp;</span>
<span></span>
</div>
</div>
</li>
</div>
<h3>3. Bonus Calculation</h3>
<div class="text">
<p>Each Founder's Tag: +10%</p>
<p>Each Genesis Hero: +5%</p>
<p>Maximum bonus cap: +100%</p>
</div>
</a-modal>
</div>
</div>
@ -187,10 +264,12 @@
import { ref, watch, computed, onMounted } from "vue"
import ConfirmDialog from "@/components/Dialogs/confirmDialog.vue";
import {createModal} from "@/utils/model.util";
import { apiCecInfo } from "@/utils/marketplace"
import { apiCecInfo, apiExpected, apiUserData } from "@/utils/marketplace"
import { priceCalculated } from "@/configs/priceCalculate"
import { useMarketplaceStore } from "@/store/marketplace"
import {walletStore} from "@/store/wallet";
const marketplaceStore = useMarketplaceStore()
const localWalletStore = walletStore()
const bgCor = ref(['#5bbbff', '#ffc35b', '#bb7fff', '#ff6600'])
@ -250,14 +329,47 @@ const getCecInfo = async () => {
if(address) {
const {data, errcode} = await apiCecInfo(address)
// console.log(errcode,data)
if(errcode == 0) {
cecInfo.value = data
}
if(errcode == 0) {
cecInfo.value = data
}
} else {
return
}
}
const contributionPoint = ref(0)
const getExpected = async () => {
let address = localWalletStore.address
if(address) {
const {contribution_point, errcode} = await apiExpected(address)
if(errcode == 0) {
contributionPoint.value = contribution_point
}
} else {
return
}
}
const contributionPointTotal = ref(0)
const getUserData = async () => {
let address = localWalletStore.address
if(address) {
const {errcode, contribution_point, gold} = await apiUserData(address)
if(errcode == 0) {
contributionPointTotal.value = contribution_point
marketplaceStore.userGold = gold
}
} else {
return
}
}
const dataInfo = async () => {
await getCecInfo()
await getExpected()
await getUserData()
}
watch(localWalletStore,() => {
// console.log('localWalletStore.token',localWalletStore.address,localWalletStore.token)
if(!localWalletStore.address) {
@ -284,12 +396,12 @@ watch(localWalletStore,() => {
]
}
} else {
getCecInfo()
dataInfo()
}
})
onMounted(() => {
getCecInfo()
dataInfo()
})
</script>
@ -343,13 +455,19 @@ onMounted(() => {
font-family: 'Poppins';
font-weight: 500;
font-size: 14px;
color: #FFFFFF;
img {
width: 27px;
height: 23px;
margin-left: 10px;
}
.icon {
width: 30px;
height: 30px;
margin-left: 10px;
cursor: pointer;
}
span {
color: #00DEFF;
}
}
}
}
@ -705,7 +823,114 @@ onMounted(() => {
}
}
:deep(.rulesModal) {
background: #1a1821;
width: 1152px !important;
height: 805px;
background: #1A1821;
box-shadow: 0px 15px 28px 3px rgba(22,22,22,0.13);
border-radius: 100px;
border: 1px solid #B966FF;
.ant-modal-content {
width: 944px;
margin: 0 auto;
color: #FFF;
background: #1A1821;
border-radius: 100px;
box-shadow: 0 0 0 0;
.ant-modal-body {
overflow: hidden;
.log-title {
width: 944px;
margin: 0 auto;
font-family: 'Anton';
font-weight: 400;
font-size: 48px;
color: #FFFFFF;
margin-top: 23px;
border-bottom: 2px solid #3D4057;
}
.closable {
position: absolute;
right: -120px;
top: -30px;
z-index: 99;
cursor: pointer;
img {
width: 120px;
height: 120px;
}
}
h3 {
font-family: 'Poppins';
font-weight: bold;
font-size: 29px;
color: #FFFFFF;
margin-top: 20px;
}
.staking-content {
display: flex;
justify-content: space-between;
li {
width: 427px;
border-radius: 50px;
h4 {
font-family: 'Poppins';
font-weight: bold;
font-size: 30px;
color: #AB74EA;
text-align: center;
}
.hero-title {
height: 50px;
line-height: 50px;
background: #604680;
border-radius: 30px 30px 0 0;
font-family: 'Poppins';
font-weight: bold;
font-size: 18px;
color: #F6F6F6;
span {
display: inline-block;
text-align: center;
&:nth-child(1) {
width: 127px;
border-right: 2px solid #1a1821;
}
&:nth-child(2) {
width: 300px;
}
}
}
.hero-body {
div {
height: 46px;
line-height: 46px;
text-align: center;
background: #2d2738;
font-family: 'Poppins';
font-weight: 600;
font-size: 20px;
color: #F3F0FF;
border-top: 2px solid #1a1821;
span {
display: inline-block;
text-align: center;
&:nth-child(1) {
width: 127px;
border-right: 2px solid #1a1821;
}
&:nth-child(2) {
width: 300px;
}
}
&:last-child {
border-radius: 0 0 30px 30px;
}
}
}
}
}
}
}
}
}
</style>

View File

@ -6,7 +6,7 @@
</div>
<div class="card-name">
<div>
<span v-if="nftData.type == 1">HERO</span>
<span v-if="nftData.type == 1">Legacy Heroes</span>
</div>
<div class="no-sell" v-show="nftData.on_sale == 1" @click="cancelNft(nftData)">
<img src="@/assets/img/marketplace/On_SeLL.png" alt="">
@ -102,29 +102,6 @@ const sellNft = async (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) {
// if(e.message.indexOf('rejected') > -1) {
// message.error('User rejected the request')
// } else {
// message.error('Your item has failed to be unlisted.')
// }
// }
// }
const loadingDialogVisible = ref(false)
// 使
const lockToGame = async(type) => {
@ -150,17 +127,24 @@ const lockToGame = async(type) => {
}
// mint
const mintHero = async () => {
try {
const res = await new BlockChain().locker.mintNft([toRaw(props.nftData).uniid])
message.success('Mint success.')
emit('renewMyNft')
} catch (e) {
if(e.message.indexOf('rejected') > -1) {
message.error('User rejected the request')
} else if (e.message.indexOf('select wallet') > -1) {
message.error('user cancel select wallet')
} else {
message.error('Mint Failed.')
if(marketplaceStore.userGold < 0) {
const confirmResult = await createModal(ConfirmDialog, {
title: '',
message: 'Mint Failed - Negative in-game gold balance. Please adjust your balance to continue.'
}).show()
} else {
try {
const res = await new BlockChain().locker.mintNft([toRaw(props.nftData).uniid])
message.success('Mint success.')
emit('renewMyNft')
} catch (e) {
if(e.message.indexOf('rejected') > -1) {
message.error('User rejected the request')
} else if (e.message.indexOf('select wallet') > -1) {
message.error('user cancel select wallet')
} else {
message.error('Mint Failed.')
}
}
}
}

View File

@ -104,9 +104,8 @@ const getMyAssets = async () => {
if(bc.passportLogined) {
try {
let nftListBox
const ptoken = await bc.passportToken()
let res = await apiHeroList(data, ptoken)
// console.log(res,'----------------------')
// const ptoken = await bc.passportToken()
let res = await apiHeroList(data)
// return
nftList.value = [...nftList.value, ...res.rows]
// nftListBox = nftList.value.reduce((acc, obj) => {

View File

@ -37,10 +37,10 @@ import NftId from "@/configs/item.json"
import { apiAssetsState } from "@/utils/marketplace"
import {useMarketplaceStore} from "@/store/marketplace";
import {walletStore} from "@/store/wallet";
import { BlockChain } from "@/components/chain/BlockChain"
const marketplaceStore = useMarketplaceStore()
const localWalletStore = walletStore()
const nftList = ref([])
// console.log('localWalletStore', localWalletStore.token)
const overviewValue = ref()
const statusValue = ref('0')
@ -83,6 +83,9 @@ const getMyAssets = async () => {
cursor: next_cursor.value,
search_name: overviewValue.value
}
const bc = new BlockChain()
// const pstoken = await bc.token()
// const ptoken = await bc.passportToken()
if(myADdress) {
try {
let nftListBox

View File

@ -35,7 +35,7 @@
<script setup>
import { ref, onMounted, toRaw, onUnmounted, watch } from "vue";
import OverView from "@/components/common/searchView/Overview.vue";
import Status from "@/components/common/searchView/nftStatusRadio.vue";
import Status from "@/components/common/searchView/founderRadio.vue";
import Card from "./myCard.vue";
import NftId from "@/configs/item.json"
import { apiAssetsState } from "@/utils/marketplace"
@ -91,7 +91,8 @@ const getMyAssets = async () => {
}
const bc = new BlockChain()
isEoaLoginedLogin.value = bc.eoaLogined
console.log(bc.eoaLogined)
// const pstoken = await bc.token()
// const ptoken = await bc.passportToken()
if(bc.eoaLogined) {
try {
let nftListBox
@ -132,7 +133,7 @@ const handleScroll = () => {
}
const eoaLoginedLogin = async () => {
await new BlockChain().restoreEoa()
await new BlockChain().appendEoa({})
getMyAssets()
}

View File

@ -9,6 +9,8 @@
<div>
<span v-if="nftData.type == 1">GENESIS HERO</span>
<span v-if="nftData.type == 11">GOLD CARD</span>
<span v-if="nftData.type == 12">Legacy Heroes</span>
<span v-if="nftData.type == 13">Founder's Tag</span>
</div>
<div class="no-sell" v-show="nftData.on_sale == 1" @click="cancelNft(nftData)">
<img src="@/assets/img/marketplace/On_SeLL.png" alt="">
@ -17,35 +19,36 @@
<div class="card-price">
<div class="sell-price">
<div v-show="nftData.on_sale == 1">
<span>
<span class="price-col">
{{ nftPrice }}
<!-- {{cardPrice(nftData)}} -->
</span>
<img :src="icon" alt="">
</div>
<div v-if="LOCKER_ADDRESS.toLowerCase() == nftData.owner_address.toLowerCase()">
<span>22</span>
<span class="expected">+{{contribution(nftData.detail.quality)}}/d</span>
<img src="@/assets/img/marketplace/totalContribution.png" alt="">
</div>
</div>
<div v-if="LOCKER_ADDRESS.toLowerCase() == nftData.owner_address.toLowerCase()" class="link-staking" @click="unStake(nftData)">
<img src="@/assets/img/marketplace/Staking.png" alt="">
</div>
<div v-if="LOCKER_ADDRESS.toLowerCase() != nftData.owner_address.toLowerCase() && nftData.type == 11 && nftData.on_sale == 0" class="enabled" @click="lockToGame('redeem')">
<!-- <div v-if="LOCKER_ADDRESS.toLowerCase() != nftData.owner_address.toLowerCase() && nftData.type == 11 && nftData.on_sale == 0" class="enabled" @click="lockToGame('redeem')">
Redeem
</div>
<div v-if="LOCKER_ADDRESS.toLowerCase() != nftData.owner_address.toLowerCase() && nftData.type == 1 && nftData.on_sale == 0" class="link-below" @click="lockToGame('convert')">
Convert
</div> -->
<div v-if="LOCKER_ADDRESS.toLowerCase() != nftData.owner_address.toLowerCase() && (nftData.type == 1 || nftData.type == 12) && nftData.on_sale == 0" class="link-below" @click="lockToGame('convert')">
Stake
</div>
<!-- <div>{{ nftData.owner_address.substr(0,6) }}...{{ nftData.owner_address.substr(-6) }}</div> -->
</div>
</div>
<div class="card-btn" v-if="LOCKER_ADDRESS.toLowerCase() != nftData.owner_address.toLowerCase()">
<div class="card-btn" v-if="nftData.type != 13 && LOCKER_ADDRESS.toLowerCase() != nftData.owner_address.toLowerCase()">
<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>
<div class="card-btn" v-else>
<div class="card-cancel" v-if="nftData.on_sale == 0" @click="unStake(nftData)">Unstake</div>
<div class="card-cancel" v-if="LOCKER_ADDRESS.toLowerCase() == nftData.owner_address.toLowerCase()" @click="unStake(nftData)">Unstake</div>
<div class="card-sell" v-if="LOCKER_ADDRESS.toLowerCase() != nftData.owner_address.toLowerCase()" @click="lockToGame('founder')">Stake</div>
</div>
<SellDialog :sellDialogVisible="sellDialogVisible" :floorPrice="floorPrice" :sellDataArr="sellDataArr" @handleClose="sellHandleClose" />
<LoadingDialog :loadingDialogVisible="loadingDialogVisible" />
@ -64,11 +67,12 @@ 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"
import { timeFormat, contribution } from "@/configs/priceCalculate"
import { Locker } from "@/components/chain/contract/Locker"
const emit = defineEmits(['renewMyNft'])
import {formatPrice} from "@/components/chain/utils"
import { useMarketplaceStore } from "@/store/marketplace"
const marketplaceStore = useMarketplaceStore()
import { useRouter } from "vue-router";
import { BlockChain } from "@/components/chain/BlockChain"
const router = useRouter();
@ -146,19 +150,19 @@ const cancelNft = async (val) => {
const loadingDialogVisible = ref(false)
// 使
const lockToGame = async(type) => {
if(type == 'redeem') {
if(type == 'founder') {
const confirmResult = await createModal(ConfirmDialog, {
title: '',
message: `Redeem ${props.nftData.detail.gold_coins} Gold to your game account. Do you wish to proceed?`
message: `Are you sure you want to stake?`
}).show()
if (confirmResult.errcode == 0) {
loadingDialogVisible.value = true
lockToGameConfirm()
unlockMainConfirm()
}
} 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?'
message: 'Are you sure you want to stake?'
}).show()
if (confirmResult.errcode == 0) {
loadingDialogVisible.value = true
@ -185,6 +189,25 @@ const lockToGameConfirm = async () => {
}
}
const unlockMainConfirm = async () => {
try {
const bc = new BlockChain()
let res = await bc.locker.lockMain(toRaw(props.nftData).contract_address, [toRaw(props.nftData).token_id])
message.success('lockToGame success')
// router.go(-1)
emit('renewMyNft')
loadingDialogVisible.value = false
// router.push('/assets')
} catch (e) {
if(e.message.indexOf('rejected') > -1) {
message.error('User rejected the request')
} else {
message.error('lockToGame fail.')
}
loadingDialogVisible.value = false
}
}
//
const nftPrice = ref('-')
@ -202,31 +225,44 @@ const cardPrice = async (val) => {
//
const unStake = async (data) => {
try {
const bc = new BlockChain()
let res = await bc.locker.unlockOrMintGameNft(toRaw(data).contract_address,[toRaw(data).token_id])
if(res) {
let timer = setTimeout(() => {
message.success('Unstake success.')
emit('renewMyNft')
clearTimeout(timer);
}, 2000);
}
} catch (e) {
console.log(e)
if(e.message.indexOf('rejected') > -1) {
message.error('User rejected the request')
} else if (e.message.indexOf('select wallet') > -1) {
message.error('user cancel select wallet')
} else {
message.error('Unstake fail')
console.log(marketplaceStore.userGold)
if(marketplaceStore.userGold < 0) {
const confirmResult = await createModal(ConfirmDialog, {
title: '',
message: 'Unstake Failed - Negative in-game gold balance. Please adjust your balance to continue.'
}).show()
} else {
try {
const bc = new BlockChain()
let res = await bc.locker.unlockOrMintGameNft(toRaw(data).contract_address,[toRaw(data).token_id])
if(res) {
let timer = setTimeout(() => {
message.success('Unstake success.')
emit('renewMyNft')
clearTimeout(timer);
}, 2000);
}
} catch (e) {
console.log(e)
if(e.message.indexOf('rejected') > -1) {
message.error('User rejected the request')
} else if (e.message.indexOf('select wallet') > -1) {
message.error('user cancel select wallet')
} else {
message.error('Unstake fail')
}
}
}
}
//
const toDetail = () => {
router.push(`/detail/${props.nftData.contract_address}/${props.nftData.token_id}`)
if(props.nftData.type == 13) {
marketplaceStore.detailData = {nft: props.nftData}
router.push('/detail')
} else {
router.push(`/detail/${props.nftData.contract_address}/${props.nftData.token_id}`)
}
}
//
@ -283,6 +319,13 @@ onMounted(() => {
margin-left: 8px;
}
}
.founder {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 260px;
height: 260px;
}
}
}
}
@ -324,7 +367,19 @@ onMounted(() => {
.sell-price {
div {
display: flex;
align-items: center;
text-align: left;
span {
font-family: 'Poppins';
font-weight: 600;
font-size: 20px;
}
.price-col {
color: #9A50FF;
}
.expected {
color: #00DEFF;
}
}
img {
width: 25px;

View File

@ -46,7 +46,6 @@ const nftList = ref([])
// console.log('localWalletStore', localWalletStore.token)
const overviewValue = ref()
const statusValue = ref('0')
console.log(localWalletStore.walletType)
const overviewChild = (val) => {
overviewValue.value = val
next_cursor.value = ''

View File

@ -145,7 +145,7 @@ export class BlockChain {
/**
* 用于passport登录后, 添加eoa地址
*/
async appendEoa() {
async appendEoa({title, subTitle}) {
if (this.store.walletType != 3) {
return;
}

View File

@ -13,7 +13,7 @@
</div>
<div class="card-price">
<div>
<span>
<span class="price-col">
{{ price }}
</span>
<img :src="icon" alt="图片">
@ -271,6 +271,14 @@ onMounted(() => {
display: flex;
justify-content: space-between;
align-items: center;
span {
font-family: 'Poppins';
font-weight: 600;
font-size: 20px;
}
.price-col {
color: #9A50FF;
}
img {
width: 25px;
height: 25px;

View File

@ -15,7 +15,7 @@
<template #default="{ text: nft }">
<div class="status">
<div class="nft-status" v-if="nft.item_id == '10017' || nft.item_id == '10018'">Redeem</div>
<div class="nft-status" v-else>Convert</div>
<div class="nft-status" v-else>Stake</div>
</div>
</template>
</a-table-column>

View File

@ -1,6 +1,9 @@
<template>
<div class="card-img-common">
<li v-if="props.nftData.type == 1">
<li v-if="props.nftData.type == 13">
<LazyLoadImg class="founder" :src="props.nftData.image" :src-placeholder="placeholderImg" alt="图片"/>
</li>
<li v-else-if="props.nftData.type == 1 || props.nftData.type == 12">
<LazyLoadImg :src="props.nftData.image" :src-placeholder="placeholderImg" alt="图片"/>
<div class="img-top">
{{ props.nftData.detail.max_mining_days }}D
@ -43,6 +46,8 @@ const props = defineProps({
}
li {
position: relative;
display: flex;
align-items: center;
.img-top {
position: absolute;
display: flex;

View File

@ -0,0 +1,54 @@
<template>
<div class="hero-check">
<h2>Status</h2>
<a-radio-group v-model:value="props.statusValue" @change="onChangeValue">
<a-radio value="0">All</a-radio>
<a-radio value="3">Stake</a-radio>
<!-- <a-radio value="3">Staking</a-radio> -->
</a-radio-group>
</div>
</template>
<script setup>
import { ref, reactive } from "vue";
import { useMarketplaceStore } from "@/store/marketplace"
const marketplaceList = useMarketplaceStore()
const props = defineProps({
statusValue: {
type: Number,
required: true,
},
});
const emit = defineEmits(['clickStatusChild'])
// const
const onChangeValue = (e) => {
emit('clickStatusChild',e.target.value)
};
</script>
<style lang="scss" scoped>
.hero-check {
h2 {
font-family: "Poppins";
font-weight: bold;
font-size: 20px;
color: #bb7fff;
margin-bottom: 10px;
}
:deep(.ant-radio-group) {
display: block;
.ant-radio-wrapper {
display: block !important;
span {
color: #BB7FFF;
}
}
.ant-checkbox-group-item {
display: flex !important;
background: #16141b;
span {
color: #BB7FFF !important;
}
}
}
}
</style>

View File

@ -277,6 +277,7 @@ const immuTableLogout = async () => {
// immutableStore.accessToken = ''
// immutableStore.accounts = ''
// await new PassportWallet().logout()
location.reload()
} catch (e) {
console.log(e)
}

View File

@ -51,4 +51,36 @@ export const totalPrice = (price) => {
export const showTime = (time) => {
let str = time.split('.')
return str[0]
}
// 处理贡献值
export const contribution = (quality) => {
let str
if(quality == 1) {
str = 10
} else if(quality == 2) {
str = 20
} else if(quality == 3) {
str = 30
} else if(quality == 4) {
str = 40
} else if(quality == 5) {
str = 160
}
return str
}
// 质押时间
export const timeStaking = (time) => {
let timeArr = []
let now = new Date().getTime()
let str = (now/1000) - time
let d = Math.floor(str / 60 / 60 / 24);
d = d < 10 ? "0" + d : d;
let h = Math.floor((str / 60 / 60) % 24);
h = h < 10 ? "0" + h : h;
let m = Math.floor((str / 60) % 60);
m = m < 10 ? "0" + m : m;
timeArr = [d, h, m]
return timeArr
}

View File

@ -41,6 +41,7 @@ export const useMarketplaceStore = defineStore('marketplace', () => {
}
})
const detailData = ref()
const userGold = ref(0)
const updateOverviewStatus = (_connected) => {
overview.value = _connected;
@ -101,8 +102,8 @@ export const useMarketplaceStore = defineStore('marketplace', () => {
getCartList, getCartListState,
addCartListState,
delCartListState,
currencyPrice,priceDatas,
detailData,
currencyPrice, priceDatas,
detailData, userGold
}
},
{

View File

@ -134,4 +134,16 @@ export const apiUnlockOrMint = async (data, token) => {
export const apiMintNft = async (data, token) => {
const url = `${API_BASE}/api/ingame/asset/hero/mint`
return httpPost(url, data, token)
}
}
// 取每日预期所得
export const apiExpected = async (account_address) => {
const url = `${API_BASE}/api/activity/stacking/expected_daily/${account_address}`
return httpGet(url, {})
}
// 用户信息
export const apiUserData = async (account_address) => {
const url = `${API_BASE}/api/user/${account_address}`
return httpGet(url, {})
}

View File

@ -10,7 +10,8 @@
</div>
</div>
<div class="top-right">
<h2>{{ detailData.nft.name }}</h2>
<h2 v-if="detailData.nft.type == 13">Founder's Tag</h2>
<h2 v-else>{{ detailData.nft.name }}</h2>
<div class="top-right-owner">
<div>Owner:</div>
<div class="address">{{ detailData.nft.owner_address ? detailData.nft.owner_address : myAddress }}</div>
@ -32,14 +33,24 @@
</li>
</div>
<div class="back-time" v-if="localWalletStore.token && LOCKER_ADDRESS.toLowerCase() == detailData.nft.owner_address.toLowerCase()">
<img src="@/assets/img/marketplace/time.png" alt="">
<span>Time remaining : 6d:10h:22m</span>
<div>
<img src="@/assets/img/marketplace/time.png" alt="">
<span>Time remaining : &nbsp;
{{ timeStaking(detailData.nft.last_lock_time)[0] }}:d
{{ timeStaking(detailData.nft.last_lock_time)[1] }}:h
{{ timeStaking(detailData.nft.last_lock_time)[2] }}:m
</span>
</div>
<div>
<span>+{{ contribution(detailData.nft.detail.quality) }}/d</span>
<img src="@/assets/img/marketplace/totalContribution.png" alt="">
</div>
</div>
<div class="top-right-btns">
<div v-if="localWalletStore.token && LOCKER_ADDRESS.toLowerCase() == detailData.nft.owner_address.toLowerCase()">
<div class="cancel" @click="localWalletStore.token == '' ? cardLogin() : backStaking()">Unstake</div>
</div>
<div v-else>
<div v-if="(detailData.nft.type == 1 && !detailData.nft.contract_address) && LOCKER_ADDRESS.toLowerCase() != detailData.nft.owner_address.toLowerCase()">
<div class="mint" @click="mintHero">Mint</div>
</div>
<!--
@ -48,6 +59,7 @@
3购买
4
-->
<div v-if="myAddress != detailData.nft.owner_address">
<div v-if="detailData.event != null" class="buy" @click="localWalletStore.token == '' ? cardLogin() : buyNow()">Buy Now</div>
<div class="add" v-if="detailData.event != null && detailData.in_shopcart == 0" @click="localWalletStore.token == '' ? cardLogin() : addCart()">
@ -64,11 +76,12 @@
2下架
3使用
-->
<div v-else>
<div class="sell" @click="beginSell" v-if="detailData.nft.on_sale == 0">List</div>
<div v-if="myAddress == detailData.nft.owner_address">
<div class="sell" @click="beginSell" v-if="detailData.nft.on_sale == 0 && detailData.nft.type != 13">List</div>
<div class="cancel" @click="cancelSell" v-if="detailData.nft.on_sale == 1">Cancel listing</div>
<div class="redeem" @click="lockToGame('convert')" v-if="detailData.nft.on_sale == 0 && detailData.nft.type == 1">Convert</div>
<div class="redeem" @click="lockToGame('redeem')" v-if="detailData.nft.on_sale == 0 && detailData.nft.type == 11">Redeem</div>
<div class="redeem" @click="lockToGame('convert')" v-if="detailData.nft.on_sale == 0 && (detailData.nft.type == 1 || detailData.nft.type == 12)">Stake</div>
<div class="redeem" @click="lockToGame('founder')" v-else-if="detailData.nft.type == 13">Stake</div>
<!-- <div class="redeem" @click="lockToGame('redeem')" v-if="detailData.nft.on_sale == 0 && detailData.nft.type == 11">Redeem</div> -->
</div>
</div>
<div class="info">
@ -102,7 +115,7 @@
</div>
</div>
<div class="content">
<div v-if="detailData.nft.type == 1" class="btm-left">
<div v-if="detailData.nft.type == 1 || detailData.nft.type == 12" class="btm-left">
<h2>Property</h2>
<div class="btm-detail">
<li v-for="(item, val, index) in nftAbilities" :key="index">
@ -145,7 +158,7 @@
</li>
</div>
</div>
<div v-else class="btm-left">
<div v-else-if="detailData.nft.item_id == 10017 || detailData.nft.item_id == 10018" class="btm-left">
<h2>Property</h2>
<div class="gold-content">
<div class="left">
@ -191,6 +204,7 @@ import { useMarketplaceStore } from "@/store/marketplace"
import LazyLoadImg from "@/components/lazyloadimg"
import {formatPrice} from "@/components/chain/utils"
import {createModal} from "@/utils/model.util";
import { contribution, timeStaking } from "@/configs/priceCalculate"
const router = useRouter();
const route = useRoute();
const localWalletStore = walletStore()
@ -297,19 +311,19 @@ const clearCart = async () => {
// 使
const lockToGame = async(type) => {
if(type == 'redeem') {
if(type == 'founder') {
const confirmResult = await createModal(ConfirmDialog, {
title: '',
message: `Redeem ${detailData.value.nft.detail.gold_coins} Gold to your game account. Do you wish to proceed?`
message: `Are you sure you want to stake?`
}).show()
if (confirmResult.errcode == 0) {
loadingDialogVisible.value = true
lockToGameConfirm()
unlockMainConfirm()
}
} 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?'
message: 'Are you sure you want to stake?'
}).show()
if (confirmResult.errcode == 0) {
loadingDialogVisible.value = true
@ -332,26 +346,51 @@ const lockToGameConfirm = async () => {
loadingDialogVisible.value = false
}
}
//
const backStaking = async () => {
const unlockMainConfirm = async () => {
try {
const bc = new BlockChain()
let res = await bc.locker.unlockOrMintGameNft(detailData.value.nft.contract_address,[detailData.value.nft.token_id])
if(res) {
let timer = setTimeout(() => {
message.success('Unstake success.')
router.go(-1)
clearTimeout(timer);
}, 2000);
}
let res = await bc.locker.lockMain(detailData.value.nft.contract_address, [detailData.value.nft.token_id])
message.success('lockToGame success')
// router.go(-1)
emit('renewMyNft')
loadingDialogVisible.value = false
// router.push('/assets')
} catch (e) {
if(e.message.indexOf('rejected') > -1) {
message.error('User rejected the request')
} else if (e.message.indexOf('select wallet') > -1) {
message.error('user cancel select wallet')
} else {
message.error('Unstake fail')
message.error('lockToGame fail.')
}
loadingDialogVisible.value = false
}
}
//
const backStaking = async () => {
if(marketplaceList.userGold < 0) {
const confirmResult = await createModal(ConfirmDialog, {
title: '',
message: 'Unstake Failed - Negative in-game gold balance. Please adjust your balance to continue.'
}).show()
} else {
try {
const bc = new BlockChain()
let res = await bc.locker.unlockOrMintGameNft(detailData.value.nft.contract_address,[detailData.value.nft.token_id])
if(res) {
let timer = setTimeout(() => {
message.success('Unstake success.')
router.go(-1)
clearTimeout(timer);
}, 2000);
}
} catch (e) {
if(e.message.indexOf('rejected') > -1) {
message.error('User rejected the request')
} else if (e.message.indexOf('select wallet') > -1) {
message.error('user cancel select wallet')
} else {
message.error('Unstake fail')
}
}
}
}
@ -442,17 +481,24 @@ const sellHandleClose = (val) => {
// mint
const mintHero = async () => {
try {
const res = await new BlockChain().locker.mintNft([detailData.value.nft.uniid])
message.success('Mint success.')
router.go(-1)
} catch (e) {
if(e.message.indexOf('rejected') > -1) {
message.error('User rejected the request')
} else if (e.message.indexOf('select wallet') > -1) {
message.error('user cancel select wallet')
} else {
message.error('Mint Failed.')
if(marketplaceList.userGold < 0) {
const confirmResult = await createModal(ConfirmDialog, {
title: '',
message: 'Mint Failed - Negative in-game gold balance. Please adjust your balance to continue.'
}).show()
} else {
try {
const res = await new BlockChain().locker.mintNft([detailData.value.nft.uniid])
message.success('Mint success.')
router.go(-1)
} catch (e) {
if(e.message.indexOf('rejected') > -1) {
message.error('User rejected the request')
} else if (e.message.indexOf('select wallet') > -1) {
message.error('user cancel select wallet')
} else {
message.error('Mint Failed.')
}
}
}
}
@ -613,23 +659,48 @@ onMounted(() => {
}
}
.back-time {
width: 340px;
// width: 340px;
height: 40px;
line-height: 40px;
background: #272130;
border-radius: 20px;
font-family: 'Poppins';
font-weight: 300;
font-size: 18px;
color: #9A50FF;
display: flex;
align-items: center;
img {
width: 20px;
height: 25px;
margin-right: 6px;
margin-left: 24px;
div {
display: flex;
align-items: center;
background: #272130;
padding: 0 24px;
border-radius: 20px;
img {
width: 20px;
height: 25px;
margin-right: 6px;
// margin-left: 24px;
}
span {
display: inline-block;
height: 40px;
line-height: 40px;
color: #9A50FF;
}
&:nth-child(2) {
margin-left: 20px;
span {
font-family: 'Poppins';
font-weight: 600;
font-size: 20px;
color: #F3F0FF;
}
img {
width: 25px;
margin-left: 10px;
}
}
}
}
.top-right-btns {
div {