Commit ea6f8199 authored by wenglk's avatar wenglk

Merge branch 'feature-rangeSearch' into consensus

# Conflicts: # src/components/mobile/m-blockItem.vue
parents a6b78507 7615f3f3
import {
Table,
TableColumn,
Pagination,
Button,
Loading,
Select,
Option,
Message,
MessageBox,
RadioGroup,
RadioButton
} from 'element-ui'
export default {
install(V: any) {
V.use(Button)
V.use(Pagination)
V.use(Select)
V.use(Option)
V.use(Table)
V.use(TableColumn)
V.use(RadioGroup)
V.use(RadioButton)
V.use(Loading.directive)
V.prototype.$notify = Notification
V.prototype.$confirm = MessageBox.confirm
V.prototype.$message = Message
}
}
\ No newline at end of file
......@@ -73,6 +73,8 @@ export const lang = {
nextBlock: "Next Block",
no: "Nothing",
consensusAddress: "Consensus",
txnsBlocks: "Block with more than {0} txns",
mtxnsBlocks: '>{0} txns'
},
txDetail: {
detail: "Transaction details",
......
......@@ -73,6 +73,8 @@ export const lang = {
nextBlock: "下个区块",
no: "无",
consensusAddress: "共识地址",
txnsBlocks: '> {0}交易数量的区块',
mtxnsBlocks: '>{0}交易数'
},
txDetail: {
detail: "交易详情",
......
......@@ -8,7 +8,7 @@ import "./style.css";
import { Select } from "ant-design-vue";
import { i18n } from "./assets/lang/index";
import filters from "@/utils/filters";
import { Table, TableColumn, Pagination, Button, Loading } from "element-ui";
import ElementUI from './ElementConfig/index'
Object.entries(filters).forEach(([filterName, filterFunc]) => {
Vue.filter(filterName, filterFunc);
......@@ -27,11 +27,7 @@ Object.entries(filters).forEach(([filterName, filterFunc]) => {
console.log('v.0.2.0');
Vue.use(Select);
Vue.use(Table);
Vue.use(TableColumn);
Vue.use(Pagination);
Vue.use(Button);
Vue.use(Loading.directive);
Vue.use(ElementUI);
Vue.config.productionTip = false;
......
import Vue from "vue";
import { message } from "ant-design-vue";
import { getRpc } from "ycc-api/dist/cmjs/service/Rpc";
import { iBlockInBlockMixin, iGetBlocksRetResultItem } from "@/types/block";
import { yccApi } from "@/service/api";
import {
clearTimeoutFromTimerObj,
registerTimeoutToTimerObj,
} from "@/utils/common";
const Rpc = getRpc(yccApi);
const TimerObj = {} as any;
import { iBlockInBlockMixin } from "@/types/block";
import { getBlocks, getBlocksCount } from "@/service/api";
export default Vue.extend({
data() {
return {
searchValue: "",
maxHeight: 0,
startHeight: 0,
endHeight: 0,
Loading: false,
pages: {
currentPage: 1,
pageSize: 20,
total: 10,
},
showTotal: 0,
range: 0,
Blocks: [] as iBlockInBlockMixin[],
};
},
computed: {
selectOptions() {
return [
{
label: this.$t('lang.block.title'),
value: 0
},
{
label: this.$t('lang.block.txnsBlocks', [100]),
value: 100
},
{
label: this.$t('lang.block.txnsBlocks', [200]),
value: 200
},
{
label: this.$t('lang.block.txnsBlocks', [500]),
value: 500
},
{
label: this.$t('lang.block.txnsBlocks', [1000]),
value: 1000
},
{
label: this.$t('lang.block.txnsBlocks', [2000]),
value: 2000
},
{
label: this.$t('lang.block.txnsBlocks', [5000]),
value: 5000
}
]
}
},
mounted() {
this.getLastBlock();
this.getBlocks();
this.getBlocksCount()
},
methods: {
getLastBlock() {
if (this.Loading) return;
this.Loading = true;
Rpc.getLastHeader().then((data) => {
if (data.error === null) {
if (data.result.height !== this.endHeight) {
this.maxHeight = data.result.height;
this.$store.commit("saveMaxHeight", this.maxHeight);
this.pages.total = this.maxHeight;
this.getBlocks(this.maxHeight);
return;
}
this.Loading = false;
} else {
this.Loading = false;
message.warning({
content: data.error as string,
});
}
});
},
pageChange(page: number) {
clearTimeoutFromTimerObj(TimerObj);
this.pages.currentPage = page;
const newHeight =
this.maxHeight - (this.pages.currentPage - 1) * this.pages.pageSize;
this.endHeight = 0;
this.Blocks = [];
this.getBlocks(newHeight);
this.getBlocks();
},
sizeChange(size: number) {
this.pages.pageSize = size;
this.pageChange(1);
},
getBlocks(endHeight: number) {
filterBlocks(range: number) {
this.pages.currentPage = 1
this.range = range
this.getBlocksCount()
this.getBlocks()
},
async getBlocksCount() {
const { result } = await getBlocksCount(this.range)
this.showTotal = result
this.pages.total = result > 100000 ? 100000 : result;
},
async getBlocks() {
this.Loading = true;
Rpc.getBlocks(
endHeight - this.pages.pageSize >= 0
? endHeight - this.pages.pageSize
: 0,
endHeight,
true
).then((data) => {
if (data.error === null) {
const info = (data.result.items as iGetBlocksRetResultItem[])
.reverse()
.map((i) => ({
height: i.block.height,
blockTime: i.block.blockTime,
minerHash: i.block.txs[0].from,
txCount: i.block.txs.length,
}));
this.Blocks = [...info];
info.map((i) => {
Rpc.getBlockHash(i.height).then((ret) => {
const the = this.Blocks.find(
(block) => block.height === i.height
);
the && (the.hash = ret.result.hash);
this.Blocks = [...this.Blocks];
});
});
this.Loading = false;
} else {
this.Loading = false;
message.warning({
content: data.error,
});
try {
const res = await getBlocks(this.pages.currentPage, this.pages.pageSize, this.range)
if (res.result) {
this.Blocks = res.result
this.Loading = false
}
});
},
},
watch: {
Loading(val) {
if (val === false && this.pages.currentPage === 1) {
registerTimeoutToTimerObj(TimerObj, this.getLastBlock, 10 * 1e3);
else throw (res.error)
} catch (e) {
this.Loading = false;
message.warning({
content: e as string,
});
}
},
},
beforeDestroy() {
clearTimeoutFromTimerObj(TimerObj);
},
}
});
......@@ -49,7 +49,9 @@ export default Vue.extend({
},
fetchTradeFromTxHashes() {
this.loadingTable = true;
Rpc.getTxByHashes(this.txHashes).then((txRes) => {
const start = this.pages.pageSize * (this.pages.currentPage - 1)
const end = this.pages.pageSize * this.pages.currentPage - 1 < this.pages.total ? this.pages.pageSize * this.pages.currentPage : this.pages.total
Rpc.getTxByHashes(this.txHashes.slice(start, end)).then((txRes) => {
this.loadingTable = false;
if (txRes.error == null) {
console.log(txRes, "show txRes");
......@@ -67,6 +69,7 @@ export default Vue.extend({
.sort((a) => (a.type === "pack" ? -1 : 0));
this.allTrades = this.checkGroup(txRes.result.txs);
} else {
message.warning(this.$t("lang.components.tip") + txRes.error);
}
});
......@@ -154,9 +157,12 @@ export default Vue.extend({
},
pageChange(page: number) {
this.pages.currentPage = page;
this.fetchTradeFromTxHashes()
},
sizeChange(size: number) {
this.pages.pageSize = size;
this.pages.currentPage = 1
this.fetchTradeFromTxHashes()
},
},
computed: {
......@@ -170,12 +176,7 @@ export default Vue.extend({
);
},
Trades(): iCustomizedGetTxByHashesRetTxItem[] {
const end =
this.pages.pageSize * this.pages.currentPage - 1 < this.pages.total
? this.pages.pageSize * this.pages.currentPage - 1
: this.pages.total - 1;
const start = this.pages.pageSize * (this.pages.currentPage - 1);
return this.allTrades.slice(start, end + 1);
return this.allTrades
},
tabList(): any[] {
return [
......
......@@ -113,6 +113,69 @@ export function getTxList(number: number, size: number) {
});
}
/**
* 获取区块列表
*
* @export
* @param {number} number
* @param {number} size
* @param {number} gt
* @returns
*/
export function getBlocks(number: number, size: number, gt?: number) {
return axios(expandApi, {
method: "post",
params: {
id: 1,
method: "Block.BlockList",
params: [{
page: {
size,
number
},
range: [
{
gt,
key: "tx_count"
}
],
sort: [
{
key: "height",
ascending: false
}
]
}],
},
});
}
/**
* 获取区块总数
*
* @export
* @param {number} gt
* @returns
*/
export function getBlocksCount(gt: number) {
return axios(expandApi, {
method: "post",
params: {
id: 1,
method: "Block.Count",
params: [{
range: [
{
gt,
key: "tx_count"
}
]
}],
},
});
}
export function blockStatStatGets(startHeight: number, endHeight: number) {
return axios(expandApi, {
method: "post",
......
......@@ -11,14 +11,29 @@
></m-page-container>
<div class="rounded-twoPx overflow-hidden shadow-shadow1 mt-3.5">
<m-title
:title="`${$t('lang.block.title')}(${maxHeight}${$t('lang.block.count')})`"
:title="`${$t('lang.block.title')}(${showTotal}${$t(
'lang.block.count'
)})`"
></m-title>
<div class="search-container">
<el-radio-group v-model="range" @change="filterBlocks" size="small">
<el-radio-button :label="0">{{
$t("lang.block.title")
}}</el-radio-button>
<el-radio-button :label="100">{{
$t("lang.block.mtxnsBlocks", [100])
}}</el-radio-button>
<el-radio-button :label="1000">{{
$t("lang.block.mtxnsBlocks", [1000])
}}</el-radio-button>
</el-radio-group>
</div>
<m-block-item
v-for="(item, i) in Blocks"
:blockTime="item.blockTime"
:blockTime="item.block_time"
:height="item.height"
:packagingAddress="item.hash"
:txCount="item.txCount"
:packagingAddress="item.from"
:txCount="item.tx_count"
:key="i"
></m-block-item>
</div>
......@@ -34,20 +49,42 @@
</div>
</template>
<script lang="ts">
import MBlockItem from '@/components/mobile/m-blockItem.vue'
import mChainSearch from '@/components/mobile/m-chainSearch.vue'
import MPageContainer from '@/components/mobile/m-pageContainer.vue'
import MTitle from '@/components/mobile/m-title.vue'
import VueTypedMixins from 'vue-typed-mixins'
import blockMixin from '@/mixin/block'
import MBlockItem from "@/components/mobile/m-blockItem.vue";
import mChainSearch from "@/components/mobile/m-chainSearch.vue";
import MPageContainer from "@/components/mobile/m-pageContainer.vue";
import MTitle from "@/components/mobile/m-title.vue";
import VueTypedMixins from "vue-typed-mixins";
import blockMixin from "@/mixin/block";
export default VueTypedMixins(blockMixin).extend({
components: { mChainSearch, MPageContainer, MTitle, MBlockItem },
})
});
</script>
<style lang="scss" scoped>
.rounded-twoPx {
position: relative;
}
.c-block {
padding-top: 44px;
border-radius: 2px;
padding-bottom: 23px;
}
.c-title {
padding-top: 20px;
height: 130px;
align-items: flex-start;
}
.search-container {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 50px;
z-index: 1;
height: 60px;
width: 100%;
background: #fafbfc;
}
.range-select {
width: 310px;
}
</style>
<template>
<div
class="the-block min-w-1200 md:w-bodySet mx-auto flow-root"
style="padding-bottom: 60px;"
style="padding-bottom: 60px"
>
<chain-search
class="mt-7"
......@@ -11,8 +11,8 @@
<div class="pc-block inner-box">
<div class="title flex items-center justify-between">
<span class="total-block">
{{ $t('lang.block.title') }}{{ maxHeight | filterNum
}}{{ $t('lang.block.count') }}
{{ $t("lang.block.title") }}{{ showTotal | filterNum
}}{{ $t("lang.block.count") }}
</span>
<page-container
@pageChange="pageChange"
......@@ -23,85 +23,101 @@
></page-container>
</div>
<!-- 表格部分 -->
<el-table
:data="Blocks"
stripe
style="width: 100%;"
class="data-table"
v-loading="Loading"
element-loading-text="Loading..."
element-loading-spinner="el-icon-loading"
>
<template slot="empty">
<div>
<!-- <div
<div class="table-container">
<div class="search-container">
<el-radio-group v-model="range" @change="filterBlocks">
<el-radio-button :label="0">{{
$t("lang.block.title")
}}</el-radio-button>
<el-radio-button :label="100">{{
$t("lang.block.txnsBlocks", [100])
}}</el-radio-button>
<el-radio-button :label="1000">{{
$t("lang.block.txnsBlocks", [1000])
}}</el-radio-button>
</el-radio-group>
</div>
<el-table
:data="Blocks"
stripe
style="width: 100%"
class="data-table"
header-cell-class-name="header-style"
v-loading="Loading"
element-loading-text="Loading..."
element-loading-spinner="el-icon-loading"
>
<template slot="empty">
<div>
<!-- <div
v-if="Loading"
class="loading-line"
v-loading="Loading"
element-loading-text="Loading..."
element-loading-spinner="el-icon-loading"
></div> -->
<span v-if="!Loading">{{ $t('lang.page.nodata') }}</span>
</div>
</template>
<el-table-column width="40"></el-table-column>
<el-table-column :label="$t('lang.block.height')" width="180">
<template slot-scope="item">
<router-link
:to="`/blockDetail?height=${item.row.height}`"
class="light"
>
{{ item.row.height }}
</router-link>
</template>
</el-table-column>
<el-table-column prop="blockTime" :label="$t('lang.txDetail.time')">
<template slot-scope="item">
<!-- <count :time="item.row.blockTime" class="light2"></count> -->
<div class="text-darkBlue">
{{ item.row.blockTime | formatTime }}
<span v-if="!Loading">{{ $t("lang.page.nodata") }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="hash" :label="$t('lang.block.hash')">
<template slot-scope="item">
<router-link
:to="`/blockDetail?height=${item.row.height}`"
class="light"
>
{{ item.row.hash | filterHash(12) }}
</router-link>
</template>
</el-table-column>
<el-table-column :label="$t('lang.block.packingAddress')">
<template slot-scope="item">
<router-link
:to="`/blockDetail?height=${item.row.height}`"
class="light"
>
{{ item.row.minerHash | filterHash(12) }}
</router-link>
</template>
</el-table-column>
<el-table-column :label="$t('lang.block.blockReward')">
<template slot-scope="block">
<div class="light2">
{{ block.row.height | filterBlockReward }}
</div>
</template>
</el-table-column>
<el-table-column
width="80"
prop="txCount"
align="right"
:label="$t('lang.block.txCount')"
>
<template slot-scope="item">
<div class="light">{{ item.row.txCount }}</div>
</template>
</el-table-column>
<el-table-column width="40"></el-table-column>
</el-table>
<el-table-column width="40"></el-table-column>
<el-table-column :label="$t('lang.block.height')" width="180">
<template slot-scope="item">
<router-link
:to="`/blockDetail?height=${item.row.height}`"
class="light"
>
{{ item.row.height }}
</router-link>
</template>
</el-table-column>
<el-table-column prop="blockTime" :label="$t('lang.txDetail.time')">
<template slot-scope="item">
<!-- <count :time="item.row.blockTime" class="light2"></count> -->
<div class="text-darkBlue">
{{ item.row.block_time | formatTime }}
</div>
</template>
</el-table-column>
<el-table-column prop="hash" :label="$t('lang.block.hash')">
<template slot-scope="item">
<router-link
:to="`/blockDetail?height=${item.row.height}`"
class="light"
>
{{ item.row.hash | filterHash(12) }}
</router-link>
</template>
</el-table-column>
<el-table-column :label="$t('lang.block.packingAddress')">
<template slot-scope="item">
<router-link
:to="`/blockDetail?height=${item.row.height}`"
class="light"
>
{{ item.row.from | filterHash(12) }}
</router-link>
</template>
</el-table-column>
<el-table-column :label="$t('lang.block.blockReward')">
<template slot-scope="block">
<div class="light2">
{{ block.row.height | filterBlockReward }}
</div>
</template>
</el-table-column>
<el-table-column
width="80"
prop="txCount"
align="right"
:label="$t('lang.block.txCount')"
>
<template slot-scope="item">
<div class="light">{{ item.row.tx_count }}</div>
</template>
</el-table-column>
<el-table-column width="40"></el-table-column>
</el-table>
</div>
<!-- 底部分页 -->
<div class="bottom-page flex justify-end">
<page-container
......@@ -117,17 +133,32 @@
</template>
<script lang="ts">
import VueTypedMixins from 'vue-typed-mixins'
import ChainSearch from '@/components/pc/BlockChainBrowser/ChainSearch.vue'
import PageContainer from '@/components/pc/BlockChainBrowser/PageContainer.vue'
import Count from '@/components/pc/BlockChainBrowser/Count.vue'
import blockMixin from '@/mixin/block'
import VueTypedMixins from "vue-typed-mixins";
import ChainSearch from "@/components/pc/BlockChainBrowser/ChainSearch.vue";
import PageContainer from "@/components/pc/BlockChainBrowser/PageContainer.vue";
import Count from "@/components/pc/BlockChainBrowser/Count.vue";
import blockMixin from "@/mixin/block";
export default VueTypedMixins(blockMixin).extend({
components: { ChainSearch, PageContainer, Count },
})
});
</script>
<style scoped>
.table-container {
position: relative;
}
.search-container {
padding: 0 25px;
display: flex;
justify-content: flex-end;
align-items: center;
position: absolute;
top: 70px;
z-index: 1;
height: 80px;
width: 100%;
background: #fafbfc;
}
.title {
margin-top: 30px;
}
......@@ -179,3 +210,11 @@ export default VueTypedMixins(blockMixin).extend({
color: #2545cb;
}
</style>
<style>
.header-style {
padding-top: 25px !important;
height: 150px;
vertical-align: baseline !important;
}
</style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment