525 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="mkt-content">
<div class="mkt-content-left">
<OverView :overviewValue="marketplaceList.overview" @clickOverviewChild="overviewChild" />
<Sort @clickSortChild="sortChild" />
<Price @clickPriceChild="priceChild" />
<h2>Type</h2>
<Hero @clickHeroChild="heroChild" @clickRankChild="rankChild" />
<Gold @clickGoldChild="goldChild" />
</div>
<div class="mkt-content-right">
<div class="mkt-content-right-header">
<div class="bg-cor"></div>
<div class="results-total"><span v-if="nftList">{{ totalCount }}</span><span v-else>0 </span> Results</div>
<div class="search-list">
<li v-if="marketplaceList.overview">
<span>Overview: </span>
<span>{{ marketplaceList.overview }}</span>
<span v-if="marketplaceList.overview" @click="clearOverviewAll">×</span>
</li>
<!-- <li v-if="marketplaceList.sort">
<span>Sort By: </span>
<span>{{ marketplaceList.sort == '-1' ? 'From low to high' : 'From high to low'}}</span>
<span v-if="marketplaceList.sort" @click="clearSortAll">×</span>
</li> -->
<li v-if="marketplaceList.minPrice || marketplaceList.maxPrice">
<span>Price: </span>
<span v-if="!marketplaceList.maxPrice">{{ `>` }}</span>
<span>{{ marketplaceList.minPrice }}</span>
<span v-if="marketplaceList.minPrice && marketplaceList.maxPrice">~</span>
<span v-if="!marketplaceList.minPrice">{{ `<` }}</span>
<span>{{ marketplaceList.maxPrice }}</span>
<span v-if="marketplaceList.minPrice || marketplaceList.maxPrice" @click="clearPriceAll">×</span>
</li>
<li v-if="marketplaceList.hero.length != undefined && marketplaceList.hero.length > 0">
<span v-if="marketplaceList.hero.length != undefined && marketplaceList.hero.length > 0">Hero: </span>
<span v-for="(item,index) in marketplaceList.hero" :key="item">
<span>{{ searchName(item) }}</span>
<span v-if="marketplaceList.hero.length != index+1">/</span>
</span>
<span v-if="marketplaceList.hero != undefined && marketplaceList.hero.length > 0" @click="clearHeroAll">×</span>
</li>
<li v-if="marketplaceList.rank.length != undefined && marketplaceList.rank.length > 0">
<span v-if="marketplaceList.rank.length != undefined && marketplaceList.rank.length > 0">Tier: </span>
<span v-for="(item, index) in marketplaceList.rank" :key="index">
{{ searchName(item) }}
<span v-if="marketplaceList.rank.length != index+1">/</span>
</span>
<span v-if="marketplaceList.rank != undefined && marketplaceList.rank.length > 0" @click="clearRankAll">×</span>
</li>
<li v-if="marketplaceList.gold.length != undefined && marketplaceList.gold.length > 0">
<span v-if="marketplaceList.gold.length != undefined && marketplaceList.gold.length > 0">Gold: </span>
<span v-for="(item, index) in marketplaceList.gold" :key="item">
{{ searchName(item) }}
<span v-if="marketplaceList.gold.length != index+1">/</span>
</span>
<span v-if="marketplaceList.gold != undefined && marketplaceList.gold.length > 0" @click="clearGoldAll">×</span>
</li>
<li v-if="isClearAll" class="clear-all" @click="clearAll">Clear All</li>
</div>
</div>
<div class="mkt-content-right-content" ref="contentScroll">
<div class="pages" v-if="nftList != undefined && nftList.length > 0">
<li v-for="(item, index) in nftList" :key="index">
<Card v-if="nftList != undefined || nftList.length > 0" @renewNft="renewNft" :nftData="item" />
</li>
</div>
<div class="pages-no" v-else>
<div>
<img src="@/assets/img/marketplace/Empty_state.png" alt="">
</div>
<p>No NFT yet</p>
</div>
</div>
</div>
<LoadingDialog :loadingDialogVisible="loadingDialogVisible" />
</div>
</template>
<script setup>
import { ref, reactive, toRaw, onMounted, onUnmounted, getCurrentInstance, watch } from "vue";
const { proxy } = getCurrentInstance();
import OverView from "@/components/common/searchView/Overview.vue"
import Sort from "@/components/common/searchView/Sort.vue"
import Price from "@/components/common/searchView/Price.vue"
import Card from '@/components/common/card.vue'
import Hero from "@/components/common/searchView/hero.vue"
import Gold from "@/components/common/searchView/gold.vue"
import LoadingDialog from "@/components/Dialogs/loadingDialog.vue"
import NftId from "@/configs/item.json"
import {apiMarketplaceState} from "@/utils/marketplace.js"
import { useMarketplaceStore } from "@/store/marketplace"
const marketplaceList = useMarketplaceStore()
const cursorObj = ref({
count: 0,
next_cursor: '',
previous_cursor: '',
remaining: ''
})
const reqData = ref({
page_size: 20,
cursor: '',
search: {
name: '',
},
filter: {
price_min: '',
price_max: '',
item_ids: [],
hero_ranks: [],
},
sort: {
fields: [
{
name: 'price',
type: 0,
}
]
}
})
const loadingDialogVisible = ref(false)
const nftList = ref([])
const isClearAll = ref(false)
const contentScroll = ref()
const clearOverviewAll = () => {
window.scrollTo(0, 0)
marketplaceList.overview = ''
toRaw(marketplaceList.getParamsData).search.name = ''
reqData.value.search.name = ''
marketplaceList.getParamsData.cursor = ''
reqData.value.cursor = ''
nftList.value = []
getHeroData()
}
const overviewChild = (val) => {
window.scrollTo(0, 0)
marketplaceList.overview = val
toRaw(marketplaceList.getParamsData).search.name = val
reqData.value.search.name = val
marketplaceList.getParamsData.cursor = ''
nftList.value = []
getHeroData()
}
const clearSortAll = () => {
window.scrollTo(0, 0)
marketplaceList.sort = ''
toRaw(marketplaceList.getParamsData).sort.fields[0].type = ''
reqData.value.sort.fields[0].type = ''
marketplaceList.getParamsData.cursor = ''
reqData.value.cursor = ''
nftList.value = []
getHeroData()
}
const sortChild = (val) => {
window.scrollTo(0, 0)
marketplaceList.sort = val
toRaw(marketplaceList.getParamsData).sort.fields[0].type = val
reqData.value.sort.fields[0].type = val
console.log(toRaw(marketplaceList.getParamsData).sort.fields[0].name)
marketplaceList.getParamsData.cursor = ''
nftList.value = []
getHeroData()
}
const clearPriceAll = () => {
window.scrollTo(0, 0)
marketplaceList.minPrice = ''
marketplaceList.maxPrice = ''
toRaw(marketplaceList.getParamsData).filter.price_min = ''
toRaw(marketplaceList.getParamsData).filter.price_max = ''
reqData.value.filter.price_min = ''
reqData.value.filter.price_max = ''
reqData.value.cursor = ''
marketplaceList.getParamsData.cursor = ''
nftList.value = []
getHeroData()
}
const priceChild = (minPrice, maxPrice) => {
window.scrollTo(0, 0)
toRaw(marketplaceList.getParamsData).filter.price_min = minPrice ? Number(minPrice) * 1e6 : ''
toRaw(marketplaceList.getParamsData).filter.price_max = maxPrice ? Number(maxPrice) * 1e6 : ''
toRaw(reqData.value).filter.price_min = minPrice ? Number(minPrice) * 1e6 : ''
toRaw(reqData.value).filter.price_max = maxPrice ? Number(maxPrice) * 1e6 : ''
reqData.value.cursor = ''
marketplaceList.getParamsData.cursor = ''
nftList.value = []
getHeroData()
}
const clearHeroAll = () => {
window.scrollTo(0, 0)
marketplaceList.hero = []
reqData.value.filter.item_ids = [...marketplaceList.gold,...marketplaceList.hero]
toRaw(marketplaceList.getParamsData).filter.item_ids = [...marketplaceList.gold,...marketplaceList.hero]
reqData.value.cursor = ''
marketplaceList.getParamsData.cursor = ''
nftList.value = []
getHeroData()
}
const heroChild = (val) => {
window.scrollTo(0, 0)
marketplaceList.hero = val
reqData.value.filter.item_ids = [...marketplaceList.gold,...marketplaceList.hero]
toRaw(marketplaceList.getParamsData).filter.item_ids = [...marketplaceList.gold,...marketplaceList.hero]
marketplaceList.getParamsData.cursor = ''
nftList.value = []
getHeroData()
}
const clearRankAll = () => {
window.scrollTo(0, 0)
marketplaceList.rank = []
reqData.value.filter.hero_ranks = []
toRaw(marketplaceList.getParamsData).filter.hero_ranks = []
reqData.value.cursor = ''
marketplaceList.getParamsData.cursor = ''
nftList.value = []
getHeroData()
}
const rankChild = (val) => {
window.scrollTo(0, 0)
marketplaceList.rank = val
reqData.value.filter.hero_ranks = val
toRaw(marketplaceList.getParamsData).filter.hero_ranks = val
marketplaceList.getParamsData.cursor = ''
nftList.value = []
getHeroData()
}
const clearGoldAll = () => {
window.scrollTo(0, 0)
marketplaceList.gold = []
reqData.value.filter.item_ids.filter.item_ids = [...marketplaceList.gold,...marketplaceList.hero]
toRaw(marketplaceList.getParamsData).filter.item_ids = [...marketplaceList.gold,...marketplaceList.hero]
marketplaceList.getParamsData.cursor = ''
nftList.value = []
getHeroData()
}
const goldChild = (val) => {
window.scrollTo(0, 0)
marketplaceList.gold = val
reqData.value.filter.item_ids = [...marketplaceList.gold,...marketplaceList.hero]
toRaw(marketplaceList.getParamsData).filter.item_ids = [...marketplaceList.gold,...marketplaceList.hero]
marketplaceList.getParamsData.cursor = ''
nftList.value = []
getHeroData()
}
const clearAll = () => {
window.scrollTo(0, 0)
marketplaceList.overview = ''
marketplaceList.sort = ''
marketplaceList.minPrice = ''
marketplaceList.maxPrice = ''
marketplaceList.hero = []
marketplaceList.rank = []
marketplaceList.gold = []
marketplaceList.getParamsData.cursor = ''
marketplaceList.getParamsData = {
page_size: 20,
cursor: '',
search: {
name: '',
},
filter: {
price_min: '',
price_max: '',
item_ids: [],
hero_ranks: [],
},
sort: {
fields: [
{
name: 'price',
type: 0,
}
]
}
}
nftList.value = []
getHeroData()
}
const searchName = (id) => {
return NftId[id].name
}
// 更新数据
const renewNft = async() => {
let timer = setTimeout(() => {
getHeroData()
// location.reload()
clearTimeout(timer);
}, 2000);
}
// 总条数
const totalCount = ref(0)
const getHeroData = async () => {
// loadingDialogVisible.value = false;
try {
let nftListBox
// const { errcode, errmsg, rows, page } = await marketplaceList.getMarketplaceState(reqData.value)
const { errcode, errmsg, rows, page } = await apiMarketplaceState(marketplaceList.getParamsData)
// console.log((toRaw(marketplaceList.cursorObj))
if(!errmsg) {
nftList.value = [...nftList.value, ...rows]
nftListBox = Array.from(new Set(nftList.value.map(JSON.stringify))).map(JSON.parse);
// nftListBox = nftList.value.reduce((acc, obj) => {
// const existingObj = acc.find(item => item.event == obj.event)
// if(!existingObj) {
// acc.push(obj)
// }
// return acc
// },[])
nftList.value = nftListBox
totalCount.value = page.total_count
cursorObj.value = page
marketplaceList.cursorObj = page
}
// loadingDialogVisible.value = false;
} catch(e) {
// console.log(e)
// loadingDialogVisible.value = false;
}
}
// 监听筛选变化
watch(() => [marketplaceList.overview,marketplaceList.minPrice,marketplaceList.maxPrice,marketplaceList.hero,marketplaceList.rank,marketplaceList.gold],
([preTest1, preTest2, preTest3, preTest4, preTest5, preTest6],
[oldTest1, oldTest2, oldTest3, oldTest4, oldTest5, oldTest6]) => {
if(toRaw(preTest1) || toRaw(preTest2) || toRaw(preTest3) || (toRaw(preTest4) !=[] && preTest4.length > 0 ) || (toRaw(preTest5) !=[] && toRaw(preTest5).length > 0 ) || (toRaw(preTest6) !=[] && toRaw(preTest6).length > 0 )) {
isClearAll.value = true
} else {
isClearAll.value = false
}
})
// 滚动条变化修改游标
const marketHandleScroll = () => {
var scrollTop =
document.documentElement.scrollTop || document.body.scrollTop; //变量windowHeight是可视区的高度
var windowHeight =
document.documentElement.clientHeight || document.body.clientHeight; //变量scrollHeight是滚动条的总高度
var scrollHeight =
document.documentElement.scrollHeight || document.body.scrollHeight;
if (scrollTop + windowHeight == scrollHeight) {
//请求数据接口
if(toRaw(cursorObj.value).remaining != 0) {
// marketplaceList.getParamsData.cursor = ''
// toRaw(reqData.value).cursor
marketplaceList.getParamsData.cursor = toRaw(cursorObj.value).next_cursor
getHeroData()
} else {
return false;
}
return false;
}
}
onMounted(() => {
getHeroData()
window.addEventListener("scroll", marketHandleScroll, true);
})
onUnmounted(() => {
window.removeEventListener('scroll', marketHandleScroll)
})
</script>
<style lang="scss" scoped>
.mkt-content {
width: 100%;
display: flex;
justify-content: space-between;
background: #16141b;
box-shadow: 0 -80px 80px #16141b;
.mkt-content-left {
position: -webkit-sticky;
position: sticky;
top: 100px;
width: 300px;
height: 800px;
padding: 0 35px;
padding-bottom: 40px;
box-sizing: border-box;
overflow-y: auto;
overflow-x: hidden;
h2 {
font-family: "Poppins";
font-weight: bold;
font-size: 20px;
color: #bb7fff;
margin-bottom: 20px;
}
.sort {
width: 100%;
:deep(.ant-select) {
width: 100%;
.ant-select-selector {
width: 220px;
padding: 0;
background: #1a1821;
border-color: #4A4B6E;
color: #b3b5da;
padding-left: 20px;
.ant-select-item-option-active {
background: #1a1821;
}
.ant-select-item-option-selected:not(.ant-select-item-option-disabled) {
background: #1a1821 !important;
}
}
}
}
&::-webkit-scrollbar {
width: 0px;
}
&::-webkit-scrollbar-track {
background: #171220;
border-radius: 2px;
}
&::-webkit-scrollbar-corner {
display: block;
}
&::-webkit-scrollbar-thumb {
height: 15px;
background: #9950fd;
border-radius: 10px;
}
}
.mkt-content-right {
width: calc(100% - 300px);
padding-right: 40px;
margin-left: 40px;
.mkt-content-right-header {
width: calc(100% - 10px);
height: 60px;
// position: -webkit-sticky;
// position: sticky;
// top: 0;
// padding-top: 120px;
display: flex;
align-items: center;
border-bottom: 2px solid #3a3b57;
.bg-cor {
width: 15px;
height: 15px;
background: #18ff00;
margin-left: 10px;
border-radius: 50%;
}
.results-total {
display: flex;
align-items: center;
margin-left: 15px;
font-size: 14px;
color: #b3b5da;
}
.search-list {
display: flex;
align-items: center;
color: #fff;
li {
margin-left: 10px;
background: #2d2738;
padding: 5px 10px;
border-radius: 10px;
font-size: 12px;
cursor: pointer;
}
.clear-all {
background: #5a4a6d;
}
}
}
.mkt-content-right-content {
margin-top: 30px;
.pages {
display: flex;
flex-wrap: wrap;
clear: both;
li {
width: calc(25% - 10px);
margin-right: 10px;
margin-bottom: 10px;
cursor: pointer;
&:nth-child(4n) {
margin-right: 0;
}
}
}
.pages-no {
position: relative;
margin-top: 150px;
div {
margin: 0 auto;
width: 401px;
height: 322px;
img {
width: 100%;
height: 100%;
}
}
p {
position: absolute;
top: 260px;
left: 52%;
transform: translateX(-50%);
font-family: 'Poppins';
font-weight: bold;
font-size: 40px;
color: #8587B2;
}
}
}
}
}
</style>