Compare commits

...

8 Commits

Author SHA1 Message Date
de7d9b29b2 第一版本 2021-09-30 17:00:15 +08:00
d03cef9685 数据分页 2021-09-30 16:56:41 +08:00
4e1ca61828 types 2021-09-30 15:42:53 +08:00
7785e2bd5a 首页样式修改 2021-09-30 12:19:32 +08:00
9ca6c78f66 打包不显示源码的配置,获取最新高度的机制更新 2021-09-30 11:57:30 +08:00
d4c4605d7e statsh 2021-09-30 09:14:12 +08:00
zhangdongxue
4b2ce62cea 尝试计算trades 2021-09-29 21:37:55 +08:00
33dc44c4c7 首页最新交易的数据获取 2021-09-29 18:09:29 +08:00
26 changed files with 559 additions and 200 deletions

View File

@@ -1,10 +1,17 @@
NODE_ENV=production
NODE_ENV=development
BASE_URL=/
VUE_APP_VUEX_KEY=vuex
VUE_APP_VUEX_KEY=ex_vuex
VUE_APP_TITLE=Jason.Chen
VUE_APP_TITLE=联盟链浏览器
VUE_APP_API_URL=/api
VUE_APP_BLOCK_URL=https://explorer.lianshang.vip/api
VUE_APP_MAIN_COIN_SYMBOL=XHC
VUE_APP_USERNAME=
VUE_APP_PASSWORD=
VUE_APP_HOME_LIST_SIZE=6
VUE_APP_BLOCK_LIST_SIZE=20
VUE_APP_BLOCK_DETAIL_LIST_SIZE=10

View File

@@ -1,3 +1,3 @@
import Chain33Rpc from '@33cn/chain33-rpc-api'
export default new Chain33Rpc('http://47.100.214.15:8080/api', null)
export default new Chain33Rpc(process.env.VUE_APP_BLOCK_URL, null)

BIN
src/assets/home/box.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 720 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 B

View File

@@ -1,5 +1,16 @@
<template>
<div class="banner">
<div class="left-trans">
<div class="animation-area">
<img src="../assets/home/line-right.gif" class="line-left" alt="">
<img src="../assets/home/box.png" class="box-left" alt="">
<div class="circle-area">
<img src="../assets/home/cicle-out.png" class="left-out-cicle" alt="">
<img src="../assets/home/cicle-inner.png" class="left-inner-cicle" alt="">
</div>
</div>
</div>
<div class="middle">
<div class="search-box">
<h1>区块链浏览器</h1>
@@ -15,6 +26,17 @@
</div>
</div>
</div>
<div class="right-trans">
<div class="animation-area flex-between-stright">
<div class="circle-area">
<img src="../assets/home/cicle-out.png" class="right-out-cicle" alt="">
<img src="../assets/home/cicle-inner.png" class="right-inner-cicle" alt="">
</div>
<img src="../assets/home/box.png" class="box-right" alt="">
<img src="../assets/home/line-left.gif" class="line-right" alt="">
</div>
</div>
</div>
</template>
@@ -124,12 +146,107 @@ const onSearch = () => {
align-items: center;
justify-content: center;
.left-trans,
.middle,
.right-trans {
display: inline-block;
height: 556px;
}
.left-trans {
width: 150px;
background: url("../assets/home/left-line.png") no-repeat top 60px left;
overflow: hidden;
.animation-area {
position: relative;
margin-top: 60px;
height: 450px;
float: right;
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
}
.box-left {
margin-top: -40px;
margin-left: -40px;
animation: jump 2s ease-in-out 1s infinite alternate;
}
.circle-area {
position: relative;
width: 91px;
height: 91px;
.left-out-cicle {
position: absolute;
left: 0;
top: 0;
animation: clockwise 2.5s linear infinite;
}
.left-inner-cicle {
width: 70px;
position: absolute;
left: 10px;
top: 11px;
animation: anticlockwise 2.5s linear infinite;
}
}
}
.right-trans {
width: 150px;
background: url("../assets/home/right-line.png") no-repeat top 60px right;
overflow: hidden;
.animation-area {
position: relative;
margin-top: 60px;
height: 450px;
float: left;
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
}
.box-right {
margin-right: -30px;
animation: jump 2s ease-in-out 0.1s infinite alternate;
}
.circle-area {
position: relative;
width: 91px;
height: 91px;
.right-out-cicle {
position: absolute;
left: 0;
top: 0;
animation: clockwise 2.5s linear infinite;
}
.right-inner-cicle {
width: 70px;
position: absolute;
left: 10px;
top: 12px;
animation: anticlockwise 2.5s linear infinite;
}
}
}
.middle {
height: 556px;
position: relative;
width: 1000px;
flex-shrink: 0;
background: url("/assets/images/ball.png") center center no-repeat;
background: url("../assets/ball.png") center center no-repeat;
.search-box {
width: 700px;
@@ -190,4 +307,32 @@ const onSearch = () => {
}
}
}
// 动画区
@keyframes clockwise {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes anticlockwise {
0% {
transform: rotate(360deg);
}
100% {
transform: rotate(0deg);
}
}
@keyframes jump {
from {
transform: translate(0, 0);
}
to {
transform: translate(0, 15px);
}
}
</style>

View File

@@ -24,10 +24,10 @@ const navList = ref<NavItem[]>([
title: '查看区块',
route: 'Block'
},
{
title: '查看数据',
route: 'Trade'
},
// {
// title: '查看数据',
// route: 'Trade'
// },
{
title: 'Token',
route: 'Token'
@@ -43,10 +43,6 @@ const navList = ref<NavItem[]>([
{
title: '广播数据',
route: 'Broadcast'
},
{
title: '我的钱包',
route: 'Wallet'
}
])
const linkTo = (name: string) => {

View File

@@ -2,14 +2,16 @@
<div class="records">
<div class="head">
<h2>{{ title }}</h2>
<el-pagination
background
layout="total,prev,pager,next,jumper"
:total="length"
:page-size="pageSize"
@current-change="handleCurrentChange"
>
</el-pagination>
<slot name="page">
<el-pagination
background
layout="total,prev,pager,next,jumper"
:total="length"
:page-size="pageSize"
@current-change="handleCurrentChange"
>
</el-pagination>
</slot>
</div>
<slot name="default"></slot>

View File

@@ -1,22 +1,36 @@
import { block } from '@/api'
import vuex from '@/store'
import { TotalFee } from '@/types/block'
import { hexCharCodeToStr } from '@/utils/filters'
import { ElMessage } from 'element-plus'
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import { computed, ComputedRef, onActivated, ref } from 'vue'
import { onBeforeRouteLeave } from 'vue-router'
export default function () {
const maxHeight = computed(() => vuex.getters.maxHeight)
export default function (): {
maxHeight: ComputedRef<number>;
queryTotalFee: () => Promise<TotalFee>;
lastHash: ComputedRef<string>;
} {
const maxHeight: ComputedRef<number> = computed(() => vuex.getters.maxHeight)
const lastHash: ComputedRef<string> = computed(() => vuex.getters.lastHash)
// eslint-disable-next-line no-undef
const interval = ref<NodeJS.Timeout | null>()
onMounted(() => {
onActivated(() => {
getLastHeader()
console.log('开始轮询头信息')
interval.value = setInterval(() => {
getLastHeader()
}, 5000)
})
const getLastHeader = () => {
/**
* 获取最新的区块
*/
const getLastHeader = (): void => {
block.getLastHeader().then(res => {
console.log('获取最新区块', res.result.height)
if (res.error) {
clearInterval(Number(interval.value))
return ElMessage.error({
@@ -25,15 +39,26 @@ export default function () {
})
} else if (maxHeight.value !== res.result.height) {
vuex.dispatch('setMaxHeight', res.result.height).then()
vuex.dispatch('setLastHash', res.result.hash).then()
}
})
}
onBeforeUnmount(() => {
/**
* 查询从交易量和交易费
*/
const queryTotalFee = (): Promise<TotalFee> => {
return block.queryTotalFee(hexCharCodeToStr(lastHash.value))
}
onBeforeRouteLeave(() => {
console.log('结束轮询')
clearInterval(Number(interval.value))
})
return {
maxHeight
maxHeight,
lastHash,
queryTotalFee
}
}

View File

@@ -99,17 +99,6 @@ export default [
showTabBar: true
},
component: () => import(/* webpackChunkName: "other" */ '@/views/Token/index.vue')
},
{
path: '/wallet',
name: 'Wallet',
meta: {
title: '我的钱包',
keepAlive: false,
requiresAuth: true,
showTabBar: true
},
component: () => import(/* webpackChunkName: "wallet" */ '@/views/Wallet/index.vue')
},
}
] as MyRouteRecordRaw[]

View File

@@ -17,6 +17,7 @@ export interface State {
openId: string
loginAt: number
maxHeight: number
lastHash: string
user: BaseInfo
auth?: AuthState
refresh?: RefreshState
@@ -31,6 +32,7 @@ export default createStore<State>({
openId: '',
loginAt: 0,
maxHeight: 0,
lastHash: '',
user: {} as BaseInfo
},
getters: {
@@ -48,6 +50,9 @@ export default createStore<State>({
},
symbol: (): string => {
return process.env.VUE_APP_MAIN_COIN_SYMBOL as string
},
lastHash: (state: State): string => {
return state.lastHash
}
},
mutations: {
@@ -74,17 +79,23 @@ export default createStore<State>({
},
setMaxHeight: (state: State, height: number): void => {
state.maxHeight = height
},
setLastHash: (state: State, hash: string): void => {
state.lastHash = hash
}
},
actions: {
setUserInfo: ({ commit }, info: BaseInfo): void => {
setUserInfo: ({commit}, info: BaseInfo): void => {
commit('setUserInfo', info)
},
setOpenId: ({ commit }, openId: string): void => {
setOpenId: ({commit}, openId: string): void => {
commit('setOpenId', openId)
},
setMaxHeight: ({ commit }, height: number): void => {
setMaxHeight: ({commit}, height: number): void => {
commit('setMaxHeight', height)
},
setLastHash: ({commit}, hash: string): void => {
commit('setLastHash', hash)
}
},
modules: {

20
src/types/block.d.ts vendored
View File

@@ -95,3 +95,23 @@ export declare type BlockDetail = {
tyName: string
}
}
export declare type TradeItem = {
txHash: string
blockTime: number
fromAddr: string
amount: number
assets: any
tx: {
to: string
}
}
export declare type TotalFee = {
error: string | null
id: number
result: {
fee: number
txCount: number
}
}

View File

@@ -18,7 +18,7 @@ export const parseSymbol = (assets?: AssetType[]): string => {
}
}
export const timestampToTime = (timestamp: number) => {
export const timestampToTime = (timestamp: number): string => {
const date = new Date(timestamp * 1000)
const Y = date.getFullYear() + '-'
const M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'
@@ -28,3 +28,56 @@ export const timestampToTime = (timestamp: number) => {
const s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
return Y + M + D + h + m + s
}
export function bin2hex (str: string): string {
let ret = ''
const r = /[0-9a-zA-Z_.~!*()]/
for (let i = 0, l = str.length; i < l; i++) {
if (r.test(str.charAt(i))) {
ret += str.charCodeAt(i).toString(16)
console.log(ret)
} else {
ret += encodeURIComponent(str.charAt(i)).replace(/%/g, '')
}
}
return ret
}
export function hexCharCodeToStr (hexCharCodeStr: string): string[] {
const trimedStr = hexCharCodeStr.trim()
const rawStr = trimedStr.substr(0, 2).toLowerCase() === '0x' ? trimedStr.substr(2) : trimedStr
const len = rawStr.length
let curCharCode
const resultStr = []
for (let i = 0; i < len; i = i + 2) {
curCharCode = parseInt(rawStr.substr(i, 2), 16)
resultStr.push(String.fromCharCode(curCharCode))
}
return [base64Encode(`TotalFeeKey:${resultStr.join('')}`)]
}
const base64Encode = (input: string): string => {
const _keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
let output = ''
let chr1, chr2, chr3, enc1, enc2, enc3, enc4
let i = 0
while (i < input.length) {
chr1 = input.charCodeAt(i++)
chr2 = input.charCodeAt(i++)
chr3 = input.charCodeAt(i++)
enc1 = chr1 >> 2
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4)
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6)
enc4 = chr3 & 63
if (isNaN(chr2)) {
enc3 = enc4 = 64
} else if (isNaN(chr3)) {
enc4 = 64
}
output = output +
_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
_keyStr.charAt(enc3) + _keyStr.charAt(enc4)
}
return output
}

View File

@@ -60,73 +60,83 @@
</div>
<Pagination
:length="balance.txCount"
:title="`数据记录(` + balance.txCount + `)`"
:page-size="pageSize"
@current-change="handleCurrentChange"
>
<el-table :data="records" stripe class="table">
<template #empty>
<el-empty description="暂无数据"></el-empty>
</template>
<template #page>
<el-pagination
background
:page-size="pageSize"
layout="prev,next"
:total="balance.txCount"
@current-change="handleCurrentChange"
>
</el-pagination>
</template>
<template #default>
<el-table :data="records" v-loading="loading" stripe class="table">
<template #empty>
<el-empty description="暂无数据"></el-empty>
</template>
<el-table-column width="34" align="right">
<template #default="scope">
<el-icon v-if="scope.row.receipt.ty == 1">
<Warning class="warning"/>
</el-icon>
</template>
</el-table-column>
<el-table-column width="80" prop="height" label="高度"/>
<el-table-column width="34" align="right">
<template #default="scope">
<el-icon v-if="scope.row.receipt.ty == 1">
<Warning class="warning"/>
</el-icon>
</template>
</el-table-column>
<el-table-column label="交易哈希">
<template #default="scope">
<router-link :to="{name: 'TradeDetail', params: { hash: scope.row.txHash }}">
{{ filterHash(scope.row.txHash, 32) }}
</router-link>
</template>
</el-table-column>
<el-table-column width="200" label="发送方">
<template #default="scope">
<router-link :to="{name: 'Address', params: { address: scope.row.fromAddr }}">
{{ filterHash(scope.row.fromAddr) }}
</router-link>
</template>
</el-table-column>
<el-table-column label="交易哈希">
<template #default="scope">
<router-link :to="{name: 'TradeDetail', params: { hash: scope.row.txHash }}">
{{ filterHash(scope.row.txHash, 32) }}
</router-link>
</template>
</el-table-column>
<el-table-column width="200" label="发送方">
<template #default="scope">
<router-link :to="{name: 'Address', params: { address: scope.row.fromAddr }}">
{{ filterHash(scope.row.fromAddr) }}
</router-link>
</template>
</el-table-column>
<el-table-column width="40" align="center">
<template #default="scope">
<el-icon v-if="scope.row.fromAddr == address">
<DArrowRight/>
</el-icon>
<el-icon v-else>
<DArrowLeft/>
</el-icon>
</template>
</el-table-column>
<el-table-column width="40" align="center">
<template #default="scope">
<el-icon v-if="scope.row.fromAddr == address">
<DArrowRight/>
</el-icon>
<el-icon v-else>
<DArrowLeft/>
</el-icon>
</template>
</el-table-column>
<el-table-column width="200" label="接收方">
<template #default="scope">
<router-link :to="{name: 'Address', params: { address: scope.row.tx.to }}">
{{ filterHash(scope.row.tx.to) }}
</router-link>
</template>
</el-table-column>
<el-table-column width="100" label="交易量" align="center">
<template #default="scope">
{{ scope.row.amount }} {{ parseSymbol(scope.row.assets) }}
</template>
</el-table-column>
<el-table-column width="100" label="手续费" align="center">
<template #default="scope">
{{ scope.row.tx.feefmt }} {{ parseSymbol(scope.row.assets) }}
</template>
</el-table-column>
<el-table-column prop="" label="上链时间" width="165" align="center">
<template #default="scope">
<TimeFormat :time="scope.row.blockTime"/>
</template>
</el-table-column>
</el-table>
<el-table-column width="200" label="接收方">
<template #default="scope">
<router-link :to="{name: 'Address', params: { address: scope.row.tx.to }}">
{{ filterHash(scope.row.tx.to) }}
</router-link>
</template>
</el-table-column>
<el-table-column width="100" label="交易量" align="center">
<template #default="scope">
{{ scope.row.amount }} {{ parseSymbol(scope.row.assets) }}
</template>
</el-table-column>
<el-table-column width="100" label="手续费" align="center">
<template #default="scope">
{{ scope.row.tx.feefmt }} {{ parseSymbol(scope.row.assets) }}
</template>
</el-table-column>
<el-table-column prop="" label="上链时间" width="165" align="center">
<template #default="scope">
<TimeFormat :time="scope.row.blockTime"/>
</template>
</el-table-column>
</el-table>
</template>
</Pagination>
</div>
</template>
@@ -138,12 +148,12 @@ import { useStore } from '@/store'
import { AddrOverview, BlockDetail, TokenAssetItem } from '@/types/block'
import { filterHash, parseSymbol } from '@/utils/filters'
import { DArrowLeft, DArrowRight, Warning } from '@element-plus/icons'
import { computed, ref } from 'vue'
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { useRoute } from 'vue-router'
const store = useStore()
const route = useRoute()
const address = route.params.address as string
const address = computed<string>(() => route.params.address as string)
const pageSize = Number(process.env.VUE_APP_BLOCK_DETAIL_LIST_SIZE)
const balance = ref<AddrOverview>({
@@ -151,61 +161,92 @@ const balance = ref<AddrOverview>({
reciver: 0,
txCount: 0
})
/**
* 获取地址的基本信息
*/
block.getAddrOverview(address).then(res => {
balance.value.balance = res.result.balance ? res.result.balance / 1e8 : 0
balance.value.reciver = res.result.reciver ? res.result.reciver / 1e8 : 0
balance.value.txCount = res.result.txCount ? res.result.txCount : 0
})
const sended = computed(() => balance.value.reciver - balance.value.balance)
const frozen = ref<number>(0)
/**
* 获取冻结的主代币
*/
block.getAllExecBalance(address).then(res => {
if (res.result.execAccount) {
frozen.value = res.result.execAccount.find((item: { execer: string }) => item.execer == 'coins').account.frozen / 1e8
const records = ref<BlockDetail[]>([])
const token = ref<string>('')
const assets = ref<TokenAssetItem[]>([])
const loading = ref<boolean>(false)
watch(route, (to) => {
if (to.name == 'Address') {
records.value = []
initAddressData()
}
})
const records = ref<BlockDetail[]>([])
/**
* 获取全部交易
*/
block.getTxByAddr({
addr: address,
onMounted(() => {
initAddressData()
})
const initAddressData = () => {
/**
* 获取地址的基本信息
*/
block.getAddrOverview(address.value).then(res => {
balance.value.balance = res.result.balance ? res.result.balance / 1e8 : 0
balance.value.reciver = res.result.reciver ? res.result.reciver / 1e8 : 0
balance.value.txCount = res.result.txCount ? res.result.txCount : 0
})
/**
* 获取冻结的主代币
*/
block.getAllExecBalance(address.value).then(res => {
if (res.result.execAccount) {
frozen.value = res.result.execAccount.find((item: { execer: string }) => item.execer == 'coins').account.frozen / 1e8
}
})
block.getAddrTokenAssets(address.value, 'token').then(res => {
if (res.error == null) {
console.log(res)
assets.value = res.result.tokenAssets
}
})
loadTradeList()
}
const initParams = {
addr: address.value,
flag: 0,
count: pageSize,
direction: 0,
height: -1,
index: 1
}).then(res => {
if (res.error == null) {
let hashes = res.result.txInfos.map((item: { hash: string }) => item.hash)
block.getTxByHashes(hashes).then(res => {
records.value = res.result.txs
})
}
})
index: 0
}
const pageParams = reactive(initParams)
const handleCurrentChange = (e: number) => {
console.log(e)
if (e === 1) {
pageParams.direction = 0
pageParams.height = -1
} else {
pageParams.direction = 0
pageParams.height = records.value[records.value.length - 1].height
pageParams.index = records.value[records.value.length - 1].index
}
console.log(pageParams)
records.value = []
loadTradeList()
}
const token = ref<string>('')
const assets = ref<TokenAssetItem[]>([])
const loadTradeList = () => {
loading.value = true
block.getAddrTokenAssets(address, 'token').then(res => {
if (res.error == null) {
console.log(res)
assets.value = res.result.tokenAssets
}
})
block.getTxByAddr(pageParams).then(res => {
if (res.error == null) {
let hashes = res.result.txInfos.map((item: { hash: string }) => item.hash)
block.getTxByHashes(hashes).then(res => {
console.log(' pageParams.height ', pageParams.height)
records.value = res.result.txs
}).finally(() => {
loading.value = false
})
} else {
loading.value = false
}
})
}
</script>
<style scoped lang="less">

View File

@@ -1,7 +1,6 @@
<template>
<div class="container">
登录
<button @click="onLogin">一键登录</button>
</div>
</template>
@@ -14,7 +13,7 @@ const route = useRoute()
const store = useStore()
const onLogin = () => {
store.dispatch('auth/Login', { username: '15555555555', password: '123123' }).then(() => {
store.dispatch('auth/Login', { username: '', password: '' }).then(() => {
route.query.to ? router.replace({ path: route.query.to as string }) : router.replace({ name: 'Home' })
}).catch(err => {
alert(err.message)

View File

@@ -1,7 +1,5 @@
<template>
注册
<button @click="onRegister">注册一个号</button>
</template>
<script lang="ts" setup>

View File

@@ -71,6 +71,7 @@ const end = computed(() => {
const blockList = ref([])
onMounted(() => {
console.log('BLOCK INDEX')
getBlockList()
})

View File

@@ -30,15 +30,40 @@
<div class="trades">
<div class="head">
<h1>最新交易</h1>
<router-link :to="{name: 'Trade'}">查看全部</router-link>
<!-- <router-link :to="{name: 'Trade'}">查看全部</router-link>-->
</div>
<div class="items">
<div class="items" v-loading="tradeLoading">
<div class="item" v-for="(item, index) in tradeList" :key="index">
{{ item.from }}
{{ item.to }}
{{ item.hash }}
{{ item.feefmt }}
<div class="hash">
<div>
交易哈希
<router-link :to="{name: 'TradeDetail', params: {hash: item.txHash}}">
{{ filterHash(item.txHash, 10) }}
</router-link>
</div>
<div class="time">
<TimeFormat :time="item.blockTime"/>
</div>
</div>
<div class="addr">
<div>
发送方
<router-link :to="{name: 'Address', params: {address: item.fromAddr}}">
{{ filterHash(item.fromAddr, 10) }}
</router-link>
</div>
<div>
接收方
<router-link :to="{name: 'Address', params: {address: item.tx.to}}">
{{ filterHash(item.tx.to, 10) }}
</router-link>
</div>
</div>
<div class="asset">
<div>交易资产</div>
<div>{{ item.amount }} {{ parseSymbol(item.assets) }}</div>
</div>
</div>
</div>
</div>
@@ -55,8 +80,8 @@ export default {
import { block } from '@/api'
import { Banner, TimeFormat } from '@/components'
import useGetMaxHeight from '@/hooks/useGetMaxHeight'
import { BlockItem } from '@/types/block'
import { filterHash } from '@/utils/filters'
import { BlockItem, TradeItem } from '@/types/block'
import { filterHash, parseSymbol } from '@/utils/filters'
import { onMounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
@@ -65,6 +90,7 @@ const { maxHeight } = useGetMaxHeight()
const pageSize = Number(process.env.VUE_APP_HOME_LIST_SIZE)
const blockLoading = ref<boolean>(true)
const tradeLoading = ref<boolean>(true)
onMounted(() => {
getBlockList()
@@ -77,50 +103,65 @@ watch(maxHeight, (newValue, oldValue) => {
})
const blockList = ref<BlockItem[]>([])
const tradeList = ref([])
const tradeList = ref<TradeItem[]>([])
if (blockList.value.length === 0) {
let initBlock = {
const initBlock = {
height: 0,
hash: 'x',
hash: ' ',
txCount: 0,
blockTime: 0
}
} as BlockItem
for (let i = 0; i < 6; i++) {
blockList.value.push(initBlock)
}
}
if (tradeList.value.length === 0) {
const initTrade = {
txHash: ' ',
blockTime: 0,
fromAddr: ' ',
amount: 0,
assets: null,
tx: {
to: ' '
}
} as TradeItem
for (let i = 0; i < 6; i++) {
tradeList.value.push(initTrade)
}
}
const getBlockList = () => {
const start = maxHeight.value - pageSize + 1 > 0 ? maxHeight.value - pageSize + 1 : 0
block.getHeaders(start, maxHeight.value, false).then(res => {
blockList.value = res.result.items.reverse()
getTradeList()
}).finally(() => {
blockLoading.value = false
tradeLoading.value = false
})
}
async function getTradeList () {
let txHashes = []
for (let i = 0; i < blockList.value.length; i++) {
let res = await block.getBlockOverview(blockList.value[i].hash)
txHashes.push(...res.result.txHashes)
if (txHashes.length > pageSize) {
txHashes = txHashes.slice(0, 6)
break
}
}
block.getTxByHashes(txHashes).then(res => {
tradeList.value = res.result.txs
}).finally(() => {
tradeLoading.value = false
})
// block.getBlocks(start, maxHeight.value, false).then(res => {
// res.result.items.reverse().forEach((item) => {
//
// blockList.value.push({
// height: item.block.height,
// blockTime: item.block.blockTime,
// txCount: item.block.txs.length,
// // hash: block.getBlockHash(item.block.height)
// })
//
// // block.getBlockHash(item.block.height).then(hash => {
// // blockList.value.push({
// // height: item.block.height,
// // blockTime: item.block.blockTime,
// // txCount: item.block.txs.length,
// // hash: hash.result.hash
// // })
// // })
// tradeList.value.push(...item.block.txs)
// console.log(tradeList.value)
// })
// })
}
</script>
@@ -161,6 +202,10 @@ const getBlockList = () => {
height: 90px;
padding: 16px;
display: flex;
.time {
color: #9ea2a9;
}
}
}
}
@@ -198,18 +243,26 @@ const getBlockList = () => {
.num {
color: #6368de;
margin-right: 16px;
}
.time {
margin-left: 16px;
color: #9ea2a9;
}
}
}
}
.trades {
.item {
justify-content: space-between;
.hash,
.addr,
.asset {
display: flex;
flex-direction: column;
justify-content: space-between;
}
}
}
}

View File

@@ -16,7 +16,11 @@
</router-link>
</template>
</el-table-column>
<el-table-column prop="total" label="发行数量"/>
<el-table-column label="发行数量">
<template #default="scope">
{{ (scope.row.total / 1e8).toFixed(2) }}
</template>
</el-table-column>
<el-table-column label="发行时间" width="165" align="center">
<template #default="scope">
<TimeFormat :time="Number(scope.row.createdTime)"/>
@@ -36,7 +40,7 @@ export default {
import { block } from '@/api'
import { Breadcrumb, TimeFormat } from '@/components'
import { filterHash } from '@/utils/filters'
import { onMounted, ref } from 'vue'
import { ref } from 'vue'
const tokens = ref([])

View File

@@ -110,7 +110,6 @@ const detail = ref<BlockDetail>({
} as BlockDetail)
const blockHash = ref('')
block.queryTransaction(route.params.hash as string).then(res => {
console.log(res)
detail.value = res.result
block.getBlockHash(res.result.height).then(res => {

View File

@@ -2,10 +2,9 @@
<div class="container">
<Breadcrumb :path="[{name: '全部数据'}]"/>
<Pagination
:length="maxHeight"
:title="`全部区块(` + maxHeight + `)`"
:length="txCount"
:title="`数据总数(` + txCount + `)`"
:page-size="pageSize"
@current-change="handleCurrentChange"
>
@@ -23,13 +22,29 @@
</div>
</template>
<script lang="ts">
export default {
name: 'Trade'
}
</script>
<script lang="ts" setup>
import { Breadcrumb, Pagination } from '@/components'
import useGetMaxHeight from '@/hooks/useGetMaxHeight'
import { onMounted, ref } from 'vue'
import { ref } from 'vue'
const { queryTotalFee } = useGetMaxHeight()
const currentPage = ref<number>(1)
const pageSize = ref<number>(20)
onMounted(() => {
console.log('TRADE onMounted')
})
const txCount = ref<number>(0)
queryTotalFee().then(res => {
txCount.value = res.result.txCount
})
const pageSize = Number(process.env.VUE_APP_BLOCK_LIST_SIZE)
const handleCurrentChange = (e: number) => {
console.log(e)
}

View File

@@ -5,6 +5,7 @@ function resolve (dir) {
}
module.exports = {
productionSourceMap: false,
configureWebpack: {
resolve: {
alias: {