1133 lines
51 KiB
HTML
1133 lines
51 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
||
<meta name="description" content="PYXEL || Ultimate Gaming HTML Template" />
|
||
|
||
<title>Samsara DAO</title>
|
||
|
||
<!-- Favicon -->
|
||
<script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>
|
||
<!-- All CSS files -->
|
||
<link rel="stylesheet" href="static/css/font-awesome.css" />
|
||
<link rel="stylesheet" href="static/css/bootstrap.min.css" />
|
||
<link rel="stylesheet" href="static/css/app.css" />
|
||
<link rel="stylesheet" href="static/js/element-ui-min.css" />
|
||
<style>
|
||
.nft_page {
|
||
background-color: #fff;
|
||
padding: 10vh;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.nft_page_left {
|
||
width: 15%;
|
||
}
|
||
|
||
.nft_page_left .type {
|
||
padding: 2vh 0;
|
||
text-align: center;
|
||
background-color: #f2f2f2;
|
||
}
|
||
|
||
.nft_page_left .type_list {
|
||
padding: 2vh 0;
|
||
text-align: center;
|
||
background-color: #f2f2f2;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.nft_page_right {
|
||
width: calc(85% - 4vh);
|
||
}
|
||
|
||
.nft_type_active {
|
||
background-color: #446ffa;
|
||
color: #fff;
|
||
padding: 2vh 0;
|
||
text-align: center;
|
||
}
|
||
|
||
.page_nft_title {
|
||
display: flex;
|
||
margin-bottom: 4vh;
|
||
}
|
||
|
||
.page_nft_title>div {
|
||
flex: 1;
|
||
background-color: #f2f2f2;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.page_nft_title .title_active {
|
||
background-color: #446ffa;
|
||
color: #fff;
|
||
height: 7vh;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.title {
|
||
height: 7vh;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.page_nft_list {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
justify-content: flex-start;
|
||
gap: 20px;
|
||
}
|
||
|
||
.page_nft_list>div {
|
||
box-sizing: border-box;
|
||
flex-basis: 32%;
|
||
}
|
||
|
||
.good_img {
|
||
width: 40%;
|
||
max-width: 240px;
|
||
padding-bottom: 24px;
|
||
}
|
||
|
||
.page_nft_item {
|
||
background-color: #f2f2f2;
|
||
padding: 12px 18px;
|
||
|
||
&:hover {
|
||
background-color: #e9e9e9;
|
||
border-radius: 8px;
|
||
box-shadow: 3px 3px 5px #d1d1d1;
|
||
}
|
||
}
|
||
|
||
.page_nft_item>div {
|
||
padding-bottom: 8px;
|
||
}
|
||
|
||
.btn {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.btn1 {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
height: 5vh;
|
||
background-color: #446ffa;
|
||
color: #fff;
|
||
border-radius: 5px;
|
||
margin-right: 20px;
|
||
padding: 0 3vh;
|
||
}
|
||
|
||
.btn2 {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
height: 5vh;
|
||
background-color: #f2f2f2;
|
||
color: #446ffa;
|
||
border-radius: 5px;
|
||
border: #446ffa 1px solid;
|
||
padding: 0 1vh;
|
||
}
|
||
|
||
.Top {
|
||
display: flex;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.Top_left {
|
||
width: 20%;
|
||
margin-right: 5%;
|
||
}
|
||
|
||
.Top_right {
|
||
width: 80%;
|
||
}
|
||
|
||
.Top img {
|
||
width: 100%;
|
||
}
|
||
|
||
.Top_right_title {
|
||
display: flex;
|
||
}
|
||
|
||
.Top_right_desc {
|
||
display: flex;
|
||
}
|
||
|
||
.Top_right_desc_title {
|
||
width: 30%;
|
||
}
|
||
|
||
.Top_rightlabel {
|
||
margin-right: 1vh;
|
||
}
|
||
|
||
.Top_righttext {
|
||
font-weight: 600;
|
||
flex: 1;
|
||
}
|
||
|
||
.smalls {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin: 4% 0;
|
||
}
|
||
|
||
.nft {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-top: 2vh;
|
||
}
|
||
|
||
.nft >div:last-child{
|
||
flex: 1;
|
||
}
|
||
|
||
.nftbtn {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
margin-top: 7%;
|
||
}
|
||
|
||
.nftbtn-cancel {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
width: 12%;
|
||
border-radius: 10%;
|
||
height: 4vh;
|
||
background-color: #f2f2f2;
|
||
color: #999;
|
||
margin-right: 2%;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.nftbtn-save {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
width: 12%;
|
||
border-radius: 10%;
|
||
height: 4vh;
|
||
background-color: #446ffa;
|
||
color: #fff;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.page_nft_page {
|
||
margin-top: 32px;
|
||
display: flex;
|
||
justify-content: end;
|
||
|
||
}
|
||
|
||
.typeItem:hover {
|
||
background-color: #e1e1e1;
|
||
color: #446ffa;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.attr-box,
|
||
.allClass {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
justify-content: flex-start;
|
||
gap: 8px;
|
||
background-color: #e9e9e9;
|
||
padding: 12px;
|
||
margin: 12px 0;
|
||
}
|
||
|
||
.attr-box-item {
|
||
display: inline-flex;
|
||
padding: 4px 12px;
|
||
cursor: pointer;
|
||
border-radius: 4px;
|
||
border: 1px solid transparent;
|
||
|
||
&:hover {
|
||
border-color: #446ffa;
|
||
background-color: #e1e1e1;
|
||
color: #446ffa;
|
||
box-shadow: 3px 3px 5px #d1d1d1;
|
||
}
|
||
}
|
||
|
||
.allClass {
|
||
margin: 0px;
|
||
background-color: transparent;
|
||
margin-bottom: 32px;
|
||
}
|
||
|
||
.attr_active {
|
||
background-color: #446ffa;
|
||
color: #fff;
|
||
}
|
||
|
||
.disabled {
|
||
background-color: #d1d1d1;
|
||
|
||
&:hover {
|
||
cursor: no-drop;
|
||
border-color: #d1d1d1;
|
||
background-color: #d1d1d1;
|
||
color: #000;
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body class="tt-smooth-scroll">
|
||
<!-- Main Wrapper Start -->
|
||
<div id="app" v-cloak>
|
||
<!-- HEADER MENU START -->
|
||
<div id="publickHeader"></div>
|
||
<!-- HEADER MENU END -->
|
||
|
||
<!-- BG-SIGN*UP PAGE # 1 START -->
|
||
<div class="nft_page">
|
||
<div class="nft_page_left">
|
||
<div class="type">{{currentLanguage == 'zh' ? '分類':'Classification'}}</div>
|
||
<div class="typeItem" v-for="item in nfttypeList" :key="item.id"
|
||
:class="[typeactive == item.id? 'nft_type_active':'type_list']" @click="cheangetypeact(item.id)">
|
||
{{currentLanguage == 'zh' ? item.title_cn:item.title_en}}
|
||
</div>
|
||
</div>
|
||
<div class="nft_page_right">
|
||
<div class="page_nft_title">
|
||
<div :class="[titleactive == 1? 'title_active':'title']" @click="cheangetitact(1)">
|
||
NFT
|
||
</div>
|
||
<div :class="[titleactive == 2? 'title_active':'title']" @click="cheangetitact(2)">
|
||
{{currentLanguage == 'zh' ? '倉庫':'Warehouse'}}
|
||
</div>
|
||
<div :class="[titleactive == 3? 'title_active':'title']" @click="cheangetitact(3)">
|
||
{{currentLanguage == 'zh' ? '上架中':'Available now'}}
|
||
</div>
|
||
<div :class="[titleactive == 4? 'title_active':'title']" @click="cheangetitact(4)">
|
||
{{currentLanguage == 'zh' ? '租賃中':'Lease'}}
|
||
</div>
|
||
<div :class="[titleactive == 5? 'title_active':'title']" @click="cheangetitact(5)">
|
||
{{currentLanguage == 'zh' ? '交易中':'Trading'}}
|
||
</div>
|
||
</div>
|
||
<div class="attr-box" v-show="attributeList.length > 0 && titleactive == 1">
|
||
<template v-for="(item , index) in attributeList.filter(item => { return item.own > 0})">
|
||
<div :key="item.id" v-if="index < 5" @click="checkFindGoods(item.id,item.own)"
|
||
:class="{'attr_active':attrCurrent.includes(item.id),'attr-box-item':true}">
|
||
<img :src="baseUrl + item?.img" alt=""
|
||
style="width: 24px; margin-right: 12px;" />{{currentLanguage == 'zh' ?
|
||
item?.name_cn:item?.name_en}}
|
||
</div>
|
||
</template>
|
||
<div style="flex-basis: 100%; margin-top: 12px;"
|
||
v-if="attributeList.filter(item => { return item.own > 0})?.length > 0">
|
||
<el-button icon="el-icon-search" round @click="loadData">{{currentLanguage == 'zh' ? '查詢':'Search'}}</el-button>
|
||
<el-button v-if="attributeList.length > 5 " type="text"
|
||
@click="showGoodClass = true">{{currentLanguage == 'zh' ? '更 多':'More'}}</el-button>
|
||
</div>
|
||
</div>
|
||
<!-- item -->
|
||
<div class="page_nft_list">
|
||
<el-empty style="margin: 30px auto;" :description="currentLanguage == 'zh' ? '暫無數據':'No Data'"
|
||
v-if="nftList.length === 0"></el-empty>
|
||
<div class="page_nft_item" v-for="item in nftList" :key="item.id">
|
||
<div style="text-align: center;"><img class="good_img" :src="baseUrl + item?.tpl_info?.img"
|
||
alt="" /></div>
|
||
<div>
|
||
<label style="color: #828080;">{{currentLanguage == 'zh' ? '名稱:':'Name:'}}</label>
|
||
<p>{{currentLanguage == 'zh' ? item?.tpl_info?.name_cn:item?.tpl_info?.name_en}}</p>
|
||
</div>
|
||
<div>
|
||
<label style="color: #828080;">{{currentLanguage == 'zh' ? '簡介:':'Introduce:'}}</label>
|
||
<p> {{currentLanguage == 'zh' ? item?.tpl_info?.desc_cn:item?.tpl_info?.desc_en}}</p>
|
||
</div>
|
||
<div>
|
||
<label style="color: #828080;">TokenId:</label>
|
||
<p v-if="item?.tokenId">{{item?.tokenId}}<i style="margin-left: 12px; cursor: pointer;"
|
||
@click="copyText(item?.tokenId)" class="el-icon-copy-document"></i></p>
|
||
</div>
|
||
<div>
|
||
<label style="color: #828080;">{{currentLanguage == 'zh' ? '合約地址:':'Contract address:'}}</label>
|
||
<p>{{maskString(item?.tpl_info?.caddr)}} <i style="margin-left: 12px; cursor: pointer;"
|
||
@click="copyText(item?.tpl_info?.caddr)" class="el-icon-copy-document"></i></p>
|
||
</div>
|
||
<div style="text-align: end;">
|
||
<label style="color: #828080;"> {{moment(item?.updatetime * 1000).format('YYYY-MM-DD HH:mm:ss')}} </label>
|
||
</div>
|
||
<div v-if="titleactive == 4">
|
||
<label style="color: #828080;">{{currentLanguage == 'zh' ? '租賃狀態:':'Lease Status:'}}</label>
|
||
<p>{{ currentLanguage == 'zh' ? (item.leaseuid > 0 ? '已租出':'未租出') : (item.leaseuid > 0 ? 'Rented':'Not rented out')}}</p>
|
||
</div>
|
||
<div v-if="titleactive == 4 || (titleactive == 2 && item.leasetime > 0)">
|
||
<label style="color: #828080;">{{currentLanguage == 'zh' ? '租賃到期時間:':'Lease expiration date:'}}</label>
|
||
<p>{{ item.leasetime > 0 ? moment(item.leasetime * 1000).format('YYYY-MM-DD HH:mm:ss') : '' }}</p>
|
||
</div>
|
||
<div class="btn">
|
||
<div class="btn1" v-if="nftStatus == '在售' && titleactive == 3" @click="removedNft(item)">{{currentLanguage == 'zh' ? '下架':'Removed'}}</div>
|
||
<div class="btn1" v-if="nftStatus == '可售'" @click="transaction(item,1)">{{currentLanguage == 'zh' ? '交易':'transaction'}}</div>
|
||
<div class="btn1" v-if="nftStatus == '可售'" @click="transaction(item,2)">{{currentLanguage == 'zh' ? '租賃':'lease'}}</div>
|
||
<div class="btn2" v-if="nftStatus == '可售'" @click="joinwarehouse(item.id,1)">{{currentLanguage == 'zh' ? '加入倉庫':'Join Warehouse'}}</div>
|
||
<div class="btn1" v-if="nftStatus == '在仓库'&& item.status == '在仓库'" @click="joinwarehouse(item.id,2)">{{currentLanguage == 'zh' ? '拿出倉庫':'Take out the warehouse'}}</div>
|
||
<div class="btn1" v-if="titleactive == 2 && item.leaseuid == userInfos.id" @click="myNftRenewal(item)">{{currentLanguage == 'zh' ? '續租':'Renewal'}}</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 分頁 -->
|
||
<div class="page_nft_page">
|
||
<el-pagination background v-if="total > 0" layout="prev, pager, next" :total="total"
|
||
:page-size="pageSize" :current-page="currentPage" @current-change="handlePageChange">
|
||
</el-pagination>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 上架到交易中心 -->
|
||
<el-dialog :title="currentLanguage == 'zh' ? (isLease ? '租賃' : '交易') : (isLease ? 'lease':'transaction')" :visible.sync="dialogVisible" width="30%">
|
||
<div class="Top">
|
||
<div class="Top_left">
|
||
<img :src="baseUrl + transactionInfo.img" alt="" />
|
||
</div>
|
||
<div class="Top_right">
|
||
<div class="Top_right_desc">
|
||
<div class="Top_rightlabel">{{ currentLanguage == 'zh' ? '名稱:' : 'Name:' }}</div>
|
||
<div class="Top_righttext">{{ currentLanguage == 'zh' ? transactionInfo.name_cn :
|
||
transactionInfo.name_en }}</div>
|
||
</div>
|
||
<div class="Top_right_desc">
|
||
<div class="Top_rightlabel">{{ currentLanguage == 'zh' ? '簡介:' : 'Introduction:' }}</div>
|
||
<div class="Top_righttext">
|
||
{{ currentLanguage == 'zh' ? transactionInfo.desc_cn : transactionInfo.desc_en }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="nft">
|
||
<div style="margin-right: 1%;">{{ currentLanguage == 'zh' ? '價格:' : 'Price:' }}</div>
|
||
<div><el-input v-model="nftPrice"
|
||
:placeholder="currentLanguage == 'zh' ? '請輸入價格' : 'Please enter the price'"></el-input></div>
|
||
</div>
|
||
<div class="nft" v-if="isLease">
|
||
<div style="margin-right: 1%;">{{ currentLanguage == 'zh' ? '時長(天):' : 'Duration(days):' }}</div>
|
||
<div><el-input v-model="nftDuration"
|
||
:placeholder="currentLanguage == 'zh' ? '請輸入天數' : 'Please enter the number of days'"></el-input></div>
|
||
</div>
|
||
<div class="nft" v-if="isLease">
|
||
<div style="margin-right: 1%;">{{ currentLanguage == 'zh' ? '續租增幅(%):' : 'Lease renewal rate (%):' }}</div>
|
||
<div><el-input v-model="nftRenewal"
|
||
:placeholder="currentLanguage == 'zh' ? '請輸入續租增幅' : 'Please enter the renewal increase'"></el-input></div>
|
||
</div>
|
||
<div class="nft">
|
||
<div style="margin-right: 1%;">{{ currentLanguage == 'zh' ? '收款地址:' : 'Receiving address:' }}</div>
|
||
<div><el-input v-model="nftintAdress"
|
||
:placeholder="currentLanguage == 'zh' ? '請輸入收款地址' : 'Please enter the payment address'"></el-input>
|
||
</div>
|
||
</div>
|
||
<div class="nft" style="color: red;">{{ currentLanguage == 'zh' ? `溫馨提示:交易時需要支付版權費和墊付GAS費,GAS費在商品交易成功時一起返回` : `Tips: You need to pay copyright fees and advance GAS fees when trading. The GAS fee will be returned when the commodity transaction is successful.` }}</div>
|
||
<div class="nftbtn">
|
||
<div class="nftbtn-cancel" @click="dialogVisible = false">{{ currentLanguage == 'zh' ? '取消' : 'cancel'
|
||
}}</div>
|
||
<div class="nftbtn-save" @click="submitNft">{{ currentLanguage == 'zh' ? '確定' : 'confirm' }}</div>
|
||
</div>
|
||
</el-dialog>
|
||
</el-dialog>
|
||
<!-- FOOTER START -->
|
||
<div id="publciFooter"></div>
|
||
<!-- FOOTER END -->
|
||
<!-- 錢包選擇彈窗 -->
|
||
<el-dialog :visible.sync="moneyDialogVisible" width="40%" custom-class="wallet-dialog">
|
||
<div class="wallet-container">
|
||
<i class="el-icon-close" @click="moneyDialogVisible = false"></i>
|
||
<div class="wallet-left">
|
||
<h6 style="font-weight: 700;margin-bottom: 4vh;">{{currentLanguage == 'zh' ? '連接錢包' : 'Connect wallet'}}</h6>
|
||
<p class="wallet-tip">
|
||
{{ currentLanguage == 'zh' ? `首先,連接以下其中一個錢包。 請務必安全地儲存您的私密金鑰或助記詞,永遠不要與任何人分享它們。` : `Firstly,
|
||
connect one of the following wallets. Please make sure to securely store your private keys or
|
||
mnemonics and never share them with anyone.` }}
|
||
</p>
|
||
|
||
<div class="wallet-grid">
|
||
<div v-for="(wallet,index) in wallets" :key="index" class="wallet-item"
|
||
@click="selectWallet(wallet)">
|
||
<img :src="wallet.icon" :alt="wallet.name">
|
||
<span>{{ wallet.name }}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="wallet-right" v-if="selectMoney.icon">
|
||
<div class="connecting-status">
|
||
<img :src="selectMoney.icon" class="tp-logo">
|
||
<p class="status-text">{{ currentLanguage == 'zh' ? '正在打開' : 'Opening' }} {{selectMoney.name}}
|
||
</p>
|
||
<p class="confirm-text">
|
||
{{ currentLanguage == 'zh' ? '請在' : 'Please in' }}
|
||
{{selectMoney.name}}
|
||
{{ currentLanguage == 'zh' ? '中確認' : 'Confirm in the middle' }}</p>
|
||
</div>
|
||
</div>
|
||
<div v-else style="display: flex;justify-content: center;align-items: center;width: 50%;">{{
|
||
moneyTip(moneyTipMessage) }}</div>
|
||
</div>
|
||
</el-dialog>
|
||
<!-- 錢包地址彈窗 -->
|
||
<el-dialog :visible.sync="showMoneyAdress" width="30%" :close-on-click-modal="false">
|
||
<div style="color: #000;">
|
||
{{ currentLanguage == 'zh' ? '錢包地址:' : 'Wallet address:' }}
|
||
{{ userMoneyAdressAll }}
|
||
<img src="static/image/fuzhi.png" @click="copyText(userMoneyAdressAll)"
|
||
style="margin-left: 5px;vertical-align: middle;cursor: pointer;">
|
||
</div>
|
||
</el-dialog>
|
||
<el-dialog
|
||
:title=" currentLanguage == 'zh' ? nfttypeList.find(item=>item.id == typeactive)?.title_cn: nfttypeList.find(item=>item.id == typeactive)?.title_en"
|
||
:visible.sync="showGoodClass" width="80%" :close-on-click-modal="false">
|
||
<div class="allClass">
|
||
<div @click="checkFindGoods(item.id,item.own)"
|
||
:class="{'attr_active':attrCurrent.includes(item.id),'attr-box-item':true,'disabled':item.own === 0}"
|
||
v-for="item in attributeList.filter(g=>{return g.own > 0})" :key="item.id">
|
||
<img :src="baseUrl + item?.img" alt="" style="width: 24px; margin-right: 12px;" />{{currentLanguage
|
||
== 'zh' ? item?.name_cn:item?.name_en}}
|
||
</div>
|
||
<div class="attr-box-item disabled" v-for="item in attributeList.filter(g=>{return g.own < 1})"
|
||
:key="item.id">
|
||
<img :src="baseUrl + item?.img" alt="" style="width: 24px; margin-right: 12px;" />{{currentLanguage
|
||
== 'zh' ? item?.name_cn:item?.name_en}}
|
||
</div>
|
||
<div style="flex-basis: 100%; margin-top: 36px; text-align: center;">
|
||
<el-button @click="showGoodClass = false">{{currentLanguage == 'zh' ? '關 閉':'Close'}}</el-button>
|
||
<el-button icon="el-icon-search" type="primary" @click="loadData">{{currentLanguage == 'zh' ? '查詢':'Search'}}</el-button>
|
||
</div>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
<!-- Main Wrapper End -->
|
||
|
||
<!-- Back To Top Start -->
|
||
<button class="scrollToTopBtn"><i class="fa fa-arrow-up"></i></button>
|
||
<!-- Mobile Menu Start -->
|
||
<div class="mobile-nav__wrapper">
|
||
<div class="mobile-nav__overlay mobile-nav__toggler"></div>
|
||
<div class="mobile-nav__content">
|
||
<span class="mobile-nav__close mobile-nav__toggler"><i class="fa fa-times"></i></span>
|
||
<div class="logo-box">
|
||
<a href="index.html" aria-label="logo image"><img src="static/picture/logo.png" alt="" /></a>
|
||
</div>
|
||
<div class="mobile-nav__container"></div>
|
||
</div>
|
||
</div>
|
||
<!-- Mobile Menu End -->
|
||
<!-- Jquery Js -->
|
||
<script src="static/js/bootstrap.min.js"></script>
|
||
<script src="static/js/jquery-3.6.3.min.js"></script>
|
||
<script src="static/js/jquery-validator.js"></script>
|
||
<script src="static/js/publickDOM.js"></script>
|
||
<!-- 引入翻譯文件 -->
|
||
<script src="static/js/translation.js"></script>
|
||
<script src="static/js/i18n.js"></script>
|
||
<!-- 獲取用戶信息 -->
|
||
<script src="static/js/getIsUser.js"></script>
|
||
<!-- 引入 Vue.js -->
|
||
<script src="static/js/vue.js"></script>
|
||
<!-- 引入 axios -->
|
||
<script src="static/js/axios.min.js"></script>
|
||
<!-- 引入 Element UI JS -->
|
||
<script src="static/js/element-ui.js"></script>
|
||
<!-- 引入 Moment.js -->
|
||
<script src="static/js/moment.min.js"></script>
|
||
<!-- 表單提交 -->
|
||
<script>
|
||
// 創建一個增強版的 localStorage
|
||
const enhancedStorage = {
|
||
setItem: function (key, value) {
|
||
localStorage.setItem(key, value)
|
||
// 觸發自定義事件
|
||
window.dispatchEvent(
|
||
new CustomEvent('localStorageChange', {
|
||
detail: { key, value },
|
||
})
|
||
)
|
||
},
|
||
getItem: function (key) {
|
||
return localStorage.getItem(key)
|
||
},
|
||
}
|
||
|
||
// 替換原始的 setItem 方法
|
||
const originalSetItem = localStorage.setItem
|
||
localStorage.setItem = function (key, value) {
|
||
originalSetItem.call(localStorage, key, value)
|
||
window.dispatchEvent(
|
||
new CustomEvent('localStorageChange', {
|
||
detail: { key, value },
|
||
})
|
||
)
|
||
}
|
||
new Vue({
|
||
el: '#app',
|
||
data() {
|
||
return {
|
||
nftrenewalInfos:{},//nft续租信息
|
||
nftDuration:"",//时长
|
||
nftRenewal:"",
|
||
isLease:false,
|
||
sendId:"",//交易的nft的id
|
||
connectWalletType: "",
|
||
transactionInfo: {},
|
||
baseUrl,
|
||
// 錢包登錄開始
|
||
userMoneyAdressAll: "",
|
||
showGoodClass: false,
|
||
showMoneyAdress: false,
|
||
hasAdress: false,
|
||
moneyTipMessage: "",
|
||
selectMoney: {},
|
||
wallets: [
|
||
{
|
||
name: 'MetaMask',
|
||
icon: 'static/metamask.png'
|
||
},
|
||
{
|
||
name: 'TokenPocket',
|
||
icon: 'static/tokenpocket.png'
|
||
},
|
||
{
|
||
name: 'OKX Wallet',
|
||
icon: 'static/okx-wallet.png'
|
||
}
|
||
],
|
||
moneyDialogVisible: false,
|
||
userIsLogin: false,
|
||
userMoneyAdress: "",
|
||
// 錢包登錄結尾
|
||
currentLanguage: localStorage.getItem('languageNow') || 'en',
|
||
dialogVisible: false,
|
||
titleactive: 1,
|
||
typeactive: 1,
|
||
nftPrice: '',
|
||
nftintAdress: "",
|
||
nfttypeList: [], // 一級分類
|
||
attributeList: [], // 二級屬性分類
|
||
attrCurrent: [],//已選擇的二級分類屬性id
|
||
nftList: [],// 商品列表
|
||
total: 0,
|
||
page: 1,
|
||
listrow: 10,
|
||
pageSize: 6, //分頁 每頁顯示 6 條數據
|
||
currentPage: 1, // 當前頁碼
|
||
csid: '',
|
||
userInfos: [],
|
||
nftStatus: "可售",
|
||
}
|
||
},
|
||
async created() {
|
||
let userInfo = window.localStorage.getItem('userInfo')
|
||
if (userInfo) {
|
||
this.userIsLogin = true;
|
||
}
|
||
this.userInfos = JSON.parse(userInfo);
|
||
this.loadTopType()
|
||
// this.getnfttypeList();
|
||
// 錢包登錄開始
|
||
const provider = window.web3?.currentProvider;
|
||
let accounts1 = [];
|
||
let accounts2 = [];
|
||
let accounts3 = [];
|
||
if(provider){
|
||
accounts1 = await provider.request({method: 'eth_accounts'});
|
||
}
|
||
if(window.tokenpocket?.ethereum){
|
||
accounts2 = await window.tokenpocket.ethereum.request({method: 'eth_accounts'});
|
||
}
|
||
if(window.okxwallet || (window.ethereum && window.ethereum?.isOKExWallet)){
|
||
accounts3 = await window.okxwallet.request({method: 'eth_accounts'});
|
||
}
|
||
console.log(accounts1,accounts2,accounts3,'see');
|
||
let _adressM = accounts1[0] || accounts2[0] || accounts3[0];
|
||
if(_adressM){
|
||
this.userMoneyAdressAll = _adressM;
|
||
this.userMoneyAdress = _adressM.slice(0,4) + "...." + _adressM.slice(-4);
|
||
}
|
||
if(accounts1[0]?.length > 0){
|
||
this.connectWalletType = "MetaMask";
|
||
}
|
||
if(accounts2[0]?.length > 0){
|
||
this.connectWalletType = "TokenPocket";
|
||
}
|
||
if(accounts3[0]?.length > 0){
|
||
this.connectWalletType = "OKX Wallet";
|
||
}
|
||
// 錢包登錄結尾
|
||
},
|
||
mounted() {
|
||
window.addEventListener('localStorageChange', event => {
|
||
if (event.detail.key === 'languageNow') {
|
||
this.currentLanguage = event.detail.value
|
||
}
|
||
})
|
||
},
|
||
methods: {
|
||
myNftRenewal(item){
|
||
this.nftrenewalInfos = {...item};
|
||
let _that = this;
|
||
let tipmessage = _that.currentLanguage == 'zh' ? '是否確定續租一個週期?' : 'Is it confirmed to renew the lease for one period?';
|
||
let tip = this.currentLanguage == 'zh' ? '提示' : 'tips';
|
||
let confirm = this.currentLanguage == 'zh' ? '確定' : 'confirm';
|
||
let cancel = this.currentLanguage == 'zh' ? '取消' : 'cancel';
|
||
_that.$confirm(tipmessage, tip, {
|
||
confirmButtonText: confirm,
|
||
cancelButtonText: cancel,
|
||
type: 'warning'
|
||
}).then(() => {
|
||
let message = _that.currentLanguage == 'zh' ? '請連接錢包' : 'Please connect the wallet';
|
||
if(!_that.userMoneyAdressAll){
|
||
_that.$message.error(message);
|
||
setTimeout(()=>{
|
||
_that.moneyDialogVisible = true;
|
||
},1000)
|
||
return
|
||
}
|
||
_that.creatRenewalOrder();
|
||
}).catch(() => {
|
||
_that.$message("Failed");
|
||
});
|
||
},
|
||
async creatRenewalOrder(){
|
||
let _that = this;
|
||
let tip = this.currentLanguage == 'zh' ? '提示' : 'tips';
|
||
let confirm = this.currentLanguage == 'zh' ? '確定' : 'confirm';
|
||
let cancel = this.currentLanguage == 'zh' ? '取消' : 'cancel';
|
||
let res = await publikRequesFunction('api/project/leasenft','post',{
|
||
id: _that.nftrenewalInfos.id,
|
||
fromaddress:_that.userMoneyAdressAll
|
||
});
|
||
if (res.code === 1) {
|
||
let tipmessage = _that.currentLanguage == 'zh' ? `請前往支付<span style="color:red;">續租費${res.data.bnb} BNB(包含GAS費:${res.data.gasfee} BNB)</span>` : `Please go to pay the <span style="color:red;">renewal fee ${res.data.bnb} BNB (including GAS fee: ${res.data.gasfee} BNB)</span>`;
|
||
_that.$confirm(tipmessage, tip, {
|
||
confirmButtonText: confirm,
|
||
cancelButtonText: cancel,
|
||
dangerouslyUseHTMLString: true
|
||
}).then(() => {
|
||
let tipMessage1 = _that.currentLanguage == 'zh' ? '交易中,請勿刷新頁面...' : 'During the transaction, please do not refresh the page';
|
||
_that.orderLoading = _that.$loading({ lock: true, text: tipMessage1, spinner: 'el-icon-loading', background: 'rgba(0, 0, 0, 0.7)' });
|
||
_that.websentMoney(res.data,'renewal');
|
||
}).catch(() => {
|
||
_that.$message("Failed");
|
||
});
|
||
} else {
|
||
_that.$message.error(res.msg)
|
||
}
|
||
},
|
||
submitNft() {
|
||
let _that = this;
|
||
let message = _that.currentLanguage == 'zh' ? '請輸入完整資訊' : 'Please enter complete information';
|
||
let message1 = _that.currentLanguage == 'zh' ? '請連接錢包' : 'Please connect the wallet';
|
||
if (_that.isLease) {
|
||
if (!_that.nftPrice || !_that.nftDuration || !_that.nftintAdress || !_that.nftRenewal) return _that.$message.error(message);
|
||
} else {
|
||
if (!_that.nftPrice || !_that.nftintAdress) return _that.$message.error(message);
|
||
}
|
||
if(!_that.userMoneyAdressAll){
|
||
_that.$message.error(message1);
|
||
setTimeout(()=>{
|
||
_that.moneyDialogVisible = true;
|
||
},1000)
|
||
return
|
||
}
|
||
_that.creatOrder()
|
||
},
|
||
//創建交易訂單
|
||
async creatOrder(){
|
||
let tip = this.currentLanguage == 'zh' ? '提示' : 'tips';
|
||
let confirm = this.currentLanguage == 'zh' ? '確定' : 'confirm';
|
||
let cancel = this.currentLanguage == 'zh' ? '取消' : 'cancel';
|
||
let _that = this;
|
||
let params = {};
|
||
let apiUrl = "";
|
||
if(_that.isLease){
|
||
params = {
|
||
bnb: _that.nftPrice,
|
||
id: _that.sendId,
|
||
addr: _that.nftintAdress,
|
||
day: _that.nftDuration,
|
||
diffrate: _that.nftRenewal
|
||
}
|
||
apiUrl = "api/project/lease"
|
||
}else{
|
||
params = {
|
||
bnb: _that.nftPrice,
|
||
id: _that.sendId,
|
||
addr: _that.nftintAdress
|
||
}
|
||
apiUrl = "api/project/sale"
|
||
}
|
||
let res = await publikRequesFunction(apiUrl,'post',params);
|
||
if (res.code === 1) {
|
||
let tipmessage = _that.currentLanguage == 'zh' ? `請前往支付<span style="color:red;">版權費(${res.data.salefee} BNB)</span><br>和墊付<span style="color:red;">GAS費(${res.data.gasfee} BNB)</span>` : `Please go to pay the <span style="color:red;">copyright fee (${res.data.salefee} BNB)</span><br> and advance the <span style="color:red;">GAS fee (${res.data.gasfee} BNB)</span>`;
|
||
_that.$confirm(tipmessage, tip, {
|
||
confirmButtonText: confirm,
|
||
cancelButtonText: cancel,
|
||
dangerouslyUseHTMLString: true
|
||
}).then(() => {
|
||
_that.dialogVisible = false;
|
||
let tipMessage = _that.currentLanguage == 'zh' ? '交易中,請勿刷新頁面...' : 'During the transaction, please do not refresh the page';
|
||
_that.orderLoading = _that.$loading({ lock: true, text: tipMessage, spinner: 'el-icon-loading', background: 'rgba(0, 0, 0, 0.7)' });
|
||
_that.websentMoney(res.data);
|
||
}).catch(() => {
|
||
_that.$message("Failed");
|
||
});
|
||
} else {
|
||
_that.$message.error(res.msg)
|
||
}
|
||
},
|
||
//發起版權費+GAS費支付
|
||
async websentMoney(item,renewalTxt) {
|
||
let _that = this;
|
||
const provider = window.web3?.currentProvider;
|
||
let web3 = null;
|
||
if(this.connectWalletType == "MetaMask"){
|
||
web3 = new Web3(provider);
|
||
await provider.request({method: 'eth_requestAccounts'});
|
||
}
|
||
if(this.connectWalletType == "TokenPocket"){
|
||
web3 = new Web3(window.tokenpocket.ethereum);
|
||
await window.tokenpocket.ethereum.request({method: 'eth_requestAccounts'});
|
||
}
|
||
if(this.connectWalletType == "OKX Wallet"){
|
||
web3 = new Web3(window.okxwallet);
|
||
await window.okxwallet.request({method: 'eth_requestAccounts'});
|
||
}
|
||
try {
|
||
const transactions = {
|
||
from: _that.userMoneyAdressAll,
|
||
to: item.toaddress,
|
||
value: web3.utils.toWei(item.bnb, 'ether'),
|
||
gas: 21000
|
||
};
|
||
const result = await web3.eth.sendTransaction(transactions);
|
||
|
||
if(result.transactionHash){
|
||
console.log("成功哈希:",result.transactionHash);
|
||
this.submitHash(item.id,result.transactionHash,renewalTxt);
|
||
}else{
|
||
let canaltip = this.currentLanguage == 'zh' ? '交易失敗!' : 'Transaction failed!';
|
||
this.$message.error(canaltip);
|
||
this.orderLoading.close();
|
||
}
|
||
} catch (error) {
|
||
let canaltip = this.currentLanguage == 'zh' ? '交易失敗!' : 'Transaction failed!';
|
||
this.$message.error(canaltip);
|
||
this.orderLoading.close();
|
||
}
|
||
},
|
||
//支付完成提交hash
|
||
async submitHash(id,tx,renewalTxt){
|
||
let _that = this;
|
||
let apiURL = "";
|
||
renewalTxt == 'renewal' ? apiURL = 'api/common/payresult' : _that.isLease ? apiURL = "api/project/payedleaseorder" : apiURL = "api/project/payedsaleorder"
|
||
try {
|
||
let res = await publikRequesFunction(apiURL,'post',{id,tx});
|
||
if (res.code === 1) {
|
||
_that.$message.success('success');
|
||
_that.orderLoading.close();
|
||
setTimeout(()=>{
|
||
_that.loadData();
|
||
},1000)
|
||
} else {
|
||
_that.$message.error(err)
|
||
_that.orderLoading.close();
|
||
}
|
||
} catch (error) {
|
||
_that.$message.error(error)
|
||
_that.orderLoading.close();
|
||
}
|
||
},
|
||
moment,
|
||
checkFindGoods(id, own) {
|
||
if (own === 0) { return }
|
||
if (this.attrCurrent.includes(id)) {
|
||
this.attrCurrent = this.attrCurrent.filter(item => {
|
||
return item != id
|
||
})
|
||
} else {
|
||
this.attrCurrent.push(id)
|
||
}
|
||
|
||
},
|
||
// <-- -------------------------錢包登錄開始 --------------------------->
|
||
copyText(txt){
|
||
let message = this.currentLanguage == 'zh' ? '複製成功!' : 'Copy successful!';
|
||
navigator.clipboard.writeText(txt)
|
||
.then(()=>{
|
||
this.$message.success(message)
|
||
})
|
||
.catch(err=>{
|
||
console.log(err,'error');
|
||
})
|
||
},
|
||
allMoney(){
|
||
this.showMoneyAdress = true;
|
||
},
|
||
userMoneyAdressOptions(adress){
|
||
if(adress){
|
||
return adress
|
||
}else{
|
||
return this.currentLanguage == 'zh' ? '連接錢包' : 'Connect wallet'
|
||
}
|
||
},
|
||
moneyTip(txt){
|
||
if(txt){
|
||
return txt
|
||
}else{
|
||
return this.currentLanguage == 'zh' ? '請選擇連接錢包' : 'Please choose to connect the wallet'
|
||
}
|
||
},
|
||
selectWallet(wallet) {
|
||
this.selectMoney = {};
|
||
if(wallet.name == 'MetaMask') {
|
||
if(window.web3?.currentProvider){
|
||
this.selectMoney = wallet;
|
||
this.connectWallet(wallet.name);
|
||
}else{
|
||
this.moneyTipMessage = this.currentLanguage == 'zh' ? 'MetaMask未安裝' : 'MetaMask not installed';
|
||
}
|
||
}
|
||
if (wallet.name == 'TokenPocket') {
|
||
if(window.tokenpocket?.ethereum){
|
||
this.selectMoney = wallet;
|
||
this.connectWallet(wallet.name);
|
||
}else{
|
||
this.moneyTipMessage = this.currentLanguage == 'zh' ? 'TokenPocket未安裝' : 'TokenPocket not installed';
|
||
}
|
||
}
|
||
if(wallet.name == "OKX Wallet"){
|
||
if(window.okxwallet || (window.ethereum && window.ethereum.isOKExWallet)){
|
||
this.selectMoney = wallet;
|
||
this.connectWallet(wallet.name);
|
||
}else{
|
||
this.moneyTipMessage = this.currentLanguage == 'zh' ? '歐易錢包未安裝' : 'OKX Wallet not installed';
|
||
}
|
||
}
|
||
},
|
||
async connectWallet(walletType){
|
||
let account = "";
|
||
this.connectWalletType = walletType;
|
||
try {
|
||
if (walletType == 'MetaMask') {
|
||
const provider = window.web3.currentProvider;
|
||
const accounts = await provider.request({
|
||
method: 'eth_requestAccounts'
|
||
});
|
||
account = accounts[0];
|
||
}
|
||
if (walletType == 'TokenPocket') {
|
||
const tpAccounts = await window.tokenpocket.ethereum.request({
|
||
method: 'eth_requestAccounts'
|
||
});
|
||
account = tpAccounts[0];
|
||
}
|
||
if (walletType == 'OKX Wallet') {
|
||
const okxAccounts = await window.okxwallet.request({
|
||
method: 'eth_requestAccounts'
|
||
});
|
||
account = okxAccounts[0];
|
||
}
|
||
console.log(account,'xxaa');
|
||
let _adressM = account;
|
||
this.userMoneyAdressAll = account;
|
||
this.userMoneyAdress = _adressM.slice(0,4) + "...." + _adressM.slice(-4);
|
||
this.moneyDialogVisible = false;
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
},
|
||
toConnectWallet() {
|
||
if(this.userMoneyAdress){
|
||
if(this.isShowSale){
|
||
return
|
||
}
|
||
this.hasAdress = !this.hasAdress;
|
||
return
|
||
};
|
||
this.moneyDialogVisible = true;
|
||
},
|
||
//<-- -------------------------錢包登錄結尾 --------------------------->
|
||
copyText(txt) {
|
||
let message = this.currentLanguage == 'zh' ? '複製成功!' : 'Copy successful!';
|
||
navigator.clipboard.writeText(txt)
|
||
.then(() => {
|
||
this.$message.success(message)
|
||
})
|
||
.catch(err => {
|
||
console.log(err, 'error');
|
||
})
|
||
},
|
||
maskString(str) {
|
||
return str.replace(/^(.{3})(.*)(.{3})$/, function (match, p1, p2, p3) { return p1 + '*'.repeat(p2.length / 2) + p3; });
|
||
},
|
||
async loadTopType() {
|
||
let res = await publikRequesFunction('api/project/gettype','get',{});
|
||
if(res.code === 1){
|
||
this.nfttypeList = res.data;
|
||
this.typeactive = this.nfttypeList[0].id
|
||
this.getnfttypeList()
|
||
}
|
||
},
|
||
// 獲取分類
|
||
async getnfttypeList() {
|
||
let _that = this;
|
||
this.attrCurrent = []
|
||
let res = await publikRequesFunction('api/project/gettpllist','get',{
|
||
typeid:this.typeactive,showown:1,listrow:500
|
||
});
|
||
if(res.code === 1){
|
||
this.attributeList = res.data.data
|
||
if (_that.attributeList.filter(item => { return item.own > 0 }).length > 0) {
|
||
_that.loadData()
|
||
} else {
|
||
this.attrCurrent = []
|
||
this.nftList = []
|
||
this.total = 0
|
||
}
|
||
}
|
||
},
|
||
cheangetypeact(tplid) {
|
||
if (tplid == this.typeactive) { return }
|
||
this.typeactive = tplid
|
||
this.getnfttypeList()
|
||
},
|
||
async loadData() {
|
||
this.showGoodClass = false
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
let token = this.userInfos.token
|
||
const params = { page: this.currentPage, listrow: this.pageSize, status: this.nftStatus, typeid: this.typeactive }
|
||
if (this.attrCurrent.length >= 1) {
|
||
params.tplid = this.attrCurrent.length > 1 ? this.attrCurrent.join(',') : this.attrCurrent[0]
|
||
params.typeid = 0
|
||
}
|
||
let res = await publikRequesFunction('api/user/mynftlist','get',params);
|
||
loading.close()
|
||
if (res.code == 1) {
|
||
this.total = res.data.total
|
||
this.nftList = res.data.data
|
||
} else {
|
||
this.$message(res.msg)
|
||
}
|
||
},
|
||
//分頁
|
||
handlePageChange(page) {
|
||
if (this.currentPage == page) { return }
|
||
this.currentPage = page
|
||
this.loadData()
|
||
},
|
||
// nfttitle
|
||
cheangetitact(val) {
|
||
if (this.titleactive == val) { return }
|
||
this.titleactive = val;
|
||
switch (val) {
|
||
case 1:
|
||
this.nftStatus = "可售";
|
||
break;
|
||
case 2:
|
||
this.nftStatus = "在仓库";
|
||
break;
|
||
case 3:
|
||
this.nftStatus = "在售";
|
||
break;
|
||
case 4:
|
||
this.nftStatus = "租赁中";
|
||
break;
|
||
case 5:
|
||
this.nftStatus = "交易中";
|
||
break;
|
||
default:
|
||
this.nftStatus = "";
|
||
break;
|
||
}
|
||
this.loadData();
|
||
},
|
||
// 下架NFT
|
||
removedNft(item) {
|
||
let _that = this;
|
||
let message = this.currentLanguage == 'zh' ? '是否下架該NFT?下架後將不會返回任何費用?' : 'Do you want to delist the NFT? Will no fees be refunded after delisting?';
|
||
let tip = this.currentLanguage == 'zh' ? '提示' : 'tips';
|
||
let confirm = this.currentLanguage == 'zh' ? '確定' : 'confirm';
|
||
let cancel = this.currentLanguage == 'zh' ? '取消' : 'cancel';
|
||
this.$confirm(message,tip,{
|
||
confirmButtonText: confirm,
|
||
cancelButtonText: cancel,
|
||
type: 'warning'
|
||
}).then(async () => {
|
||
let res = await publikRequesFunction('api/project/undernft','post',{nftid:item.id});
|
||
if(res.code === 1){
|
||
_that.$message.success("success");
|
||
setTimeout(()=>{
|
||
_that.loadData()
|
||
},1000)
|
||
}
|
||
}).catch(() => {
|
||
_that.$message("Failed");
|
||
});
|
||
},
|
||
// 交易倉庫
|
||
transaction(item,n) {
|
||
n == 1 ? this.isLease = false : this.isLease = true;
|
||
this.transactionInfo = item.tpl_info;
|
||
this.sendId = item.id;
|
||
console.log(item.tpl_info, 'xxxxxxx');
|
||
this.dialogVisible = true;
|
||
},
|
||
joinwarehouse(id,n) {
|
||
let _that = this;
|
||
let message = this.currentLanguage == 'zh' ? (n == 1 ? '是否加入倉庫?' : '是否拿出倉庫') : (n == 1 ? 'Whether to join the warehouse?' : 'Take out the warehouse?');
|
||
let tip = this.currentLanguage == 'zh' ? '提示' : 'tips';
|
||
let confirm = this.currentLanguage == 'zh' ? '確定' : 'confirm';
|
||
let cancel = this.currentLanguage == 'zh' ? '取消' : 'cancel';
|
||
let apiSelect = "";
|
||
n == 1 ? apiSelect = 'api/project/instore' : apiSelect = 'api/project/outstore'
|
||
this.$confirm(message,tip,{
|
||
confirmButtonText: confirm,
|
||
cancelButtonText: cancel,
|
||
type: 'warning'
|
||
}).then(async () => {
|
||
let res = await publikRequesFunction(apiSelect,'post',{id});
|
||
if(res.code === 1){
|
||
_that.$message.success("success");
|
||
setTimeout(()=>{
|
||
_that.loadData()
|
||
},1000)
|
||
}
|
||
}).catch(() => {
|
||
_that.$message("Failed");
|
||
});
|
||
},
|
||
// headers
|
||
mobileLang() {
|
||
this.currentLanguage = mobileLang()
|
||
},
|
||
},
|
||
})
|
||
</script>
|
||
<script src="static/js/app.js"></script>
|
||
</body>
|
||
|
||
</html> |