给 Node 页面添加了 本节点打包的区块列表模板。

给 各页面都读入了页头的数据,如IP地址,邻居数量。
This commit is contained in:
luk.lu
2018-11-28 16:38:52 +08:00
parent aca23682ca
commit f70e5bd73d
11 changed files with 241 additions and 55 deletions

View File

@@ -57,13 +57,13 @@ const necessaryPath = (path) => {
} }
ssh.connect(connection).then(async () => { ssh.connect(connection).then(async () => {
console.log(`[ mv ${dist} ${dist}-backup-${new Date().toISOString()} ... ]`) console.log(`[ ${root} > mv ${dist} ${dist}-backup-${new Date().toISOString()} ... ]`)
await ssh.execCommand(`mv ${dist} ${dist}-backup-${new Date().toISOString()}`, { cwd:root }) await ssh.execCommand(`mv ${dist} ${dist}-backup-${new Date().toISOString()}`, { cwd:root })
console.log(`[ mkdir ${dist} ... ]`) console.log(`[ ${root} > mkdir ${dist} ... ]`)
await ssh.execCommand(`mkdir ${dist}`, { cwd:root }) await ssh.execCommand(`mkdir ${dist}`, { cwd:root })
const toCreate = necessaryPath('./dist') const toCreate = necessaryPath('./dist')
for (const name of toCreate) { for (const name of toCreate) {
console.log(`[ mkdir ${dist}/${name.join('/')} ... ]`) console.log(`[ ${root} > mkdir ${dist}/${name.join('/')} ... ]`)
await ssh.execCommand(`mkdir ${dist}/${name.join('/')}`, { cwd:root }) await ssh.execCommand(`mkdir ${dist}/${name.join('/')}`, { cwd:root })
} }
@@ -77,13 +77,13 @@ ssh.connect(connection).then(async () => {
return !baseName.endsWith('.map'); return !baseName.endsWith('.map');
}, },
tick: (localPath, remotePath, error) => { tick: (localPath, remotePath, error) => {
console.log(`Uploading "${localPath}" ===> "${remotePath}" ${error || 'succeeded!'}`) console.log(`"${localPath}" ===> "${remotePath}" ... ${error || 'succeeded!'}`)
err = error err = error
}, },
}) })
ssh.dispose() ssh.dispose()
if (err) { if (err) {
console.log('[ Uploaded with error! ]') console.log('[ Upload failed! ]')
process.exit(1) process.exit(1)
} else { } else {
console.log('[ Uploaded successfully! ]') console.log('[ Uploaded successfully! ]')

View File

@@ -8,9 +8,9 @@
}, },
home: { home: {
titleOwner: 'Owner', titleOwner: 'Owner',
titleChain: 'Chain',
titleNode: 'Node', titleNode: 'Node',
titleNetwork: 'Network', titleNetwork: 'Network',
titleChain: 'Chain',
titleMarket: 'Market', titleMarket: 'Market',
}, },
owner: { owner: {
@@ -32,7 +32,7 @@
thIndex: '序号', thIndex: '序号',
thAddress: '连接地址', thAddress: '连接地址',
thStatus: '连接状态', thStatus: '连接状态',
thNeighbour: '邻居主人的账户地址', thPeerOwnerAddress: '邻居主人的账户地址',
tableNone: '暂无数据', tableNone: '暂无数据',
}, },
chain: { chain: {

View File

@@ -7,10 +7,10 @@
errorMnemonic: '输入的密语无效', errorMnemonic: '输入的密语无效',
}, },
home: { home: {
titleOwner: '人', titleOwner: '人',
titleChain: '区块',
titleNode: '节点', titleNode: '节点',
titleNetwork: '网络', titleNetwork: '网络',
titleChain: '区块',
titleMarket: '应用', titleMarket: '应用',
}, },
owner: { owner: {
@@ -32,11 +32,20 @@
thIndex: '序号', thIndex: '序号',
thAddress: '连接地址', thAddress: '连接地址',
thStatus: '连接状态', thStatus: '连接状态',
thNeighbour: '邻居主人的账户地址', thPeerOwnerAddress: '邻居主人的账户地址',
tableNone: '暂无数据', tableNone: '暂无数据',
}, },
chain: { chain: {
tableHeader: '区块列表', tableHeader: '区块',
searchHolder: '输入要查询的区块高度或者区块哈希',
thHeight: '区块高度',
thTimestamp: '时间戳',
thType: '区块类型',
thHash: '区块哈希',
tableNone: '暂无数据',
},
node: {
tableHeader: '本节点打包的区块列表',
searchHolder: '输入要查询的区块高度或者区块哈希', searchHolder: '输入要查询的区块高度或者区块哈希',
thHeight: '区块高度', thHeight: '区块高度',
thTimestamp: '时间戳', thTimestamp: '时间戳',

View File

@@ -1,5 +1,5 @@
import axios from 'axios' import axios from 'axios'
// import app from './app' // import app from './app'
// 控制台应当默认访问控制台所在主机(localhost 或者 window.location.hostname)的 TIC后台或者访问用户自己设置的主机。 // 控制台应当默认访问控制台所在主机(localhost 或者 window.location.hostname)的 TIC后台或者让用户在控制台启动时,自己设置一个节点主机。
axios.defaults.baseURL = `http://${window.location.hostname}:6842/api/` axios.defaults.baseURL = `http://${window.location.hostname}:6842/api/`

View File

@@ -1,4 +1,6 @@
export default { import axios from 'axios'
export default {
namespaced: true, namespaced: true,
state: { state: {
@@ -7,27 +9,45 @@
{ text: 'network.thIndex', value: 'index', align: 'center' }, { text: 'network.thIndex', value: 'index', align: 'center' },
{ text: 'network.thAddress', value: 'address', align: 'center' }, { text: 'network.thAddress', value: 'address', align: 'center' },
{ text: 'network.thStatus', value: 'status', align: 'center' }, { text: 'network.thStatus', value: 'status', align: 'center' },
{ text: 'network.thNeighbour', value: 'neighbour', align: 'center' }, { text: 'network.thPeerOwnerAddress', value: 'peerOwnerAddress', align: 'center' },
], ],
desserts: [ desserts: [
{ // {
index: '1', // index: '',
address: '192.168.0.1', // address: '',
status: '0', // status: '',
neighbour: 'ajlk;gaklewklgjqwejj', // peerOwnerAddress: '',
}, // },
], ],
fetching: false, fetching: false,
filter: '', filter: '',
peerNumber: 'unknown',
nodeNumber: ' unknown',
}, },
mutations: { mutations: {
inputFilter(state, filter) { inputFilter(state, filter) {
state.filter = filter state.filter = filter
}, },
updatePeerNumber(state, peerNumber) {
state.peerNumber = peerNumber
},
updateNodeNumber(state, nodeNumber) {
state.nodeNumber = nodeNumber
},
updateDesserts(state, peerList) {
state.desserts = peerList
},
}, },
actions: {}, actions: {
async updateNetInfo({ state, commit }) {
let result = await axios.post('Peer/sharePeer', {})
commit('updatePeerNumber', (result && result.data) ? result.data.length : 0)
commit('updateDesserts', result.data || [])
},
},
getters: {}, getters: {},
} }

View File

@@ -1,7 +1,46 @@
export default { import axios from 'axios'
export default {
namespaced: true, namespaced: true,
state: {}, state: {
mutations: {}, pageEntity: [5, 10, 25],
actions: {}, headers: [
{ text: 'node.thHeight', value: 'height', align: 'center' },
{ text: 'node.thTimestamp', value: 'timestamp', align: 'center' },
{ text: 'node.thType', value: 'type', align: 'center' },
{ text: 'node.thHash', value: 'hash', align: 'center' },
],
desserts: [
{
height: '1',
timestamp: '2011-11-20',
type: '0',
hash: 'null',
},
],
fetching: false,
filter: '',
modal: false,
ipAddress: '',
},
mutations: {
inputFilter(state, filter) {
state.filter = filter
},
updateIpAddress(state, ipAddress) {
state.ipAddress = ipAddress
},
updateDesserts(state, desserts) {
state.desserts = desserts
},
},
actions: {
updateNodeInfo({ state, commit }) {
commit('updateIpAddress', axios.defaults.baseURL)
},
},
getters: {}, getters: {},
} }

View File

@@ -29,7 +29,7 @@ export default {
], ],
fetching: false, fetching: false,
filter: '', filter: '',
balance: 0, balance: '',
address: '', address: '',
}, },
@@ -44,11 +44,11 @@ export default {
updateAddress(state, address) { updateAddress(state, address) {
state.address = address state.address = address
} },
}, },
actions: { actions: {
async queryAccount({ state, commit }) { async updateOwnerInfo({ state, commit }) {
let account = sessionStorage.getItem('KEY_ACCOUNT') let account = sessionStorage.getItem('KEY_ACCOUNT')
try { try {
account = JSON.parse(account) account = JSON.parse(account)
@@ -56,7 +56,7 @@ export default {
const result = await axios.post('Account/getBalance', { const result = await axios.post('Account/getBalance', {
Account: { address: account.address }, Account: { address: account.address },
}) })
commit('updateBalance', result.data || 0) commit('updateBalance', (result && result.data) ? result.data : 0)
} catch (e) {} } catch (e) {}
}, },
}, },

View File

@@ -89,8 +89,10 @@ import Vue from 'vue'
import store from '../store' import store from '../store'
import VueSocketio from 'vue-socket.io' import VueSocketio from 'vue-socket.io'
import io from 'socket.io-client' import io from 'socket.io-client'
const { mapState, mapGetters, mapActions, mapMutations } = createNamespacedHelpers('chain') const { mapState, mapGetters, mapActions, mapMutations } = createNamespacedHelpers('chain')
Vue.use(VueSocketio, io('http://localhost:6842'), store)
Vue.use(VueSocketio, io(`http://${window.location.hostname}:6842/api/`), store) // todo: luk: 整个控制台应当依赖于同一个全局的节点地址变量。
export default { export default {
name: 'Chain', name: 'Chain',
@@ -114,9 +116,6 @@ export default {
this.addNewBlock(msg) this.addNewBlock(msg)
}, },
}, },
mounted() {
this.queryBlockList()
},
methods: { methods: {
...mapActions([ ...mapActions([
@@ -130,6 +129,11 @@ export default {
'addDesserts', 'addDesserts',
]), ]),
}, },
mounted() {
this.queryBlockList()
},
} }
</script> </script>
@@ -165,7 +169,7 @@ export default {
margin: 0 20px; margin: 0 20px;
.search-input { .search-input {
width: 400px; width: 80%;
} }
} }

View File

@@ -1,13 +1,13 @@
<template> <template>
<div class="network-page"> <div class="network-page">
<div class="card-content"> <div class="card-content">
<div class="app-card elevation-1"></div> <div class="app-card elevation-1">
<div>当前邻居节点数 <br>{{ peerNumber }}</div>
</div>
<div class="app-sep"></div> <div class="app-sep"></div>
<div class="app-card elevation-1"></div> <div class="app-card elevation-1">
<div class="app-sep"></div> <div>当前全网节点数 <br>{{ nodeNumber }}</div>
<div class="app-card elevation-1"></div> </div>
<div class="app-sep"></div>
<div class="app-card elevation-1"></div>
</div> </div>
<div class="table-content elevation-1"> <div class="table-content elevation-1">
@@ -38,7 +38,7 @@
<td>{{ props.item.index }}</td> <td>{{ props.item.index }}</td>
<td>{{ props.item.address }}</td> <td>{{ props.item.address }}</td>
<td>{{ props.item.status }}</td> <td>{{ props.item.status }}</td>
<td>{{ props.item.neighbour }}</td> <td>{{ props.item.peerOwnerAddress }}</td>
</template> </template>
<template slot="no-results"> <template slot="no-results">
{{ $t('network.tableNone') }} {{ $t('network.tableNone') }}
@@ -66,17 +66,27 @@ export default {
'pageEntity', 'pageEntity',
'fetching', 'fetching',
'filter', 'filter',
'peerNumber',
'nodeNumber',
]), ]),
...mapGetters([]), ...mapGetters([]),
}, },
methods: { methods: {
...mapActions([ ...mapActions([
'updateNetInfo',
]), ]),
...mapMutations([ ...mapMutations([
'inputFilter', 'inputFilter',
'updatePeerNumber',
'updateNodeNumber',
]), ]),
}, },
mounted() {
this.updateNetInfo()
},
} }
</script> </script>
@@ -112,7 +122,7 @@ export default {
margin: 0 20px; margin: 0 20px;
.search-input { .search-input {
width: 400px; width: 80%;
} }
} }

View File

@@ -1,16 +1,92 @@
<template> <template>
<div class="node-page"> <div class="node-page">
<div class="card-content"> <div class="card-content">
<div class="app-card elevation-1"></div> <div class="app-card elevation-1">
<div>主机地址 <br> {{ ipAddress }}</div>
</div>
<div class="app-sep"></div> <div class="app-sep"></div>
<div class="app-card elevation-1"></div> <div class="app-card elevation-1">
<div>在线用户 <br> </div>
</div>
</div> </div>
<div class="table-content elevation-1">
<div class="panel-header">
<h3>{{ $t('node.tableHeader') }}</h3>
<div class="search-input">
<v-text-field
:placeholder="$t('node.searchHolder')"
:value="filter"
@input="inputFilter"
append-icon="search" />
</div>
</div>
<template>
<v-data-table
:headers="headers"
:items="desserts"
:total-items="100"
:rows-per-page-items="pageEntity"
:loading="fetching"
class="panel-content elevation-1"
>
<template slot="headerCell" slot-scope="props">
<span>{{ $t(props.header.text) }}</span>
</template>
<template slot="items" slot-scope="props">
<td>{{ props.item.height }}</td>
<td>{{ props.item.timestamp }}</td>
<td>{{ props.item.type }}</td>
<td>{{ props.item.hash }}</td>
</template>
<template slot="no-results">
{{ $t('node.tableNone') }}
</template>
</v-data-table>
</template>
</div>
</div> </div>
</template> </template>
<script> <script>
import {
createNamespacedHelpers,
} from 'vuex'
const { mapState, mapGetters, mapActions, mapMutations } = createNamespacedHelpers('node')
export default { export default {
name: 'Node', name: 'Node',
computed: {
...mapState([
'headers',
'desserts',
'pageEntity',
'fetching',
'filter',
'modal',
'ipAddress',
]),
...mapGetters([]),
},
methods: {
...mapActions([
'updateNodeInfo',
]),
...mapMutations([
'inputFilter',
'updateIpAddress',
]),
},
mounted() {
this.updateNodeInfo()
},
} }
</script> </script>
@@ -23,7 +99,7 @@ export default {
.app-card { .app-card {
flex: 1; flex: 1;
height: 200px; height: 100px;
background-color: white; background-color: white;
} }
@@ -32,5 +108,29 @@ export default {
} }
} }
.table-content {
flex: 1;
margin: 0 20px 20px;
background-color: white;
display: flex;
flex-direction: column;
.panel-header {
display: flex;
justify-content: space-between;
align-items: center;
margin: 0 20px;
.search-input {
width: 80%;
}
}
.panel-content {
margin: 0 20px 20px;
}
}
} }
</style> </style>

View File

@@ -2,11 +2,12 @@
<div class="owner-page"> <div class="owner-page">
<div class="card-content"> <div class="card-content">
<div class="app-card elevation-1"> <div class="app-card elevation-1">
<div>主人地址 {{ address }}</div> <div>主人地址 <br> {{ address }}</div>
<div>余额为 {{ balance }}</div>
</div> </div>
<div class="app-sep"></div> <div class="app-sep"></div>
<div class="app-card elevation-1"></div> <div class="app-card elevation-1">
<div>余额 <br> {{ balance }}</div>
</div>
</div> </div>
<div class="table-content elevation-1"> <div class="table-content elevation-1">
<div class="panel-header"> <div class="panel-header">
@@ -74,18 +75,21 @@ export default {
...mapGetters([]), ...mapGetters([]),
}, },
mounted() {
this.queryAccount()
},
methods: { methods: {
...mapActions([ ...mapActions([
'queryAccount', 'updateOwnerInfo',
]), ]),
...mapMutations([ ...mapMutations([
'inputFilter', 'inputFilter',
'updateBalance', // luk: 发现不写这句也没影响。但还是写吧,万一有用呢。
'updateAddress',
]), ]),
}, },
mounted() {
this.updateOwnerInfo()
},
} }
</script> </script>
@@ -104,7 +108,7 @@ export default {
.app-card { .app-card {
flex: 1; flex: 1;
height: 200px; height: 100px;
background-color: white; background-color: white;
} }
@@ -128,7 +132,7 @@ export default {
margin: 0 20px; margin: 0 20px;
.search-input { .search-input {
width: 400px; width: 80%;
} }
} }