update
This commit is contained in:
parent
c5236f9ad3
commit
d6250577fe
@ -2,7 +2,7 @@
|
|||||||
Description=JCNet WebIO
|
Description=JCNet WebIO
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=/usr/bin/node /home/node/webio/app.js
|
ExecStart=/usr/bin/node /usr/local/node/webio/app.js
|
||||||
Restart=always
|
Restart=always
|
||||||
User=root
|
User=root
|
||||||
Environment="NODE_ENV=production"
|
Environment="NODE_ENV=production"
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -246,6 +246,7 @@
|
|||||||
"systime": "系統時間",
|
"systime": "系統時間",
|
||||||
"sysip": "系統IP",
|
"sysip": "系統IP",
|
||||||
"sysinfo": "系統資訊",
|
"sysinfo": "系統資訊",
|
||||||
|
"sysversion": "系統版本",
|
||||||
"hsts": "溫濕度資訊",
|
"hsts": "溫濕度資訊",
|
||||||
"devstats": "裝置狀態",
|
"devstats": "裝置狀態",
|
||||||
"label": {
|
"label": {
|
||||||
|
@ -1,11 +1,27 @@
|
|||||||
const express = require('express');
|
const express = require('express');
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
const errMng = require('../../includes/errorManager');
|
const errMng = require('../../includes/errorManager');
|
||||||
|
const so = require('../../includes/storeObject');
|
||||||
|
|
||||||
router
|
router
|
||||||
.get('/', (req, res) => {
|
.get('/', (req, res) => {
|
||||||
res.send({ name: 'WebIO API System' });
|
res.send({ name: 'WebIO API System' });
|
||||||
})
|
})
|
||||||
|
.all('*', (req,res,n)=>{
|
||||||
|
if('x-auth-token' in req.headers) {
|
||||||
|
let token = req.headers['x-auth-token'];
|
||||||
|
if(so.chkKey(token)){
|
||||||
|
let obj = so.get(token);
|
||||||
|
if(obj != null) {
|
||||||
|
so.set(token, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
n();
|
||||||
|
})
|
||||||
|
.get('/showallso', (req,res)=>{
|
||||||
|
res.send(so.show());
|
||||||
|
})
|
||||||
.use('/system', require('./system.js'))
|
.use('/system', require('./system.js'))
|
||||||
.use('/log', require('./log.js'))
|
.use('/log', require('./log.js'))
|
||||||
.use('/leone', require('./leone.js'))
|
.use('/leone', require('./leone.js'))
|
||||||
|
@ -627,6 +627,23 @@ export const get_dashboard = () => dispatch => {
|
|||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(json => {
|
.then(json => {
|
||||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||||
|
let rt = json.data.rt;
|
||||||
|
dispatch(dashboard(rt.ip[0]? rt.ip[0].ip : '', rt.version[0]? rt.version[0].version : '', rt.di, rt.leone))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dashboard = (ip, version, di, leone) => ({
|
||||||
|
type: 'dashboard',
|
||||||
|
ip,
|
||||||
|
version,
|
||||||
|
di,
|
||||||
|
leone
|
||||||
|
})
|
||||||
|
|
||||||
|
export const toggle_dashboard = (flag) => ({
|
||||||
|
type: flag ? 'ui_show_dashboard' : 'ui_hide_dashboard'
|
||||||
|
})
|
||||||
|
|
||||||
|
export const clear_dashboard = () => ({
|
||||||
|
type: 'clear_dashboard'
|
||||||
|
})
|
22
src/components/DashBoard/AlertItem.js
Normal file
22
src/components/DashBoard/AlertItem.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {List, Grid, Label} from 'semantic-ui-react';
|
||||||
|
|
||||||
|
const AlertItem = ({i18n, name, type}) => {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Grid.Row columns={3} color="red">
|
||||||
|
<Grid.Column>
|
||||||
|
<Label basic content={type == 'di' ? "DigitInput" : "LeOne"} />
|
||||||
|
</Grid.Column>
|
||||||
|
<Grid.Column>
|
||||||
|
<Label basic content={i18n&&i18n.t ? i18n.t('dashboard.label.name') : ''} />{name}
|
||||||
|
</Grid.Column>
|
||||||
|
<Grid.Column>
|
||||||
|
<Label basic content={i18n&&i18n.t ? i18n.t('dashboard.label.status') : ''} />
|
||||||
|
{i18n&&i18n.t ? ( type == 'di' ? i18n.t('dashboard.status.digitinput') : i18n.t('dashboard.status.leone') ): ''}
|
||||||
|
</Grid.Column>
|
||||||
|
</Grid.Row>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AlertItem;
|
@ -1,40 +1,103 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Container, Segment, Divider, Grid, Label} from 'semantic-ui-react';
|
import {Container, Segment, Divider, Grid, Label, List} from 'semantic-ui-react';
|
||||||
|
import {getRequest} from '../../actions';
|
||||||
|
import {convertTime} from '../../tools';
|
||||||
|
import AlertItem from './AlertItem';
|
||||||
|
|
||||||
class DashBoardUnit extends React.Component {
|
class DashBoardUnit extends React.Component {
|
||||||
|
state = {
|
||||||
|
timeOffset: 0,
|
||||||
|
timeStr: '',
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
|
||||||
tick = null;
|
tick = null;
|
||||||
|
|
||||||
runTick = () => {
|
runTick = () => {
|
||||||
|
let time = Date.now();
|
||||||
|
if(Math.floor(time/1000)%5 == 0){
|
||||||
|
this.props.getDashboard();
|
||||||
|
}
|
||||||
|
this.setState({
|
||||||
|
timeStr: convertTime((time + this.state.timeOffset), true)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount(){
|
componentDidMount(){
|
||||||
|
this.checkRunTick();
|
||||||
|
fetch('/api/system/gettime', getRequest())
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(json => {
|
||||||
|
if(json.status != 1) return this.props.showDialog(json.message);
|
||||||
|
let t = Date.now();
|
||||||
|
let timeOffset = t - (json.data.record[0].time * 1000);
|
||||||
|
this.setState({
|
||||||
|
timeOffset
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps (np) {
|
||||||
|
if(np.show != this.state.show) {
|
||||||
|
this.setState({
|
||||||
|
show: np.show
|
||||||
|
}, ()=>{
|
||||||
|
this.checkRunTick();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkRunTick = () => {
|
||||||
|
if(this.state.show){
|
||||||
this.tick = setInterval(this.runTick, 1000)
|
this.tick = setInterval(this.runTick, 1000)
|
||||||
|
}else{
|
||||||
|
clearInterval(this.tick);
|
||||||
|
this.props.clearList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
clearInterval(this.tick);
|
||||||
|
this.props.clearList();
|
||||||
}
|
}
|
||||||
|
|
||||||
render(){
|
render(){
|
||||||
let {i18n} = this.props;
|
let {i18n, data} = this.props;
|
||||||
|
if(!this.state.show) return null;
|
||||||
return (
|
return (
|
||||||
<Container style={{fontSize: '20px'}}>
|
<Container style={{fontSize: '20px', marginBottom: '30px'}}>
|
||||||
<Segment>
|
<Segment>
|
||||||
<Divider horizontal>{i18n&&i18n.t ? i18n.t('dashboard.sysinfo') : ''}</Divider>
|
<Divider horizontal>{i18n&&i18n.t ? i18n.t('dashboard.sysinfo') : ''}</Divider>
|
||||||
<Grid columns={3}>
|
<Grid columns={3}>
|
||||||
<Grid.Column textAlign="center">
|
<Grid.Column textAlign="center">
|
||||||
<Label basic size="large" content={i18n&&i18n.t?i18n.t('dashboard.systime') : ''} />
|
<Label basic size="large" content={i18n&&i18n.t?i18n.t('dashboard.systime') : ''} />
|
||||||
<br />
|
<br />
|
||||||
|
{this.state.timeStr}
|
||||||
</Grid.Column>
|
</Grid.Column>
|
||||||
<Grid.Column textAlign="center">
|
<Grid.Column textAlign="center">
|
||||||
<Label basic size="large" content={i18n&&i18n.t?i18n.t('dashboard.sysip') : ''} />
|
<Label basic size="large" content={i18n&&i18n.t?i18n.t('dashboard.sysip') : ''} />
|
||||||
<br />
|
<br />
|
||||||
|
{data.ip}
|
||||||
</Grid.Column>
|
</Grid.Column>
|
||||||
<Grid.Column textAlign="center">
|
<Grid.Column textAlign="center">
|
||||||
<Label basic size="large" content={i18n&&i18n.t?i18n.t('dashboard.sysversion') : ''} />
|
<Label basic size="large" content={i18n&&i18n.t?i18n.t('dashboard.sysversion') : ''} />
|
||||||
<br />
|
<br />
|
||||||
|
{data.version}
|
||||||
</Grid.Column>
|
</Grid.Column>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Divider horizontal>{i18n&&i18n.t ? i18n.t('dashboard.devstats') : ''}</Divider>
|
<Divider horizontal>{i18n&&i18n.t ? i18n.t('dashboard.devstats') : ''}</Divider>
|
||||||
|
<Grid>
|
||||||
|
{
|
||||||
|
data.di.map((t,idx)=>(
|
||||||
|
<AlertItem key={`di${idx}`} i18n={i18n} name={t.diname} type="di" />
|
||||||
|
))
|
||||||
|
}
|
||||||
|
{
|
||||||
|
data.leone.map((t,idx)=>(
|
||||||
|
<AlertItem key={`le${idx}`} i18n={i18n} name={t.leonename} type="leone" />
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</Grid>
|
||||||
</Segment>
|
</Segment>
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
|
@ -3,7 +3,7 @@ import {Sidebar, Menu, Segment, Icon, Container} from 'semantic-ui-react';
|
|||||||
import {Link} from 'react-router';
|
import {Link} from 'react-router';
|
||||||
import MItem from './Item';
|
import MItem from './Item';
|
||||||
|
|
||||||
const MainMenu = ({i18n, show, toggleMenu, children, permissions}) => (
|
const MainMenu = ({i18n, show, toggleMenu, children, permissions, showDashboard, toggleDashboard}) => (
|
||||||
<div style={{height: '100%'}}>
|
<div style={{height: '100%'}}>
|
||||||
<Sidebar.Pushable as={Segment} style={{zIndex: 100}}>
|
<Sidebar.Pushable as={Segment} style={{zIndex: 100}}>
|
||||||
<Sidebar as={Menu} animation="push" width="thin" visible={show} icon="labeled" vertical inverted>
|
<Sidebar as={Menu} animation="push" width="thin" visible={show} icon="labeled" vertical inverted>
|
||||||
@ -28,6 +28,17 @@ const MainMenu = ({i18n, show, toggleMenu, children, permissions}) => (
|
|||||||
<Icon name="sidebar" />
|
<Icon name="sidebar" />
|
||||||
{i18n && 't' in i18n ? i18n.t('menu.title') : ''}
|
{i18n && 't' in i18n ? i18n.t('menu.title') : ''}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
<Menu.Menu position="right">
|
||||||
|
<Menu.Item onClick={()=>{
|
||||||
|
let ss = !showDashboard;
|
||||||
|
toggleDashboard(ss)
|
||||||
|
localStorage.setItem('show_dashboard', ss ? '1' : '0');
|
||||||
|
}}>
|
||||||
|
{i18n&&i18n.t ? (
|
||||||
|
showDashboard ? '關閉Dashboard' : '開啟Dashboard'
|
||||||
|
) : ''}
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu.Menu>
|
||||||
</Menu>
|
</Menu>
|
||||||
<Container style={{paddingTop: '45px', paddingBottom: '40px'}}>
|
<Container style={{paddingTop: '45px', paddingBottom: '40px'}}>
|
||||||
{children}
|
{children}
|
||||||
|
@ -4,6 +4,8 @@ import Datetime from 'react-datetime';
|
|||||||
import MainMenu from '../../containers/MenuControl';
|
import MainMenu from '../../containers/MenuControl';
|
||||||
import Loading from '../../containers/LoadingControl';
|
import Loading from '../../containers/LoadingControl';
|
||||||
import Dialog from '../DialogControl';
|
import Dialog from '../DialogControl';
|
||||||
|
import Dashboard from '../../containers/DashBoard';
|
||||||
|
import {toggle_dashboard} from '../../actions'
|
||||||
|
|
||||||
class AdmPage extends React.Component {
|
class AdmPage extends React.Component {
|
||||||
|
|
||||||
@ -11,6 +13,13 @@ class AdmPage extends React.Component {
|
|||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount(){
|
||||||
|
let showDashboard = localStorage.getItem('show_dashboard');
|
||||||
|
if(showDashboard != null && showDashboard == 1){
|
||||||
|
this.props.toggleDashboard(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let {i18n, children} = this.props;
|
let {i18n, children} = this.props;
|
||||||
if(!i18n || Object.keys(i18n).length == 0 || !i18n.t || !i18n.getResource) return null;
|
if(!i18n || Object.keys(i18n).length == 0 || !i18n.t || !i18n.getResource) return null;
|
||||||
@ -19,6 +28,7 @@ class AdmPage extends React.Component {
|
|||||||
<Loading />
|
<Loading />
|
||||||
<Dialog />
|
<Dialog />
|
||||||
<MainMenu i18n={i18n} >
|
<MainMenu i18n={i18n} >
|
||||||
|
<Dashboard />
|
||||||
{children}
|
{children}
|
||||||
</MainMenu>
|
</MainMenu>
|
||||||
</div>
|
</div>
|
||||||
@ -30,4 +40,10 @@ const mapStateToProps = (state) => ({
|
|||||||
i18n: state.i18n
|
i18n: state.i18n
|
||||||
})
|
})
|
||||||
|
|
||||||
export default connect(mapStateToProps)(AdmPage);
|
const mapDispatchToProps = (dispatch, ownProps) =>({
|
||||||
|
toggleDashboard: (flag)=>{
|
||||||
|
dispatch(toggle_dashboard(flag))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(AdmPage);
|
23
src/containers/DashBoard.js
Normal file
23
src/containers/DashBoard.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import {connect} from 'react-redux';
|
||||||
|
import {add_dialog_msg,get_dashboard, clear_dashboard} from '../actions';
|
||||||
|
import DashBoard from '../components/DashBoard';
|
||||||
|
|
||||||
|
const mapStateToProps = (state) => ({
|
||||||
|
i18n: state.i18n,
|
||||||
|
data: state.sysinfo.dashboard,
|
||||||
|
show: state.ui.showDashboard
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||||
|
showDialog: (msg) => {
|
||||||
|
dispatch(add_dialog_msg(msg));
|
||||||
|
},
|
||||||
|
clearList: () => {
|
||||||
|
dispatch(clear_dashboard());
|
||||||
|
},
|
||||||
|
getDashboard: () => {
|
||||||
|
dispatch(get_dashboard());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(DashBoard);
|
@ -1,9 +1,10 @@
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import MainMenu from '../components/MainMenu';
|
import MainMenu from '../components/MainMenu';
|
||||||
import { toggle_menu } from '../actions'
|
import { toggle_menu, toggle_dashboard } from '../actions'
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
show: state.ui.showMenu,
|
show: state.ui.showMenu,
|
||||||
|
showDashboard: state.ui.showDashboard,
|
||||||
permissions: (function() {
|
permissions: (function() {
|
||||||
let p = sessionStorage.getItem('permissions');
|
let p = sessionStorage.getItem('permissions');
|
||||||
if (!p) return {};
|
if (!p) return {};
|
||||||
@ -20,6 +21,9 @@ const mapStateToProps = (state) => ({
|
|||||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||||
toggleMenu: (flag) => {
|
toggleMenu: (flag) => {
|
||||||
dispatch(toggle_menu(flag));
|
dispatch(toggle_menu(flag));
|
||||||
|
},
|
||||||
|
toggleDashboard: (flag) => {
|
||||||
|
dispatch(toggle_dashboard(flag));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ const defState = () => ({
|
|||||||
network: {},
|
network: {},
|
||||||
time: '',
|
time: '',
|
||||||
dashboard: {
|
dashboard: {
|
||||||
time: '',
|
|
||||||
ip: '',
|
ip: '',
|
||||||
version: '',
|
version: '',
|
||||||
di: [],
|
di: [],
|
||||||
@ -16,6 +15,23 @@ const sysinfoReducer = (state = defState(), action) => {
|
|||||||
return {...state, network: action.network};
|
return {...state, network: action.network};
|
||||||
case 'system_time':
|
case 'system_time':
|
||||||
return {...state, time: action.time || ''};
|
return {...state, time: action.time || ''};
|
||||||
|
case 'dashboard':
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
dashboard: {
|
||||||
|
ip: action.ip,
|
||||||
|
version: action.version,
|
||||||
|
di: action.di,
|
||||||
|
leone: action.leone
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 'clear_dashboard':
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
dashboard:{
|
||||||
|
...defState().dashboard
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
const uiReducer = (state = {
|
const defState = () => ({
|
||||||
showMenu: false,
|
showMenu: false,
|
||||||
showLoading: false
|
showLoading: false,
|
||||||
}, action) => {
|
showDashboard: false
|
||||||
|
})
|
||||||
|
const uiReducer = (state = defState(), action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case 'ui_show_menu':
|
case 'ui_show_menu':
|
||||||
return {...state, showMenu: true };
|
return {...state, showMenu: true };
|
||||||
@ -11,6 +13,10 @@ const uiReducer = (state = {
|
|||||||
return {...state, showLoading: true};
|
return {...state, showLoading: true};
|
||||||
case 'ui_hide_loading':
|
case 'ui_hide_loading':
|
||||||
return {...state, showLoading: false};
|
return {...state, showLoading: false};
|
||||||
|
case 'ui_show_dashboard':
|
||||||
|
return {...state, showDashboard: true};
|
||||||
|
case 'ui_hide_dashboard':
|
||||||
|
return {...state, showDashboard: false};
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user