525 lines
16 KiB
Vue
525 lines
16 KiB
Vue
<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> |