提交 349f355e 编写于 作者: U unknown

完成首页ui部分和账本切换功能

上级 6f8be54c
import { Component } from 'react';
import { capitalize } from './src/utils/util';
import Message from 'flarej/lib/components/antd/message';
import notification from 'flarej/lib/components/antd/notification';
class Bundle extends Component {
constructor(props) {
super(props);
......@@ -11,7 +12,51 @@ class Bundle extends Component {
}
componentWillMount() {
// 销毁全局的消息提示
Message.destroy();
notification.destroy();
// 初始化全局数据
const { store:{common} } = this.props;debugger;
if (common&&common.ledgers.length==0) {
Promise.all([
common.getLedgersInfo("")
]).then(() => {
let ledgerDafault=localStorage.getItem("defaultledger"),
ledgers=common.ledgers;
if (ledgerDafault) {
for (let i = 0; i < ledgers.length; i++) {
if(ledgers[i].value==ledgerDafault){
common.setDefaultLedger(ledgerDafault);
this.load(this.props);
return false;
}
}
if (ledgers.length>0) {
common.setDefaultLedger(ledgers[0].value);
localStorage.setItem('defaultledger',ledgers[0].value);
}
else{
// 没有账本时的操作
localStorage.removeItem("defaultledger");
}
this.load(this.props);
}
else{
if (ledgers.length>0) {
common.setDefaultLedger(ledgers[0].value);
localStorage.setItem('defaultledger',ledgers[0].value);
}
else{
// 没有账本时的操作
localStorage.removeItem("defaultledger");
}
this.load(this.props);
}
});
}
else{
this.load(this.props);
}
}
componentWillReceiveProps(nextProps) {
......
......@@ -47,6 +47,10 @@ const renderApp = appRoutes => {
<div id="outer-container">
<${HeaderWithRouter} />
${appRoutes()}
<div class="footContent">
Copyright © 2004-2019 JD.COM 京东版权所有 Power by
<a href="http://ledger.jd.com/" target="_blank" class="linker" title="京东区块链">&nbsp;京东区块链平台</a>
</div>
</div>
</HashRouter>
</mobx-Provider>
......
......@@ -2,7 +2,7 @@
<!DOCTYPE html>
<html>
<head>
<title>react-mst-boilerplate</title>
<title>区块链浏览器</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
......
......@@ -82,7 +82,7 @@ app.get('/common/logout', function(req, res) {
res.redirect('http://localhost:8080/dist/web/home.html');
});
let server = app.listen(8089, function() {
let server = app.listen(8088, function() {
let host = server.address().address;
let port = server.address().port;
......
......@@ -10,13 +10,25 @@ export const UserInfo = types.model('UserInfo', {
export const CommonStore = types
.model('CommonStore', {
userInfo: types.maybe(UserInfo),
})
}).volatile(self => ({
ledgers: [],
defaultledger:'',
}))
.views(self => ({
get isDemo() {
return self.userInfo.pin && self.userInfo.pin.trim().toLowerCase() === 'jd_653e751552511';
}
}))
.actions(self => ({
//设置当前账本
setDefaultLedger(v){
self.defaultledger=v;
},
getDefaultLedger(){
return localStorage.getItem("clusterID");
},
getCurrentUserInfo() {
return fetchData(`${__HOST}/common/getCurrentUserInfo`,
self.setCurrentUserInfo,
......@@ -37,7 +49,28 @@ export const CommonStore = types
duration: null
});
}
}
},
getLedgersInfo() {
return fetchData(`${__HOST}/ledgers`,
self.setLedgersInfo,
null, { method: 'get' })
.catch((ex) => {
Notification.error({
description: '获取账本信息异常:' + ex,
duration: null
});
});
},
setLedgersInfo(result) {
if (result.success) {
self.ledgers = result.data;
} else {
Notification.error({
description: '获取账本信息错误:' + result.message,
duration: null
});
}
},
}));
export const Category = types.model('Category', {
......
import { types } from 'mobx-state-tree';
import { observable, toJS } from 'mobx';
import fetchData from 'flarej/lib/utils/fetchData';
import { fetchData } from '../../utils/fetchConfig';
import Notification from '../../utils/notification';
const SearchStore = types
......@@ -27,53 +27,8 @@ const SearchStore = types
menuIds: null,
authTreeData: null,
menuData: null,
detailData: []
}))
.views(self => ({
//获取树节点的展开形式
getExpandedKeys(arr) {
return arr.filter(n => n.level == 1 || n.level == 2).map(m => {
return m.id.toString();
});
},
getDefaultCheckedKeys() {
let keys = [];
self.menuData.filter(n => n.level == 3)
.forEach(item => {
if (item.selected) {
keys.push(item.id.toString());
}
});
return keys;
},
getAuthTreeDataMap(authList) {
const authTreeDataMap = {};
authList.forEach(node => {
authTreeDataMap[node.id] = node;
});
return authTreeDataMap;
},
getAuthTreeData(authList, authMap, level = 1, node, pids = []) {
if (level == 4) {
return null;
}
return authList
.filter(n => n.level == level && (!node ? true : n.pid == node.id.toString()))
.map(n => {
authMap[n.id].pids = pids;
return {
key: n.id.toString(),
title: n.name,
children: self.getAuthTreeData(authList, authMap, level + 1, n, [...pids, n.id.toString()])
};
});
}
detailData: [],
blockHeight:0,// 区块高度
}))
.actions(self => ({
afterCreate() {
......@@ -167,7 +122,7 @@ const SearchStore = types
},
getRoleManagementData(params) {
return fetchData(`${__HOST}/search/getRoleManagementData`,
return fetchData(`${__HOST}/api/v1/search`,
self.setRoleManagementData,
params, { method: 'get' })
.catch((ex) => {
......@@ -282,7 +237,111 @@ const SearchStore = types
} else {
Notification.error({ description: '删除角色数据异常:' + result.message, duration: null });
}
}
},
// 获取区块高度
getBlockHeight(param) {
fetchData(`${__HOST}/ledgers/${param}/blocks/latest`,
self.setBlockHeight,
'', {
method: 'get',
headers: {
cookie: document.cookie,
}
}
).catch(error => {
console.log(error);
});
},
setBlockHeight(result) {
if (result&&result.success) {
self.blockHeight=result.data.height||0;
}
// let response = result;
// this.overviewHeadData.blockHeight = response && response.data && response.data.height ? response.data.height : 0;
},
// 获取交易总数
getTransactionTotal() {
fetchData(`${G_WEB_DOMAIN}/ledgers/${localStorage.defaultValue}/txs/count`,
this.setTransactionTotal,
'', {
method: 'get',
headers: {
// accept: 'application/json',
cookie: document.cookie,
}
}
).catch(error => {
console.log(error);
});
},
setTransactionTotal(result) {
let response = result;
this.overviewHeadData.transactionTotal = response && response.data ? response.data : 0;
},
// 获取用户总数
getUserTotal() {
fetchData(`${G_WEB_DOMAIN}/ledgers/${localStorage.defaultValue}/users/count`,
this.setUserTotal,
'', {
method: 'get',
headers: {
// accept: 'application/json',
cookie: document.cookie,
}
}
).catch(error => {
console.log(error);
});
},
setUserTotal(result) {
let response = result;
this.overviewHeadData.userTotal = response && response.data ? response.data : 0;
},
// 获取数据账户总数
getLedgerTotal() {
fetchData(`${G_WEB_DOMAIN}/ledgers/${localStorage.defaultValue}/accounts/count`,
this.setLedgerTotal,
'', {
method: 'get',
headers: {
// accept: 'application/json',
cookie: document.cookie,
}
}
).catch(error => {
console.log(error);
});
},
setLedgerTotal(result) {
let response = result;
this.overviewHeadData.dataLedgersTotal = response && response.data ? response.data : 0;
},
// 合约总数
getContractTotal() {
fetchData(`${G_WEB_DOMAIN}/ledgers/${localStorage.defaultValue}/contracts/count`,
this.setContractTotal,
'', {
method: 'get',
headers: {
// accept: 'application/json',
cookie: document.cookie,
}
}
).catch(error => {
console.log(error);
});
},
setContractTotal(result) {
let response = result;
this.overviewHeadData.contractTotal = response && response.data ? response.data : 0;
},
}));
export default SearchStore;
\ No newline at end of file
import querystring from 'querystring';
export function handleErrors(response) {
if (response.status*1==401) {
var keys=document.cookie.match(/[^ =;]+(?=\=)/g);
if (keys) {
for (var i = keys.length; i--;) {
document.cookie=keys[i]+'="";expires=' + new Date(0).toUTCString()+";path=/;";
document.cookie=keys[i]+'="";expires=' + new Date(0).toUTCString()+";path=/;domain=."+window.location.hostname;
}
}
window.location.href="https://"+window.location.host+"/login";
return;
}
if (response.status*1==400) {
return response;
}
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}
const _defaultOptions = { useApplicationJson: true };
export function setDefaultOptions(options = {}) {
return Object.assign(_defaultOptions, options);
}
export function fetchData(url, callback, params, cfgs) {
const configs = Object.assign({
method: 'get',
credentials: 'include',
mode: 'cors',
cache: 'reload'
}, _defaultOptions, cfgs);
configs.method = configs.method.toLowerCase();
if (params) {
if (configs.method === 'get') {
if (url.indexOf('?')>-1) {
url +=querystring.encode(params);
}
else{
url += '?' + querystring.encode(params);
}
} else if (configs.method === 'post' || configs.method === 'put' || configs.method === 'delete') {
if (configs.useApplicationJson) {
if (!configs.headers) {
configs.headers = {};
}
if (!configs.headers.Accept) {
configs.headers.Accept = 'application/json';
}
if (!configs.headers['Content-Type']) {
configs.headers['Content-Type'] = 'application/json';
}
configs.body = JSON.stringify(params);
} else if (configs.useApplicationForm) {
if (!configs.headers['Content-Type']) {
configs.headers['Content-Type'] = 'application/x-www-form-urlencoded';
}
configs.body = querystring.encode(params);
} else {
configs.body = params;
}
}
}
return fetch(url, configs)
.then(handleErrors)
.then((response) => {
return response.json();
})
.then(callback);
}
\ No newline at end of file
......@@ -14,8 +14,10 @@ import template from './header.t.html';
export default class Header extends Component {
render() {
const { store: { common } } = this.props;
return template(this.props, this, {
styles,
common,
headerPic: require('../../images/pic-header.png')
});
}
......
......@@ -2,13 +2,13 @@
font-size: 16px;
height: 79px;
border-bottom: 1px solid #ebebeb;
position: fixed;
width: 100%;
z-index: 100;
transition: all 0.5s ease-out;
box-shadow: 0 1px 3px 0 rgba(0, 34, 77, 0.05);
background: linear-gradient(90deg,#5a77d3,#3c4c9c);
display: flex;
flex: auto 0 0;
.nav {
font-size: 0.875rem;
......@@ -39,7 +39,7 @@
.note{
color: #fff;
float:right;
padding-right: 30px;
padding: 22px;
.value{
width: 200px;
border: 1px solid #ADC6FF;
......@@ -54,7 +54,7 @@
float: left;
text-align: center;
line-height: 80px;
margin-left: 60px;
margin-left: 20px;
position: relative;
height: 79px;
overflow: hidden;
......@@ -124,4 +124,20 @@
}
}
}
.footContent {
display: flex;
justify-content: center;
align-items: center;
font-family: MicrosoftYaHei;
font-size: 12px;
color: #999999;
.linker {
text-decoration: none;
color: #5A77D3;
}
.linker:hover {
color: #5A77D3;
}
}
}
<header class="site-header">
<div class="logo">
</div>
<ant-Menu mode="horizontal" class="nav">
<ant-MenuItem key="../../pages/search.html"> <ant-Icon type="home" />首页</ant-MenuItem>
<ant-MenuItem key="../../pages/ledgers.html"> <ant-Icon type="switcher" />数据账户</ant-MenuItem>
<ant-MenuItem key="../../pages/history.html"> <ant-Icon type="block" />区块</ant-MenuItem>
<ant-Menu mode="horizontal" class="nav" defaultValue="1">
<ant-MenuItem key="1"> <ant-Icon type="home" />首页</ant-MenuItem>
<ant-MenuItem key="2"> <ant-Icon type="switcher" />数据账户</ant-MenuItem>
<ant-MenuItem key="3"> <ant-Icon type="block" />区块</ant-MenuItem>
<ant-MenuItem key="4"> <ant-Icon type="swap" />交易</ant-MenuItem>
<ant-MenuItem key="5"> <ant-Icon type="user" />用户</ant-MenuItem>
</ant-Menu>
......@@ -13,8 +13,10 @@
<!-- <ant-Select placeholder="请选择账本" class={styles.value} >
<ant-Option value="64hnH4a8n48LeEP5HU2bMWmNxUPcaZ1JRCehRwvuNS8Ty" >64hnH4a8n48LeEP5HU2bMWmNxUPcaZ1JRCehRwvuNS8Ty</ant-Option>
</ant-Select> -->
<ant-Select defaultValue="lucy">
<ant-Option value="jack">Jack</ant-Option>
<ant-Select value="{common.defaultledger}" style="width:300px;" >
<#each {{common.ledgers}}>
<ant-Option value="{{value}}">{{value}}</ant-Option>
</#each>
</ant-Select>
</div>
</header>
\ No newline at end of file
......@@ -69,7 +69,7 @@ table {
body {
color: #333;
background: #f4f5f8;
background: #f2f3f5;
-webkit-appearance: none;
-webkit-font-smoothing: auto;
font-size: 14px;
......@@ -224,3 +224,21 @@ div.fj-area-chart-area {
margin-right: 30px;
float: left;
}
.footContent{
flex: 0 0 auto;
text-align: center;
line-height: 52px;
border-top: 1px solid #e8e8e9;
margin: 0 30px;
}
#app,#outer-container{
height: 100%;
display: flex;
flex-direction: column;
flex: auto;
}
#page-wrap{
flex: auto;
}
\ No newline at end of file
<svg id="Layer_6" data-name="Layer 6" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 911.57 1024"><defs><style>.cls-1{fill:url(#linear-gradient);}.cls-2{fill:url(#linear-gradient-2);}.cls-3{fill:url(#linear-gradient-3);}.cls-4{fill:url(#linear-gradient-4);}</style><linearGradient id="linear-gradient" x1="338.03" y1="709.19" x2="498.7" y2="504.94" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff"/></linearGradient><linearGradient id="linear-gradient-2" x1="203.85" y1="903.73" x2="807.6" y2="136.22" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-3" x1="472.64" y1="567.31" x2="560.39" y2="455.75" xlink:href="#linear-gradient"/><linearGradient id="linear-gradient-4" x1="532.81" y1="520.05" x2="693.48" y2="315.8" xlink:href="#linear-gradient"/></defs><title>区块高度 icon</title><g id="Page-1"><g id="_1-1-1-1-摘要" data-name="1-1-1-1-摘要"><path class="cls-1" d="M425.18,538V445.8H351.39a36.9,36.9,0,0,0-36.9,36.9V667.18a36.9,36.9,0,0,0,36.9,36.9H535.87a36.9,36.9,0,0,0,36.9-36.9V611.84H499A73.79,73.79,0,0,1,425.18,538Z" transform="translate(-56.22)"/><path class="cls-2" d="M922.19,222.64,557.57,12.2a91.16,91.16,0,0,0-91.13,0L101.81,222.64a91.16,91.16,0,0,0-45.59,79V722.41a91.16,91.16,0,0,0,45.59,79l364.63,210.44a91.15,91.15,0,0,0,91.13,0L922.19,801.36a91.16,91.16,0,0,0,45.59-79V301.59A91.16,91.16,0,0,0,922.19,222.64ZM757.26,538a73.79,73.79,0,0,1-73.79,73.79H609.67v55.35A73.79,73.79,0,0,1,535.87,741H351.39a73.79,73.79,0,0,1-73.79-73.79V482.7a73.79,73.79,0,0,1,73.79-73.79h73.79V353.56A73.79,73.79,0,0,1,499,279.77H683.46a73.79,73.79,0,0,1,73.79,73.79Z" transform="translate(-56.22)"/><path class="cls-3" d="M535.87,445.8H462.08V538a36.9,36.9,0,0,0,36.9,36.9h73.79V482.7A36.9,36.9,0,0,0,535.87,445.8Z" transform="translate(-56.22)"/><path class="cls-4" d="M683.46,316.66H499a36.9,36.9,0,0,0-36.9,36.9v55.35h73.79a73.79,73.79,0,0,1,73.79,73.79v92.24h73.79a36.9,36.9,0,0,0,36.9-36.9V353.56A36.9,36.9,0,0,0,683.46,316.66Z" transform="translate(-56.22)"/></g></g></svg>
\ No newline at end of file
<svg id="Layer_3" data-name="Layer 3" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 911.57 1024"><defs><style>.cls-1{fill:url(#linear-gradient);}.cls-2{fill:url(#linear-gradient-2);}</style><linearGradient id="linear-gradient" x1="369.07" y1="695.22" x2="649.11" y2="339.22" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff"/></linearGradient><linearGradient id="linear-gradient-2" x1="203.85" y1="903.73" x2="807.6" y2="136.22" xlink:href="#linear-gradient"/></defs><title>合约总数icon</title><path class="cls-1" d="M618.35,325.13H405.65a45.63,45.63,0,0,0-45.58,45.58V656.33a45.63,45.63,0,0,0,45.58,45.58h212.7a45.63,45.63,0,0,0,45.58-45.58V370.71A45.63,45.63,0,0,0,618.35,325.13Zm-197.51,79H530.23v36.46H420.84ZM603.16,622.91H420.84V586.45H603.16Zm0-91.16H420.84V495.29H603.16Z" transform="translate(-56.22)"/><path class="cls-2" d="M922.19,222.64,557.57,12.2a91.16,91.16,0,0,0-91.13,0L101.81,222.64a91.16,91.16,0,0,0-45.59,79V722.41a91.16,91.16,0,0,0,45.59,79l364.63,210.44a91.15,91.15,0,0,0,91.13,0L922.19,801.36a91.16,91.16,0,0,0,45.59-79V301.59A91.16,91.16,0,0,0,922.19,222.64ZM694.31,656.33a76.05,76.05,0,0,1-76,76H405.65a76.05,76.05,0,0,1-76-76V370.71a76.05,76.05,0,0,1,76-76h212.7a76.05,76.05,0,0,1,76,76Z" transform="translate(-56.22)"/></svg>
\ No newline at end of file
<svg id="Layer_7" data-name="Layer 7" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 911.57 1024"><defs><style>.cls-1{fill:url(#linear-gradient);}</style><linearGradient id="linear-gradient" x1="203.85" y1="903.73" x2="807.6" y2="136.22" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff"/></linearGradient></defs><title>账户总数icon</title><path class="cls-1" d="M922.19,222.64,557.57,12.2a91.16,91.16,0,0,0-91.13,0L101.81,222.64a91.16,91.16,0,0,0-45.59,79V722.41a91.16,91.16,0,0,0,45.59,79l364.63,210.44a91.15,91.15,0,0,0,91.13,0L922.19,801.36a91.16,91.16,0,0,0,45.59-79V301.59A91.16,91.16,0,0,0,922.19,222.64ZM377.27,545.27,481.71,440.84a14.57,14.57,0,0,1,20.61,0l91.37,91.37L703.46,422.43A14.57,14.57,0,0,1,724.07,443L604,563.12a14.57,14.57,0,0,1-20.61,0L492,471.75,397.9,565.86a14.52,14.52,0,0,1-10.3,4.27h0a14.57,14.57,0,0,1-10.3-24.87ZM725.29,729H324.07a40,40,0,0,1-40-40V321.47a14.57,14.57,0,0,1,29.14,0V689a10.83,10.83,0,0,0,10.82,10.82H725.29a14.57,14.57,0,0,1,0,29.14Z" transform="translate(-56.22 0)"/></svg>
\ No newline at end of file
<svg id="Layer_5" data-name="Layer 5" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 911.57 1024"><defs><style>.cls-1{fill:url(#linear-gradient);}</style><linearGradient id="linear-gradient" x1="203.85" y1="903.73" x2="807.6" y2="136.22" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff"/></linearGradient></defs><title>交易总数icon</title><g id="Page-1"><g id="_1-1-1-1-摘要" data-name="1-1-1-1-摘要"><path class="cls-1" d="M922.19,222.64,557.57,12.2a91.16,91.16,0,0,0-91.13,0L101.81,222.64a91.16,91.16,0,0,0-45.59,79V722.41a91.16,91.16,0,0,0,45.59,79l364.63,210.44a91.15,91.15,0,0,0,91.13,0L922.19,801.36a91.16,91.16,0,0,0,45.59-79V301.59A91.16,91.16,0,0,0,922.19,222.64ZM312.54,580.81a15.19,15.19,0,0,1,0-21.49l222-222H407.17a15.19,15.19,0,0,1,0-30.39H571.25A15.21,15.21,0,0,1,582,332.83l-248,248A15.19,15.19,0,0,1,312.54,580.81ZM711.46,467.72l-222,222h127.4a15.19,15.19,0,0,1,0,30.39H452.75c-.05,0-.1,0-.15,0a15.14,15.14,0,0,1-15-15s0-.08,0-.12,0-.08,0-.12A15.25,15.25,0,0,1,442,694.21l248-248a15.19,15.19,0,0,1,21.49,21.49Z" transform="translate(-56.22)"/></g></g></svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="60px" height="69px" viewBox="0 0 60 69" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 49.3 (51167) - http://www.bohemiancoding.com/sketch -->
<title>用户总数 icon</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="16.650396%" y1="10.1623052%" x2="79.5569605%" y2="90.1306636%" id="linearGradient-1">
<stop stop-color="#FFFFFF" offset="0%"></stop>
<stop stop-color="#FFFFFF" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1-1-1-1-摘要" transform="translate(-1154.000000, -203.000000)" fill="url(#linearGradient-1)">
<g id="用户总数-icon" transform="translate(1154.000000, 203.000000)">
<path d="M32.9991399,1.60311649 L56.9991399,15.4542269 C58.856031,16.5258937 60,18.5069274 60,20.6508758 L60,48.3491242 C60,50.4930726 58.856031,52.4741063 56.9991399,53.5457731 L32.9991399,67.3968835 C31.1431706,68.4680183 28.8568294,68.4680183 27.0008601,67.3968835 L3.0008601,53.5457731 C1.14396896,52.4741063 2.30926389e-14,50.4930726 1.95399252e-14,48.3491242 L0,20.6508758 C0,18.5069274 1.14396896,16.5258937 3.0008601,15.4542269 L27.0008601,1.60311649 C28.8568294,0.531981705 31.1431706,0.531981705 32.9991399,1.60311649 Z M24.532696,35.3972206 C19.335589,37.0550242 15.6235294,41.1268741 15.6235294,45.9823376 C15.6235294,53.2058875 43.8588235,53.2058875 43.8588235,45.9823376 C43.8588235,41.1268741 40.146764,37.0550242 34.9496569,35.3972206 C37.4833535,33.6769581 39.1529412,30.7373552 39.1529412,27.4 C39.1529412,22.0980664 34.9391506,17.8 29.7411765,17.8 C24.5432024,17.8 20.3294118,22.0980664 20.3294118,27.4 C20.3294118,30.7373552 21.9989994,33.6769581 24.532696,35.3972206 Z" id="Combined-Shape"></path>
<g id="Group-11" transform="translate(17.600000, 19.800000)">
<path d="M12.1411765,14.8 C16.0396571,14.8 19.2,11.5764502 19.2,7.6 C19.2,3.6235498 16.0396571,0.4 12.1411765,0.4 C8.24269588,0.4 5.08235294,3.6235498 5.08235294,7.6 C5.08235294,11.5764502 8.24269588,14.8 12.1411765,14.8 Z" id="Oval-3"></path>
<path d="M23.9058824,26.1823376 C23.9058824,21.2995621 18.6955703,17.2 12.1411765,17.2 C5.58678261,17.2 0.376470588,21.2995621 0.376470588,26.1823376 C0.376470588,30.2058875 23.9058824,30.2058875 23.9058824,26.1823376 Z" id="Oval-3"></path>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
......@@ -14,7 +14,6 @@ import 'flarej/lib/components/antd/tree';
import 'flarej/lib/components/antd/checkbox';
import Modal from 'flarej/lib/components/antd/modal';
import Tree from 'flarej/lib/components/antd/tree';
import Input from 'flarej/lib/components/antd/input';
import Message from 'flarej/lib/components/antd/message';
import Notification from '../../../utils/notification';
import styles from './search.m.scss';
......@@ -36,352 +35,17 @@ export default class Search extends Component {
const closeLoading = Message.loading('正在获取数据...', 0);
Promise.all([
search.getRoleManagementData(),
search.getRoleMenuTree().then(() => search.initTree())
search.getBlockHeight(this.props.store.common.getDefaultLedger()),
]).then(() => {
closeLoading();
});
}
@autobind
onInputRole(e) {
this.inputRole = e.target.value;
}
@autobind
onSearch() {
if (this.inputRole == '') {
const closeLoading = Message.loading('正在获取数据...', 0);
Promise.all([
this.props.store.search.getRoleManagementData(),
]).then(() => {
closeLoading();
});
} else {
const { store: { search } } = this.props;
const searchRole = search.tableDataO.filter(n => n.name.indexOf(this.inputRole.trim()) > -1);
search.setTableData(searchRole);
}
}
@autobind
onAddRole() {
const { store: { search } } = this.props;
search.setAddModalVisible(true);
search.setDisable(true);
search.setActiveKey('tab1');
search.setAddInputRole('');
search.setAddInputDes('');
}
@autobind
onDeleteRole() {
const { store: { search } } = this.props;
if (this.selectedRowKeys.length == 0) {
Notification.error({ description: '请勾选要删除的角色!', duration: 3 });
} else {
Modal.confirm({
title: '你确认要删除角色吗?',
onOk: () => {
const closeLoading = Message.loading('正在获取数据...', 0);
const roleId = this.selectedRows.map((item) => item.roleId);
Promise.all([
search.deleteRole({ roleId: roleId })
]).then(() => {
search.getRoleManagementData();
}).then(() => {
this.selectedRowKeys = [];
closeLoading();
});
}
});
}
}
@computed get tableColumns() {
return [{
title: '序号',
dataIndex: 'key',
}, {
title: '角色名称',
dataIndex: 'name',
}, {
title: '角色描述',
dataIndex: 'describe',
}, {
title: '创建时间',
dataIndex: 'cTime',
}, {
title: '修改时间',
dataIndex: 'mTime',
}, {
title: '操作',
dataIndex: 'handler',
render: (text, record, index) => nj `
<span>
<a href="javascript:;" onClick=${()=>this.onEdit(record, index)} className="btn-link">编辑</a>
<a href="javascript:;" onClick=${()=>this.onDetail(record, index)} className="btn-link">用户明细</a>
</span>
` (),
}];
}
@autobind
onEdit(record, index) {
const { store: { search } } = this.props;
search.setEditModalVisible(true);
search.setSaveBtnDisabled(true);
search.setActiveKey('tab1');
search.setAddInputRole(record.name);
search.setAddInputDes(record.describe);
search.setRoleId(record.roleId);
search.setDisable(false);
const closeLoading = Message.loading('正在获取数据...', 0);
Promise.all([
search.getRoleMenuTree({ roleId: record.roleId }).then(() => search.initTree()),
]).then(() => {
closeLoading();
});
}
@autobind
onDetail(record, index) {
const { store: { search } } = this.props;
search.setDetailModalVisible(true);
search.setDetailData(record.users);
}
getRowSelection() {
return {
selectedRowKeys: this.selectedRowKeys,
onChange: (selectedRowKeys, selectedRows) => {
this.selectedRowKeys = selectedRowKeys;
this.selectedRows = selectedRows;
}
};
}
render() {
const { store: { search } } = this.props;
return tmpls.container(this.props, this, {
styles,
search,
tableData: toJS(search.tableData),
rowSelection: this.getRowSelection(),
});
}
}
@registerTmpl('ModalFormSearch')
@inject('store')
@observer
class ModalForm extends Component {
@observable autoExpandParent = false;
//获取树节点的展开形式
getExpandedKeys(arr) {
return arr.filter(n => n.level == 1 || n.level == 2).map(m => { return m.id.toString(); });
}
getDefaultCheckedKeys() {
let keys = [];
this.props.store.search.menuData.filter(n => n.level == 3)
.forEach(item => {
if (item.selected) {
keys.push(item.id.toString());
}
});
return keys;
}
//获取选中的 checkbox 包含父级未选中状态
getAllCheckedKeys(key) {
const _map = toJS(this.props.store.search.authTreeDataMap);
if (key.length > 1) {
let pids = key.map(item => { return _map[item].pids; });
return Array.from(new Set([].concat(...pids)));
} else {
return _map[key].pids;
}
}
@autobind
onExpand(expandedKeys) {
const { store: { search } } = this.props;
search.setExpandedKeys(expandedKeys);
this.autoExpandParent = true;
}
@autobind
onCheck(checkedKeys) {
const { store: { search } } = this.props;
search.setSaveBtnDisabled(false);
search.setCheckedKeys(checkedKeys);
if (checkedKeys.length == 0) {
search.setMenuIds([]);
} else {
let allChecked = Array.from(new Set(this.getAllCheckedKeys(checkedKeys).concat(checkedKeys)));
search.setMenuIds(allChecked);
}
}
@autobind
onAddModalCancel() {
if (this.props.tabName == '增加角色') {
this.props.store.search.setAddModalVisible(false);
}
else {
this.props.store.search.setEditModalVisible(false);
}
this.props.store.search.setSaveBtnDisabled(false);
}
@autobind
onTabChange(key) {
this.props.store.search.setActiveKey(key);
}
@autobind
onAddInputRoleChange(e) {
this.props.store.search.setAddInputRole(e.target.value);
}
@autobind
onAddInputDesChange(e) {
this.props.store.search.setAddInputDes(e.target.value);
}
@autobind
onAddSaveRole() {
const { store: { search } } = this.props;
if (search.addInputRole.trim() == '') {
Notification.error({ description: '请输入角色名称!', duration: 1 });
} else {
const closeLoading = Message.loading('正在获取数据...', 0);
let params = {
roleName: search.addInputRole,
roleDescribe: search.addInputDes
};
if (this.props.tabName == '编辑角色' && search.roleId != null) {
params.roleId = search.roleId;
}
Promise.all([
search.saveRole(params)
]).then(() => {
search.getRoleManagementData();
}).then(() => {
search.setActiveKey('tab2');
closeLoading();
});
}
}
@autobind
onAddCancel() {
const { store: { search } } = this.props;
if (this.props.tabName == '增加角色') {
search.setAddModalVisible(false);
} else {
search.setEditModalVisible(false);
}
}
@autobind
onSavePermission() {
const { store: { search } } = this.props;
if (this.props.tabName == '增加角色') {
console.log(search.menuIds);
search.saveRolePermission({
roleId: search.addRoleId,
menuIds: search.menuIds
}).then(() => search.setAddModalVisible(false));
} else {
search.saveRolePermission({
roleId: search.roleId,
menuIds: search.menuIds
}).then(() => search.setEditModalVisible(false));
}
}
disabledTreeNodes = ['权限管理', '角色管理'];
render() {
const { store: { search } } = this.props;
const TreeNode = Tree.TreeNode;
let level = 1;
const loop = data => data.map((item) => {
const disableCheckbox = this.disabledTreeNodes.indexOf(item.title) > -1 ? true : false;
if (item.children) {
const disabled = level == 1 ? true : item.children.filter(n => this.disabledTreeNodes.indexOf(n.title) > -1).length > 0;
level++;
return nj `
<${TreeNode} key=${item.key} title=${item.title} disableCheckbox=${disableCheckbox} disabled=${disabled}>
${loop(item.children)}
</${TreeNode}>
` ();
}
return nj `<${TreeNode} key=${item.key} title=${item.title} disableCheckbox=${disableCheckbox} />` ();
});
return tmpls.modalForm({
components: { 'ant-TextArea': Input.TextArea },
styles,
search,
loop,
treeData: toJS(search.authTreeData) || [],
}, this.props, this);
}
}
@registerTmpl('ModalDetailSearch')
@inject('store')
@observer
class ModalDetail extends Component {
@autobind
onDetailModalCancel() {
const { store: { search } } = this.props;
search.setDetailModalVisible(false);
}
@computed get detailColumns() {
return [{
title: '序号',
dataIndex: 'key',
}, {
title: '登录名',
dataIndex: 'loginName',
}, {
title: '姓名',
dataIndex: 'name',
}, {
title: '邮箱',
dataIndex: 'email',
}, {
title: '部门',
dataIndex: 'department',
}, {
title: '职务',
dataIndex: 'duty',
}, {
title: '开通时间',
dataIndex: 'oTime',
}];
}
render() {
const { store: { search } } = this.props;
return tmpls.modalDetail(this.props, this, {
styles,
search,
getDetailRowKey: (record, index) => `${record.key}-${index}`
});
}
}
\ No newline at end of file
.search {
background-color: #fff;
padding: 100px 40px 40px;
padding:0 30px;
h2 {
margin-bottom: 25px;
font-size: 16px;
font-size: 20px;
line-height: 70px;
height: 70px;
border-bottom: 1px solid #e8e8e9;
}
.handlerBox {
margin-bottom: 20px;
border-bottom: 1px solid #eee;
padding-bottom: 20px;
}
.handlerBox:after {
content: '';
display: table;
clear: both;
}
.lable {
float: left;
margin-right: 10px;
line-height: 28px;
}
.input {
width: 200px;
margin-right: 20px;
border-color: #d9d9d9;
}
}
.btnArea {
text-align: center;
padding: 10px;
}
.treeWrap {
height: 420px;
overflow: scroll;
overflow-x: hidden;
}
.main{
margin: 100px auto 0 auto;
.checks {
border-top: 1px solid #eaeaea;
margin-top: 15px;
padding: 15px 0;
text-align: center;
}
:global {
.ant-table-thead tr th {
text-align: center;
}
.ant-table-tbody tr td {
text-align: center;
padding: 10px 5px;
.btn-link {
margin: 0 5px;
.headtitle{
font-size: 36px;
font-weight: bold;
text-align: center;
}
}
.frombox {
padding: 20px;
li {
margin-bottom: 10px;
display: block;
.action{
width:1000px;
height:100px;
margin: 15px auto 0 auto;
border-radius: 5px;
box-shadow: 0px 0px 14px #5a77d3;
background: linear-gradient(90deg, #5a77d3, #3c4c9c);
.bg{
height: inherit;
background: url(../../images/overview_bg.png) no-repeat;
display: flex;
justify-content: center;
align-items: center;
.title{
font-size: 14px;
color: #fff;
}
.input{
width: 676px;
margin: 0 15px;
}
.btn{
background-color: #3c4c9c;
color: #fff;
border: 1px solid #819df3;
}
}
}
.textarea {
.summary {
width: 100%;
border: 1px solid #d9d9d9;
display: flex;
flex-direction: row;
justify-content: center;
margin-top: 100px;
margin-bottom: 30px;
// 区块高度等页签样式
.tabs {
height: 132px;
width:243px;
margin-right: 30px;
padding: 24px;
box-shadow: 0 0 8px 0 rgba(0,0,0,0.08);
border-radius: 4px;
.span {
display: flex;
flex-direction: row;
.left {
width: 75%;
}
.right {
width: 25%;
.logo {
min-width: 60px;
background-size: 60px 67px;
width: 100%;
height: 160px;
}
.logoBH {
background: url('../../images/blockheightIcon.svg') no-repeat;
}
.logoTR {
background: url('../../images/transactionIcon.svg') no-repeat;
}
.logoUS {
background: url('../../images/userIcon.svg') no-repeat;
}
.logoLE {
background: url('../../images/ledgersIcon.svg') no-repeat;
}
.logoCO {
background: url('../../images/contractIcon.svg') no-repeat;
}
}
}
}
.blockHeight {
background: #0DB18C;
background-image: url('../../images/overview_bg.png');
background-repeat: no-repeat;
background-size: 250px;
}
.transactions {
background: #10A647;
background-image: url('../../images/overview_bg.png');
background-repeat: no-repeat;
background-size: 250px;
}
.users {
background: #037CC1;
background-image: url('../../images/overview_bg.png');
background-repeat: no-repeat;
background-size: 250px;
}
.ledgers {
background: #5A77D2;
background-image: url('../../images/overview_bg.png');
background-repeat: no-repeat;
background-size: 250px;
}
.contracts {
background: #3C4C9C;
margin-right: 0;
background-image: url('../../images/overview_bg.png');
background-repeat: no-repeat;
background-size: 250px;
}
.title {
font-size: 14px;
color: #FFFFFF;
line-height: 14px;
}
.data {
font-family: ArialMT;
font-size: 3em;
color: #FFFFFF;
line-height: 54px;
margin-top: 27px;
}
}
.red:before {
content: '*';
color: red;
font-size: 14px;
position: absolute;
margin: 3px;
.list{
width: 100%;
background: #fff;
border-radius: 4px;
padding: 30px;
}
}
.btn {
margin-right: 20px;
}
}
<template name="container">
<div class="{styles.search}">
<h2>角色管理 search</h2>
<div class="{styles.handlerBox}">
<span class="{styles.lable}">角色名称</span>
<ant-input class="{styles.input}" value="{inputRole}" onChange={onInputRole}/>
<ant-Button class="btn" onClick={onSearch}>查询</ant-Button>
<ant-Button class="btn" onClick={onAddRole}>新增</ant-Button>
<ant-Button class="btn" onClick={onDeleteRole}>删除</ant-Button>
</div>
<ant-Table rowSelection={rowSelection}
columns={toJS(tableColumns)}
dataSource={toJS(tableData)}
bordered />
<ModalFormSearch tabName="增加角色" />
<ModalFormSearch tabName="编辑角色" />
<ModalDetailSearch />
</div>
</template>
<template name="modalForm">
<ant-Modal width={500} visible="{tabName == '增加角色' ?: (search.addModalVisible, search.editModalVisible)}" footer={null} onCancel={onAddModalCancel}>
<ant-Tabs activeKey={search.activeKey} onChange={onTabChange}>
<ant-TabPane tab="增加角色" key="tab1">
<ul class="frombox">
<li>角色名称 <span class="red"></span></li>
<li><ant-input onChange={onAddInputRoleChange} value="{search.addInputRole}"/></li>
<li>角色描述</li>
<li><ant-TextArea rows={4} onChange={onAddInputDesChange} class="textarea" value="{search.addInputDes}" /></li>
<li class="{styles.btnArea}">
<ant-Button class="btn" onClick={onAddSaveRole}>保存</ant-Button>
<ant-Button class="btn" onClick={onAddCancel}>取消</ant-Button>
</li>
</ul>
</ant-TabPane>
<ant-TabPane tab="配置权限" key="tab2" disabled="{tabName == '增加角色' ?: search.isDisable}">
<div class="{styles.treeWrap}">
<ant-Tree checkable
onExpand={onExpand}
expandedKeys={toJS(search.expandedKeys)}
{autoExpandParent}
onCheck={onCheck}
checkedKeys={toJS(search.checkedKeys)}>
{loop(treeData)}
</ant-Tree>
<div class="{styles.main}">
<p class="{styles.headtitle}">JD Chain</p>
<div class="{styles.action}">
<div class="{styles.bg}">
<span class="{styles.title}">输入搜索:</span>
<ant-Input class="{styles.input}"/>
<ant-Button class="{styles.btn}" icon="search">搜索</ant-Button>
</div>
</div>
<div class="{styles.summary}">
<div class="{styles.tabs} {styles.blockHeight}">
<div class="{styles.span}">
<div class="{styles.left}">
<p class="{styles.title}">区块高度</p>
<p class="{styles.data}">{search.blockHeight || 0}</p>
</div>
<div class="{styles.right}">
<div class="{styles.logo} {styles.logoBH}">
</div>
</div>
</div>
</div>
<div class="{styles.tabs} {styles.transactions}">
<div class="{styles.span}">
<div class="{styles.left}">
<p class="{styles.title}">交易总数</p>
<p class="{styles.data}">{store.overviewHeadData.transactionTotal || 0}</p>
</div>
<div class="{styles.right}">
<div class="{styles.logo} {styles.logoTR}">
</div>
</div>
</div>
</div>
<div class="{styles.tabs} {styles.users}">
<div class="{styles.span}">
<div class="{styles.left}">
<p class="{styles.title}">用户总数</p>
<p class="{styles.data}">{store.overviewHeadData.userTotal || 0}</p>
</div>
<div class="{styles.right}">
<div class="{styles.logo} {styles.logoUS}">
</div>
</div>
</div>
</div>
<div class="{styles.btnArea}">
<ant-Button class="btn" onClick={onSavePermission} disabled="{tabName == '编辑角色' ?: search.saveBtnDisabled}">保存</ant-Button>
<ant-Button class="btn" onClick={onAddCancel}>取消</ant-Button>
<div class="{styles.tabs} {styles.ledgers}">
<div class="{styles.span}">
<div class="{styles.left}">
<p class="{styles.title}">数据账户总数</p>
<p class="{styles.data}">{store.overviewHeadData.dataLedgersTotal || 0}</p>
</div>
<div class="{styles.right}">
<div class="{styles.logo} {styles.logoLE}">
</div>
</div>
</div>
</div>
</ant-TabPane>
</ant-Tabs>
</ant-Modal>
</template>
<template name="modalDetail">
<ant-Modal width={800} visible={search.detailModalVisible} footer={null} onCancel={onDetailModalCancel}>
<@title>
<div class={styles.modalTitle}>用户明细</div>
</@title>
<ant-Table pagination={true} columns={toJS(detailColumns)} dataSource={toJS(search.detailData)} rowKey={getDetailRowKey} bordered />
</ant-Modal>
<div class="{styles.tabs} {styles.contracts}">
<div class="{styles.span}">
<div class="{styles.left}">
<p class="{styles.title}">合约总数</p>
<p class="{styles.data}">{store.overviewHeadData.contractTotal || 0}</p>
</div>
<div class="{styles.right}">
<div class="{styles.logo} {styles.logoCO}">
</div>
</div>
</div>
</div>
</div>
<div class="{styles.list}">
<div style="font-size: 12px; color: gray">
找到相关的<span style="color: #000; font-weight: bold">{store.total}</span>个区块,&nbsp;&nbsp;
<span style="color: #000; font-weight: bold">{store.transNum}</span>个交易,&nbsp;&nbsp;
<span style="color: #000; font-weight: bold">{store.transNum}</span>条交易内容
</div>
<ant-Tabs>
<ant-TabPane tab="全部" key='0'>
<div>
<#if {{store.allData}}>
<#each {{store.allData}}>
<div key={@index}>
<article style="padding: 10px; min-height: 100px; border-bottom: 1px solid #eaecf3">
<p style="margin-bottom: 2em">
<span style="font-size: 18px; color: #999">哈希值(HASH):</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-size: 18px; color: #5a77d3; cursor: pointer">{{hash_id}}</span>
</p>
<p>
<#if {{@item.height}}>
<span style="font-size: 14px; color: #999">高度:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-size: 14px; color: #333">{{height}}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</#if>
<#if {{@item.block_height}}>
<span style="font-size: 14px; color: #999">所在区块高度(Height):</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-size: 14px; color: #333">{{block_height}}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</#if>
<#if {{@item.block_detail}}>
<span style="font-size: 14px; color: #999">所在区块哈希值(HASH):</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-size: 14px; color: #333">{{block_detail.hash_id}}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</#if>
</p>
<p>
<#if {{@item.endpoint_public_key}}>
<span style="font-size: 14px; color: #999">签名者公钥:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-size: 14px; color: #333">{{endpoint_public_key}}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</#if>
</p>
<p>
<#if {{@item.node_public_key}}>
<span style="font-size: 14px; color: #999">节点公钥:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-size: 14px; color: #333">{{node_public_key}}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</#if>
</p>
</article>
</div>
</#each>
<div style="padding: 30px 0; text-align: right">
<ant-Pagination showQuickjumper={true} hideOnSinglePage={true} defaultCurrent={2} total={{store.total}}/>
</div>
</#if>
</div>
</ant-TabPane>
<ant-TabPane tab="区块" key='1'>
<div>
<#if {{store.blockData}}>
<#each {{store.blockData}}>
<div key={@index}>
<article style="padding: 10px; min-height: 100px; border-bottom: 1px solid #eaecf3">
<p style="margin-bottom: 2em">
<span style="font-size: 18px; color: #999">哈希值(HASH):</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-size: 18px; color: #5a77d3; cursor: pointer">{{hash_id}}</span>
</p>
<p>
<span style="font-size: 14px; color: #999">高度:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-size: 14px; color: #999">{{height}}</span>
</p>
</article>
</div>
</#each>
<div style="padding: 30px 0; text-align: right">
<ant-Pagination showQuickjumper={true} hideOnSinglePage={true} defaultCurrent={2} total={{store.total}}/>
</div>
</#if>
</div>
</ant-TabPane>
<ant-TabPane tab="交易" key='2'>
<#if {{store.transData}}>
<#each {{store.transData}}>
<div key={@index}>
<p style="margin-bottom: 2em">
<span style="font-size: 18px; color: #999">哈希值(HASH):</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-size: 18px; color: #5a77d3; cursor: pointer">{{hash_id}}</span>
</p>
<p>
<#if {{@item.height}}>
<span style="font-size: 14px; color: #999">高度:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-size: 14px; color: #333">{{height}}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</#if>
<#if {{@item.block_height}}>
<span style="font-size: 14px; color: #999">所在区块高度(Height):</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-size: 14px; color: #333">{{block_height}}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</#if>
<#if {{@item.block_detail}}>
<span style="font-size: 14px; color: #999">所在区块哈希值(HASH):</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-size: 14px; color: #333">{{block_detail.hash_id}}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</#if>
</p>
<p>
<#if {{@item.endpoint_public_key}}>
<span style="font-size: 14px; color: #999">签名者公钥:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-size: 14px; color: #333">{{endpoint_public_key}}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</#if>
</p>
<p>
<#if {{@item.node_public_key}}>
<span style="font-size: 14px; color: #999">节点公钥:</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<span style="font-size: 14px; color: #333">{{node_public_key}}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</#if>
</p>
</div>
</#each>
<div style="padding: 30px 0; text-align: right">
<ant-Pagination showQuickjumper={true} hideOnSinglePage={true} defaultCurrent={2} total={{store.total}}/>
</div>
<#else>
暂无数据
</#else>
</#if>
</ant-TabPane>
</ant-Tabs>
</div>
</div>
</div>
</template>
\ No newline at end of file
......@@ -8,6 +8,7 @@
const isProd = process.env.NODE_ENV == 'production';
const isTest = process.env.NODE_ENV == 'test';
const isLocal = process.env.Project == 'local';
const isSelf = true;// true使用代理服务,false不使用
const pxToRem = require('postcss-pxtorem');
const VERSION = '20170928';
const modifyVars = Object.assign({});
......@@ -204,6 +205,18 @@ module.exports = {
]
}
]
},
devServer: {
proxy: [
{
context: ['/auth', '/api'],
target: 'http://192.168.151.39:10001',
},
{
context: ['/ledgers'],
target: 'http://192.168.151.45:8081',
},
]
}
};
......@@ -240,7 +253,7 @@ module.exports.plugins = [
new webpack.NamedModulesPlugin(),
new webpack.DefinePlugin({
__ENV: isProd || isTest ? "'pro'" : "'dev'",
__HOST: isProd || isTest ? "''" : "'http://localhost:8089'",
__HOST: isProd || isTest || isSelf ? "''" : "'http://localhost:8088'",
'process.env': {
NODE_ENV: JSON.stringify(isProd ? 'production' : 'development')
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册