新增下链历史记录

This commit is contained in:
yuyongdong 2024-07-11 20:03:06 +08:00
parent c79c6223b4
commit 2ef71a1961
9 changed files with 583 additions and 19 deletions

View File

@ -6,9 +6,10 @@
</li>
</div>
<div class="content">
<Collectibles v-show="navIndex == 0" />
<Hanging v-show="navIndex == 1" />
<Trading v-show="navIndex == 2" />
<Collectibles v-if="navIndex == 0" />
<Hanging v-else-if="navIndex == 1" />
<Trading v-else-if="navIndex == 2" />
<Convert v-else-if="navIndex == 3" />
</div>
</div>
</template>
@ -20,6 +21,7 @@ import Status from "@/components/common/searchView/status.vue"
import Collectibles from "./collectibles.vue"
import Hanging from "./hanging.vue"
import Trading from "./trading.vue"
import Convert from "./convert.vue"
import { useMarketplaceStore } from "@/store/marketplace"
const marketplaceList = useMarketplaceStore()
@ -34,6 +36,9 @@ const navList = ref([
{
name: "Trading History"
},
{
name: "Activity"
},
])
const navIndex = ref(0)
const nftList = ref([])

View File

@ -9,6 +9,9 @@
<div>
</div>
</div>
<!-- <div class="uaw-listing">
<div>uaw</div>
</div> -->
</div>
</template>
@ -38,10 +41,14 @@ const imageUrl = computed(() => {
<style lang="scss" scoped>
.mkt-header {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding-top: 168px;
.assets-user {
display: flex;
// margin: 168px 0 45px 77px;
padding: 168px 0 45px 77px;
padding: 0 0 45px 77px;
.assets-user-img {
width: 173.8px;
height: 173.8px;
@ -60,5 +67,17 @@ const imageUrl = computed(() => {
color: #FFFFFF;
}
}
.uaw-listing {
color: #FFFFFF;
// padding-top: 168px;
// padding-right: 80px;
margin-right: 77px;
border: 2px solid #3a3b57;
box-sizing: border-box;
div {
width: 180px;
height: 180px;
}
}
}
</style>

View File

@ -0,0 +1,264 @@
<template>
<div class="collection">
<div class="content-left">
<div class="left-content-left">
<OverView :overviewValue="overviewValue" @clickOverviewChild="overviewChild" />
<!-- <Status :statusValue="statusValue" @clickStatusChild="statusChild" /> -->
<Hero :heroArr="heroValue" :rankArr="rankValue" @clickHeroChild="heroChild" @clickRankChild="rankChild" />
<Gold :goldArr="goldValue" @clickGoldChild="goldChild" />
</div>
</div>
<div class="content-right">
<div class="content-right-header">
<div class="bg-cor"></div>
<div class="results-total">{{ nftList.length }} Results</div>
</div>
<div class="content-right-content">
<div class="pages-horizontal" v-show="nftList !== undefined && nftList.length > 0">
<Card v-if="nftList != undefined || nftList.length > 0" :nftData="nftList" />
</div>
<div class="pages-no" v-show="nftList == undefined || nftList.length <= 0">
<div>
<img src="@/assets/img/marketplace/Empty_state.png" alt="">
</div>
<p>No NFT yet</p>
</div>
</div>
</div>
</div>
</template>
<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 Hero from "@/components/common/searchView/hero.vue"
import Gold from "@/components/common/searchView/gold.vue"
import Card from "@/components/common/convertCard.vue";
import NftId from "@/configs/item.json"
import { apiLockState } from "@/utils/marketplace"
import {useMarketplaceStore} from "@/store/marketplace";
import {walletStore} from "@/store/wallet";
const marketplaceStore = useMarketplaceStore()
const localWalletStore = walletStore()
const nftList = ref([])
// console.log('localWalletStore', localWalletStore.token)
const overviewValue = ref()
const heroValue = ref([])
const rankValue = ref([])
const goldValue = ref([])
const reqData = ref({
page_size: 20, //
cursor: "", //
search: {
name: ""
}, //struct list,
filter: { //struct list,
item_ids: [], //id ()
hero_ranks: [],
},
sort: { //struct list,
fields: [ //
]
}
})
const next_cursor = ref({
count: "",
next_cursor: "",
previous_cursor: "",
remaining: "",
total_count: "",
})
const overviewChild = (val) => {
window.scrollTo(0, 0)
overviewValue.value = val
reqData.value.search.name = val
next_cursor.value = ''
marketplaceStore.cursorObj.next_cursor = ''
nftList.value = []
getMyAssets()
}
const heroChild = (val) => {
window.scrollTo(0, 0)
reqData.value.filter.item_ids = [...val, ...goldValue.value]
next_cursor.value = ''
heroValue.value = val
nftList.value = []
getMyAssets()
}
const rankChild = (val) => {
window.scrollTo(0, 0)
rankValue.value = val
reqData.value.filter.hero_ranks = val
next_cursor.value = ''
nftList.value = []
getMyAssets()
}
const goldChild = (val) => {
window.scrollTo(0, 0)
goldValue.value = val
next_cursor.value = ''
reqData.value.filter.item_ids = [...val, ...heroValue.value]
nftList.value = []
getMyAssets()
}
const getMyAssets = async () => {
// nftList.value = []
const myADdress = localWalletStore.address
// console.log(data)
// return
if(myADdress) {
try {
reqData.value.cursor = next_cursor.value.next_cursor
let res = await apiLockState(myADdress, reqData.value)
// return
nftList.value = [...nftList.value, ...res.rows]
// nftListBox = nftList.value.reduce((acc, obj) => {
// const existingObj = acc.find(item => item.token_id == obj.token_id)
// if(!existingObj) {
// acc.push(obj)
// }
// return acc
// },[])
// nftList.value = nftListBox
marketplaceStore.cursorObj = res.page
next_cursor.value = res.page
} catch(e) {
console.log(e)
}
}
}
const handleScroll = () => {
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) {
//
// console.log('scrollTop + windowHeight == scrollHeight',toRaw(marketplaceStore.cursorObj), scrollTop, windowHeight, scrollHeight)
if(toRaw(next_cursor.value).remaining != 0) {
getMyAssets()
}
return false;
}
}
watch(localWalletStore,() => {
// console.log('localWalletStore.token',localWalletStore.address,localWalletStore.token)
if(!localWalletStore.token) {
nftList.value = []
} else {
getMyAssets()
}
})
onMounted(() => {
getMyAssets()
window.addEventListener("scroll", handleScroll, true);
})
onUnmounted(() => {
window.removeEventListener('scroll', handleScroll)
})
</script>
<style lang="scss" scoped>
.collection {
width: 100%;
display: flex;
justify-content: space-between;
background: #16141b;
box-shadow: 0 -10px 10px #16141b;
.content-left {
width: 300px;
height: 800px;
position: sticky;
top: 140px;
padding: 0 35px;
box-sizing: border-box;
.left-content-left {
}
}
.content-right {
width: calc(100% - 300px);
padding-right: 40px;
.content-right-header {
width: calc(100% - 10px);
height: 60px;
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;
}
}
.content-right-content {
margin-top: 30px;
.pages-horizontal {
display: flex;
// justify-content: space-between;
flex-wrap: wrap;
clear: both;
li {
width: calc(25% - 10px);
// height: 360px;
margin-right: 10px;
margin-bottom: 10px;
cursor: pointer;
&:nth-child(4n) {
margin-right: 0;
}
}
}
.pages-no {
position: relative;
margin-top: 256px;
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;
}
}
.pages-vertical {
color: #fff;
}
}
}
}
</style>

View File

@ -0,0 +1,255 @@
<template>
<div>
<a-table :dataSource="nftData" :pagination="false">
<a-table-column title="NFT" data-index="nft" :width="400">
<template #default="{ text: nft }">
<div class="nft">
<div class="nft-img">
<ImgCard :nftData="nft" />
</div>
<div class="nft-name">{{ nft.name }}</div>
</div>
</template>
</a-table-column>
<a-table-column title="Status" data-index="nft" :width="400">
<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>
</template>
</a-table-column>
<a-table-column title="Quantity" data-index="nft" :width="400">
<template #default="{ text: nft }">
<div class="quantity">
<div v-if="nft.detail.quality" class="nft-quantity">{{ nft.detail.quality }}</div>
<div v-else class="nft-quantity">{{ nft.detail.gold_coins }}</div>
</div>
</template>
</a-table-column>
<a-table-column title="From" data-index="event" :width="400">
<template #default="{ text: event }">
<div class="sender">
<div class="nft-sender">{{ sliceAddress(localWalletStore.address) }}</div>
</div>
</template>
</a-table-column>
<a-table-column title="" data-index="event">
<template #default="{ text: nft }">
<div class="from-to-icon">
<img src="@/assets/img/marketplace/Arrows.png" alt="">
</div>
</template>
</a-table-column>
<a-table-column title="To" data-index="nft" :width="400">
<template #default="{ text: nft }">
<div class="recipient">
<div class="nft-recipient">{{ sliceAddress(nft.owner_address) }}</div>
</div>
</template>
</a-table-column>
<a-table-column title="Date" data-index="nft" :width="400">
<template #default="{ text: nft }">
<div class="date">
<div class="nft-date">{{ timeFormat(nft.last_lock_time*1000) }}</div>
</div>
</template>
</a-table-column>
<a-table-column title="Contract" data-index="nft" :width="400">
<template #default="{ text: nft }">
<div class="contract">
<div class="nft-contract">
<a :href="chainExpolor(nft)" target="_back">
<span>lmmutascan</span>
<img src="@/assets/img/marketplace/Links_web_icon.png" alt="">
</a>
</div>
</div>
</template>
</a-table-column>
</a-table>
</div>
</template>
<script setup>
import { ref, toRaw } from "vue"
import ImgCard from "@/components/common/imgCard.vue"
import { sliceAddress, showTime, priceCalculated } from "@/configs/priceCalculate"
import { timeFormat } from "@/configs/priceCalculate"
import { currentChainCfg } from '@/components/chain/utils'
import {walletStore} from "@/store/wallet";
const localWalletStore = walletStore()
const props = defineProps({
nftData: {
type: Array,
required: true,
},
});
const chainExpolor = (nft) => {
return `${import.meta.env.VUE_APP_EXPLORER_URL}/token/${nft.contract_address}/instance/${nft.token_id}`
}
</script>
<style lang="scss" scoped>
div {
:deep(.ant-table-wrapper) {
.ant-spin-nested-loading {
.ant-spin-container {
.ant-table {
color: #fff;
background: #16141b;
.ant-table-container {
.ant-table-content {
.ant-table-thead {
tr {
th {
color: #B3B5DA;
background: #16141b;
border-color: #34354e;
text-align: center;
font-size: 24px;
&::before {
display: none;
}
}
}
}
.ant-table-tbody {
tr {
background: #16141b;
td {
border-color: #34354e;
background: #16141b !important;
overflow: visible !important;
vertical-align: middle;
// padding: 12px;
>div {
text-align: center;
font-family: 'Poppins';
font-weight: 600;
font-size: 20px;
color: #F3F0FF;
}
.nft {
display: flex;
align-items: center;
justify-content: space-evenly;
.nft-img {
width: 213px;
height: 100%;
.card-img-common {
.img-top {
width: 60px;
height: 20px;
top: 10px;
left: 10px;
font-size: 14px;
}
.img-btm {
bottom: 15px;
left: 20px;
>div {
width: 58px;
height: 20px;
font-size: 12px;
}
div:nth-child(2) {
margin-left: 8px;
}
}
}
}
.nft-name {
width: 160px;
text-align: left;
margin-left: 5px;
}
}
.status {
color: #FFC35B;
}
.price {
min-width: 80px;
color: #BB7FFF;
font-weight: 400;
position: relative;
.nft-price {
font-family: 'Anton';
font-size: 42px;
}
p {
width: 100%;
position: absolute;
left: 50%;
transform: translateX(-50%);
font-size: 24px;
}
}
.price-icon {
width: 43px;
span {
display: none;
}
img {
width: 43px;
height: 43px;
}
}
.from-to-icon {
width: 34px;
span {
display: none;
}
img {
width: 34px;
height: 16px;
}
}
.nft-date {
width: 120px;
margin: 0 auto;
}
.nft-contract {
a {
display: flex;
align-items: end;
color: #9950FD;
font-size: 15px;
span {
border-bottom: 2px solid #9950FD;
}
img {
width: 21px;
height: 20px;
margin-left: 16px;
}
}
}
&:nth-child(1) {
padding-left: 0px;
}
}
&:hover {
background: #16141b !important;
td {
background: #16141b !important;
}
.ant-table-cell-row-hover {
background: #16141b !important;
}
.ant-table-cell {
background: #16141b !important;
}
}
}
}
}
}
}
}
}
}
}
</style>

View File

@ -6,7 +6,7 @@
<span>{{ item.label }}</span>
<span>{{ goldList.length }}</span>
</a-checkbox> -->
<a-checkbox-group :value="marketplaceList.gold" :options="goldList" @change="onChangeValue" />
<a-checkbox-group :value="goldArr" :options="goldList" @change="onChangeValue" />
<template #extra>{{ goldList.length }}</template>
</a-collapse-panel>
</a-collapse>
@ -17,20 +17,24 @@ import { ref, reactive } from "vue";
// import { SettingOutlined } from "@ant-design/icons-vue";
import { useMarketplaceStore } from "@/store/marketplace"
const marketplaceList = useMarketplaceStore()
const props = defineProps({
goldArr: {
type: Array,
required: true,
},
});
const emit = defineEmits(['clickGoldChild'])
const goldList = [
const goldList = [
{ label: "Gold Card", value: "10017" },
{ label: "Black Gold Card", value: "10018" },
];
const checkArr = ref([])
const state = reactive({
value: ["10000"],
});
const expandIconPosition = ref("end");
const handleClick = (event) => {
// If you don't want click extra trigger collapse, you can prevent this:
event.stopPropagation();
};
const onChangeValue = (e) => {
// ToDo:
marketplaceList.gold = e

View File

@ -5,9 +5,9 @@
<!-- <a-checkbox v-for="item in goldList" :key="item.value" @change="onChangeValue(item.value)">
<span>{{ item.label }}</span>
</a-checkbox> -->
<a-checkbox-group :value="marketplaceList.hero" :options="heroList" @change="onChangeValue" />
<a-checkbox-group :value="heroArr" :options="heroList" @change="onChangeValue" />
<h2>Tier</h2>
<a-checkbox-group :value="marketplaceList.rank" :options="rankList" @change="onChange" />
<a-checkbox-group :value="rankArr" :options="rankList" @change="onChange" />
<template #extra>{{ heroList.length }}</template>
</a-collapse-panel>
</a-collapse>
@ -19,6 +19,17 @@ import { ref, reactive } from "vue";
import { useMarketplaceStore } from "@/store/marketplace"
const marketplaceList = useMarketplaceStore()
const props = defineProps({
heroArr: {
type: Array,
required: true,
},
rankArr: {
type: Array,
required: true,
},
});
const emit = defineEmits(['clickHeroChild','clickRankChild'])
const heroList = [

View File

@ -5,8 +5,8 @@
<Sort @clickSortChild="sortChild" />
<Price @clickPriceChild="priceChild" />
<h2>Type</h2>
<Hero @clickHeroChild="heroChild" @clickRankChild="rankChild" />
<Gold @clickGoldChild="goldChild" />
<Hero :heroArr="marketplaceList.hero" :rankArr="marketplaceList.rank" @clickHeroChild="heroChild" @clickRankChild="rankChild" />
<Gold :goldArr="marketplaceList.gold" @clickGoldChild="goldChild" />
</div>
<div class="mkt-content-right">
<div class="mkt-content-right-header">

View File

@ -30,7 +30,7 @@ export const sliceAddress = (address) => {
// 处理时间
export const timeFormat = (value) => {
return moment(value).format('YYYY/MM/DD HH:mm')
return moment(value).format('YYYY-MM-DD HH:mm:ss')
}
export const royaltiesPrice = (price) => {

View File

@ -71,6 +71,12 @@ export const apiHistoryState = async (account_address,data) => {
return httpGet(url, data)
}
// 账号游戏内资产
export const apiLockState = async (account_address,data) => {
const url = `${API_BASE}/api/market/product/lock/${net_id}/${account_address}`
return httpPost(url, data)
}
// 详情
export const apiDetail = async (account_address) => {
const url = `${API_BASE}/api/market/transaction/history/${net_id}/${account_address}`