diff --git a/src/layouts/BlockchainLayout.vue b/src/layouts/BlockchainLayout.vue index 99e8730..5d0c17b 100644 --- a/src/layouts/BlockchainLayout.vue +++ b/src/layouts/BlockchainLayout.vue @@ -5,17 +5,49 @@
- FISCO BCOS Explorer - Testnet + FISCO BCOS 区块链浏览器 + 测试网
-
@@ -38,4 +70,8 @@ from { transform: rotate(0deg); } to { transform: rotate(360deg); } } + +.router-link-active .active-indicator { + transform: scaleX(1); +} diff --git a/src/router/index.js b/src/router/index.js index 669d8fe..f607314 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -68,6 +68,21 @@ const routes = [ path: 'explorer', name: 'BlockchainExplorer', component: () => import('../views/blockchain/Explorer.vue') + }, + { + path: 'blocks', + name: 'BlockchainBlocks', + component: () => import('../views/blockchain/Blocks.vue') + }, + { + path: 'transactions', + name: 'BlockchainTransactions', + component: () => import('../views/blockchain/Transactions.vue') + }, + { + path: 'contracts', + name: 'BlockchainContracts', + component: () => import('../views/blockchain/Contracts.vue') } ] } diff --git a/src/stores/blockchain.js b/src/stores/blockchain.js new file mode 100644 index 0000000..451b7aa --- /dev/null +++ b/src/stores/blockchain.js @@ -0,0 +1,110 @@ +import { defineStore } from 'pinia' +import { ref, onMounted, onUnmounted } from 'vue' + +export const useBlockchainStore = defineStore('blockchain', () => { + const stats = ref([ + { label: '区块高度', value: '8,441', icon: '📦' }, + { label: '交易总数', value: '142,506', icon: '🔗' }, + { label: '活跃节点', value: '21/21', icon: '🌐' }, + { label: '平均出块时间', value: '2.1s', icon: '⚡' } + ]) + + const blocks = ref([ + { height: 8435, hash: '0x12e6...5027', txs: 5, time: '14s', details: [] }, + { height: 8436, hash: '0xb844...0080', txs: 4, time: '12s', details: [] }, + { height: 8437, hash: '0x5532...581a', txs: 2, time: '10s', details: [] }, + { height: 8438, hash: '0xc34d...7dbd', txs: 4, time: '8s', details: [] }, + { height: 8439, hash: '0xd31b...cc3b', txs: 5, time: '6s', details: [] }, + { height: 8440, hash: '0x0d90...9885', txs: 1, time: '4s', details: [] }, + { height: 8441, hash: '0xa592...8b0d', txs: 6, time: '2s', details: [] }, + ]) + + const transactions = ref([ + { hash: '0x7d21...4e1a', type: 'Evidence', from: 'Robot-SN088', to: 'Contract:Main', time: '10s' }, + { hash: '0x9b32...1f82', type: 'TokenTransfer', from: 'Agency-Node', to: 'Robot-SN012', time: '15s' }, + { hash: '0x1c84...9a23', type: 'Alert', from: 'Robot-SN045', to: 'Admin-Node', time: '20s' }, + { hash: '0x4e55...bb12', type: 'Evidence', from: 'Robot-SN102', to: 'Contract:Main', time: '25s' }, + { hash: '0x2a91...cc84', type: 'ContractDeploy', from: 'Admin-Node', to: 'Blockchain-Net', time: '30s' }, + { hash: '0x8f32...dd91', type: 'TokenTransfer', from: 'Robot-SN099', to: 'Agency-Node', time: '35s' }, + ]) + + const generateRandomTxs = (count) => { + const types = ['Evidence', 'TokenTransfer', 'Alert', 'ContractDeploy'] + return Array.from({ length: count }).map(() => ({ + hash: '0x' + Math.random().toString(16).substring(2, 10) + '...', + type: types[Math.floor(Math.random() * types.length)], + from: `Robot-SN0${Math.floor(Math.random() * 999)}`, + to: Math.random() > 0.5 ? 'Contract:Main' : 'Agency-Node', + status: 'Success' + })) + } + + // 初始化区块详情 + blocks.value.forEach(b => { + if (!b.details || b.details.length === 0) { + b.details = generateRandomTxs(b.txs) + } + }) + + let timer = null + + const startSimulation = () => { + if (timer) return + timer = setInterval(() => { + // 1. 生成新区块 + const currentHeight = parseInt(stats.value[0].value.replace(',', '')) + const newHeight = currentHeight + 1 + const txCountInBlock = Math.floor(Math.random() * 6) + 1 + + // 2. 更新统计数据 + stats.value[0].value = newHeight.toLocaleString() + const currentTotalTxs = parseInt(stats.value[1].value.replace(',', '')) + stats.value[1].value = (currentTotalTxs + txCountInBlock).toLocaleString() + + // 3. 将新块从右侧推入 + const newHash = '0x' + Math.random().toString(16).substring(2, 6) + '...' + Math.random().toString(16).substring(2, 6) + const newBlock = { + height: newHeight, + hash: newHash, + txs: txCountInBlock, + time: '0s', + details: generateRandomTxs(txCountInBlock) + } + blocks.value.push(newBlock) + if (blocks.value.length > 20) blocks.value.shift() + + // 4. 同步生成交易记录 + const newTxs = newBlock.details.map(d => ({ + ...d, + time: '0s' + })) + transactions.value.unshift(...newTxs) + if (transactions.value.length > 50) transactions.value.splice(50) + + // 5. 更新存量时间 + blocks.value.forEach((b) => { + const seconds = parseInt(b.time) + 2 + b.time = `${seconds}s` + }) + transactions.value.forEach((tx) => { + const seconds = parseInt(tx.time) + 2 + tx.time = `${seconds}s` + }) + }, 2100) + } + + const stopSimulation = () => { + if (timer) { + clearInterval(timer) + timer = null + } + } + + return { + stats, + blocks, + transactions, + startSimulation, + stopSimulation + } +}) diff --git a/src/views/blockchain/Blocks.vue b/src/views/blockchain/Blocks.vue new file mode 100644 index 0000000..809a5ba --- /dev/null +++ b/src/views/blockchain/Blocks.vue @@ -0,0 +1,150 @@ + + + diff --git a/src/views/blockchain/Contracts.vue b/src/views/blockchain/Contracts.vue new file mode 100644 index 0000000..8c06564 --- /dev/null +++ b/src/views/blockchain/Contracts.vue @@ -0,0 +1,99 @@ + + + diff --git a/src/views/blockchain/Explorer.vue b/src/views/blockchain/Explorer.vue index f326519..aa6d392 100644 --- a/src/views/blockchain/Explorer.vue +++ b/src/views/blockchain/Explorer.vue @@ -9,21 +9,95 @@ -
-
+
+ +
-
-
- #{{ block.height }} - + +
+ +
+
+ #{{ block.height }} + +
+
+ {{ block.hash }} +
+
+ {{ block.txs }} 交易 + {{ block.time }} 前 +
+
+
+
+
+ + +
+
+
+ +
+
+

区块 #{{ selectedBlock.height }} 详情

+

{{ selectedBlock.hash }}

+
+
-
- {{ block.hash }} + + +
+
+
+ 包含交易数 + {{ selectedBlock.txs }} +
+
+ 生成时间 + {{ selectedBlock.time }} 前 +
+
+ +

交易列表

+
+
+
+
+ {{ tx.type.charAt(0) }} +
+
+
{{ tx.hash }}
+
{{ tx.from }} → {{ tx.to }}
+
+
+
+ + {{ translateType(tx.type) }} + + + 已确认 + +
+
+
-
- {{ block.txs }} txs - {{ block.time }} ago + + +
+
@@ -31,28 +105,28 @@
-

Latest Transactions

- +

最新交易

+
- - - - - + + + + + - +
Tx HashTypeFromToStatus交易哈希类型发送方接收方状态
{{ tx.hash }} - {{ tx.type }} + {{ translateType(tx.type) }} {{ tx.from }} {{ tx.to }}Success成功
@@ -61,33 +135,74 @@ + + diff --git a/src/views/blockchain/Transactions.vue b/src/views/blockchain/Transactions.vue new file mode 100644 index 0000000..7563936 --- /dev/null +++ b/src/views/blockchain/Transactions.vue @@ -0,0 +1,95 @@ + + +