SamsaraDao/nft.html

1133 lines
51 KiB
HTML
Raw Normal View History

2025-04-19 15:31:22 +08:00
<!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;
2025-05-07 09:13:07 +08:00
margin-bottom: 4vh;
2025-04-19 15:31:22 +08:00
}
.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>
2025-05-07 09:13:07 +08:00
<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>
2025-04-19 15:31:22 +08:00
</div>
2025-05-07 09:13:07 +08:00
<div class="attr-box" v-show="attributeList.length > 0 && titleactive == 1">
2025-04-19 15:31:22 +08:00
<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>
2025-05-07 09:13:07 +08:00
<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>
2025-04-19 15:31:22 +08:00
<div class="btn">
2025-05-09 18:28:03 +08:00
<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>
2025-05-07 09:13:07 +08:00
<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>
2025-04-19 15:31:22 +08:00
</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>
<!-- 上架到交易中心 -->
2025-05-07 09:13:07 +08:00
<el-dialog :title="currentLanguage == 'zh' ? (isLease ? '租賃' : '交易') : (isLease ? 'lease':'transaction')" :visible.sync="dialogVisible" width="30%">
2025-04-19 15:31:22 +08:00
<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>
2025-05-07 09:13:07 +08:00
<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>
2025-04-19 15:31:22 +08:00
<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 {
2025-05-07 09:13:07 +08:00
nftrenewalInfos:{},//nft续租信息
nftDuration:"",//时长
nftRenewal:"",
isLease:false,
2025-04-19 15:31:22 +08:00
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: [],
2025-05-07 09:13:07 +08:00
nftStatus: "可售",
2025-04-19 15:31:22 +08:00
}
},
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: {
2025-05-07 09:13:07 +08:00
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");
});
},
2025-05-07 13:42:14 +08:00
async creatRenewalOrder(){
2025-05-07 09:13:07 +08:00
let _that = this;
let tip = this.currentLanguage == 'zh' ? '提示' : 'tips';
let confirm = this.currentLanguage == 'zh' ? '確定' : 'confirm';
let cancel = this.currentLanguage == 'zh' ? '取消' : 'cancel';
2025-05-07 13:42:14 +08:00
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)
}
2025-05-07 09:13:07 +08:00
},
2025-04-19 15:31:22 +08:00
submitNft() {
let _that = this;
let message = _that.currentLanguage == 'zh' ? '請輸入完整資訊' : 'Please enter complete information';
let message1 = _that.currentLanguage == 'zh' ? '請連接錢包' : 'Please connect the wallet';
2025-05-07 09:13:07 +08:00
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);
}
2025-04-19 15:31:22 +08:00
if(!_that.userMoneyAdressAll){
_that.$message.error(message1);
setTimeout(()=>{
_that.moneyDialogVisible = true;
},1000)
return
}
2025-05-07 09:13:07 +08:00
_that.creatOrder()
2025-04-19 15:31:22 +08:00
},
//創建交易訂單
2025-05-07 13:42:14 +08:00
async creatOrder(){
2025-04-19 15:31:22 +08:00
let tip = this.currentLanguage == 'zh' ? '提示' : 'tips';
let confirm = this.currentLanguage == 'zh' ? '確定' : 'confirm';
let cancel = this.currentLanguage == 'zh' ? '取消' : 'cancel';
let _that = this;
2025-05-07 09:13:07 +08:00
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 = {
2025-04-19 15:31:22 +08:00
bnb: _that.nftPrice,
id: _that.sendId,
addr: _that.nftintAdress
2025-05-07 09:13:07 +08:00
}
apiUrl = "api/project/sale"
}
2025-05-07 13:42:14 +08:00
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)
}
2025-04-19 15:31:22 +08:00
},
//發起版權費+GAS費支付
2025-05-07 09:13:07 +08:00
async websentMoney(item,renewalTxt) {
2025-04-19 15:31:22 +08:00
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);
2025-05-07 09:13:07 +08:00
this.submitHash(item.id,result.transactionHash,renewalTxt);
2025-04-19 15:31:22 +08:00
}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
2025-05-07 13:42:14 +08:00
async submitHash(id,tx,renewalTxt){
2025-04-19 15:31:22 +08:00
let _that = this;
2025-05-07 09:13:07 +08:00
let apiURL = "";
renewalTxt == 'renewal' ? apiURL = 'api/common/payresult' : _that.isLease ? apiURL = "api/project/payedleaseorder" : apiURL = "api/project/payedsaleorder"
2025-04-19 15:31:22 +08:00
try {
2025-05-07 13:42:14 +08:00
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();
}
2025-04-19 15:31:22 +08:00
} 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; });
},
2025-05-07 13:42:14 +08:00
async loadTopType() {
let res = await publikRequesFunction('api/project/gettype','get',{});
if(res.code === 1){
this.nfttypeList = res.data;
2025-04-19 15:31:22 +08:00
this.typeactive = this.nfttypeList[0].id
this.getnfttypeList()
2025-05-07 13:42:14 +08:00
}
2025-04-19 15:31:22 +08:00
},
// 獲取分類
2025-05-07 13:42:14 +08:00
async getnfttypeList() {
let _that = this;
2025-04-19 15:31:22 +08:00
this.attrCurrent = []
2025-05-07 13:42:14 +08:00
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()
2025-04-19 15:31:22 +08:00
} else {
this.attrCurrent = []
this.nftList = []
this.total = 0
}
2025-05-07 13:42:14 +08:00
}
2025-04-19 15:31:22 +08:00
},
cheangetypeact(tplid) {
if (tplid == this.typeactive) { return }
this.typeactive = tplid
this.getnfttypeList()
},
2025-05-07 13:42:14 +08:00
async loadData() {
2025-04-19 15:31:22 +08:00
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
}
2025-05-07 13:42:14 +08:00
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)
}
2025-04-19 15:31:22 +08:00
},
//分頁
handlePageChange(page) {
if (this.currentPage == page) { return }
this.currentPage = page
this.loadData()
},
// nfttitle
cheangetitact(val) {
if (this.titleactive == val) { return }
this.titleactive = val;
2025-05-07 09:13:07 +08:00
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;
2025-04-19 15:31:22 +08:00
}
this.loadData();
},
2025-05-09 18:28:03 +08:00
// 下架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");
});
},
2025-04-19 15:31:22 +08:00
// 交易倉庫
2025-05-07 09:13:07 +08:00
transaction(item,n) {
n == 1 ? this.isLease = false : this.isLease = true;
2025-04-19 15:31:22 +08:00
this.transactionInfo = item.tpl_info;
this.sendId = item.id;
console.log(item.tpl_info, 'xxxxxxx');
this.dialogVisible = true;
},
2025-05-07 09:13:07 +08:00
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'
2025-05-07 13:42:14 +08:00
}).then(async () => {
let res = await publikRequesFunction(apiSelect,'post',{id});
if(res.code === 1){
_that.$message.success("success");
setTimeout(()=>{
_that.loadData()
},1000)
}
2025-05-07 09:13:07 +08:00
}).catch(() => {
_that.$message("Failed");
});
2025-04-19 15:31:22 +08:00
},
// headers
mobileLang() {
this.currentLanguage = mobileLang()
},
},
})
</script>
<script src="static/js/app.js"></script>
</body>
</html>