Merge branch 'master' into release

This commit is contained in:
Jay 2017-04-11 16:48:52 +08:00
commit 87525f2597
12 changed files with 1342 additions and 813 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -270,6 +270,7 @@
"iocmd": "IO CMD", "iocmd": "IO CMD",
"schedule": "排程控制", "schedule": "排程控制",
"modbus": "Modbus", "modbus": "Modbus",
"modbus_preview": "Modbus 總覽",
"modbuscmd": "Modbus CMD", "modbuscmd": "Modbus CMD",
"modbuslog": "Modbus Log", "modbuslog": "Modbus Log",
"link": "連動", "link": "連動",

View File

@ -307,6 +307,53 @@ router
n(); n();
}) })
}) })
.post('/getwristbandlocpath', (req, res, n) => {
if (!config.permission.wristband) return n('ERR9000');
let arr = req.body;
if (!arr.data) return n('ERR0000');
if (!arr.data.mac) return n('ERR0060');
if (!arr.data.stime || !arr.data.etime) return n('ERR0015');
let pros = [];
let query = "select log.*, dev.`name` as devname \
from ??.?? log \
left join ??.?? dev \
on dev.`serialnumber` = log.`wloclogloc` \
where \
log.`wloclogmac` = ? \
and log.`wloclogtst` >= ? \
and log.`wloclogtst` <= ? \
order by log.`wloclogtst` desc";
let param = [config.db.db9, 'wlocationlog', config.db.db9, 'location', arr.data.mac, arr.data.stime, arr.data.etime];
pros.push(tool.promiseQuery(res, query, param, 'record'));
let rtq = "select * from ??.?? where `mac` = ?";
let rtp = [config.db.db9, 'wristband', arr.data.mac];
pros.push(tool.promiseQuery(res, rtq, rtp, 'rt'));
res.api_res = {
record: [],
rt: {
wristband: []
}
}
Promise.all(pros)
.then(d => {
for (let i in d) {
let tmp = d[i];
if (tmp.key == 'rt') {
res.api_res.rt.wristband = tool.checkArray(tmp.data);
}
if (tmp.key == 'record') {
res.api_res.record = tool.checkArray(tmp.data);
}
}
return n();
})
.catch(err => rt.err(res, err, n, 'ERR8000'));
})
.post('/getlocationlist', (req, res, n) => { .post('/getlocationlist', (req, res, n) => {
if (!config.permission.wristband) return n('ERR9000'); if (!config.permission.wristband) return n('ERR9000');

View File

@ -0,0 +1,14 @@
import React from 'react';
import {Container, Segment, Grid, List, Label} from 'semantic-ui-react';
class ModbusPreview extends React.Component {
render() {
return (
null
)
}
}
export default ModbusPreview;

View File

@ -1,13 +1,14 @@
import React from 'react'; import React from 'react';
import { Table, Button } from 'semantic-ui-react'; import { Table, Button } from 'semantic-ui-react';
const ListItem = ({ i18n, data, delWristband, editWristband }) => { const ListItem = ({ i18n, data, delWristband, editWristband, showPathInfo }) => {
return ( return (
<Table.Row> <Table.Row>
<Table.Cell> <Table.Cell>
<Button content="Edit" basic onClick={()=>{editWristband(1, data)}} /> <Button content="Edit" basic onClick={()=>{editWristband(1, data)}} />
<Button content="Delete" basic onClick={()=>{delWristband(data.uid)}} /> <Button content="Delete" basic onClick={()=>{delWristband(data.uid)}} />
<Button content="地點紀錄" basic onClick={()=>{showPathInfo(data.mac, data.name)}} />
</Table.Cell> </Table.Cell>
<Table.Cell>{data.mac}</Table.Cell> <Table.Cell>{data.mac}</Table.Cell>
<Table.Cell>{data.name}</Table.Cell> <Table.Cell>{data.name}</Table.Cell>

View File

@ -0,0 +1,104 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Modal, List, Menu, Button, Input, Label } from 'semantic-ui-react';
import Datetime from 'react-datetime';
import {convertTime, padding} from '../../../../tools'
const getDayTime = ()=>{
let d = new Date();
d.setHours(0, 0, 0, 0);
return d.getTime();
}
class WristbandPathInfo extends React.Component{
state = {
list: [],
stime: (getDayTime()),
etime: (Date.now())
}
componentDidMount(){
}
closeView = () => {
this.setState({
list: [],
stime: (getDayTime()),
etime: (Date.now())
}, ()=>{
this.props.closeModal();
})
}
getList = () => {
let {mac, showDialog, getRequest} = this.props;
fetch('/api/wristband/getwristbandlocpath', getRequest({
mac,
stime: Math.floor(this.state.stime / 1000),
etime: Math.floor(this.state.etime / 1000)
}))
.then(response=>response.json())
.then(json => {
if(json.status != 1) return showDialog(json.message);
this.setState({
list: json.data.record || []
})
})
}
render() {
let {closeModal, open} = this.props;
return (
<Modal open={open} onClose={()=>{this.closeView()}}>
<Modal.Header>
手環名稱: {this.props.wbname}
</Modal.Header>
<Modal.Content>
<Menu>
<Menu.Item>
<Input label="起始時間" input={
<Datetime dateFormat="YYYY-MM-DD"
timeFormat="HH:mm"
value={this.state.stime}
input={true}
onChange={(e)=>{ this.setState({stime: (e.valueOf())}) }} />
}/>
</Menu.Item>
<Menu.Item>
<Input label="結束時間" input={
<Datetime dateFormat="YYYY-MM-DD"
timeFormat="HH:mm"
value={this.state.etime}
input={true}
onChange={(e)=>{ this.setState({etime: (e.valueOf())}) }} />
}/>
</Menu.Item>
<Menu.Menu position="right">
<Menu.Item>
<Button type="button" content="搜尋" size="tiny" basic onClick={()=>{this.getList()}} />
</Menu.Item>
</Menu.Menu>
</Menu>
<List divided>
{
this.state.list.map((t,idx) => {
return (
<List.Item key={idx}>
{
t.devname ?
`時間 ${convertTime(t.wloclogtst, true)} 位於 ${t.devname} 附近` :
`時間 ${convertTime(t.wloclogtst, true)} 不在範圍內`
}
</List.Item>
)
})
}
</List>
</Modal.Content>
</Modal>
)
}
}
export default WristbandPathInfo;

View File

@ -3,6 +3,7 @@ import { Container, Segment, Table, Button } from 'semantic-ui-react';
import {getRequest} from '../../../../actions'; import {getRequest} from '../../../../actions';
import ListItem from './ListItem'; import ListItem from './ListItem';
import WristbandModal from './WristbandModal'; import WristbandModal from './WristbandModal';
import WristbandPathInfo from './WristbandPathInfo';
const stateDefault = ()=>({ const stateDefault = ()=>({
list: [], list: [],
@ -10,6 +11,11 @@ const stateDefault = ()=>({
open: false, open: false,
type: 0, type: 0,
data: {} data: {}
},
pathinfo: {
open: false,
mac: '',
name: ''
} }
}) })
@ -84,6 +90,24 @@ class WristbandInfo extends React.Component {
}) })
} }
showPathInfo = (mac, name) => {
if(!mac) return ;
this.setState({
pathinfo:{
open: true,
mac,
name
}
})
}
closePathInfo = () => {
this.setState({
pathinfo: {
...stateDefault().pathinfo
}
})
}
render() { render() {
let { i18n } = this.props; let { i18n } = this.props;
return ( return (
@ -105,7 +129,7 @@ class WristbandInfo extends React.Component {
<Table.Body> <Table.Body>
{ {
this.state.list.map((t,idx) => ( this.state.list.map((t,idx) => (
<ListItem key={idx} data={t} i18n={i18n} delWristband={this.delWristband} editWristband={this.openModal}/> <ListItem key={idx} data={t} i18n={i18n} delWristband={this.delWristband} editWristband={this.openModal} showPathInfo={this.showPathInfo}/>
)) ))
} }
</Table.Body> </Table.Body>
@ -117,6 +141,13 @@ class WristbandInfo extends React.Component {
data={this.state.modal.data} data={this.state.modal.data}
closeModal={this.closeModal} closeModal={this.closeModal}
submitModal={this.submitModal} /> submitModal={this.submitModal} />
<WristbandPathInfo i18n={i18n}
open={this.state.pathinfo.open}
mac={this.state.pathinfo.mac}
wbname={this.state.pathinfo.name}
closeModal={this.closePathInfo}
showDialog={this.props.showDialog}
getRequest={getRequest} />
</Container> </Container>
) )
} }

View File

@ -49,10 +49,10 @@ class WristbandPage extends React.Component{
定位點設定 定位點設定
</Menu.Item> </Menu.Item>
<Menu.Item active={this.state.page == 'locstatus'} onClick={()=>{ this.changePage('locstatus'); }}> <Menu.Item active={this.state.page == 'locstatus'} onClick={()=>{ this.changePage('locstatus'); }}>
位置資訊 即時資訊總覽
</Menu.Item> </Menu.Item>
<Menu.Item active={this.state.page == 'locstatus_wloc'} onClick={()=>{ this.changePage('locstatus_wloc'); }}> <Menu.Item active={this.state.page == 'locstatus_wloc'} onClick={()=>{ this.changePage('locstatus_wloc'); }}>
位置資訊 - 地點分類 位置資訊
</Menu.Item> </Menu.Item>
</Menu.Menu> </Menu.Menu>
</Menu.Item> </Menu.Item>

View File

@ -16,6 +16,7 @@ const MainMenu = ({i18n, show, toggleMenu, children, permissions, showDashboard,
<MItem toLink="/admin/iocmd" txt={i18n && 't' in i18n ? i18n.t('menu.item.iocmd') : ''} permission={permissions.iocmd} onClick={()=>toggleMenu()} /> <MItem toLink="/admin/iocmd" txt={i18n && 't' in i18n ? i18n.t('menu.item.iocmd') : ''} permission={permissions.iocmd} onClick={()=>toggleMenu()} />
<MItem toLink="/admin/schedule" txt={i18n && 't' in i18n ? i18n.t('menu.item.schedule') : ''} permission={permissions.schedule} onClick={()=>toggleMenu()} /> <MItem toLink="/admin/schedule" txt={i18n && 't' in i18n ? i18n.t('menu.item.schedule') : ''} permission={permissions.schedule} onClick={()=>toggleMenu()} />
<MItem toLink="/admin/modbus" txt={i18n && 't' in i18n ? i18n.t('menu.item.modbus') : ''} permission={permissions.modbus} onClick={()=>toggleMenu()} /> <MItem toLink="/admin/modbus" txt={i18n && 't' in i18n ? i18n.t('menu.item.modbus') : ''} permission={permissions.modbus} onClick={()=>toggleMenu()} />
<MItem toLink="/admin/modbuspreview" txt={i18n && 't' in i18n ? i18n.t('menu.item.modbus_preview') : ''} permission={permissions.modbus} onClick={()=>toggleMenu()} />
<MItem toLink="/admin/modbuscmd" txt={i18n && 't' in i18n ? i18n.t('menu.item.modbuscmd') : ''} permission={permissions.modbus} onClick={()=>toggleMenu()} /> <MItem toLink="/admin/modbuscmd" txt={i18n && 't' in i18n ? i18n.t('menu.item.modbuscmd') : ''} permission={permissions.modbus} onClick={()=>toggleMenu()} />
<MItem toLink="/admin/modbuslog" txt={i18n && 't' in i18n ? i18n.t('menu.item.modbuslog') : ''} permission={permissions.modbus} onClick={()=>toggleMenu()} /> <MItem toLink="/admin/modbuslog" txt={i18n && 't' in i18n ? i18n.t('menu.item.modbuslog') : ''} permission={permissions.modbus} onClick={()=>toggleMenu()} />
<MItem toLink="/admin/link" txt={i18n && 't' in i18n ? i18n.t('menu.item.link') : ''} permission={permissions.link} onClick={()=>toggleMenu()} /> <MItem toLink="/admin/link" txt={i18n && 't' in i18n ? i18n.t('menu.item.link') : ''} permission={permissions.link} onClick={()=>toggleMenu()} />

View File

@ -0,0 +1,19 @@
import { connect } from 'react-redux';
import { add_dialog_msg, toggle_loading, getRequest } from '../../actions';
import ModbusPreview from '../../components/AdminPage/ModbusPreview';
const mapStateToProps = (state) => ({
i18n: state.i18n
});
const mapDispatchToProps = (dispatch, ownProps) => ({
showDialog: (msg) => {
dispatch(add_dialog_msg(msg));
},
toggleLoading: (flag = false) => {
dispatch(toggle_loading(flag));
},
getRequest
})
export default connect(mapStateToProps, mapDispatchToProps)(ModbusPreview);

View File

@ -16,6 +16,7 @@ import ActionLink from './containers/AdminPage/ActionLink';
import ActionLinkAdd from './containers/AdminPage/ActionLinkAdd'; import ActionLinkAdd from './containers/AdminPage/ActionLinkAdd';
import IPCam from './containers/AdminPage/IPCam'; import IPCam from './containers/AdminPage/IPCam';
import Wristband from './containers/AdminPage/Wristband'; import Wristband from './containers/AdminPage/Wristband';
import ModbusPreview from './containers/AdminPage/ModbusPreview';
const Routes = ( const Routes = (
<Route path="/admin" component={AdminPage}> <Route path="/admin" component={AdminPage}>
@ -28,6 +29,7 @@ const Routes = (
<Route path="iocmd" component={IOCmd} /> <Route path="iocmd" component={IOCmd} />
<Route path="schedule" component={Schedule} /> <Route path="schedule" component={Schedule} />
<Route path="modbus" component={Modbus} /> <Route path="modbus" component={Modbus} />
<Route path="modbuspreview" component={ModbusPreview} />
<Route path="link" component={ActionLink} /> <Route path="link" component={ActionLink} />
<Route path="addlink" component={ActionLinkAdd} /> <Route path="addlink" component={ActionLinkAdd} />
<Route path="modbuscmd" component={ModbusCmd} /> <Route path="modbuscmd" component={ModbusCmd} />