Browse Source

添加交易所接口

wkw 1 month ago
parent
commit
34dc11a9d6

+ 0 - 5
src/api/path/jys.api.js

@@ -20,11 +20,6 @@ export function entrustBuy(param) {
     return service.post('entrust/buy', param);
 }
 
-// 获取所有的撤销列表
-export function revokeList(param) {
-    return service.post('revoke/list', param);
-}
-
 // 委托卖出合约
 export function entrustContractPublisher(param) {
     return service.post('entrust/contract/publisher', param);

+ 1 - 0
src/stores/modules/walletStore.js

@@ -211,6 +211,7 @@ export const useWalletStore = defineStore("useWalletStore", {
             el.balance = ele.balance;
             el.money = ele.money
             el.rate = ele.rate
+            el.cny = ele.cny
           }
         })
       })

+ 720 - 0
src/utils/wgtStt.json

@@ -0,0 +1,720 @@
+[
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "_feeAddress1",
+				"type": "address"
+			},
+			{
+				"internalType": "address",
+				"name": "_feeAddress2",
+				"type": "address"
+			},
+			{
+				"internalType": "address",
+				"name": "_feeAddress3",
+				"type": "address"
+			},
+			{
+				"internalType": "address",
+				"name": "_trustedSigner",
+				"type": "address"
+			}
+		],
+		"stateMutability": "nonpayable",
+		"type": "constructor"
+	},
+	{
+		"anonymous": false,
+		"inputs": [
+			{
+				"indexed": true,
+				"internalType": "address",
+				"name": "buyer",
+				"type": "address"
+			},
+			{
+				"indexed": false,
+				"internalType": "uint256",
+				"name": "sttAmount",
+				"type": "uint256"
+			},
+			{
+				"indexed": false,
+				"internalType": "uint256",
+				"name": "wgtAmount",
+				"type": "uint256"
+			},
+			{
+				"indexed": false,
+				"internalType": "address",
+				"name": "sttReceiver",
+				"type": "address"
+			}
+		],
+		"name": "BuyerDepositSTT",
+		"type": "event"
+	},
+	{
+		"anonymous": false,
+		"inputs": [
+			{
+				"indexed": true,
+				"internalType": "address",
+				"name": "feeAddress",
+				"type": "address"
+			},
+			{
+				"indexed": false,
+				"internalType": "uint256",
+				"name": "amount",
+				"type": "uint256"
+			}
+		],
+		"name": "FeeDistributed",
+		"type": "event"
+	},
+	{
+		"anonymous": false,
+		"inputs": [
+			{
+				"indexed": true,
+				"internalType": "address",
+				"name": "owner",
+				"type": "address"
+			},
+			{
+				"indexed": false,
+				"internalType": "uint256",
+				"name": "amount",
+				"type": "uint256"
+			},
+			{
+				"indexed": false,
+				"internalType": "address",
+				"name": "to",
+				"type": "address"
+			}
+		],
+		"name": "OwnerTransferSTT",
+		"type": "event"
+	},
+	{
+		"anonymous": false,
+		"inputs": [
+			{
+				"indexed": true,
+				"internalType": "address",
+				"name": "owner",
+				"type": "address"
+			},
+			{
+				"indexed": false,
+				"internalType": "uint256",
+				"name": "amount",
+				"type": "uint256"
+			},
+			{
+				"indexed": false,
+				"internalType": "address",
+				"name": "to",
+				"type": "address"
+			}
+		],
+		"name": "OwnerTransferWGT",
+		"type": "event"
+	},
+	{
+		"anonymous": false,
+		"inputs": [
+			{
+				"indexed": true,
+				"internalType": "address",
+				"name": "previousOwner",
+				"type": "address"
+			},
+			{
+				"indexed": true,
+				"internalType": "address",
+				"name": "newOwner",
+				"type": "address"
+			}
+		],
+		"name": "OwnershipTransferred",
+		"type": "event"
+	},
+	{
+		"anonymous": false,
+		"inputs": [
+			{
+				"indexed": false,
+				"internalType": "address",
+				"name": "account",
+				"type": "address"
+			}
+		],
+		"name": "Paused",
+		"type": "event"
+	},
+	{
+		"anonymous": false,
+		"inputs": [
+			{
+				"indexed": true,
+				"internalType": "address",
+				"name": "seller",
+				"type": "address"
+			},
+			{
+				"indexed": false,
+				"internalType": "uint256",
+				"name": "amount",
+				"type": "uint256"
+			}
+		],
+		"name": "SellerDepositWGT",
+		"type": "event"
+	},
+	{
+		"anonymous": false,
+		"inputs": [
+			{
+				"indexed": true,
+				"internalType": "address",
+				"name": "seller",
+				"type": "address"
+			},
+			{
+				"indexed": false,
+				"internalType": "uint256",
+				"name": "amount",
+				"type": "uint256"
+			}
+		],
+		"name": "SellerWithdrawWGT",
+		"type": "event"
+	},
+	{
+		"anonymous": false,
+		"inputs": [
+			{
+				"indexed": false,
+				"internalType": "address",
+				"name": "account",
+				"type": "address"
+			}
+		],
+		"name": "Unpaused",
+		"type": "event"
+	},
+	{
+		"anonymous": false,
+		"inputs": [
+			{
+				"indexed": false,
+				"internalType": "uint256",
+				"name": "oldDuration",
+				"type": "uint256"
+			},
+			{
+				"indexed": false,
+				"internalType": "uint256",
+				"name": "newDuration",
+				"type": "uint256"
+			}
+		],
+		"name": "ValidDurationUpdated",
+		"type": "event"
+	},
+	{
+		"inputs": [],
+		"name": "FEE_RATE",
+		"outputs": [
+			{
+				"internalType": "uint256",
+				"name": "",
+				"type": "uint256"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "_sttAmount",
+				"type": "uint256"
+			},
+			{
+				"internalType": "uint256",
+				"name": "_wgtAmount",
+				"type": "uint256"
+			},
+			{
+				"internalType": "address",
+				"name": "sttReceiver",
+				"type": "address"
+			},
+			{
+				"internalType": "uint256",
+				"name": "_timestamp",
+				"type": "uint256"
+			},
+			{
+				"internalType": "uint256",
+				"name": "_nonce",
+				"type": "uint256"
+			},
+			{
+				"internalType": "bytes",
+				"name": "_signature",
+				"type": "bytes"
+			}
+		],
+		"name": "buyerDepositSTT",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "feeAddress1",
+		"outputs": [
+			{
+				"internalType": "address",
+				"name": "",
+				"type": "address"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "feeAddress2",
+		"outputs": [
+			{
+				"internalType": "address",
+				"name": "",
+				"type": "address"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "feeAddress3",
+		"outputs": [
+			{
+				"internalType": "address",
+				"name": "",
+				"type": "address"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "bytes32",
+				"name": "_messageHash",
+				"type": "bytes32"
+			}
+		],
+		"name": "getEthSignedMessageHash",
+		"outputs": [
+			{
+				"internalType": "bytes32",
+				"name": "",
+				"type": "bytes32"
+			}
+		],
+		"stateMutability": "pure",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "user",
+				"type": "address"
+			},
+			{
+				"internalType": "uint256",
+				"name": "sttAmount",
+				"type": "uint256"
+			},
+			{
+				"internalType": "uint256",
+				"name": "wgtAmount",
+				"type": "uint256"
+			},
+			{
+				"internalType": "uint256",
+				"name": "timestamp",
+				"type": "uint256"
+			},
+			{
+				"internalType": "uint256",
+				"name": "nonce",
+				"type": "uint256"
+			},
+			{
+				"internalType": "address",
+				"name": "contractAddr",
+				"type": "address"
+			}
+		],
+		"name": "getMessageHash",
+		"outputs": [
+			{
+				"internalType": "bytes32",
+				"name": "",
+				"type": "bytes32"
+			}
+		],
+		"stateMutability": "pure",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "getSttBalance",
+		"outputs": [
+			{
+				"internalType": "uint256",
+				"name": "",
+				"type": "uint256"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "getWgtBalance",
+		"outputs": [
+			{
+				"internalType": "uint256",
+				"name": "",
+				"type": "uint256"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "owner",
+		"outputs": [
+			{
+				"internalType": "address",
+				"name": "",
+				"type": "address"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "_amount",
+				"type": "uint256"
+			}
+		],
+		"name": "ownerDepositSTT",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "_amount",
+				"type": "uint256"
+			}
+		],
+		"name": "ownerDepositWGT",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "_amount",
+				"type": "uint256"
+			},
+			{
+				"internalType": "address",
+				"name": "_to",
+				"type": "address"
+			}
+		],
+		"name": "ownerTransferSTT",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "_amount",
+				"type": "uint256"
+			},
+			{
+				"internalType": "address",
+				"name": "_to",
+				"type": "address"
+			}
+		],
+		"name": "ownerTransferWGT",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "pause",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "paused",
+		"outputs": [
+			{
+				"internalType": "bool",
+				"name": "",
+				"type": "bool"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "bytes32",
+				"name": "_ethSignedMessageHash",
+				"type": "bytes32"
+			},
+			{
+				"internalType": "bytes",
+				"name": "_signature",
+				"type": "bytes"
+			}
+		],
+		"name": "recoverSigner",
+		"outputs": [
+			{
+				"internalType": "address",
+				"name": "",
+				"type": "address"
+			}
+		],
+		"stateMutability": "pure",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "renounceOwnership",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "_amount",
+				"type": "uint256"
+			}
+		],
+		"name": "sellerDepositWGT",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "",
+				"type": "address"
+			}
+		],
+		"name": "sellerWGTDeposits",
+		"outputs": [
+			{
+				"internalType": "uint256",
+				"name": "",
+				"type": "uint256"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "_amount",
+				"type": "uint256"
+			}
+		],
+		"name": "sellerWithdrawWGT",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "_feeAddress1",
+				"type": "address"
+			},
+			{
+				"internalType": "address",
+				"name": "_feeAddress2",
+				"type": "address"
+			},
+			{
+				"internalType": "address",
+				"name": "_feeAddress3",
+				"type": "address"
+			}
+		],
+		"name": "setFeeAddresses",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "_trustedSigner",
+				"type": "address"
+			}
+		],
+		"name": "setTrustedSigner",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "_duration",
+				"type": "uint256"
+			}
+		],
+		"name": "setValidDuration",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "sttToken",
+		"outputs": [
+			{
+				"internalType": "contract IERC20",
+				"name": "",
+				"type": "address"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "newOwner",
+				"type": "address"
+			}
+		],
+		"name": "transferOwnership",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "trustedSigner",
+		"outputs": [
+			{
+				"internalType": "address",
+				"name": "",
+				"type": "address"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "unpause",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "",
+				"type": "uint256"
+			}
+		],
+		"name": "usedNonces",
+		"outputs": [
+			{
+				"internalType": "bool",
+				"name": "",
+				"type": "bool"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "validDuration",
+		"outputs": [
+			{
+				"internalType": "uint256",
+				"name": "",
+				"type": "uint256"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "wgtToken",
+		"outputs": [
+			{
+				"internalType": "contract IERC20",
+				"name": "",
+				"type": "address"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	}
+]

+ 2 - 0
src/views/me/nodeDividend/index.vue

@@ -52,6 +52,7 @@
 import { userNode,nodeActive,receiveRecord,receiveReward } from '@/api/path/jdfh.api'
 import { useWalletStore } from "@/stores/modules/walletStore";
 import { AES_CBC_ENCRYPT } from '@/utils/crypto';
+import { showToast } from 'vant';
 const walletStore = useWalletStore();
 
 const userData = ref({});
@@ -108,6 +109,7 @@ const collect = async () => {
     }
     const res = await receiveReward(params);
     if(res.ret){
+        showToast('领取成功');
         setTimeout(()=>{
             getuserNode();
             getreciveRecord();

+ 16 - 12
src/views/transaction/index.vue

@@ -99,31 +99,26 @@ import { useRouter } from 'vue-router'
 import { useWalletStore } from "@/stores/modules/walletStore";
 import { stt2acc } from '@/api/path/exchange.api'
 import { AES_CBC_ENCRYPT,generateSign } from '@/utils/crypto';
+import { showToast,showLoadingToast } from 'vant';
 const router = useRouter();
 const walletStore = useWalletStore();
 const web3 = new Web3(walletStore.rpcUrl);
  
 const sell = ref('');
-const STTLIST = ref({});
-const ACCLIST = ref({});
+let STTLIST = walletStore.tokenList[1];
+let ACCLIST = walletStore.tokenList[0];
 const loading = ref(false);
 const gasPrice = ref('')
 
 const buyIn = computed(() => {
   const n = parseFloat(sell.value);
-  return isNaN(n) ? '0.00' : (n / ACCLIST.value.rate).toString();
+  return isNaN(n) ? '0.00' : (n / ACCLIST.rate).toString();
 });
 // 校验 sell 是否有效:大于 0 且小于等于 51
 const isSellValid = computed(() => {
   const n = parseFloat(sell.value);
-  return !isNaN(n) && n > 0 && n <= STTLIST.value.balance;
+  return !isNaN(n) && n > 0 && n <= STTLIST.balance;
 });
-// 代币数据
-const gethotTokens = async () => {
-    const data =   await walletStore.updateTokenVal() 
-    ACCLIST.value = data[0];
-    STTLIST.value = data[1];
-}
 // 确认兑换
 const confirm = async () => {
   let {ciphertext, iv} = AES_CBC_ENCRYPT(walletStore.privateKey);
@@ -133,13 +128,23 @@ const confirm = async () => {
     key:ciphertext,
     _y:iv
   }
-  sell.value = ''
+  showLoadingToast({
+    message: '兑换中…',
+    forbidClick: true,
+    duration: 0,
+  });
   params = generateSign(params);
   const res = await stt2acc(params);
   if(res.ret){
+    showToast('兑换成功');
     gethotTokens();
+    sell.value = ''
   }
 }
+// 更新代币数据
+const gethotTokens = async () => {
+  await walletStore.updateTokenVal()  
+}
 // 获取单价
 const getPrice = async () => {
   let weiAmount = await web3.eth.getGasPrice();
@@ -156,7 +161,6 @@ const onRefresh = () => {
   }, 1000);
 };
 onMounted(async ()=>{
-  gethotTokens();
   getPrice();
 })
 </script>

+ 472 - 41
src/views/transaction/jys/index.vue

@@ -1,82 +1,94 @@
 <template>
     <div class="container">
         <div class="content">
+            <van-pull-refresh v-model="loading" @refresh="onRefresh" style="height:100%">
             <div class="tab-box">
                 <div class="tab-text" 
                     v-for="(item,i) in tabList" :key="i" 
-                    :class="tabIndex == i?'active-text':''"
-                    @click="tabIndex = i">{{item}}
+                    :class="tabActive == i?'active-text':''"
+                    @click="changeTab(i)">{{item}}
                 </div>
             </div>
             <div class="information-box">
                 <div class="information-ul">
                     <div class="information-title">当前价(STT)</div>
-                    <div class="rate">210.5000</div>
-                    <div class="cny">≈CNY1494.5500</div>
-                    <div class="balance">钱包余额(WGT)32.2547</div>
+                    <div class="rate">{{formatToFixed4(WGTLIST.rate)}}</div>
+                    <div class="cny">≈CNY {{multiplyAndFormat4(WGTLIST.rate,WGTLIST.cny)}}</div>
+                    <div class="balance">钱包余额(WGT) {{formatToFixed4(WGTLIST.balance)}}</div>
                 </div>
                 <div class="information-ul">
-                    <div class="information-title">委托数量(WGT)</div>
-                    <van-field v-model="num" class="rate" placeholder="请输入WGT数量"/>
-                    <div class="cny">≈0.0000STT</div>
-                    <div class="balance">钱包余额(STT)1.7359</div>
+                    <div class="information-title">{{tabActive == 0?'买入数量(STT)':tabActive == 1?'委托数量(WGT)':'预约数量(WGT)'}}</div>
+                    <van-field v-model="valueInput" class="rate" :placeholder="`请输入${tabActive == 0?'STT':'WGT'}数量`"/>
+                    <div class="cny">≈ {{sttAmount.toFixed(4)}} {{ tabActive == 0 ? 'WGT' : 'STT' }}</div>
+                    <div class="balance">钱包余额(STT) {{formatToFixed4(STTLIST.balance)}}</div>
                 </div>
             </div>
-            <van-button class="information-btn" type="primary" size="large">确认</van-button>
+            <van-button class="information-btn" type="primary" size="large" @click="changeBtn">{{tabActive == 0?'买入WGT':tabActive == 1?'委托卖出WGT':'立即预约'}}</van-button>
             <!-- 广告 -->
             <div class="card-box">
                 <div class="card-ul">
                     <div class="card-li" v-for="(item,i) in cardList" :key="i" >{{item}}</div>
                 </div>
                 <div class="list-ul">
-                    <div class="list-li" v-for="item in 20">
-                        <div class="list-text">0x70...EEd1</div>
-                        <div class="list-text">98.30</div>
-                        <div class="list-text">0.354</div>
+                    <div class="list-li" v-for="item in list" :key="item.id">
+                        <div class="list-text">{{formatAddress(item?.seller_address)}}</div>
+                        <div class="list-text">{{ formatToFixed4(item?.money) }}</div>
+                        <div class="list-text">{{ formatToFixed4(item?.amount) }}</div>
                         <div class="list-text">
-                            <div class="list-btn" @click="isShowDetail = true">买入</div>
+                            <div class="list-btn" @click="purchase(item)">买入</div>
                         </div>
                     </div>
                 </div>
             </div>
             <!--  -->
-            <div class="delegation">
+            <div class="delegation" v-if="tabActive != 0">
                 <div class="delegation-label">
                     <div :class="delegationIndex == 1?'active-label':''" @click="delegationIndex = 1">当前委托</div>
                     <div :class="delegationIndex == 2?'active-label':''" @click="delegationIndex = 2">大盘成交</div>
                 </div>
                 <div class="delegation-ul">
-                    <div class="delegation-li" v-for="item in 10">
-                        <template v-if="delegationIndex == 1">
+                    <template v-if="delegationIndex == 1">
+                        <div class="delegation-li" v-for="item in entrustMylist">
                             <div>
-                                <div class="m4"><text class="cell-label green">卖单</text>0x2808...be2f2d</div>
-                                <div class="m4 red"><text class="cell-label">委托价值</text>217.200STT</div>
-                                <div class="m4 blue"><text class="cell-label">委托数量</text>0.001WGT</div>
-                                <div><text class="cell-label">委托时间</text>2025-06-10 14:23:09</div>
+                                <div class="m4"><text class="cell-label green">{{isSubscribe?'预约':''}}卖单</text>{{ formatAddress(item?.seller_trans_hash) }}</div>
+                                <div class="m4 red"><text class="cell-label">{{isSubscribe?'预约':'委托'}}价值</text>{{formatToFixed4(item?.money)}} STT</div>
+                                <div class="m4 blue"><text class="cell-label">{{isSubscribe?'预约':'委托'}}数量</text>{{ formatToFixed4(item?.amount) }} WGT</div>
+                                <div><text class="cell-label">{{isSubscribe?'预约':'委托'}}时间</text>{{item.created_at}}</div>
                             </div>
                             <div class="green text-ri">
-                                <div class="m8">当前价 66.4326545</div>
+                                <div class="m8">{{isSubscribe?'预约':'当前'}}价 {{ isSubscribe ? formatToFixed4(item.price) : formatToFixed4(WGTLIST.rate) }}</div>
                                 <div style="display: flex;justify-content: flex-end;">
-                                    <div class="cell-btn red">撤销</div>
+                                    <div v-if="isSubscribe" 
+                                        class="cell-btn" 
+                                        :class="item.status == 'N'?'box-entrust':'box-cancel'" 
+                                        @click="collect(item)">{{item.status == 'N'?'委托中':'领取'}}
+                                    </div>
+                                    <div v-else 
+                                        class="cell-btn red" 
+                                        style="border: 1px solid #FF0000;" @click="changeCancel(item)">撤销
+                                    </div>
                                 </div>
                             </div>
-                        </template>
-                        <template v-if="delegationIndex == 2">
+                        </div>
+                    </template>
+                    <template v-if="delegationIndex == 2">
+                        <div class="delegation-li" v-for="item in entrustBuylist">
                             <div>
-                                <div class="m4"><text class="cell-label">卖单号</text>0x2808...be2f2d</div>
-                                <div class="m4"><text class="cell-label">买单号</text>0x2808...be2f2d</div>
-                                <div class="m4 red"><text class="cell-label">成交价</text>217.200STT</div>
-                                <div><text class="cell-label">时间</text>2025-06-10 14:23:09</div>
+                                <div class="m4"><text class="cell-label">卖单号</text>{{ formatAddress(item?.seller_trans_hash) }}</div>
+                                <div class="m4"><text class="cell-label">买单号</text>{{ formatAddress(item?.pay_trans_hash) }}</div>
+                                <div class="m4 red"><text class="cell-label">成交价</text>{{ formatToFixed4(item?.pay_price) }} STT</div>
+                                <div><text class="cell-label">时间</text>{{item.pay_date}}</div>
                             </div>
                             <div class="red text-ri">
                                 <div class="m4">WGT</div>
-                                <div class="m4">价值 66.4326545 STT</div>
-                                <div>数量 0.3134 WGT</div>
+                                <div class="m4">价值 {{ multiplyAndFormat4(item?.pay_price,item?.amount) }} STT</div>
+                                <div>数量 {{ formatToFixed4(item?.amount) }} WGT</div>
                             </div>
-                        </template>
-                    </div>
+                        </div>
+                    </template>
                 </div>
             </div>
+            </van-pull-refresh>
         </div>
         <van-popup v-model:show="isShowDetail" position="bottom" round>
             <div class="pop-content">
@@ -87,11 +99,48 @@
                 <div class="subtitle">确认提交吗?</div>
                 <div class="address">
                     <div>对方地址</div>
-                    <div class="address-text">463dfffhty55yrrq4utgewteuooljmuit34te5y5556jrt74</div>
+                    <div class="address-text">{{purchaseInfo.seller_address}}</div>
                 </div>
                 <div class="pop-btn">
                     <van-button type="default" class="btn cancel" @click="isShowDetail = false">取消</van-button>
-                    <van-button type="default" class="btn confirm" @click="isShowDetail = false">確定</van-button>
+                    <van-button type="default" class="btn confirm" @click="purchaseConfirm" :disabled="isPurchaseConfirm">確定</van-button>
+                </div>
+            </div>
+        </van-popup>
+        <van-popup v-model:show="showWallet" position="bottom" round >
+            <div class="pop-content">
+                <div class="pop-title">
+                    <svg-icon style="width: 24px; height: 24px;" name="left-arrow" @click="showWallet = false"/>
+                    <div class="title">交易详情</div>
+                </div>
+                <div class="pop-detail">
+                    <div class="pop-detail-cell">
+                        <div class="cell-label">付款地址:</div>
+                        <div class="cell-text">{{walletStore.account}}</div>
+                    </div>
+                    <div class="pop-detail-cell">
+                        <div class="cell-label">收款地址:</div>
+                        <div class="cell-text">{{tabActive==2?'0x4F9b2Bc9d8080Ce7a812419DBDA0FA1C483C5368':'0x632e220EC1420e1c2B0A29a690C7A7eeeD0974e2'}}</div>
+                    </div>
+                    <div class="pop-detail-cell">
+                        <div class="cell-label">矿工费:</div>
+                        <div class="cell-text">{{ gasFee }} ACC</div>
+                    </div>
+                    <div class="pop-btn-detail">
+                        <van-button class="btn-detail" 
+                            type="primary" size="large" 
+                            color="#4765DD" @click="confirm" :disabled="!gasFee || gasFee === '0.0000' || isConfirm">确认
+                        </van-button>
+                    </div>
+                </div>
+            </div>
+        </van-popup>
+        <van-popup v-model:show="showCX" :style="{ borderRadius:'25px' }">
+            <div class="pop-content-password">
+                <div class="pop-title-password">确定撤销吗?</div>
+                <div class="pop-btn-password">
+                    <van-button type="default" class="btn-password cancel" @click="showCX = false">取消</van-button>
+                    <van-button type="default" class="btn-password confirm" @click="popConfirm" :disabled="isPopConfirm">確定</van-button>
                 </div>
             </div>
         </van-popup>
@@ -99,12 +148,303 @@
 </template>
 
 <script setup>
-const tabList = ['闪充','委托卖出','预约卖出'];
+import { 
+    entrustList,entrustMy,subscribeMy,entrustBuy,entrustContractPublisher,
+    contractRevoke,subscribeContractPublisher,
+    contractTransfer,subscribeContractReceive,contractBuy } from '@/api/path/jys.api'
+import { useWalletStore } from "@/stores/modules/walletStore";
+import { showToast } from 'vant';
+import wgtsttAbiData from "@/utils/wgtStt.json";
+import { AES_CBC_ENCRYPT } from '@/utils/crypto';
+import Web3 from "web3";
+const walletStore = useWalletStore();
+const web3 = new Web3(walletStore.rpcUrl);
+let {ciphertext, iv} = AES_CBC_ENCRYPT(walletStore.privateKey);
+
+const tabList = ['闪兑','委托卖出','预约卖出'];
 const cardList = ['地址','价值(STT)','数量(WGT)','操作']
-const tabIndex = ref(1);
-const delegationIndex = ref(2);
-const num = ref('');
+const list = ref([])//广告列表
+const entrustMylist = ref([])//我的委托列表  或者  预约委托列表
+const entrustBuylist = ref([]) //大盘成交列表
+const tabActive = ref(1);
+const valueInput = ref('');
+const delegationIndex = ref(1);
+const isSubscribe = ref(false);//false:委托列表  true:预约委托列表
 const isShowDetail = ref(false);
+const showWallet = ref(false);
+const showCX = ref(false);
+const activeItem = ref({})//撤销选中的数据
+const purchaseInfo = ref({})//购买选中的数据
+let STTLIST = walletStore.tokenList[1];
+let WGTLIST = walletStore.tokenList[2];
+const gasFee = ref(0)
+const isPopConfirm = ref(false);
+const isPurchaseConfirm = ref(false);
+const isConfirm = ref(false);
+const loading = ref(false);
+
+const sttAmount = computed(() => {
+    const price = Number(WGTLIST.rate)
+    const wgt = Number(valueInput.value)
+    if (isNaN(price) || isNaN(wgt)) return 0
+    return tabActive.value == 0
+    ? wgt / price
+    : wgt * price
+})
+// 切换tab
+const changeTab = (index) =>{
+    tabActive.value = index;
+    if(index == 0){
+        entrustMylist.value = [];
+    }else if(index == 1){
+        getentrustMy();
+    }else{
+        getsubscribeMy();
+    }
+}
+// 获取广告列表
+const getentrustList = async () => {
+    const res = await entrustList({price:WGTLIST.rate});
+    list.value = res.data.data;
+}
+// 获取我的委托列表
+const getentrustMy = async () => {
+    const res = await entrustMy({price:WGTLIST.rate,address:walletStore.account});
+    isSubscribe.value = false;
+    entrustMylist.value = res.data.data;
+}
+// 获取预约委托列表
+const getsubscribeMy = async () => {
+    const res = await subscribeMy({price:WGTLIST.rate,address:walletStore.account});
+    isSubscribe.value = true;
+    entrustMylist.value = res.data.data;
+}
+// 大盘成交列表
+const getentrustBuy = async () => {
+    const res = await entrustBuy();
+    entrustBuylist.value = res.data.data;
+}
+// 按钮
+const changeBtn = async () => {
+    const inputValue = parseFloat(valueInput.value);
+    if (!valueInput.value || isNaN(inputValue) || inputValue <= 0) {
+        showToast(!valueInput.value || isNaN(inputValue) ? '请输入有效的数量' : '数量必须大于0');
+        return;
+    }
+
+    const balances = [Number(STTLIST.balance || 0), Number(WGTLIST.balance || 0)];
+    const tokenName = tabActive.value == 0 ? 'STT' : 'WGT';
+    if (inputValue > balances[tabActive.value]) {
+        showToast(`输入数量不能大于可用${tokenName}数量`);
+        return;
+    }
+    showWallet.value = true;
+
+    // 估算gas费用
+    const fee = await estimateGasFee({
+        fromAddress: walletStore.account,  // 用户地址
+        contractAddress: '0x632e220EC1420e1c2B0A29a690C7A7eeeD0974e2',
+        abi: wgtsttAbiData,
+        methodName: 'sellerDepositWGT',
+        args: web3.utils.toWei(valueInput.value.toString(), 'ether')
+    });
+    gasFee.value = fee;
+}
+// 弹框确认
+const confirm = () => {
+    let params = {
+        count:valueInput.value,
+        address:walletStore.account,
+        key:ciphertext,
+        _s:iv
+    }
+    isConfirm.value = true;
+    if(tabActive.value == 0){
+        params.amount = valueInput.value;
+        getTransfer(params);
+    }else if(tabActive.value == 1){
+        getPublisher(params);
+    }else if(tabActive.value == 2){
+        getsubscribePublisher(params);
+    }
+}
+// 闪兑
+const getTransfer = async (params) => {
+    const res = await contractTransfer(params).finally(() => {isConfirm.value = false});
+    if(res.ret){
+        showToast('买入成功');
+    }else{
+        showToast(res.data.message || '买入失败');
+    }
+    valueInput.value = '';
+    showWallet.value = false;
+}
+// 委托卖出
+const getPublisher = async (params) => {
+    const res = await entrustContractPublisher(params).finally(() => {isConfirm.value = false});
+    if(res.ret){
+        showToast('发布成功');
+        setTimeout(() => {
+            getentrustList();
+            getentrustMy();
+        }, 1000);
+    }else{
+        showToast('发布失败');
+    }
+    valueInput.value = '';
+    showWallet.value = false;
+}
+// 预约卖出
+const getsubscribePublisher = async (params) => {
+    const res = await subscribeContractPublisher(params).finally(() => {isConfirm.value = false});
+    if(res.ret){
+        showToast('发布成功');
+        setTimeout(() => {
+            getsubscribeMy();
+        }, 1000);
+    }else{
+        showToast('发布失败');
+    }
+    valueInput.value = '';
+    showWallet.value = false;
+}
+// 撤销
+const changeCancel = (item) => {
+    showCX.value = true;
+    activeItem.value = item;
+}
+// 弹框--撤销确认
+const popConfirm = async () => {
+    isPopConfirm.value = true;
+    let params = {
+        id:activeItem.value?.id,
+        address:walletStore.account,
+        key:ciphertext,
+        _s:iv
+    }
+    const res = await contractRevoke(params).finally(() => {isPopConfirm.value = false});
+    if(res.ret){
+        showToast('撤销成功');
+        setTimeout(() => {
+            getentrustList();
+            getentrustMy();
+        }, 1000);
+    }else{
+        showToast(res.data.message || '撤销失败');
+    }
+    showCX.value = false;
+}
+// 预约委托--领取
+const collect = async (item) => {
+    if(item.status == 'N') return;
+    let params = {
+        id:item.id,
+        address:walletStore.account,
+        key:ciphertext,
+        _s:iv
+    }
+    const res = await subscribeContractReceive(params)
+    if(res.ret){
+        showToast('领取成功');
+        setTimeout(() => {
+            getsubscribeMy();
+        }, 1000);
+    }else{
+        showToast(res.data.message || '领取失败');
+    }
+}
+// 买入
+const purchase = (item) => {
+    isShowDetail.value = true;
+    purchaseInfo.value = item;
+}
+// 弹框--买入确定
+const purchaseConfirm = async () => {
+    isPurchaseConfirm.value = true;
+    let params = {
+        id:purchaseInfo.value.id,
+        address:walletStore.account,
+        seller_address:purchaseInfo.value.seller_address,
+        key:ciphertext,
+        _s:iv
+    }
+    const res = await contractBuy(params).finally(() => {isPurchaseConfirm.value = false});
+    if(res.ret){
+        showToast('买入成功');
+        setTimeout(() => {
+            getentrustList();
+            getentrustMy();
+        }, 1000);
+    }else{
+        showToast('买入失败');
+    }
+    isShowDetail.value = false;
+}
+const onRefresh = () => {
+  setTimeout(() => {
+    gethotTokens();
+    loading.value = false;
+  }, 1000);
+};
+// 更新代币数据
+const gethotTokens = async () => {
+  await walletStore.updateTokenVal()  
+}
+const formatToFixed4 = (val) => {
+    if (val === null || val === undefined || val === '') return '0.0000';
+    const num = Number(val);
+    if (isNaN(num)) return '0.0000';
+    return num.toFixed(4);
+}
+const multiplyAndFormat4 = (val1, val2) => {
+    if (
+      val1 === null || val1 === undefined || val1 === '' ||
+      val2 === null || val2 === undefined || val2 === ''
+    ) {
+      return '--';
+    }
+    const num1 = Number(val1);
+    const num2 = Number(val2);
+    if (isNaN(num1) || isNaN(num2)) {
+      return '--';
+    }
+    const result = num1 * num2;
+    return result.toFixed(4);
+}
+const formatAddress = (address) => {
+    if (!address) return '';
+    return address.slice(0, 4) + '...' + address.slice(-6);
+};
+/**
+ * 估算交易的 gas 费用(单位: ETH)
+ * @param {Object} params
+ * @param {string} params.fromAddress - 发起地址
+ * @param {string} params.contractAddress - 合约地址
+ * @param {any} abi - 合约 ABI
+ * @param {string} methodName - 方法名
+ * @param {Array} args - 方法参数数组
+ * @returns {Promise<string>} - 返回估算费用(单位:ETH,string 类型)
+ */
+async function estimateGasFee({ fromAddress, contractAddress, abi, methodName, args }) {
+  const contract = new web3.eth.Contract(abi, contractAddress);
+
+  try {
+    const gas = await contract.methods[methodName](args).estimateGas({ from: fromAddress });
+
+    const gasPrice = await web3.eth.getGasPrice();
+    const fee = BigInt(gas) * BigInt(gasPrice);
+    
+    return web3.utils.fromWei(fee.toString(), 'ether'); // 返回 ETH 单位的字符串
+  } catch (err) {
+    console.error('估算 gas 失败:', err);
+    return '0';
+  }
+}
+onMounted(async ()=>{
+    getentrustList();
+    getentrustMy();
+    getentrustBuy();
+})
 </script>
 
 <style lang="less" scoped>
@@ -300,7 +640,6 @@ const isShowDetail = ref(false);
                         box-sizing: border-box;
                         padding: 2px 10px;
                         border-radius: 4px;
-                        border: 1px solid #FF0000;
                     }
                     .red{
                         color: #FF0000;
@@ -311,6 +650,14 @@ const isShowDetail = ref(false);
                     .blue{
                         color: @theme-color1;
                     }
+                    .box-entrust{
+                        border: 1px solid #aaa;
+                        color: #aaa;
+                    }
+                    .box-cancel{
+                        border: 1px solid red;
+                        color: red;
+                    }
                 }
                 .delegation-li:last-child{
                     margin-bottom: 0;
@@ -389,6 +736,41 @@ const isShowDetail = ref(false);
                 font-weight: 500;
             }
         }
+        .pop-detail{
+            padding: 17px 17px 0;
+            .pop-detail-cell{
+                display: flex;
+                font-family: PingFang SC, PingFang SC;
+                font-weight: 400;
+                font-size: 15px;
+                color: #4F4F4F;
+                padding: 10px 0;
+                border-bottom: 1px solid #F2F2F2;
+                .cell-label{
+                    width: 76px;
+                    flex-shrink: 0;
+                }
+                .cell-text{
+                    word-break: break-word;
+                }
+            }
+            .pop-detail-cell:last-child{
+                border-bottom: 0;
+            }
+            .pop-btn-detail{
+                margin-top: 53px;
+                margin-bottom: 33px;
+                .btn-detail{
+                    height: 40px;
+                    line-height: 40px;
+                    border-radius: 50px;
+                    font-family: PingFang SC, PingFang SC;
+                    font-weight: 500;
+                    font-size: 15px;
+                    color: #FFFFFF;
+                }
+            }
+        }
     }
 }
 :deep(.van-cell){
@@ -397,4 +779,53 @@ const isShowDetail = ref(false);
 :deep(.van-button--primary){
     border: none !important;
 }
+.pop-content-password{
+    padding: 27px 35px 25px 34px;
+    .pop-title-password{
+        font-family: PingFang SC, PingFang SC;
+        font-weight: 500;
+        font-size: 17px;
+        color: #000000;
+        text-align: center;
+    }
+    .pop-btn-password{
+        margin-top: 50px;
+        display: flex;
+        justify-content: center;
+        .btn-password{
+            width: 83px;
+            height: 29px;
+            line-height: 29px;
+            padding: 5px 0 !important;
+            border-radius: 6px;
+            font-family: PingFang SC, PingFang SC;
+            font-weight: 400;
+            font-size: 15px;
+            box-sizing:border-box;
+        }
+        .cancel{
+            margin-right: 17px !important;
+            border: 1px solid #D8D8D8;
+            color: #000 !important;
+        }
+        .confirm{
+            background: @theme-color1;
+            color: #FFF;
+            font-weight: 500;
+        }
+    }
+}
+:deep(.van-popup--center) {
+    margin: 0 40px !important;
+    width: auto !important;
+}
+:deep(.van-pull-refresh){
+    display: flex !important;
+    flex-direction: column !important;
+    overflow: initial !important;
+}
+:deep(.van-pull-refresh__track){
+    display: flex !important;
+    flex-direction: column !important;
+}
 </style>

+ 4 - 4
src/views/wallet/index.vue

@@ -314,10 +314,10 @@
    const tokensHandle  = (item)=>{
     walletStore.changeToten(item.name)
   }
-  // 获取代币信息
-const gethotTokens = async () => {
-  await walletStore.updateTokenVal();
-}
+  // 更新代币信息
+  const gethotTokens = async () => {
+    await walletStore.updateTokenVal();
+  }
 
   const formatAddress = (address) => {
     if (!address) return '';

+ 12 - 30
src/views/wallet/transferDetail/index.vue

@@ -69,7 +69,7 @@
                     </div>
                 </div>
                 <div class="pop-detail" v-if="selectType == 2">
-                    <div class="pop-detail-title">-{{gasFee}} ACC</div>
+                    <!-- <div class="pop-detail-title">-{{gasFee}} ACC</div> -->
                     <div class="pop-detail-cell">
                         <div class="cell-label">付款地址:</div>
                         <div class="cell-text">{{walletStore.account}}</div>
@@ -106,7 +106,7 @@ import { useRouter } from 'vue-router'
 import { useWalletStore } from "@/stores/modules/walletStore";
 import Web3 from "web3";
 import pubData from "@/utils/pub.json";
-import { showLoadingToast, showToast } from 'vant';
+import { showToast } from 'vant';
 import { showNotify } from 'vant';
 const router = useRouter();
 const walletStore = useWalletStore();
@@ -117,8 +117,8 @@ const unitNum = ref('')
 const showWallet = ref(false)
 const showPassWord = ref(false)
 const selectType = ref('');
-const hotTokensList = ref([]);
-const selecctList = ref({})
+let hotTokensList = walletStore.tokenList;
+let selecctList = walletStore.tokenList[0];
 const passWord = ref('')
 const gasFee = ref('');
 const isDisabledConfirm = ref(false)
@@ -128,16 +128,10 @@ const isDisabled = computed(() => {
   return (
     !walletAddress.value ||                // 钱包地址为空
     !unitNum.value ||                     // 输入为空
-    isNaN(num) || num <= 0 || num >= selecctList.value.balance   // 非法数值
+    isNaN(num) || num <= 0 || num >= selecctList.balance   // 非法数值
   );
 });
 
-// 获取代币信息
-const gethotTokens = async () => {
-    const data =   await walletStore.updateTokenVal() 
-    hotTokensList.value = data;
-    selecctList.value = data[0];
-}
 const goToAddress = () => {
     router.push('addressManagement')
 }
@@ -159,7 +153,7 @@ const estimateGasFee = async () => {
 
     if (!from || !to || !amount) return;
 
-    const isACC = selecctList.value.name === 'ACC';
+    const isACC = selecctList.name === 'ACC';
 
     let tx;
     if (isACC) {
@@ -171,11 +165,11 @@ const estimateGasFee = async () => {
       };
     } else {
       // ② ERC20 代币转账
-      const contract = new web3.eth.Contract(pubData, selecctList.value.address);
+      const contract = new web3.eth.Contract(pubData, selecctList.address);
       const value = web3.utils.toWei(amount.toString(), 'ether'); // 注意小数位
       tx = {
         from,
-        to: selecctList.value.address,
+        to: selecctList.address,
         data: contract.methods.transfer(to, value).encodeABI(),
       };
     }
@@ -192,7 +186,7 @@ const estimateGasFee = async () => {
 };
 
 const changeList = (item) => {
-    selecctList.value = item;
+    selecctList = item;
     showWallet.value = false;
     unitNum.value = ''
 }
@@ -216,15 +210,10 @@ const popConfirm = () => {
 }
 // 请求链
 const getData = async () => {
-  showLoadingToast({
-    message: '转账中…',
-    forbidClick: true,
-    duration: 0,
-  });
   isDisabledConfirm.value = true;
   try {
     let receipt;
-    if (selecctList.value.name === 'ACC') {
+    if (selecctList.name === 'ACC') {
       // ETH 转账
       receipt = await sendETH(
         walletStore.privateKey,
@@ -235,17 +224,14 @@ const getData = async () => {
       // ERC‑20 代币转账
       receipt = await sendToken(
         walletStore.privateKey,
-        selecctList.value.address,
+        selecctList.address,
         walletAddress.value,
         unitNum.value
       );
     }
+    showToast('转账成功');
     router.push('/wallet');
   } catch (err) {
-    // console.error('⚠️ 转账失败:', err);
-    // const msg =
-    //   err?.message?.replace('Returned error: ', '') ||
-    //   '发生未知错误,请稍后重试';
     showToast('转账失败');
   } finally {
     showWallet.value = false;
@@ -291,10 +277,6 @@ const sendToken = async (privateKey, tokenAddress, toAddress, amount) => {
   const signedTx = await web3.eth.accounts.signTransaction(tx, privateKey);
   return await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
 };
-
-onMounted(async ()=>{
-    gethotTokens();
-  })
 </script>
 
 <style lang="less" scoped>

+ 7 - 9
src/views/wallet/ybExchange/index.vue

@@ -73,7 +73,7 @@ const ybbalance = ref(0);
 const text = ref('')
 const show = ref(false);
 const selectIndex = ref(1);//1:wgt-元宝   2:元宝-wgt
-const WGTbalance = ref(0);
+let WGTbalance = walletStore.tokenList[2].balance;
 const loading = ref(false);
 const isDisabled = ref(false);
 const changePop = (i) => {
@@ -90,10 +90,10 @@ const getbalanceInfo = async () => {
     const { data } = await syceeBalance({address:walletStore.account})
     ybbalance.value = data.balance
 }
-// 代币数据
+// 更新代币数据
 const gethotTokens = async () => {
-    const data =   await walletStore.updateTokenVal() 
-    WGTbalance.value = data[2].balance;
+    await walletStore.updateTokenVal();
+    WGTbalance = walletStore.tokenList[2].balance;
 }
 // 取消
 const cancel = () => {
@@ -113,7 +113,7 @@ const confirm = () => {
 	    return;
 	}
 	
-	let maxValue = selectIndex.value == 1 ? parseFloat(WGTbalance.value) : parseFloat(ybbalance.value);
+	let maxValue = selectIndex.value == 1 ? parseFloat(WGTbalance) : parseFloat(ybbalance.value);
 	let tokenName = selectIndex.value == 1 ? 'WGT' : '元宝';
 	if (inputValue > maxValue) {
         showToast(`输入数量不能大于可用${tokenName}数量`);
@@ -135,11 +135,10 @@ const confirm = () => {
 const getwgt2sycee = async (params) => {
     let res = ''
     if(selectIndex.value == 1){
-        res = await wgt2sycee(params);
+        res = await wgt2sycee(params).finally(() => {isDisabled.value = false});
     }else{
-        res = await sycee2wgt(params);
+        res = await sycee2wgt(params).finally(() => {isDisabled.value = false});
     }
-    isDisabled.value = false;
     show.value  = false;
 }
 const onRefresh = () => {
@@ -153,7 +152,6 @@ const onRefresh = () => {
 onMounted(async ()=>{
     getList();
     getbalanceInfo();
-    gethotTokens();
 })
 </script>