forked from UzTech/Vue3-typescript-demo
youhua
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
import auth from './interfaces/auth'
|
||||
import user from './interfaces/user'
|
||||
import block from './interfaces/block'
|
||||
import esdb from './interfaces/esdb'
|
||||
import user from './interfaces/user'
|
||||
|
||||
export {
|
||||
auth,
|
||||
user,
|
||||
block
|
||||
block,
|
||||
esdb,
|
||||
user
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import Chain33Rpc from '@33cn/chain33-rpc-api'
|
||||
|
||||
export default new Chain33Rpc(process.env.VUE_APP_BLOCK_URL, null)
|
||||
export default new Chain33Rpc(process.env.VUE_APP_BLOCK_URL as string, null)
|
||||
|
||||
46
src/api/interfaces/esdb.ts
Normal file
46
src/api/interfaces/esdb.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { AuthResponse } from '@/types/auth'
|
||||
import axios, { AxiosRequestConfig } from 'axios'
|
||||
|
||||
const request = axios.create({
|
||||
baseURL: process.env.VUE_APP_API_URL as string + process.env.VUE_APP_ESDB_URL as string,
|
||||
timeout: 5000
|
||||
})
|
||||
const axiosConf = (config: AxiosRequestConfig) => {
|
||||
config.headers.Accept = 'application/json'
|
||||
return config
|
||||
}
|
||||
request.interceptors.response.use(async (response) => {
|
||||
if (response.data?.error !== null) {
|
||||
return Promise.reject(response.data.error)
|
||||
}
|
||||
return Promise.resolve(response.data?.result)
|
||||
}, () => {
|
||||
return Promise.reject('网络请求超时')
|
||||
})
|
||||
|
||||
request.interceptors.request.use(axiosConf, err => {
|
||||
return Promise.reject(err)
|
||||
})
|
||||
|
||||
const txList = (size?: number): Promise<AuthResponse> => {
|
||||
const body = {
|
||||
id: 1,
|
||||
method: 'Tx.TxList',
|
||||
params: [{
|
||||
'sort': [{
|
||||
'key': 'height',
|
||||
'ascending': false
|
||||
}],
|
||||
'page': {
|
||||
'number': 1,
|
||||
'size': size
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
return request.post('', body)
|
||||
}
|
||||
|
||||
export default {
|
||||
txList
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="header">
|
||||
<div class="wrap">
|
||||
<div class="logo" @click="router.push({name: 'Home'})">
|
||||
LOGO
|
||||
JZC Explorer
|
||||
</div>
|
||||
<Nav/>
|
||||
</div>
|
||||
@@ -34,6 +34,7 @@ const router = useRouter()
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 32px;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin-right: 32px;
|
||||
|
||||
@@ -32,10 +32,10 @@ const navList = ref<NavItem[]>([
|
||||
title: 'Token',
|
||||
route: 'Token'
|
||||
},
|
||||
{
|
||||
title: '节点',
|
||||
route: 'Nodes'
|
||||
},
|
||||
// {
|
||||
// title: '节点',
|
||||
// route: 'Nodes'
|
||||
// },
|
||||
{
|
||||
title: '解析数据',
|
||||
route: 'Analytical'
|
||||
|
||||
@@ -5,12 +5,14 @@ import App from './App.vue'
|
||||
import router from './router'
|
||||
import store, { key } from './store'
|
||||
import zhCn from 'element-plus/es/locale/lang/zh-cn'
|
||||
import directives from '@/utils/directives'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(ElementPlus, {
|
||||
locale: zhCn,
|
||||
})
|
||||
app.use(directives)
|
||||
app.use(store, key)
|
||||
app.use(router)
|
||||
app.mount('#app')
|
||||
|
||||
22
src/utils/directives.ts
Normal file
22
src/utils/directives.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { App, DirectiveBinding } from '@vue/runtime-core'
|
||||
import ClipboardJS from 'clipboard'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
export default (Vue: App) => {
|
||||
Vue.directive('copy', {
|
||||
updated (el: Element, binding: DirectiveBinding) {
|
||||
const clipboard = new ClipboardJS(el, {
|
||||
text: () => {
|
||||
return binding.value
|
||||
}
|
||||
})
|
||||
|
||||
clipboard.on('error', (): void => {
|
||||
ElMessage.warning({
|
||||
message: '当前浏览器不支持复制'
|
||||
})
|
||||
clipboard.destroy()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -3,8 +3,12 @@
|
||||
<Breadcrumb :path="[{name: '地址信息'}]"/>
|
||||
|
||||
<div class="top-info">
|
||||
<span>地址</span>
|
||||
<span>地址:</span>
|
||||
<span class="addr">{{ address }}</span>
|
||||
<el-tag size="medium" v-if="isContract">合约地址</el-tag>
|
||||
<el-tag size="medium" type="info" v-else>普通地址</el-tag>
|
||||
|
||||
<el-button type="primary" v-copy="address" size="mini">复制</el-button>
|
||||
</div>
|
||||
|
||||
<div class="assets">
|
||||
@@ -16,24 +20,24 @@
|
||||
<div class="item">
|
||||
<img src="../../assets/dots/red.png">
|
||||
<label>余额</label>
|
||||
<span>{{ balance.balance.toFixed(2) }} {{ store.getters.symbol }}</span>
|
||||
<span>{{ balance.balance.toFixed(2) }} {{ symbol }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="../../assets/dots/blue.png">
|
||||
<label>总接收</label>
|
||||
<span>{{ balance.reciver.toFixed(2) }} {{ store.getters.symbol }}</span>
|
||||
<span>{{ balance.reciver.toFixed(2) }} {{ symbol }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="../../assets/dots/green.png">
|
||||
<label>总发送</label>
|
||||
<span>{{ sended.toFixed(2) }} {{ store.getters.symbol }}</span>
|
||||
<span>{{ sended.toFixed(2) }} {{ symbol }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="item">
|
||||
<img src="../../assets/dots/blue.png">
|
||||
<label>冻结</label>
|
||||
<span>{{ frozen.toFixed(2) }} {{ store.getters.symbol }}</span>
|
||||
<span>{{ frozen.toFixed(2) }} {{ symbol }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="../../assets/dots/green.png">
|
||||
@@ -78,7 +82,7 @@
|
||||
<el-empty description="暂无数据"></el-empty>
|
||||
</template>
|
||||
|
||||
<el-table-column width="80" prop="height" label="高度"/>
|
||||
<el-table-column prop="height" label="高度"/>
|
||||
<el-table-column width="34" align="right">
|
||||
<template #default="scope">
|
||||
<el-icon v-if="scope.row.receipt.ty == 1">
|
||||
@@ -87,17 +91,18 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="交易哈希">
|
||||
<el-table-column width="200" label="交易哈希">
|
||||
<template #default="scope">
|
||||
<router-link :to="{name: 'TradeDetail', params: { hash: scope.row.txHash }}">
|
||||
{{ filterHash(scope.row.txHash, 32) }}
|
||||
{{ filterHash(scope.row.txHash, 16) }}
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="200" label="发送方">
|
||||
|
||||
<el-table-column width="160" label="发送方">
|
||||
<template #default="scope">
|
||||
<router-link :to="{name: 'Address', params: { address: scope.row.fromAddr }}">
|
||||
{{ filterHash(scope.row.fromAddr) }}
|
||||
{{ filterHash(scope.row.fromAddr, 10) }}
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -113,28 +118,38 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column width="200" label="接收方">
|
||||
<el-table-column width="160" label="接收方">
|
||||
<template #default="scope">
|
||||
<router-link :to="{name: 'Address', params: { address: scope.row.tx.to }}">
|
||||
{{ filterHash(scope.row.tx.to) }}
|
||||
{{ filterHash(scope.row.tx.to, 10) }}
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="100" label="交易量" align="center">
|
||||
<el-table-column label="交易量" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.amount }} {{ parseSymbol(scope.row.assets) }}
|
||||
{{ (scope.row.amount / 1e8).toFixed(4) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="100" label="手续费" align="center">
|
||||
<el-table-column label="手续费" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.tx.feefmt }} {{ parseSymbol(scope.row.assets) }}
|
||||
{{ scope.row.tx.feefmt }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="" label="上链时间" width="165" align="center">
|
||||
<el-table-column label="调用函数" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.actionName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="165" label="上链时间" align="center">
|
||||
<template #default="scope">
|
||||
<TimeFormat :time="scope.row.blockTime"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="交易资产" align="center">
|
||||
<template #default="scope">
|
||||
{{ parseSymbol(scope.row.assets) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
</Pagination>
|
||||
@@ -156,6 +171,8 @@ const route = useRoute()
|
||||
const address = computed<string>(() => route.params.address as string)
|
||||
const pageSize = Number(process.env.VUE_APP_BLOCK_DETAIL_LIST_SIZE)
|
||||
|
||||
const symbol = computed<string>(() => store.getters.symbol)
|
||||
|
||||
const balance = ref<AddrOverview>({
|
||||
balance: 0,
|
||||
reciver: 0,
|
||||
@@ -167,6 +184,7 @@ const records = ref<BlockDetail[]>([])
|
||||
const token = ref<string>('')
|
||||
const assets = ref<TokenAssetItem[]>([])
|
||||
const loading = ref<boolean>(false)
|
||||
const isContract = ref<boolean>(false)
|
||||
|
||||
watch(route, (to) => {
|
||||
if (to.name == 'Address') {
|
||||
@@ -180,6 +198,15 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
const initAddressData = () => {
|
||||
block.callPromiseAPI('Query', {
|
||||
execer: 'evm',
|
||||
funcName: 'CheckAddrExists',
|
||||
payload: {
|
||||
addr: address.value
|
||||
}
|
||||
}).then(res => {
|
||||
isContract.value = res.result.contract
|
||||
})
|
||||
/**
|
||||
* 获取地址的基本信息
|
||||
*/
|
||||
@@ -259,6 +286,13 @@ const loadTradeList = () => {
|
||||
color: #516379;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.el-tag,
|
||||
.el-button {
|
||||
vertical-align: middle;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.warning {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<div class="height">
|
||||
<h2>区块高度 {{ info.height }}</h2>
|
||||
<div>区块哈希 {{ info.hash }}
|
||||
<el-button type="primary" round size="mini">复 制</el-button>
|
||||
<el-button type="primary" v-copy="info.hash" round size="mini">复 制</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<div class="item">
|
||||
<img src="../../assets/dots/green.png">
|
||||
<label>上个区块</label>
|
||||
<span v-if="info.height -1 > 0">
|
||||
<span v-if="info.height - 1 > 0">
|
||||
<router-link :to="{name: 'BlockDetail', params: {hash: info.parentHash}}">
|
||||
{{ info.height - 1 }}
|
||||
</router-link>
|
||||
@@ -42,7 +42,7 @@
|
||||
<div class="item">
|
||||
<img src="../../assets/dots/red.png">
|
||||
<label>时间</label>
|
||||
<span>{{ info.blockTime }}</span>
|
||||
<span><TimeFormat :time="info.blockTime"/></span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="../../assets/dots/green.png">
|
||||
@@ -76,35 +76,44 @@
|
||||
<el-empty description="暂无数据"></el-empty>
|
||||
</template>
|
||||
|
||||
<el-table-column label="交易哈希">
|
||||
<el-table-column width="200" label="交易哈希">
|
||||
<template #default="scope">
|
||||
<router-link :to="{name: 'TradeDetail', params: { hash: scope.row.txHash }}">
|
||||
{{ filterHash(scope.row.txHash) }}
|
||||
{{ filterHash(scope.row.txHash, 16) }}
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="发送方">
|
||||
<el-table-column width="160" label="发送方">
|
||||
<template #default="scope">
|
||||
<router-link :to="{name: 'Address', params: { address: scope.row.fromAddr }}">
|
||||
{{ filterHash(scope.row.fromAddr) }}
|
||||
{{ filterHash(scope.row.fromAddr, 10) }}
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="接收方">
|
||||
<el-table-column width="160" label="接收方">
|
||||
<template #default="scope">
|
||||
<router-link :to="{name: 'Address', params: { address: scope.row.tx.to }}">
|
||||
{{ filterHash(scope.row.tx.to) }}
|
||||
{{ filterHash(scope.row.tx.to, 10) }}
|
||||
</router-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="100" prop="amount" label="交易量" align="center"/>
|
||||
<el-table-column width="100" prop="tx.feefmt" label="手续费" align="center"/>
|
||||
<el-table-column prop="" label="上链时间" width="165" align="center">
|
||||
<el-table-column label="交易量" align="center">
|
||||
<template #default="scope">
|
||||
{{ (scope.row.amount / 1e8).toFixed(4) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="tx.feefmt" label="手续费" align="center"/>
|
||||
<el-table-column label="上链时间" width="165" align="center">
|
||||
<template #default="scope">
|
||||
<TimeFormat :time="scope.row.blockTime"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column width="100" label="交易资产" align="center">
|
||||
<el-table-column label="调用函数" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.actionName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="交易资产" align="center">
|
||||
<template #default="scope">
|
||||
{{ parseSymbol(scope.row.assets) }}
|
||||
</template>
|
||||
@@ -124,18 +133,20 @@ import { useRoute } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
const pageSize = Number(process.env.VUE_APP_BLOCK_DETAIL_LIST_SIZE)
|
||||
const thisHash = ref<string>('')
|
||||
|
||||
onMounted(() => {
|
||||
thisHash.value = route.params.hash as string
|
||||
loadBlockData()
|
||||
})
|
||||
|
||||
watch(route, (to) => {
|
||||
if (to.name === 'BlockDetail') {
|
||||
thisHash.value = info.value.parentHash
|
||||
loadBlockData()
|
||||
}
|
||||
})
|
||||
|
||||
const hash: string = route.params.hash as string
|
||||
|
||||
const handleCurrentChange = (e: number) => {
|
||||
console.log(e)
|
||||
@@ -157,10 +168,7 @@ const next = ref({
|
||||
const records = ref([])
|
||||
|
||||
const loadBlockData = () => {
|
||||
console.log('jiazai shuju ')
|
||||
|
||||
block.getBlockOverview(hash).then(res => {
|
||||
console.log('更新INFO A ')
|
||||
block.getBlockOverview(thisHash.value).then(res => {
|
||||
info.value = res.result.head
|
||||
|
||||
block.getTxByHashes(res.result.txHashes).then(txs => {
|
||||
|
||||
@@ -77,7 +77,7 @@ export default {
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { block } from '@/api'
|
||||
import { block, esdb } from '@/api'
|
||||
import { Banner, TimeFormat } from '@/components'
|
||||
import useGetMaxHeight from '@/hooks/useGetMaxHeight'
|
||||
import { BlockItem, TradeItem } from '@/types/block'
|
||||
@@ -262,6 +262,10 @@ async function getTradeList () {
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.asset {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<div class="height">
|
||||
<h2>数据详情</h2>
|
||||
<div>数据哈希 {{ detail.tx.hash }}
|
||||
<el-button type="primary" round size="mini">复 制</el-button>
|
||||
<el-button type="primary" v-copy="detail.tx.hash" round size="mini">复 制</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>资产</label>
|
||||
<div>{{ detail.amount }} {{ parseSymbol(detail.assets) }}</div>
|
||||
<div>{{ (detail.amount / 1e8).toFixed(4) }} {{ parseSymbol(detail.assets) }}</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<label>GAS费</label>
|
||||
@@ -108,7 +108,9 @@ const detail = ref<BlockDetail>({
|
||||
payload: {}
|
||||
}
|
||||
} as BlockDetail)
|
||||
const blockHash = ref('')
|
||||
|
||||
const blockHash = ref<string>('')
|
||||
|
||||
block.queryTransaction(route.params.hash as string).then(res => {
|
||||
detail.value = res.result
|
||||
|
||||
@@ -116,7 +118,6 @@ block.queryTransaction(route.params.hash as string).then(res => {
|
||||
blockHash.value = res.result.hash
|
||||
})
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
Reference in New Issue
Block a user