Compare commits
89 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e1fa3d2bc7 | |||
| a8adbf4cfd | |||
| efbd54191f | |||
| ee67fb6636 | |||
| fec43a6840 | |||
| 08dcdf08ae | |||
| b3e752792d | |||
| cf66e9d94e | |||
| af02ee856d | |||
| 5e751abbdc | |||
| c8c4c28dfc | |||
| feac093bda | |||
| f02af21b7b | |||
| 3062208332 | |||
| f64ab2ae82 | |||
| 06ab118cfe | |||
| 712a78c4ed | |||
| e27d143330 | |||
| 48b178ac3a | |||
| b07e51ef7c | |||
| 847bd06ac6 | |||
| 6f50504660 | |||
| 27d2209ea2 | |||
| a4b949bbfe | |||
| 588c5d77ab | |||
| 768bad6e2d | |||
| 9b70a544df | |||
| 2d958f2d85 | |||
| a92d29e107 | |||
| 85cb31b013 | |||
| b849574ee1 | |||
| 5429ffbb73 | |||
| a4ac4742be | |||
| 1a0a4fdc4d | |||
| 88255a1ae2 | |||
| 26f669fb96 | |||
| eb6b8d9ad5 | |||
| 12ff3a4020 | |||
| 54f41a85e6 | |||
| 6b34422a63 | |||
| afd3994e95 | |||
| d504f26bda | |||
| 29a5543c44 | |||
| e3a3307340 | |||
| efdc7e01c2 | |||
| 91effa014a | |||
| 0ea24f857d | |||
| e5bf72435c | |||
| 87525f2597 | |||
| 64ad807310 | |||
| 0cdbd319c8 | |||
| b1ad20d86c | |||
| 6e0f6faa25 | |||
| 5c02a34897 | |||
| 59331f9b1c | |||
| 7a30f23138 | |||
| 108e7db8f3 | |||
| 0fdcaf3bfc | |||
| 2434db599d | |||
| 05e38c2e2d | |||
| b8ccbe4cd3 | |||
| e18fa6546b | |||
| b781efabea | |||
| c132be1ed0 | |||
| 8d8b4818ae | |||
| 34f2d0e24a | |||
| b684672ad2 | |||
| 57a37b047f | |||
| 7cfdf4f2af | |||
| e529794956 | |||
| c1b443b9d2 | |||
| b419194b6b | |||
| f8f3cbe0d8 | |||
| e1ce5290da | |||
| 3e66691b67 | |||
| 77bf5f58d2 | |||
| eeead43baf | |||
| 52e18de9ac | |||
| e2040a181e | |||
| 493dd36e18 | |||
| 404fb8c346 | |||
| 57c8083012 | |||
| 37d854334d | |||
| 1df91aac09 | |||
| 7f93ea3bd6 | |||
| 40fa771e43 | |||
| c434a59910 | |||
| 4ae177e455 | |||
| c990935194 |
@@ -1 +1,3 @@
|
||||
node_modules
|
||||
public/js/admin_bundle.js
|
||||
public/js/index_bundle.js
|
||||
|
||||
@@ -7,13 +7,14 @@ const logger = require('morgan');
|
||||
const path = require('path');
|
||||
const config = require('./config');
|
||||
const so = require('./includes/storeObject');
|
||||
const exec = require('child_process').exec;
|
||||
|
||||
const app = express();
|
||||
|
||||
const api_route = require('./route/api');
|
||||
|
||||
// storeObject interval clear
|
||||
const clearStore = setInterval(() =>{
|
||||
const clearStore = setInterval(() => {
|
||||
so.clear();
|
||||
}, 30000)
|
||||
|
||||
@@ -34,6 +35,10 @@ app.use(express.static(path.resolve(__dirname, 'public')));
|
||||
app.use('/semantic', express.static(path.resolve(__dirname, 'node_modules', 'semantic-ui-css')));
|
||||
app.use('/react-datetime', express.static(path.resolve(__dirname, 'node_modules', 'react-datetime', 'css')));
|
||||
|
||||
app.use(/\/locales\/(\w+).json/, (req, res, n) => {
|
||||
res.sendFile(path.resolve(__dirname, 'public', 'locales', 'zh.json'));
|
||||
})
|
||||
|
||||
const server = app.listen(app.get('port'), () => {
|
||||
console.log(`Server start on port ${server.address().port}`);
|
||||
});
|
||||
@@ -45,6 +50,29 @@ app.get('/', (req, res) => {
|
||||
res.sendFile(path.resolve(__dirname, 'views', 'index.html'));
|
||||
});
|
||||
|
||||
app.get(['/admin','/admin/*'], (req,res) => {
|
||||
app.get(['/admin', '/admin/*'], (req, res) => {
|
||||
res.sendFile(path.resolve(__dirname, 'views', 'admin.html'));
|
||||
});
|
||||
|
||||
app.get('/servcmd', (req, res) => {
|
||||
res.send({ status: `exit time ${Date.now()}` });
|
||||
setTimeout(() => { process.exit(1) }, 2000);
|
||||
});
|
||||
|
||||
app.get('/fixmysql', (req, res) => {
|
||||
exec('systemctl stop mysqld', (err, sout, serr) => {
|
||||
let cmd = 'rm /home/www/mydb/aria*';
|
||||
let json = {
|
||||
rm: '',
|
||||
restart: ''
|
||||
};
|
||||
exec(cmd, (err, stdout, stderr) => {
|
||||
let cmd = 'systemctl restart mysqld';
|
||||
json.rm = stdout;
|
||||
exec(cmd, (err, sout, serr) => {
|
||||
json.restart = sout;
|
||||
res.send(json);
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
+10
-4
@@ -17,7 +17,10 @@
|
||||
"db5": "jcmbset",
|
||||
"db6": "jcmbrt",
|
||||
"db7": "jcioclc",
|
||||
"db8": "jciocln"
|
||||
"db8": "jciocln",
|
||||
"db9": "jcbtwristband",
|
||||
"db10": "jcmblog",
|
||||
"db11": "jciocserver"
|
||||
},
|
||||
"permission": {
|
||||
"dio": true,
|
||||
@@ -26,10 +29,13 @@
|
||||
"iogroup": true,
|
||||
"iocmd": true,
|
||||
"schedule": true,
|
||||
"modbus": true,
|
||||
"link": true
|
||||
"modbus": false,
|
||||
"link": true,
|
||||
"ipcam": false,
|
||||
"wristband": true,
|
||||
"server": false
|
||||
},
|
||||
"cmdpath":{
|
||||
"cmdpath": {
|
||||
"manualip": "/home/www/cmd/manualip",
|
||||
"dhcpip": "/home/www/cmd/dhcpip",
|
||||
"sysinfo": "/home/www/sysinfo",
|
||||
|
||||
@@ -54,6 +54,18 @@
|
||||
"ERR0052": "ScaleMin輸入錯誤",
|
||||
"ERR0053": "ScaleMax輸入錯誤",
|
||||
"ERR0054": "此位址設定已存在",
|
||||
"ERR0055": "Func Code 輸入錯誤",
|
||||
"ERR0056": "LeOne數量已達上限",
|
||||
"ERR0057": "連動資料輸入錯誤",
|
||||
"ERR0058": "timezone輸入錯誤",
|
||||
"ERR0059": "timezone設定失敗",
|
||||
"ERR0060": "手環ID輸入錯誤",
|
||||
"ERR0061": "手環ID已存在",
|
||||
"ERR0062": "機器序號輸入錯誤",
|
||||
"ERR0063": "機器序號已存在",
|
||||
"ERR0064": "MAC Addr 輸入錯誤",
|
||||
"ERR0065": "版本輸入錯誤",
|
||||
"ERR0066": "SNMP Level輸入錯誤",
|
||||
|
||||
"ERR7000": "命令執行失敗",
|
||||
|
||||
@@ -61,5 +73,7 @@
|
||||
"ERR8001": "資料新增失敗",
|
||||
"ERR8002": "資料更新失敗",
|
||||
"ERR8003": "資料刪除失敗",
|
||||
"ERR9000": "操作權限不足"
|
||||
"ERR8100": "DB連線失敗",
|
||||
"ERR9000": "操作權限不足",
|
||||
"ERR9001": "登入Token無效"
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
const StoreObj = (() => {
|
||||
|
||||
let memStore = {};
|
||||
let maxAge = 3600000;
|
||||
let maxAge = 86400000;
|
||||
|
||||
/**
|
||||
* @param {string} uuid
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
const mysql = require('mysql');
|
||||
const config = require('../config.json');
|
||||
|
||||
class MySQLPool {
|
||||
constructor() {
|
||||
this._user = '';
|
||||
this._password = '';
|
||||
this._host = '';
|
||||
this._port = 3306;
|
||||
this._database = '';
|
||||
this._socketPath = '/var/lib/mysql/mysql.sock'
|
||||
this._pool = null;
|
||||
this.autoclose = false;
|
||||
}
|
||||
|
||||
createPool(){
|
||||
this._pool = mysql.createPool({
|
||||
connectionLimit: 30,
|
||||
user: this._user,
|
||||
password: this._password,
|
||||
host: this._host,
|
||||
port: this._port,
|
||||
socketPath: this._socketPath
|
||||
});
|
||||
}
|
||||
|
||||
async getConn() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this._pool.getConnection((err, conn) => {
|
||||
if(err) return reject(err);
|
||||
return resolve(conn)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
formatQuery(query, arg) {
|
||||
return mysql.format(query, arg);
|
||||
}
|
||||
|
||||
escape(val) {
|
||||
return mysql.escape(val);
|
||||
}
|
||||
|
||||
recordPage(rows, page, maxPage) {
|
||||
if (!page || !isFinite(page) || page < 1) page = 1;
|
||||
|
||||
let totalpage = Math.ceil(rows / maxPage);
|
||||
|
||||
let prevpage = page - 1;
|
||||
let nextpage = page + 1;
|
||||
|
||||
if (prevpage < 1) prevpage = 1;
|
||||
if (nextpage > totalpage) nextpage = totalpage;
|
||||
|
||||
let rec_start = (page - 1) * maxPage + 1
|
||||
let rec_end = (rec_start + maxPage - 1);
|
||||
if (rec_end > rows) rec_end = rows;
|
||||
|
||||
let json = {
|
||||
rec_start,
|
||||
rec_end,
|
||||
total: rows,
|
||||
prevpage,
|
||||
nextpage,
|
||||
totalpage,
|
||||
page
|
||||
};
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
set user(str) { this._user = str; }
|
||||
set host(str) { this._host = str; }
|
||||
set password(str) { this._password = str; }
|
||||
set port(str) { this._port = str; }
|
||||
set database(str) { this._database = str; }
|
||||
}
|
||||
|
||||
|
||||
let Pool = (()=>{
|
||||
let pool = new MySQLPool();
|
||||
pool.user = config.db.user;
|
||||
pool.password = config.db.pass;
|
||||
pool.host = config.db.host;
|
||||
pool.port = config.db.port;
|
||||
pool.createPool();
|
||||
|
||||
return pool
|
||||
})()
|
||||
|
||||
module.exports = Pool;
|
||||
+14
-8
@@ -6,19 +6,25 @@ div#app {
|
||||
}
|
||||
|
||||
.login-grid {
|
||||
height: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.login-column {
|
||||
max-width: 450px;
|
||||
max-width: 450px;
|
||||
}
|
||||
|
||||
.clearfix:after {
|
||||
content: ".";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
content: ".";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.hide-element {
|
||||
display: 'none' !important;
|
||||
display: 'none' !important;
|
||||
}
|
||||
|
||||
.pointer {
|
||||
cursor: pointer !important;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+13
-8
@@ -74,8 +74,8 @@
|
||||
},
|
||||
"dio": {
|
||||
"title": {
|
||||
"di": "DigitInput",
|
||||
"do": "DigitOutput"
|
||||
"di": "DigitalInput",
|
||||
"do": "DigitalOutput"
|
||||
},
|
||||
"form": {
|
||||
"label": {
|
||||
@@ -255,7 +255,7 @@
|
||||
},
|
||||
"status": {
|
||||
"leone": "無回應(網路問題或是IP/密碼錯誤)",
|
||||
"digitinput": "觸發"
|
||||
"digitalinput": "觸發"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
@@ -270,7 +270,12 @@
|
||||
"iocmd": "IO CMD",
|
||||
"schedule": "排程控制",
|
||||
"modbus": "Modbus",
|
||||
"modbus_preview": "Modbus 總覽",
|
||||
"modbuscmd": "Modbus CMD",
|
||||
"modbuslog": "Modbus Log",
|
||||
"link": "連動",
|
||||
"ipcam": "網路攝影機",
|
||||
"wristband": "藍芽手環",
|
||||
"logout": "登出"
|
||||
}
|
||||
},
|
||||
@@ -338,17 +343,17 @@
|
||||
"sun": "週日"
|
||||
},
|
||||
"porttype": [
|
||||
{"code": "1", "name":"DigitOutput"},
|
||||
{"code": "2", "name":"DigitInput"},
|
||||
{"code": "3", "name":"AnalogyOutput"},
|
||||
{"code": "4", "name":"AnalogyInput"}
|
||||
{ "code": "1", "name": "DigitalOutput" },
|
||||
{ "code": "2", "name": "DigitalInput" },
|
||||
{ "code": "3", "name": "AnalogOutput" },
|
||||
{ "code": "4", "name": "AnalogInput" }
|
||||
],
|
||||
"select": {
|
||||
"select_action": "請選擇動作",
|
||||
"dev_type": "請選擇裝置類型",
|
||||
"dev_name": "請選擇裝置",
|
||||
"action": "請選擇動作",
|
||||
"digitoutput": "DigitOutput",
|
||||
"digitaloutput": "DigitalOutput",
|
||||
"leone": "LeOne",
|
||||
"iogroup": "IOGroup"
|
||||
}
|
||||
|
||||
+15
-2
@@ -2,8 +2,10 @@ const errList = require('../includes/errorManager');
|
||||
|
||||
function send(req, res) {
|
||||
if ('db' in res && typeof res.db == 'object' && 'close' in res.db && typeof res.db.close == 'function') res.db.close();
|
||||
if ('db' in res && typeof res.db == 'object' && 'release' in res.db && typeof res.db.release == 'function') res.db.release();
|
||||
|
||||
let lngs = req.headers['accept-language'].split(',');
|
||||
let lngs = req.headers['accept-language'] || '';
|
||||
lngs = lngs.split(',');
|
||||
let lng = null;
|
||||
if (lngs.length > 0) {
|
||||
lng = lngs[0].substring(0, 2);
|
||||
@@ -30,7 +32,18 @@ function send(req, res) {
|
||||
};
|
||||
}
|
||||
|
||||
if('sys_err' in res) {
|
||||
json.sys_err = res.sys_err
|
||||
}
|
||||
|
||||
res.send(json);
|
||||
}
|
||||
|
||||
module.exports = { send: send };
|
||||
const err = (res, err, n, code = null) => {
|
||||
if(process.env.NODE_ENV != 'production') res.sys_err = 'toString' in err && typeof err.toString == 'function' ? err.toString() : err;
|
||||
|
||||
if(!code) return n();
|
||||
return n(code);
|
||||
}
|
||||
|
||||
module.exports = { send, err };
|
||||
+14
-29
@@ -3,7 +3,7 @@ const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const fs = require('fs');
|
||||
const mysql = require('../../libs/mysql_cls');
|
||||
const mysql = require('../../libs/mysql_pool');
|
||||
const tool = require('../../includes/apiTool');
|
||||
const exec = require('child_process').exec;
|
||||
const so = require('../../includes/storeObject');
|
||||
@@ -13,6 +13,15 @@ router
|
||||
.get('/', (req, res) => {
|
||||
res.send({ name: 'WebIO DIO Api' });
|
||||
})
|
||||
.post('*', async(req,res,n) => {
|
||||
try{
|
||||
res.db = await mysql.getConn();
|
||||
}catch(e){
|
||||
console.log(`Get DB Connection ERROR ${e}`);
|
||||
return n('ERR8100');
|
||||
}
|
||||
n();
|
||||
})
|
||||
.post('/getio', (req, res, n) => {
|
||||
if (!config.permission.dio) return n('ERR9000');
|
||||
|
||||
@@ -65,7 +74,7 @@ router
|
||||
})
|
||||
.catch(e => n());
|
||||
})
|
||||
.post('/dotrun', (req, res, n) => {
|
||||
.post('/dotrun', (req, res, n) => {
|
||||
if (!config.permission.dio) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
@@ -77,14 +86,6 @@ router
|
||||
record: []
|
||||
};
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let obj = so.get(req.headers['x-auth-token']);
|
||||
let u = '';
|
||||
if (obj != null && 'user' in obj && 'account' in obj.user) u = obj.user.account;
|
||||
@@ -101,17 +102,9 @@ router
|
||||
});
|
||||
});
|
||||
})
|
||||
.post('/getdioinfo', (req, res, n) => {
|
||||
.post('/getdioinfo', (req, res, n) => {
|
||||
if (!config.permission.dio) return n('ERR9000');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let q = "select * from ??.??";
|
||||
let pdi = tool.promiseQuery(res, q, [config.db.db1, 'dilist'], 'di');
|
||||
let pdo = tool.promiseQuery(res, q, [config.db.db1, 'dolist'], 'do');
|
||||
@@ -132,7 +125,7 @@ router
|
||||
}
|
||||
return n();
|
||||
})
|
||||
.catch(e => n('ERR8000'));
|
||||
.catch(e => rt.err(res,e, n,'ERR8000'));
|
||||
})
|
||||
.post('/setdioinfo', (req,res,n) => {
|
||||
if(!config.permission.dio) return n('ERR9000');
|
||||
@@ -146,14 +139,6 @@ router
|
||||
record: []
|
||||
}
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "update ??.?? set ?? = unix_timestamp() , ";
|
||||
let sub = " ?? = case ?? ";
|
||||
let dos = [];
|
||||
@@ -192,7 +177,7 @@ router
|
||||
|
||||
Promise.all([pdi, pdo])
|
||||
.then(r => n())
|
||||
.catch(e => n('ERR8002'))
|
||||
.catch(e => rt.err(res,e,n,'ERR8002'))
|
||||
})
|
||||
.all('*', rt.send);
|
||||
|
||||
|
||||
+13
-4
@@ -2,6 +2,7 @@ const express = require('express');
|
||||
const router = express.Router();
|
||||
const errMng = require('../../includes/errorManager');
|
||||
const so = require('../../includes/storeObject');
|
||||
const mysql = require('../../libs/mysql_pool');
|
||||
|
||||
router
|
||||
.get('/', (req, res) => {
|
||||
@@ -30,22 +31,30 @@ router
|
||||
.use('/schedule', require('./schedule.js'))
|
||||
.use('/dio', require('./dio.js'))
|
||||
.use('/link', require('./link.js'))
|
||||
.use('/modbus', require('./modbus.js'));
|
||||
.use('/modbus', require('./modbus.js'))
|
||||
.use('/ipcam', require('./ipcam.js'))
|
||||
.use('/wristband', require('./wristband.js'));
|
||||
|
||||
// api error handler
|
||||
router.use((err, req, res, n) => {
|
||||
if ('db' in res && typeof res.db == 'object' && 'close' in res.db && typeof res.db.close == 'function') res.db.close();
|
||||
if ('db' in res && typeof res.db == 'object' && 'release' in res.db && typeof res.db.release == 'function') res.db.release();
|
||||
|
||||
let lngs = req.headers['accept-language'].split(',');
|
||||
let lngs = req.headers['accept-language'] || '';
|
||||
lngs = lngs.split(',');
|
||||
let lng = null;
|
||||
if (lngs.length > 0) {
|
||||
lng = lngs[0].substring(0, 2);
|
||||
}
|
||||
res.send({
|
||||
let json = {
|
||||
errorCode: (typeof err != 'string' ? err.toString() : err),
|
||||
message: errMng(err, lng),
|
||||
status: 0
|
||||
});
|
||||
};
|
||||
|
||||
if('sys_err' in res && process.env.NODE_ENV != 'production') json.sys_err = res.sys_err;
|
||||
|
||||
res.send(json);
|
||||
})
|
||||
|
||||
module.exports = router;
|
||||
+10
-10
@@ -2,7 +2,7 @@ const express = require('express');
|
||||
const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const mysql = require('../../libs/mysql_cls');
|
||||
const mysql = require('../../libs/mysql_pool');
|
||||
const tool = require('../../includes/apiTool');
|
||||
const exec = require('child_process').exec;
|
||||
const execSync = require('child_process').execSync;
|
||||
@@ -12,6 +12,15 @@ router
|
||||
.get('/', (req, res) => {
|
||||
res.send({ name: 'WebIO IOCmd API' });
|
||||
})
|
||||
.post('*', async(req,res,n) => {
|
||||
try{
|
||||
res.db = await mysql.getConn();
|
||||
}catch(e){
|
||||
console.log(`Get DB Connection ERROR ${e}`);
|
||||
return n('ERR8100');
|
||||
}
|
||||
n();
|
||||
})
|
||||
.post('/iocmd', (req, res, n) => {
|
||||
if (!config.permission.iocmd) return n('ERR9000');
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
@@ -30,15 +39,6 @@ router
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let dos = [];
|
||||
let les = [];
|
||||
let ios = [];
|
||||
|
||||
+15
-38
@@ -2,13 +2,22 @@ const express = require('express');
|
||||
const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const mysql = require('../../libs/mysql_cls');
|
||||
const mysql = require('../../libs/mysql_pool');
|
||||
const tool = require('../../includes/apiTool');
|
||||
|
||||
router
|
||||
.get('/', (req, res) => {
|
||||
res.send({ name: 'WebIO IOGroup API' });
|
||||
})
|
||||
.post('*', async(req,res,n) => {
|
||||
try{
|
||||
res.db = await mysql.getConn();
|
||||
}catch(e){
|
||||
console.log(`Get DB Connection ERROR ${e}`);
|
||||
return n('ERR8100');
|
||||
}
|
||||
n();
|
||||
})
|
||||
.post(['/getiogrouplist', '/getiogroup'], (req, res, n) => {
|
||||
if (!config.permission.iogroup) return n('ERR9000');
|
||||
let s = false;
|
||||
@@ -19,14 +28,6 @@ router
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
}
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select * from ??.?? ";
|
||||
let order = " order by `iogroupuid` desc ";
|
||||
let param = [config.db.db1, 'iogroup'];
|
||||
@@ -36,7 +37,7 @@ router
|
||||
}
|
||||
|
||||
res.db.query(query + order, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
if (err) return rt.err(res,err,n,'ERR8000');
|
||||
|
||||
let dos = [];
|
||||
let les = [];
|
||||
@@ -87,7 +88,7 @@ router
|
||||
return n();
|
||||
})
|
||||
.catch(err => {
|
||||
if (err) return n('ERR8000');
|
||||
if (err) return rt.err(res,err,n,'ERR8000');
|
||||
});
|
||||
});
|
||||
})
|
||||
@@ -99,19 +100,11 @@ router
|
||||
if (!arr.data.name) return n('ERR0026');
|
||||
if (!arr.data.devs) return n('ERR0029');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "insert into ??.?? (`iogroupname`,`iogroupid`,`iogroup_add_date`) values (?, ?, unix_timestamp())";
|
||||
let param = [config.db.db1, 'iogroup', arr.data.name, arr.data.devs];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8001');
|
||||
if (err) return rt.err(res,err,n,'ERR8001');
|
||||
|
||||
let data = {};
|
||||
data.record = [];
|
||||
@@ -128,14 +121,6 @@ router
|
||||
if (!arr.data.name) return n('ERR0026');
|
||||
if (!arr.data.devs) return n('ERR0029');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "update ??.?? set \
|
||||
`iogroupname` = ?, \
|
||||
`iogroupid` = ?, \
|
||||
@@ -144,7 +129,7 @@ router
|
||||
`iogroupuid` = ?";
|
||||
let param = [config.db.db1, 'iogroup', arr.data.name, arr.data.devs, arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8002');
|
||||
if (err) return rt.err(res,err,n,'ERR8002');
|
||||
|
||||
let data = {};
|
||||
data.record = [];
|
||||
@@ -159,18 +144,10 @@ router
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "delete from ??.?? where `iogroupuid` = ? ";
|
||||
let param = [config.db.db1, 'iogroup', arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8003');
|
||||
if (err) return rt.err(res,err,n,'ERR8003');
|
||||
|
||||
let data = {};
|
||||
data.record = [];
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const fs = require('fs');
|
||||
const mysql = require('../../libs/mysql_pool');
|
||||
const tool = require('../../includes/apiTool');
|
||||
const exec = require('child_process').exec;
|
||||
const so = require('../../includes/storeObject');
|
||||
const crypt = require('../../libs/crypto');
|
||||
|
||||
router
|
||||
.get('/', (req, res, n) => {
|
||||
res.send({ name: 'WebIO IPCam API' });
|
||||
})
|
||||
.post('*', async(req,res,n) => {
|
||||
try{
|
||||
res.db = await mysql.getConn();
|
||||
}catch(e){
|
||||
console.log(`Get DB Connection ERROR ${e}`);
|
||||
return n('ERR8100');
|
||||
}
|
||||
n();
|
||||
})
|
||||
.post('/getipcamlist', (req,res,n) => {
|
||||
if(!config.permission.ipcam) return n('ERR9000');
|
||||
|
||||
let query = "select * from ??.??";
|
||||
let param = [config.db.db1, 'ipcam'];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if(err) return rt.err(res,err,n,'ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
}
|
||||
|
||||
n();
|
||||
});
|
||||
})
|
||||
.post('/addipcam', (req,res,n) => {
|
||||
if(!config.permission.ipcam) return n('ERR9000');
|
||||
if(!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if(!arr.data) return n('ERR0000');
|
||||
if(!arr.data.ip) return n('ERR0010');
|
||||
if(!arr.data.name) return n('ERR0026');
|
||||
|
||||
if(!/^\d{1,3}\.\d{1,3}.\d{1,3}.\d{1,3}$/.test(arr.data.ip)) return n('ERR0025');
|
||||
|
||||
let query = "select count(*) as c from ??.?? where `ip` = ?";
|
||||
let param = [config.db.db1, 'ipcam', arr.data.ip];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if(err || row.length == 0) return rt.err(res,err,n,'ERR8000');
|
||||
if(row[0]['c'] > 0) return n('ERR0027');
|
||||
|
||||
let query = "insert into ??.?? (`name`, `ip`) values (?,?)";
|
||||
let param = [config.db.db1, 'ipcam', arr.data.name, arr.data.ip];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if(err) return rt.err(res,err,n,'ERR8001');
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
n();
|
||||
});
|
||||
});
|
||||
})
|
||||
.post('/delipcam', (req,res,n) => {
|
||||
if(!config.permission.ipcam) return n('ERR9000');
|
||||
if(!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if(!arr.data) return n('ERR0000');
|
||||
if(!arr.data.id) return n('ERR0028');
|
||||
|
||||
let query = "delete from ??.?? where `uid` = ?";
|
||||
let param = [config.db.db1, 'ipcam', arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if(err) return rt.err(res,err,n,'ERR8003');
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
n();
|
||||
})
|
||||
})
|
||||
.post('/editipcam', (req,res,n) => {
|
||||
if(!config.permission.ipcam) return n('ERR9000');
|
||||
if(!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if(!arr.data) return n('ERR0000');
|
||||
if(!arr.data.id) return n('ERR0028');
|
||||
if(!arr.data.name) return n('ERR0026');
|
||||
|
||||
let query = "update ??.?? set `name` = ? where `uid` = ?";
|
||||
let param = [config.db.db1, 'ipcam', arr.data.name, arr.data.id];
|
||||
res.db.query(query, param, (err,row) => {
|
||||
if(err) return rt.err(res,err,n,'ERR8002');
|
||||
res.api_res = {
|
||||
record: []
|
||||
}
|
||||
n();
|
||||
})
|
||||
})
|
||||
.all('*', rt.send);
|
||||
|
||||
module.exports = router;
|
||||
+22
-68
@@ -3,7 +3,7 @@ const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const fs = require('fs');
|
||||
const mysql = require('../../libs/mysql_cls');
|
||||
const mysql = require('../../libs/mysql_pool');
|
||||
const tool = require('../../includes/apiTool');
|
||||
const exec = require('child_process').exec;
|
||||
|
||||
@@ -11,6 +11,15 @@ router
|
||||
.get('/', (req, res) => {
|
||||
res.send({name: 'WebIO Leone API'});
|
||||
})
|
||||
.post('*', async(req,res,n) => {
|
||||
try{
|
||||
res.db = await mysql.getConn();
|
||||
}catch(e){
|
||||
console.log(`Get DB Connection ERROR ${e}`);
|
||||
return n('ERR8100');
|
||||
}
|
||||
n();
|
||||
})
|
||||
.post('/scanleone', (req, res, n) => {
|
||||
if (!config.permission.leone) return n('ERR9000');
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
@@ -38,18 +47,11 @@ router
|
||||
! function chkEnd() {
|
||||
fs.exists(config.cmdpath.scanleone_end, exists => {
|
||||
if (exists) {
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select `leonename`, `leoneip`, `leonelistuid` from ??.?? where `temporary` = '1' ";
|
||||
let param = [config.db.db1, 'leonelist'];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
if (err) return rt.err(res,err,n,'ERR8000');
|
||||
|
||||
let data = {};
|
||||
data.record = tool.checkArray(row);
|
||||
@@ -73,14 +75,6 @@ router
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
}
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select * from ??.?? where `temporary` = '0' ";
|
||||
let param = [config.db.db1, 'leonelist'];
|
||||
if (s) {
|
||||
@@ -89,7 +83,7 @@ router
|
||||
}
|
||||
let order = " order by `leonelistuid` desc ";
|
||||
res.db.query(query + order, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
if (err) return rt.err(res,err,n,'ERR8000');
|
||||
|
||||
tool.getLeoneRT(rts => {
|
||||
let data = {};
|
||||
@@ -110,30 +104,22 @@ router
|
||||
if (!arr.data.ip) return n('ERR0010');
|
||||
if (!arr.data.password) return n('ERR0017');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select count(*) as num from ??.?? where `temporary` = '0' ";
|
||||
let param = [config.db.db1, 'leonelist'];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err || row.length == 0) return n('ERR8000');
|
||||
if (row[0].num >= config.leone_limit) return n('ERR0048');
|
||||
if (err || row.length == 0) return rt.err(res,err,n,'ERR8000');
|
||||
if (row[0].num >= config.leone_limit) return n('ERR0056');
|
||||
|
||||
let query = "select count(*) from ??.?? where `leoneip` = ? ";
|
||||
let p = [...param, arr.data.ip];
|
||||
res.db.query(query, p, (err, row) => {
|
||||
if (err || row.length == 0) return n('ERR8000');
|
||||
if (err || row.length == 0) return rt.err(res,err,n,'ERR8000');
|
||||
if (row[0].num > 0) return n('ERR0027');
|
||||
|
||||
let query = "insert into ??.?? (`leoneip`,`leonename`,`leonepassword`,`leone_add_date`,`leone_modify_date`) values (?,?,?,unix_timestamp(),unix_timestamp())";
|
||||
let p = [...param, arr.data.ip, arr.data.name, arr.data.password];
|
||||
res.db.query(query, p, (err, row) => {
|
||||
if (err) return n('ERR8001');
|
||||
if (err) return rt.err(res,err,n,'ERR8001');
|
||||
|
||||
let data = {};
|
||||
data.record = [];
|
||||
@@ -150,18 +136,10 @@ router
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "delete from ??.?? where `leonelistuid` = ? ";
|
||||
let param = [config.db.db1, 'leonelist', arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8003');
|
||||
if (err) return rt.err(res,err,n,'ERR8003');
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
@@ -177,14 +155,6 @@ router
|
||||
if (!arr.data.name) return n("ERR0026");
|
||||
if (!arr.data.password) return n('ERR0017');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "update ??.?? set \
|
||||
`leonename` = ?,\
|
||||
`leonepassword` = ?,\
|
||||
@@ -193,7 +163,7 @@ router
|
||||
`leonelistuid` = ? ";
|
||||
let param = [config.db.db1, 'leonelist', arr.data.name, arr.data.password, arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8002');
|
||||
if (err) return rt.err(res,err,n,'ERR8002');
|
||||
|
||||
let data = {};
|
||||
data.record = [];
|
||||
@@ -202,7 +172,7 @@ router
|
||||
let query = "select * from ??.?? where `leonelistuid` = ? ";
|
||||
let param = [config.db.db1, 'leonelist', arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n();
|
||||
if (err) return rt.err(res,err,n);
|
||||
if (row.length == 0) return n();
|
||||
|
||||
let { leoneip, leonename, leonepassword } = row[0];
|
||||
@@ -220,14 +190,6 @@ router
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id || !Array.isArray(arr.data.id)) return n('ERR0028');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let ids = [];
|
||||
for (var i in arr.data.id) {
|
||||
let t = arr.data.id[i];
|
||||
@@ -245,12 +207,12 @@ router
|
||||
let query = "select count(*) as num from ??.?? where `temporary` = '0' or `leonelistuid` in (?)";
|
||||
let param = [config.db.db1, 'leonelist', ids];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err || row.length == 0) return n('ERR8000');
|
||||
if (row[0].num >= config.leone_limit) return n('ERR0048');
|
||||
if (err || row.length == 0) return rt.err(res,err,n,'ERR8000');
|
||||
if (row[0].num >= config.leone_limit) return n('ERR0056');
|
||||
|
||||
let query = "update ??.?? set `temporary` = '0', `leone_modify_date` = unix_timestamp() where `leonelistuid` in (?)";
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8002');
|
||||
if (err) return rt.err(res,err,n,'ERR8002');
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
@@ -262,14 +224,6 @@ router
|
||||
if (!config.permission.leone) return n('ERR9000');
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "delete from ??.?? where `temporary` = '1'";
|
||||
let param = [config.db.db1, 'leonelist'];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
|
||||
+19
-49
@@ -2,24 +2,25 @@ const express = require('express');
|
||||
const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const mysql = require('../../libs/mysql_cls');
|
||||
const mysql = require('../../libs/mysql_pool');
|
||||
const tool = require('../../includes/apiTool');
|
||||
|
||||
router
|
||||
.get('/', (req, res) => {
|
||||
res.send({ name: 'WebIO Link API' });
|
||||
})
|
||||
.post('*', async(req,res,n) => {
|
||||
try{
|
||||
res.db = await mysql.getConn();
|
||||
}catch(e){
|
||||
console.log(`Get DB Connection ERROR ${e}`);
|
||||
return n('ERR8100');
|
||||
}
|
||||
n();
|
||||
})
|
||||
.post('/getlinklist', (req, res, n) => {
|
||||
if (!config.permission.link) return n('ERR9000');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db8;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select * from ??.?? \
|
||||
where \
|
||||
`jcioclntuid` not in ( \
|
||||
@@ -35,7 +36,7 @@ router
|
||||
let param = [config.db.db8, 'jcioclnt', config.db.db8, 'jcioclnt', config.db.db8, 'jcioclnt'];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
if (err) return rt.err(res,err,n,'ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
@@ -50,14 +51,6 @@ router
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db8;
|
||||
res.db.connect();
|
||||
|
||||
res.api_res = {
|
||||
record: [{ root: arr.data.id }],
|
||||
rt: {
|
||||
@@ -70,7 +63,7 @@ router
|
||||
let param = [config.db.db8, 'getLink', arr.data.id];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err || row.length == 0) return n('ERR8000');
|
||||
if (err || row.length == 0) return rt.err(res,err,n,'ERR8000');
|
||||
|
||||
let ids = row[0].ids;
|
||||
let id = ids.split(',');
|
||||
@@ -111,7 +104,7 @@ router
|
||||
}
|
||||
return n();
|
||||
})
|
||||
.catch(err => n('ERR8000'));
|
||||
.catch(err => rt.err(res,err,n,'ERR8000'));
|
||||
});
|
||||
})
|
||||
.post('/addlink', (req, res, n) => {
|
||||
@@ -119,18 +112,10 @@ router
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.link || Object.keys(arr.data.link).length == 0) return n('ERR0049');
|
||||
if (!arr.data.link || Object.keys(arr.data.link).length == 0) return n('ERR0057');
|
||||
if (!('active' in arr.data)) return n('ERR0032');
|
||||
if (!arr.data.action) return n('ERR0030');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db8;
|
||||
res.db.connect();
|
||||
|
||||
! function runLoop(unit, cb) {
|
||||
if (typeof unit != 'object' || Object.keys(unit).length == 0) return cb(0);
|
||||
if (unit.type == 'ln') {
|
||||
@@ -188,7 +173,7 @@ router
|
||||
let param = [config.db.db8, 'jcioclnt', (arr.data.active == 1 ? 1 : 0), arr.data.action, id.substr(2)];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8002');
|
||||
if (err) return rt.err(res,err,n,'ERR8002');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
@@ -204,14 +189,6 @@ router
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db8;
|
||||
res.db.connect();
|
||||
|
||||
let query = "update ??.?? set \
|
||||
`lnactive` = (case when `lnactive` = 1 then 0 else 1 end), \
|
||||
`lnmodtst` = unix_timestamp() \
|
||||
@@ -220,7 +197,7 @@ router
|
||||
let param = [config.db.db8, 'jcioclnt', arr.data.id];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8002');
|
||||
if (err) return rt.err(res,err,n,'ERR8002');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
@@ -237,19 +214,11 @@ router
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db8;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select ??.??(?) as ids";
|
||||
let param = [config.db.db8, 'getLink', arr.data.id];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err || row.length == 0) return n('ERR8000');
|
||||
if (err || row.length == 0) return rt.err(res,err,n,'ERR8000');
|
||||
let ids = row[0].ids;
|
||||
let id = ids.split(',');
|
||||
id.splice(0, 1);
|
||||
@@ -258,6 +227,7 @@ router
|
||||
if (t != '') return t;
|
||||
});
|
||||
|
||||
res.db.query(`use ${config.db.db8}`);
|
||||
let query = "delete c,n from ??.?? n \
|
||||
left join ??.?? c \
|
||||
on \
|
||||
@@ -273,7 +243,7 @@ router
|
||||
n.`jcioclntuid` in (?)";
|
||||
let param = [config.db.db8, 'jcioclnt', config.db.db7, 'jcioclct', ida];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8003');
|
||||
if (err) return rt.err(res,err,n,'ERR8003');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
|
||||
+13
-12
@@ -2,37 +2,38 @@ const express = require('express');
|
||||
const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const mysql = require('../../libs/mysql_cls');
|
||||
const mysql = require('../../libs/mysql_pool');
|
||||
const tool = require('../../includes/apiTool');
|
||||
|
||||
router
|
||||
.get('/', (req, res) => {
|
||||
res.send({ name: 'WebIO Log API' })
|
||||
})
|
||||
.post('*', async(req,res,n) => {
|
||||
try{
|
||||
res.db = await mysql.getConn();
|
||||
}catch(e){
|
||||
console.log(`Get DB Connection ERROR ${e}`);
|
||||
return n('ERR8100');
|
||||
}
|
||||
n();
|
||||
})
|
||||
.post('/getlog', (req, res, n) => {
|
||||
if(!config.permission.log) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
let p = arr.data && arr.data.p && isFinite(arr.data.p) && arr.data.p > 0 ? arr.data.p : 1;
|
||||
let per = arr.data && arr.data.perpage && isFinite(arr.data.perpage) && arr.data.perpage > 0 ? arr.data.perpage : config.perpage;
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db2;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select count(*) as num from ??.??";
|
||||
let param = [config.db.db2, 'jciocert'];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if(err || row.length == 0) return n('ERR0023');
|
||||
let page = res.db.recordPage(row[0].num, p, per);
|
||||
if(err || row.length == 0) return rt.err(res,err,n,'ERR0023');
|
||||
let page = mysql.recordPage(row[0].num, p, per);
|
||||
|
||||
let query = "select * from ??.?? order by `ioeventtst` desc ";
|
||||
let limit = ` limit ${page.rec_start} , ${per} `;
|
||||
res.db.query(query + limit, param, (err, row) => {
|
||||
if(err) return n('ERR8000');
|
||||
if(err) return rt.err(res,err,n,'ERR8000');
|
||||
let data = {};
|
||||
data.page = page;
|
||||
data.record = tool.checkArray(row);
|
||||
|
||||
+262
-162
@@ -2,33 +2,32 @@ const express = require('express');
|
||||
const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const fs = require('fs');
|
||||
const mysql = require('../../libs/mysql_cls');
|
||||
const mysql = require('../../libs/mysql_pool');
|
||||
const tool = require('../../includes/apiTool');
|
||||
const exec = require('child_process').exec;
|
||||
const so = require('../../includes/storeObject');
|
||||
const crypt = require('../../libs/crypto');
|
||||
|
||||
router
|
||||
.get('/', (req, res) => {
|
||||
res.send({ name: 'WebIO Modbus API' });
|
||||
})
|
||||
.post('*', async(req, res, n) => {
|
||||
try {
|
||||
res.db = await mysql.getConn();
|
||||
} catch (e) {
|
||||
console.log(`Get DB Connection ERROR ${e}`);
|
||||
return n('ERR8100');
|
||||
}
|
||||
n();
|
||||
})
|
||||
.post('/getmodbuslist', (req, res, n) => {
|
||||
if (!config.permission.modbus) return n('ERR9000');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select * from ??.?? order by `uid` desc";
|
||||
let param = [config.db.db5, 'device'];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
if (err) return rt.err(res, err, n, 'ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
@@ -44,19 +43,11 @@ router
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select * from ??.?? where `uid` = ?";
|
||||
let param = [config.db.db5, 'device', arr.data.id];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err || row.length == 0) return n('ERR8000');
|
||||
if (err || row.length == 0) return rt.err(res, err, n, 'ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row),
|
||||
@@ -89,25 +80,17 @@ router
|
||||
}
|
||||
return n();
|
||||
})
|
||||
.catch(err => n('ERR8000'));
|
||||
.catch(err => rt.err(res, err, n, 'ERR8000'));
|
||||
});
|
||||
})
|
||||
.post('/getporttype', (req, res, n) => {
|
||||
if (!config.permission.modbus) return n('ERR9000');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select * from ??.?? order by `uid` ";
|
||||
let param = [config.db.db5, 'porttype'];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
if (err) return rt.err(res, err, n, 'ERR8000');
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
};
|
||||
@@ -122,23 +105,17 @@ router
|
||||
if (!arr.data.name) return n('ERR0026');
|
||||
if (!('node' in arr.data)) return n('ERR0038');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
let type = arr.data.type && isFinite(arr.data.type) ? arr.data.type : 0;
|
||||
|
||||
let u = '';
|
||||
let obj = so.get(req.headers['x-auth-token']);
|
||||
if (obj != null && 'user' in obj && 'account' in obj.user) u = obj.user.account;
|
||||
|
||||
let query = "insert into ??.?? (`name`, `node`, `adduser`, `moduser`, `ctime`, `mtime`) values (?,?,?,?, unix_timestamp(), unix_timestamp())";
|
||||
let param = [config.db.db5, 'device', arr.data.name, arr.data.node, u, u];
|
||||
let query = "insert into ??.?? (`name`, `node`, `type`, `adduser`, `moduser`, `ctime`, `mtime`) values (?,?,?,?,?, unix_timestamp(), unix_timestamp())";
|
||||
let param = [config.db.db5, 'device', arr.data.name, arr.data.node, type, u, u];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8001');
|
||||
if (err) return rt.err(res, err, n, 'ERR8001');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
@@ -156,18 +133,12 @@ router
|
||||
if (!arr.data.name) return n('ERR0026');
|
||||
if (!('node' in arr.data) || !('original_node' in arr.data)) return n('ERR0038');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
let type = arr.data.type && isFinite(arr.data.type) ? arr.data.type : 0;
|
||||
|
||||
let query = "select count(*) as num from ??.?? where `node` = ? and `uid` != ?";
|
||||
let param = [config.db.db5, 'device', arr.data.node, arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err || row.length == 0) return n('ERR8000');
|
||||
if (err || row.length == 0) return rt.err(res, err, n, 'ERR8000');
|
||||
if (row[0].num > 0) return n('ERR0047');
|
||||
|
||||
let u = '';
|
||||
@@ -177,13 +148,14 @@ router
|
||||
let query = "update ??.?? set \
|
||||
`name` = ?, \
|
||||
`node` = ?, \
|
||||
`type` = ?, \
|
||||
`moduser` = ?, \
|
||||
`mtime` = unix_timestamp() \
|
||||
where \
|
||||
`uid` = ?";
|
||||
let param = [config.db.db5, 'device', arr.data.name, arr.data.node, u, arr.data.id];
|
||||
let param = [config.db.db5, 'device', arr.data.name, arr.data.node, type, u, arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8002');
|
||||
if (err) return rt.err(res, err, n, 'ERR8002');
|
||||
|
||||
let q = "delete from ??.?? where `node` in (?)";
|
||||
let p = [config.db.db6, 'jcmbrt', [arr.data.node, arr.data.original_node]];
|
||||
@@ -204,13 +176,7 @@ router
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
res.db.query(`use ${config.db.db5}`);
|
||||
|
||||
let query = "delete d,i,s,rt from ??.?? d \
|
||||
left join ??.?? i \
|
||||
@@ -223,7 +189,7 @@ router
|
||||
d.`uid` = ?";
|
||||
let param = [config.db.db5, 'device', config.db.db5, 'iolist', config.db.db5, 'aioset', config.db.db6, 'jcmbrt', arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8003');
|
||||
if (err) return rt.err(res, err, n, 'ERR8003');
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
@@ -237,27 +203,24 @@ router
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
if (!arr.data.type) return n('ERR0009');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select rt.* from ??.?? rt \
|
||||
let query = "select rt.*, a.`name` as name from ??.?? rt \
|
||||
left join ??.?? d \
|
||||
on d.`node` = rt.`node` \
|
||||
left join ??.?? i \
|
||||
on i.`devuid` = d.`uid` and i.`type` = ? \
|
||||
left join ??.?? a \
|
||||
on a.`iouid` = i.`uid` \
|
||||
and a.`portnum` = rt.`port`\
|
||||
where \
|
||||
d.`uid` = ? \
|
||||
and rt.`type` = ? \
|
||||
and i.`uid` is not null ";
|
||||
let param = [config.db.db6, 'jcmbrt', config.db.db5, 'device', config.db.db5, 'iolist', arr.data.type, arr.data.id, arr.data.type];
|
||||
and i.`uid` is not null \
|
||||
and ( a.`name` is not null or rt.`type` in (1,2)) \
|
||||
order by rt.`port` asc";
|
||||
let param = [config.db.db6, 'jcmbrt', config.db.db5, 'device', config.db.db5, 'iolist', arr.data.type, config.db.db5, 'aioset', arr.data.id, arr.data.type];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
if (err) return rt.err(res, err, n, 'ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
@@ -265,24 +228,65 @@ router
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/getalliostatus', (req, res, n) => {
|
||||
if (!config.permission.modbus) return n('ERR9000');
|
||||
|
||||
let pros = [];
|
||||
|
||||
let query = "select rt.*, a.`name` as name \
|
||||
from ??.?? rt \
|
||||
left join ??.?? d \
|
||||
on d.`node` = rt.`node` \
|
||||
left join ??.?? i \
|
||||
on i.`devuid` = d.`uid` \
|
||||
and i.`type` = rt.`type` \
|
||||
left join ??.?? a \
|
||||
on a.`iouid` = i.`uid` \
|
||||
and a.`portnum` = rt.`port`\
|
||||
where \
|
||||
i.`uid` is not null \
|
||||
and ( a.`name` is not null or rt.`type` in (1,2)) \
|
||||
order by rt.`type` asc, rt.`port` asc";
|
||||
let param = [config.db.db6, 'jcmbrt', config.db.db5, 'device', config.db.db5, 'iolist', config.db.db5, 'aioset'];
|
||||
|
||||
pros.push(tool.promiseQuery(res, query, param, 'record'));
|
||||
|
||||
let rtq = "select * from ??.?? ";
|
||||
let rtp = [config.db.db5, 'device'];
|
||||
|
||||
pros.push(tool.promiseQuery(res, rtq, rtp, 'rt'));
|
||||
|
||||
res.api_res = {
|
||||
record: [],
|
||||
rt: {
|
||||
device: []
|
||||
}
|
||||
}
|
||||
|
||||
Promise.all(pros)
|
||||
.then(d => {
|
||||
for (let i in d) {
|
||||
if (d[i].key == 'record') {
|
||||
res.api_res.record = tool.checkArray(d[i].data);
|
||||
}
|
||||
if (d[i].key == 'rt') {
|
||||
res.api_res.rt.device = tool.checkArray(d[i].data);
|
||||
}
|
||||
}
|
||||
n();
|
||||
})
|
||||
.catch(err => rt.err(res, err, n, 'ERR8000'));
|
||||
})
|
||||
.post('/getiolist', (req, res, n) => {
|
||||
if (!config.permission.modbus) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select * from ??.?? where `uid` = ? ";
|
||||
let param = [config.db.db5, 'iolist', arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
if (err) return rt.err(res, err, n, 'ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
@@ -301,13 +305,7 @@ router
|
||||
if (!arr.data.addr) return n('ERR0048');
|
||||
if (!arr.data.num) return n('ERR0049');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
let dlen = arr.data.datalen || 2;
|
||||
|
||||
let query = "select count(*) as c from ??.?? \
|
||||
where \
|
||||
@@ -316,14 +314,14 @@ router
|
||||
and `addr` = ?";
|
||||
let param = [config.db.db5, 'iolist', arr.data.id, arr.data.type, arr.data.addr];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err || row.length == 0) return n('ERR8000');
|
||||
if (err || row.length == 0) return rt.err(res, err, n, 'ERR8000');
|
||||
|
||||
if (row[0].c > 0) return n('ERR0054');
|
||||
|
||||
let query = "insert into ??.?? (`devuid`,`type`,`addr`,`num`,`ctime`,`mtime`) values (?, ?, ?, ?, unix_timestamp(), unix_timestamp())";
|
||||
let param = [config.db.db5, 'iolist', arr.data.id, arr.data.type, arr.data.addr, arr.data.num];
|
||||
let query = "insert into ??.?? (`devuid`,`type`,`addr`,`num`,`datalen`,`ctime`,`mtime`) values (?, ?, ?, ?, ?, unix_timestamp(), unix_timestamp())";
|
||||
let param = [config.db.db5, 'iolist', arr.data.id, arr.data.type, arr.data.addr, arr.data.num, dlen];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8001');
|
||||
if (err) return rt.err(res, err, n, 'ERR8001');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
@@ -341,15 +339,9 @@ router
|
||||
if (!arr.data.addr) return n('ERR0048');
|
||||
if (!arr.data.num) return n('ERR0049');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
let dlen = arr.data.datalen || 2;
|
||||
|
||||
let query = "select count(*) sa c from ??.?? i \
|
||||
let query = "select count(*) as c from ??.?? i \
|
||||
left join ??.?? i2 \
|
||||
on i2.`type` = i.`type` \
|
||||
and i2.`addr` = ? \
|
||||
@@ -360,18 +352,19 @@ router
|
||||
and i2.`uid` is not null ";
|
||||
let param = [config.db.db5, 'iolist', config.db.db5, 'iolist', arr.data.addr, arr.data.id, arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err || row.length == 0) return n('ERR8000');
|
||||
if (err || row.length == 0) return rt.err(res, err, n, 'ERR8000');
|
||||
if (row[0].c > 0) return n('ERR0054');
|
||||
|
||||
let q = "update ??.?? set \
|
||||
`addr` = ?, \
|
||||
`num` = ?, \
|
||||
`datalen` = ?, \
|
||||
`mtime` = unix_timestamp() \
|
||||
where \
|
||||
`uid` = ?";
|
||||
let p = [config.db.db5, 'iolist', arr.data.addr, arr.data.num, arr.data.id];
|
||||
let p = [config.db.db5, 'iolist', arr.data.addr, arr.data.num, dlen, arr.data.id];
|
||||
res.db.query(q, p, (err, row) => {
|
||||
if (err) return n('ERR8002');
|
||||
if (err) return rt.err(res, err, n, 'ERR8002');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
@@ -387,13 +380,7 @@ router
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
res.db.query(`use ${config.db.db5}`);
|
||||
|
||||
let query = "delete i, a from ??.?? i \
|
||||
left join ??.?? a \
|
||||
@@ -402,7 +389,7 @@ router
|
||||
i.`uid` = ?";
|
||||
let param = [config.db.db5, 'iolist', config.db.db5, 'aioset', arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8003');
|
||||
if (err) return rt.err(res, err, n, 'ERR8003');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
@@ -416,14 +403,6 @@ router
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select a.* from ??.?? a \
|
||||
left join ??.?? i \
|
||||
on a.`iouid` = i.`uid` \
|
||||
@@ -431,7 +410,7 @@ router
|
||||
i.`uid` = ?";
|
||||
let param = [config.db.db5, 'aioset', config.db.db5, 'iolist', arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
if (err) return rt.err(res, err, n, 'ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
@@ -445,18 +424,10 @@ router
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select * from ??.?? where `uid` = ?";
|
||||
let param = [config.db.db5, 'aioset', arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
if (err) return rt.err(res, err, n, 'ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
@@ -471,18 +442,10 @@ router
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
|
||||
let query = "delete from ??.?? where `uid` = ?";
|
||||
let param = [config.db.db5, 'aioset', arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8003');
|
||||
if (err) return rt.err(res, err, n, 'ERR8003');
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
@@ -497,31 +460,24 @@ router
|
||||
if (!arr.data.iouid) return n('ERR0028');
|
||||
if (!arr.data.name) return n('ERR0026');
|
||||
if (!('portnum' in arr.data)) return n('ERR0048');
|
||||
if (!('type' in arr.data)) return n('ERR0009');
|
||||
if (!('range_min' in arr.data)) return n('ERR0050');
|
||||
if (!('range_max' in arr.data)) return n('ERR0051');
|
||||
if (!('scale_min' in arr.data)) return n('ERR0052');
|
||||
if (!('scale_max' in arr.data)) return n('ERR0053');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select count(*) as count from ??.?? where `iouid` = ? and `portnum` = ?";
|
||||
let param = [config.db.db5, 'aioset', arr.data.iouid, arr.data.portnum];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err || row.length == 0) return n('ERR8000');
|
||||
if (err || row.length == 0) return rt.err(res, err, n, 'ERR8000');
|
||||
|
||||
if (row[0].count > 0) return n('ERR0054');
|
||||
|
||||
let q = "insert into ??.?? (`iouid`, `name`, `portnum`, `range_min`, `range_max`, `scale_min`, `scale_max`, `ctime`, `mtime`) values \
|
||||
(?, ?, ?, ?, ?, ?, ?, unix_timestamp(), unix_timestamp())";
|
||||
let p = [config.db.db5, 'aioset', arr.data.iouid, arr.data.name, arr.data.portnum, arr.data.range_min, arr.data.range_max, arr.data.scale_min, arr.data.scale_max];
|
||||
let q = "insert into ??.?? (`iouid`, `name`, `portnum`, `type`, `range_min`, `range_max`, `scale_min`, `scale_max`, `ctime`, `mtime`) values \
|
||||
(?, ?, ?, ?, ?, ?, ?, ?, unix_timestamp(), unix_timestamp())";
|
||||
let p = [config.db.db5, 'aioset', arr.data.iouid, arr.data.name, arr.data.portnum, arr.data.type, arr.data.range_min, arr.data.range_max, arr.data.scale_min, arr.data.scale_max];
|
||||
res.db.query(q, p, (err, row) => {
|
||||
if (err) return n('ERR8001');
|
||||
if (err) return rt.err(res, err, n, 'ERR8001');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
@@ -539,20 +495,13 @@ router
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
if (!arr.data.iouid) return n('ERR0028');
|
||||
if (!arr.data.name) return n('ERR0026');
|
||||
if (!arr.data.portnum) return n('ERR0048');
|
||||
if (!('portnum' in arr.data)) return n('ERR0048');
|
||||
if (!('type' in arr.data)) return n('ERR0009');
|
||||
if (!('range_min' in arr.data)) return n('ERR0050');
|
||||
if (!('range_max' in arr.data)) return n('ERR0051');
|
||||
if (!('scale_min' in arr.data)) return n('ERR0052');
|
||||
if (!('scale_max' in arr.data)) return n('ERR0053');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db5;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select count(*) as count from ??.?? \
|
||||
where \
|
||||
`iouid` = ? \
|
||||
@@ -560,21 +509,22 @@ router
|
||||
and `uid` != ?";
|
||||
let param = [config.db.db5, 'aioset', arr.data.iouid, arr.data.portnum, arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err || row.length == 0) return n('ERR8000');
|
||||
if (err || row.length == 0) return rt.err(res, err, n, 'ERR8000');
|
||||
if (row[0].length > 0) return n('ERR0054');
|
||||
|
||||
let query = "update ??.?? set \
|
||||
`name` = ?, \
|
||||
`portnum` = ?, \
|
||||
`type` = ?, \
|
||||
`range_min` = ?, \
|
||||
`range_max` = ?, \
|
||||
`scale_min` = ?, \
|
||||
`scale_max` = ?, \
|
||||
`mtime` = unix_timestamp() \
|
||||
where `uid` = ?";
|
||||
let param = [config.db.db5, 'aioset', arr.data.name, arr.data.portnum, arr.data.range_min, arr.data.range_max, arr.data.scale_min, arr.data.scale_max, arr.data.id];
|
||||
let param = [config.db.db5, 'aioset', arr.data.name, arr.data.portnum, arr.data.type, arr.data.range_min, arr.data.range_max, arr.data.scale_min, arr.data.scale_max, arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8002');
|
||||
if (err) return rt.err(res, err, n, 'ERR8002');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
@@ -583,6 +533,156 @@ router
|
||||
});
|
||||
});
|
||||
})
|
||||
.post('/modbuscmd', (req, res, n) => {
|
||||
if (!config.permission.modbus) return n('ERR9000');
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.ip) return n('ERR0010');
|
||||
if (!('node' in arr.data) || arr.data.node.length == 0) return n('ERR0038');
|
||||
if (!('func' in arr.data) || arr.data.func.length == 0) return n('ERR0055');
|
||||
if (!('addr' in arr.data) || arr.data.addr.length == 0) return n('ERR0048');
|
||||
if (!('value' in arr.data) || arr.data.value.length == 0) return n('ERR0049');
|
||||
if (arr.data.value > 65535) return n('ERR0049');
|
||||
|
||||
let cmd = `mbtcpm ${arr.data.ip} ${arr.data.node} ${arr.data.func} ${arr.data.addr} ${arr.data.value}`;
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
exec(cmd, (err, stdout, stderr) => {
|
||||
let msg = err ? err.toString() : `${stdout}${stderr}`;
|
||||
res.api_res.record.push({ msg });
|
||||
|
||||
n();
|
||||
})
|
||||
})
|
||||
.post('/getmodbuslog', (req, res, n) => {
|
||||
if (!config.permission.modbus) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.ids || !Array.isArray(arr.data.ids)) return n('ERR0028');
|
||||
if (!arr.data.stime || !arr.data.etime) return n('ERR0015');
|
||||
|
||||
let query = "select log.`node`, log.`type`, log.`port`, log.`value2` as value, log.`tst`, dev.`name` as devname, aio.`name` as aioname \
|
||||
from ??.?? log \
|
||||
left join ??.?? dev \
|
||||
on dev.`node` = log.`node`\
|
||||
left join ??.?? io \
|
||||
on io.`devuid` = dev.`uid` \
|
||||
and io.`type` = log.`type` \
|
||||
left join ??.?? aio \
|
||||
on aio.`iouid` = io.`uid` \
|
||||
and aio.`portnum` = log.`port` \
|
||||
where \
|
||||
dev.`uid` in (?) \
|
||||
and ( log.`tst` >= ? \
|
||||
and log.`tst` <= ? ) \
|
||||
and io.`uid` is not null \
|
||||
and ( aio.`name` is not null or log.`type` in (1,2)) \
|
||||
order by log.`uid` desc, log.`tst` desc \
|
||||
limit 0, 100";
|
||||
let param = [config.db.db10, 'jcmbrt', config.db.db5, 'device', config.db.db5, 'iolist', config.db.db5, 'aioset', arr.data.ids, arr.data.stime, arr.data.etime];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return rt.err(res, err, n, 'ERR8000');
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
}
|
||||
n();
|
||||
})
|
||||
})
|
||||
.post('/getmodbustype', (req, res, n) => {
|
||||
if (!config.permission.modbus) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
let query = "select io.`type` \
|
||||
from ??.?? io \
|
||||
left join ??.?? dev \
|
||||
on dev.`uid` = io.`devuid` \
|
||||
where \
|
||||
dev.`uid` = ? \
|
||||
group by io.`type` \
|
||||
order by io.`type` ";
|
||||
let param = [config.db.db5, 'iolist', config.db.db5, 'device', arr.data.id];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return rt.err(res, err, n, 'ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
}
|
||||
|
||||
n();
|
||||
})
|
||||
})
|
||||
.post('/getmodbusport', (req, res, n) => {
|
||||
if (!config.permission.modbus) return n('ERR9000')
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
if (!arr.data.type) return n('ERR0009');
|
||||
|
||||
let type = arr.data.type;
|
||||
if (type == 5) type = 1;
|
||||
if (type == 6) type = 3;
|
||||
|
||||
if (type == 3 || type == 4) {
|
||||
let query = "select a.`name`, a.`portnum` \
|
||||
from ??.?? a \
|
||||
left join ??.?? io \
|
||||
on io.`uid` = a.`iouid` \
|
||||
left join ??.?? dev \
|
||||
on dev.`uid` = io.`devuid` \
|
||||
where \
|
||||
io.`type` = ? \
|
||||
and dev.`uid` = ? ";
|
||||
let param = [config.db.db5, 'aioset', config.db.db5, 'iolist', config.db.db5, 'device', type, arr.data.id];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return rt.err(res, err, n, 'ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
}
|
||||
|
||||
n();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == 1 || type == 2) {
|
||||
let query = "select * \
|
||||
from ??.?? io \
|
||||
left join ??.?? dev \
|
||||
on dev.`uid` = io.`devuid` \
|
||||
where \
|
||||
dev.`uid` = ? \
|
||||
and io.`type` = ?";
|
||||
let param = [config.db.db5, 'iolist', config.db.db5, 'device', arr.data.id, type];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return rt.err(res, err, n, 'ERR8000');
|
||||
let arr = [];
|
||||
let num = 0;
|
||||
for (let i in row) {
|
||||
num += parseInt(row[i].num);
|
||||
}
|
||||
for (let i = 0; i < num; i++) {
|
||||
arr.push({ portnum: (i + 1), name: '' })
|
||||
}
|
||||
|
||||
res.api_res = {
|
||||
record: arr
|
||||
}
|
||||
n();
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
return n('ERR0009');
|
||||
})
|
||||
.all('*', rt.send);
|
||||
|
||||
module.exports = router;
|
||||
+16
-47
@@ -3,7 +3,7 @@ const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const fs = require('fs');
|
||||
const mysql = require('../../libs/mysql_cls');
|
||||
const mysql = require('../../libs/mysql_pool');
|
||||
const tool = require('../../includes/apiTool');
|
||||
const exec = require('child_process').exec;
|
||||
const so = require('../../includes/storeObject');
|
||||
@@ -13,6 +13,15 @@ router
|
||||
.get('/', (req, res) => {
|
||||
res.send({ name: 'WebIO Schedule API' });
|
||||
})
|
||||
.post('*', async(req,res,n) => {
|
||||
try{
|
||||
res.db = await mysql.getConn();
|
||||
}catch(e){
|
||||
console.log(`Get DB Connection ERROR ${e}`);
|
||||
return n('ERR8100');
|
||||
}
|
||||
n();
|
||||
})
|
||||
.post(['/getschedulelist', '/getschedule'], (req, res, n) => {
|
||||
if (!config.permission.schedule) return n('ERR9000');
|
||||
let s = false;
|
||||
@@ -23,14 +32,6 @@ router
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
}
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select * from ??.?? ";
|
||||
let order = " order by `ioscheduleuid` desc ";
|
||||
let param = [config.db.db1, 'ioschedulet'];
|
||||
@@ -40,7 +41,7 @@ router
|
||||
}
|
||||
|
||||
res.db.query(query + order, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
if (err) return rt.err(res,err,n,'ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row),
|
||||
@@ -105,7 +106,7 @@ router
|
||||
return n();
|
||||
})
|
||||
.catch(err => {
|
||||
return n();
|
||||
return rt.err(res,err,n);
|
||||
})
|
||||
});
|
||||
})
|
||||
@@ -116,19 +117,11 @@ router
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "delete from ??.?? where `ioscheduleuid` = ? ";
|
||||
let param = [config.db.db1, 'ioschedulet', arr.data.id];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8003');
|
||||
if (err) return rt.err(res,err,n,'ERR8003');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
@@ -145,19 +138,11 @@ router
|
||||
|
||||
// let active = arr.data.active == 1 ? 1 : 0;
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "update ??.?? set `ioscheduleactive` = (case when `ioscheduleactive` = '1' then '0' else '1' end) where `ioscheduleuid` = ? ";
|
||||
let param = [config.db.db1, 'ioschedulet', arr.data.id];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8002');
|
||||
if (err) return rt.err(res,err,n,'ERR8002');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
@@ -184,14 +169,6 @@ router
|
||||
let tmp = arr.data.action.split(',');
|
||||
if (tmp.length != 2) return n('ERR0030');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let active = arr.data.active == 1 ? 1 : 0;
|
||||
|
||||
let d = '';
|
||||
@@ -221,7 +198,7 @@ router
|
||||
let param = [config.db.db1, 'ioschedulet', arr.data.name, active, arr.data.devs, arr.data.action, arr.data.min, arr.data.hour, d, m, w];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8001');
|
||||
if (err) return rt.err(res,err,n,'ERR8001');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
@@ -249,14 +226,6 @@ router
|
||||
let tmp = arr.data.action.split(',');
|
||||
if (tmp.length != 2) return n('ERR0030');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let active = arr.data.active == 1 ? 1 : 0;
|
||||
|
||||
let d = '';
|
||||
@@ -288,7 +257,7 @@ router
|
||||
let param = [config.db.db1, 'ioschedulet', arr.data.name, active, arr.data.devs, arr.data.action, arr.data.min, arr.data.hour, d, m, w, arr.data.id];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8002');
|
||||
if (err) return rt.err(res,err,n,'ERR8002');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const fs = require('fs');
|
||||
const mysql = require('../../libs/mysql_pool');
|
||||
const tool = require('../../includes/apiTool');
|
||||
const exec = require('child_process').exec;
|
||||
const so = require('../../includes/storeObject');
|
||||
const crypt = require('../../libs/crypto');
|
||||
|
||||
router
|
||||
.get('/', (req, res, n) => {
|
||||
res.send({ name: 'WebIO Server IPMI/SNMP API' });
|
||||
})
|
||||
.post('*', async(req, res, n) => {
|
||||
try {
|
||||
res.db = await mysql.getConn();
|
||||
} catch (e) {
|
||||
console.log(`Get DB Connection ERROR ${e}`);
|
||||
return n('ERR8100');
|
||||
}
|
||||
n();
|
||||
})
|
||||
.post('/getserverlist', (req, res, n) => {
|
||||
if (!config.permission.server) return n('ERR9000');
|
||||
|
||||
let query = "select * from ??.??";
|
||||
let param = [config.db.db11, 'jciocservert'];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return rt.err(res, err, n, 'ERR8000');
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
}
|
||||
n();
|
||||
})
|
||||
})
|
||||
.post('/addserver', (req, res, n) => {
|
||||
if (!config.permission.server) return n('ERR9000');
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.name) return n('ERR0026');
|
||||
if (arr.data.iip) {
|
||||
if (!arr.data.iaccount) return n('ERR0016');
|
||||
if (!arr.data.ipassword) return n('ERR0017');
|
||||
if (!arr.data.imac) return n('ERR0064');
|
||||
if (!arr.data.itype) return n('ERR0009');
|
||||
}
|
||||
if (arr.data.sip) {
|
||||
if (!arr.data.smac) return n('ERR0064');
|
||||
if (!arr.data.stype) return n('ERR0009');
|
||||
if (!arr.data.sname) return n('ERR0026');
|
||||
if (!arr.data.sver) return n('ERR0065');
|
||||
if (arr.data.sver == 'v3' && !arr.data.v3level) return n('ERR0066');
|
||||
if (arr.data.v3level) {
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
.all('*', rt.send);
|
||||
|
||||
module.exports = router;
|
||||
+96
-61
@@ -3,7 +3,7 @@ const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const fs = require('fs');
|
||||
const mysql = require('../../libs/mysql_cls');
|
||||
const mysql = require('../../libs/mysql_pool');
|
||||
const tool = require('../../includes/apiTool');
|
||||
const exec = require('child_process').exec;
|
||||
const so = require('../../includes/storeObject');
|
||||
@@ -21,6 +21,15 @@ router
|
||||
|
||||
res.send({ name: 'WebIO System API' });
|
||||
})
|
||||
.post('*', async(req,res,n) => {
|
||||
try{
|
||||
res.db = await mysql.getConn();
|
||||
}catch(e){
|
||||
console.log(`Get DB Connection ERROR ${e}`);
|
||||
return n('ERR8100');
|
||||
}
|
||||
n();
|
||||
})
|
||||
.post('/getnetwork', (req, res, n) => {
|
||||
fs.exists(config.cmdpath.sysinfo, (exists) => {
|
||||
if (!exists) return n('ERR0014');
|
||||
@@ -101,17 +110,9 @@ router
|
||||
if (!arr.data.account) return n('ERR0016');
|
||||
if (!arr.data.password) return n('ERR0017');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select * from ??.?? where `account` = ? and `user_password` = ?";
|
||||
res.db.query(query, [config.db.db1, 'userlist', arr.data.account, arr.data.password], (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
if (err) return rt.err(res, err, n, 'ERR8000');
|
||||
if (row.length == 0) return n('ERR0019');
|
||||
delete row[0]['user_password'];
|
||||
|
||||
@@ -159,13 +160,6 @@ router
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.account) return n('ERR0016');
|
||||
}
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "select * from ??.??";
|
||||
let param = [config.db.db1, 'userlist']
|
||||
@@ -176,7 +170,7 @@ router
|
||||
}
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
if (err) return rt.err(res, err, n, 'ERR8000');
|
||||
|
||||
for (var i in row) {
|
||||
delete row[i]['user_password'];
|
||||
@@ -195,18 +189,10 @@ router
|
||||
if (!arr.data.account) return n('ERR0016');
|
||||
if (arr.data.account == 'admin') return n('ERR0037');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "delete from ??.?? where `account` = ?";
|
||||
let param = [config.db.db1, 'userlist', arr.data.account];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR0020');
|
||||
if (err) return rt.err(res,err, n, 'ERR0020');
|
||||
|
||||
let data = {};
|
||||
data.record = [];
|
||||
@@ -229,14 +215,6 @@ router
|
||||
r = 1;
|
||||
}
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "update ??.?? set `write_privilege` = ? , `read_privilege` = ? " +
|
||||
(pass.length > 0 ? " , `user_password` = ? " : "") + " where `account` = ? ";
|
||||
let param = [config.db.db1, 'userlist', w.toString(), r.toString()];
|
||||
@@ -244,7 +222,7 @@ router
|
||||
param.push(arr.data.account);
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR0021');
|
||||
if (err) return rt.err(res,err,n,'ERR0021');
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
@@ -261,19 +239,11 @@ router
|
||||
let w = arr.data.write_privilege && arr.data.write_privilege == '1' ? 1 : 0;
|
||||
let r = arr.data.read_privilege && arr.data.read_privilege == '1' ? 1 : 0;
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let query = "insert into ??.?? (`account`,`user_password`,`write_privilege`,`read_privilege`,`user_add_date`) values (?,?,?,?,unix_timestamp())";
|
||||
let param = [config.db.db1, 'userlist', arr.data.account, arr.data.password, w.toString(), r.toString()];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR0022');
|
||||
if (err) return rt.err(res,err,n,'ERR0022');
|
||||
|
||||
let data = {};
|
||||
data.record = [];
|
||||
@@ -282,13 +252,6 @@ router
|
||||
});
|
||||
})
|
||||
.post('/dashboard', (req, res, n) => {
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
let data = {
|
||||
record: [],
|
||||
@@ -391,7 +354,7 @@ router
|
||||
return n();
|
||||
})
|
||||
.catch(e => {
|
||||
return n();
|
||||
return rt.err(res, e, n);
|
||||
});
|
||||
})
|
||||
.post('/getselectlist', (req, res, n) => {
|
||||
@@ -399,14 +362,6 @@ router
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.type) return n('ERR0009');
|
||||
|
||||
res.db = new mysql();
|
||||
res.db.user = config.db.user;
|
||||
res.db.password = config.db.pass;
|
||||
res.db.host = config.db.host;
|
||||
res.db.port = config.db.port;
|
||||
res.db.database = config.db.db1;
|
||||
res.db.connect();
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
@@ -415,25 +370,35 @@ router
|
||||
let q, p;
|
||||
switch (arr.data.type) {
|
||||
case 'do':
|
||||
if(!config.permission.dio) return n('ERR9000');
|
||||
q = "select `doname` as name, `douid` as id from ??.??";
|
||||
p = [config.db.db1, 'dolist'];
|
||||
pro = tool.promiseQuery(res, q, p, '');
|
||||
break;
|
||||
case 'di':
|
||||
if(!config.permission.dio) return n('ERR9000');
|
||||
q = "select `diname` as name, `diuid` as id from ??.??";
|
||||
p = [config.db.db1, 'dilist'];
|
||||
pro = tool.promiseQuery(res, q, p, '');
|
||||
break;
|
||||
case 'leone':
|
||||
if(!config.permission.leone) return n('ERR9000');
|
||||
q = "select `leonename` as name, `leonelistuid` as id from ??.??";
|
||||
p = [config.db.db1, 'leonelist'];
|
||||
pro = tool.promiseQuery(res, q, p, '');
|
||||
break;
|
||||
case 'iogroup':
|
||||
if(!config.permission.iogroup) return n('ERR9000');
|
||||
q = "select `iogroupname` as name, `iogroupuid` as id from ??.??";
|
||||
p = [config.db.db1, 'iogroup'];
|
||||
pro = tool.promiseQuery(res, q, p, '');
|
||||
break;
|
||||
case 'modbus':
|
||||
if(!config.permission.modbus) return n('ERR9000');
|
||||
q = "select `name`, `uid` as id from ??.??";
|
||||
p = [config.db.db5, 'device'];
|
||||
pro = tool.promiseQuery(res,q,p, '');
|
||||
break;
|
||||
default:
|
||||
return n();
|
||||
}
|
||||
@@ -447,6 +412,76 @@ router
|
||||
return n();
|
||||
})
|
||||
})
|
||||
.post('/chklogin', (req,res,n) => {
|
||||
if(!tool.checkPermission(req)) return n('ERR9001');
|
||||
res.api_res = {
|
||||
record: []
|
||||
}
|
||||
n();
|
||||
})
|
||||
.post('/gettimezonelist', (req,res,n) => {
|
||||
exec('timedatectl list-timezones', (err, stdout, stderr) => {
|
||||
if(err) return n("ERR8000");
|
||||
|
||||
let zones = stdout.split(/\n/);
|
||||
let json = {
|
||||
zone: []
|
||||
};
|
||||
|
||||
for(let i in zones){
|
||||
let str = zones[i].trim();
|
||||
if(!str) continue;
|
||||
let tz = str.split('/');
|
||||
if(tz.length != 2) continue;
|
||||
let flag = false;
|
||||
for(let j in json.zone){
|
||||
if(json.zone[j].name == tz[0]) {
|
||||
flag = true;
|
||||
json.zone[j].location.push(tz[1]);
|
||||
}
|
||||
}
|
||||
if(!flag) json.zone.push({name: tz[0], location: [tz[1]]})
|
||||
}
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(json.zone)
|
||||
}
|
||||
n();
|
||||
})
|
||||
})
|
||||
.post('/gettimezoneset', (req,res,n) => {
|
||||
let query = "select * from ??.?? where `type` = ? limit 1";
|
||||
let param = [config.db.db1, 'system', 'timezone'];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if(err) return rt.err(res,err,n, 'ERR8000');
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
}
|
||||
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/settimezone', (req,res,n) => {
|
||||
if(!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if(!arr.data) return n('ERR0000');
|
||||
if(!arr.data.timezone) return n('ERR0058');
|
||||
|
||||
let cmd = `timedatectl set-timezone ${arr.data.timezone}`;
|
||||
exec(cmd, (err, stdout, stderr) => {
|
||||
if(err) return rt.err(res,err, n, 'ERR0059');
|
||||
|
||||
let query = "update ??.?? set `value` = ? where `type` = ?";
|
||||
let param = [config.db.db1, 'system', arr.data.timezone, 'timezone'];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if(err ) return rt.err(res, err, n, 'ERR8002');
|
||||
res.api_res = {
|
||||
record: []
|
||||
}
|
||||
n();
|
||||
})
|
||||
})
|
||||
})
|
||||
.all('*', rt.send);
|
||||
|
||||
module.exports = router;
|
||||
@@ -0,0 +1,500 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const fs = require('fs');
|
||||
const mysql = require('../../libs/mysql_pool');
|
||||
const tool = require('../../includes/apiTool');
|
||||
const exec = require('child_process').exec;
|
||||
const so = require('../../includes/storeObject');
|
||||
const crypt = require('../../libs/crypto');
|
||||
|
||||
router
|
||||
.get('/', (req, res) => {
|
||||
res.send({ name: 'WebIO Wristband API' });
|
||||
})
|
||||
.get('/pushdata', async(req, res, n) => {
|
||||
try {
|
||||
res.db = await mysql.getConn();
|
||||
} catch (e) {
|
||||
console.log(`Get DB Connection ERROR ${e}`);
|
||||
return n('ERR8100');
|
||||
}
|
||||
|
||||
let arr = req.query;
|
||||
if (!arr.mac) return n('ERR0000');
|
||||
if (!arr.devid) return n('ERR0000');
|
||||
let query = "insert into ??.?? values (null, ?, ?,?,?,?,?,?,?,?,?,?,?,?,unix_timestamp())";
|
||||
let param = [
|
||||
config.db.db9,
|
||||
'rawdata',
|
||||
arr.devid || '',
|
||||
arr.mac || '',
|
||||
arr.val2 || '',
|
||||
arr.val3 || '',
|
||||
arr.val4 || '',
|
||||
arr.val5 || '',
|
||||
arr.val6 || '',
|
||||
arr.val7 || '',
|
||||
arr.val8 || '',
|
||||
arr.val9 || '',
|
||||
arr.val10 || '',
|
||||
arr.val11 || '',
|
||||
arr.timestamp || '',
|
||||
];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8001');
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
let q = "select count(*) as c from ??.?? where `mac` = ?";
|
||||
let p = [config.db.db9, 'wristband', arr.mac];
|
||||
res.db.query(q, p, (err, row) => {
|
||||
let pros = [];
|
||||
if (!(err || row.length == 0 || row[0].c > 0)) {
|
||||
let q = "insert into ??.?? (`mac`, `name`, `cuser`, `muser`, `ctime`, `mtime`) values (?, '', 'API', 'API', unix_timestamp(), unix_timestamp())";
|
||||
let p = [config.db.db9, 'wristband', arr.mac];
|
||||
pros.push(tool.promiseQuery(res, q, p, 'q1'));
|
||||
}
|
||||
|
||||
let lq = "insert into ??.?? (`mac`, `devid`, `val2`, `val3`, `val4`, `val5`, `val6`, `val7`, `val8`, `val9`, `val10`, `val11`, `timestamp`, `ctime`, `mtime`) values \
|
||||
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, unix_timestamp(), unix_timestamp()) ON DUPLICATE KEY \
|
||||
update \
|
||||
`devid` = ?, \
|
||||
`val2` = ?, \
|
||||
`val3` = ?, \
|
||||
`val4` = ?, \
|
||||
`val5` = ?, \
|
||||
`val6` = ?, \
|
||||
`val7` = ?, \
|
||||
`val8` = ?, \
|
||||
`val9` = ?, \
|
||||
`val10` = ?, \
|
||||
`val11` = ?, \
|
||||
`timestamp` = ?, \
|
||||
`mtime` = unix_timestamp()";
|
||||
let lp = [config.db.db9, 'lastdata',
|
||||
arr.mac,
|
||||
arr.devid,
|
||||
arr.val2 || '',
|
||||
arr.val3 || '',
|
||||
arr.val4 || '',
|
||||
arr.val5 || '',
|
||||
arr.val6 || '',
|
||||
arr.val7 || '',
|
||||
arr.val8 || '',
|
||||
arr.val9 || '',
|
||||
arr.val10 || '',
|
||||
arr.val11 || '',
|
||||
arr.timestamp || '',
|
||||
arr.devid,
|
||||
arr.val2 || '',
|
||||
arr.val3 || '',
|
||||
arr.val4 || '',
|
||||
arr.val5 || '',
|
||||
arr.val6 || '',
|
||||
arr.val7 || '',
|
||||
arr.val8 || '',
|
||||
arr.val9 || '',
|
||||
arr.val10 || '',
|
||||
arr.val11 || '',
|
||||
arr.timestamp || ''
|
||||
]
|
||||
|
||||
pros.push(tool.promiseQuery(res, lq, lp, 'q2'));
|
||||
|
||||
Promise.all(pros)
|
||||
.then(r => {
|
||||
n()
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
n();
|
||||
})
|
||||
|
||||
})
|
||||
// n();
|
||||
})
|
||||
})
|
||||
.post('*', async(req, res, n) => {
|
||||
try {
|
||||
res.db = await mysql.getConn();
|
||||
} catch (e) {
|
||||
console.log(`Get DB Connection ERROR ${e}`);
|
||||
return n('ERR8100');
|
||||
}
|
||||
n();
|
||||
})
|
||||
.post('/getstatus', (req, res, n) => {
|
||||
if (!config.permission.wristband) return n('ERR9000');
|
||||
|
||||
let query = "select w.`name`, w.`mac` as wristband, \
|
||||
coalesce(l.`name`, l2.`name`) as locname, \
|
||||
coalesce(case when tmp2.`wlocrtloc` = 'NG' then null else tmp2.`wlocrtloc` end, ll.`devid`) as locid, \
|
||||
case when tmp2.`wlocrtloc` = 'NG' then 1 else 0 end as loss, \
|
||||
ll.* \
|
||||
from ??.?? w \
|
||||
left join ??.?? tmp2 \
|
||||
on tmp2.`wlocrtmac` = w.`mac` \
|
||||
left join ??.?? ll \
|
||||
on ll.`mac` = w.`mac` \
|
||||
left join ??.?? l \
|
||||
on \
|
||||
l.`serialnumber` = tmp2.`wlocrtloc` \
|
||||
and tmp2.`wlocrtloc` != 'NG' \
|
||||
left join ??.?? l2\
|
||||
on \
|
||||
l2.`serialnumber` = ll.`devid` \
|
||||
where \
|
||||
w.`switch` = 1 ";
|
||||
let param = [config.db.db9, 'wristband', config.db.db9, 'wlocationrt', config.db.db9, 'lastdata', config.db.db9, 'location', config.db.db9, 'location', ];
|
||||
|
||||
let sortfield = '';
|
||||
let sortorder = '';
|
||||
|
||||
if (req.body.data && req.body.data.sort) {
|
||||
if (req.body.data.sort.field) sortfield = req.body.data.sort.field;
|
||||
if (req.body.data.sort.order) sortorder = req.body.data.sort.order;
|
||||
}
|
||||
|
||||
switch (sortfield) {
|
||||
case 'mac':
|
||||
case 'val2':
|
||||
case 'val3':
|
||||
case 'val4':
|
||||
case 'val5':
|
||||
case 'val6':
|
||||
case 'val7':
|
||||
case 'val8':
|
||||
case 'val9':
|
||||
case 'val10':
|
||||
case 'val11':
|
||||
query += `order by ll.${sortfield} ${sortorder}`;
|
||||
break;
|
||||
case 'loc':
|
||||
query += `order by locname ${sortorder}`;
|
||||
break;
|
||||
case 'time':
|
||||
query += 'order by ll.`timestamp` ' + sortorder;
|
||||
break;
|
||||
case 'name':
|
||||
query += `order by w.name ${sortorder}`;
|
||||
default:
|
||||
query += 'order by w.`uid`';
|
||||
break;
|
||||
}
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return rt.err(res, err, n, 'ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
}
|
||||
n();
|
||||
})
|
||||
})
|
||||
.post('/getwristbandlist', (req, res, n) => {
|
||||
if (!config.permission.wristband) return n('ERR9000');
|
||||
|
||||
let query = "select * from ??.?? ";
|
||||
let param = [config.db.db9, 'wristband'];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return rt.err(res, err, n, 'ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
};
|
||||
|
||||
n();
|
||||
})
|
||||
})
|
||||
.post('/delwristband', (req, res, n) => {
|
||||
if (!config.permission.wristband) return n('ERR9000');
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
res.db.query(`use ${config.db.db9}`);
|
||||
let query = "delete from ??.?? where `uid` = ?";
|
||||
let param = [config.db.db9, 'wristband', arr.data.id];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return rt.err(res, err, n, 'ERR8003');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
n();
|
||||
});
|
||||
})
|
||||
.post('/addwristband', (req, res, n) => {
|
||||
if (!config.permission.wristband) return n('ERR9000');
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000')
|
||||
if (!arr.data.mac) return n('ERR0060');
|
||||
|
||||
let query = "select count(*) as c from ??.?? where `mac` = ?";
|
||||
let param = [config.db.db9, 'wristband', arr.data.mac];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err || row.length == 0) return rt.err(res, err, n, "ERR8000");
|
||||
if (row[0].c > 0) return n("ERR0061");
|
||||
|
||||
let name = arr.data.name || '';
|
||||
let identity = arr.data.identity || 0;
|
||||
let monitor = arr.data.monitor || 0;
|
||||
let notify = arr.data.notify || 0;
|
||||
let sw = arr.data.switch || 0;
|
||||
|
||||
let u = '';
|
||||
let obj = so.get(req.headers['x-auth-token']);
|
||||
if (obj != null && 'user' in obj && 'account' in obj.user) {
|
||||
u = obj.user.account;
|
||||
}
|
||||
|
||||
let query = "insert into ??.?? (`mac`, `name`, `identity`, `monitor`, `notify`, `switch`, `cuser`, `muser`, `ctime`, `mtime`) values \
|
||||
( ?, ?, ?, ?, ?, ?, ?, ?, unix_timestamp(), unix_timestamp() )";
|
||||
let param = [config.db.db9, 'wristband', arr.data.mac, name, identity, monitor, notify, sw, u, u];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return rt.err(res, err, n, 'ERR8001');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
n();
|
||||
});
|
||||
})
|
||||
})
|
||||
.post('/editwristband', (req, res, n) => {
|
||||
if (!config.permission.wristband) return n('ERR9000');
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
let name = arr.data.name || '';
|
||||
let identity = arr.data.identity || 0;
|
||||
let monitor = arr.data.monitor || 0;
|
||||
let notify = arr.data.notify || 0;
|
||||
let sw = arr.data.switch || 0;
|
||||
|
||||
let u = '';
|
||||
let obj = so.get(req.headers['x-auth-token']);
|
||||
if (obj != null && 'user' in obj && 'account' in obj.user) {
|
||||
u = obj.user.account;
|
||||
}
|
||||
|
||||
let query = "update ??.?? set \
|
||||
`name` = ?, \
|
||||
`identity` = ?, \
|
||||
`monitor` = ?, \
|
||||
`notify` = ?, \
|
||||
`switch` = ?, \
|
||||
`muser` = ?, \
|
||||
`mtime` = unix_timestamp() \
|
||||
where \
|
||||
`uid` = ?";
|
||||
let param = [config.db.db9, 'wristband', name, identity, monitor, notify, sw, u, arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return rt.err(res, err, n, 'ERR8002');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
}
|
||||
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('/getwristbandhealthinfo', (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.* \
|
||||
from ??.?? log \
|
||||
where \
|
||||
log.`wphylogmac` = ? \
|
||||
and log.`wphylogtst` >= ? \
|
||||
and log.`wphylogtst` <= ? \
|
||||
order by log.`wphylogtst` desc";
|
||||
let param = [config.db.db9, 'wphylog', 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) => {
|
||||
if (!config.permission.wristband) return n('ERR9000');
|
||||
|
||||
let query = "select * from ??.??";
|
||||
let param = [config.db.db9, 'location'];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return rt.err(res, err, n, "ERR8000");
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
}
|
||||
n();
|
||||
});
|
||||
})
|
||||
.post('/addlocation', (req, res, n) => {
|
||||
if (!config.permission.wristband) return n('ERR9000');
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.sn) return n("ERR0062");
|
||||
if (!arr.data.name) return n('ERR0026');
|
||||
|
||||
let query = "select count(*) as c from ??.?? where `serialnumber` = ?";
|
||||
let param = [config.db.db9, 'location', arr.data.sn];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err || row.length == 0) return rt.err(res, err, n, 'ERR8000');
|
||||
if (row[0].c > 0) return n('ERR0063');
|
||||
|
||||
let u = '';
|
||||
let obj = so.get(req.headers['x-auth-token']);
|
||||
if (obj != null && 'user' in obj && 'account' in obj.user) {
|
||||
u = obj.user.account;
|
||||
}
|
||||
|
||||
let query = "insert into ??.?? (`name`, `serialnumber`, `cuser`, `ctime`, `muser`, `mtime`) values (?, ?, ?, unix_timestamp(), ?, unix_timestamp())";
|
||||
let param = [config.db.db9, 'location', arr.data.name, arr.data.sn, u, u];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return rt.err(res, err, n, 'ERR8001');
|
||||
res.api_res = {
|
||||
record: []
|
||||
}
|
||||
n();
|
||||
});
|
||||
})
|
||||
})
|
||||
.post('/editlocation', (req, res, n) => {
|
||||
if (!config.permission.wristband) return n('ERR9000');
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
if (!arr.data.name) return n('ERR0026');
|
||||
|
||||
let u = '';
|
||||
let obj = so.get(req.headers['x-auth-token']);
|
||||
if (obj != null && 'user' in obj && 'account' in obj.user) {
|
||||
u = obj.user.account;
|
||||
}
|
||||
|
||||
let query = "update ??.?? set \
|
||||
`name` = ?, \
|
||||
`muser` = ?, \
|
||||
`mtime` = unix_timestamp() \
|
||||
where \
|
||||
`uid` = ? ";
|
||||
let param = [config.db.db9, 'location', arr.data.name, u, arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return rt.err(res, err, n, 'ERR8002');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
n();
|
||||
})
|
||||
})
|
||||
.post('/dellocation', (req, res, n) => {
|
||||
if (!config.permission.wristband) return n('ERR9000');
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.id) return n('ERR0028');
|
||||
|
||||
res.db.query(`use ${config.db.db9}`);
|
||||
|
||||
let query = "delete from ??.?? where `uid` = ?";
|
||||
let param = [config.db.db9, 'location', arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return rt.err(res, err, n, 'ERR8003');
|
||||
res.api_res = {
|
||||
record: []
|
||||
}
|
||||
n();
|
||||
})
|
||||
})
|
||||
.all('*', rt.send);
|
||||
|
||||
module.exports = router;
|
||||
+395
-369
File diff suppressed because it is too large
Load Diff
+22
-14
@@ -8,6 +8,7 @@ import routes from './routes';
|
||||
import thunk from 'redux-thunk';
|
||||
import {set_i18n} from './actions';
|
||||
import i18next from 'i18next';
|
||||
import {getRequest} from './actions';
|
||||
|
||||
const middleware = [thunk];
|
||||
|
||||
@@ -34,21 +35,28 @@ const store = createStore(reducers, NODE_ENV && NODE_ENV == 'production' ? apply
|
||||
class PageRoot extends React.Component {
|
||||
|
||||
componentDidMount(){
|
||||
let lang = navigator
|
||||
.language
|
||||
.substring(0, 2);
|
||||
fetch(`/locales/${lang}.json`).then(response => {
|
||||
if (response.status == 200)
|
||||
return response.json();
|
||||
return {}
|
||||
}).then(json => {
|
||||
i18next.init({
|
||||
lng: lang,
|
||||
resources: json
|
||||
}, () => {
|
||||
store.dispatch(set_i18n(i18next));
|
||||
fetch('/api/system/chklogin', getRequest())
|
||||
.then(response=>response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return location.replace('/');
|
||||
let slang = sessionStorage.getItem('lang');
|
||||
let lang = slang || navigator
|
||||
.language
|
||||
.substring(0, 2);
|
||||
fetch(`/locales/${lang}.json`).then(response => {
|
||||
if (response.status == 200)
|
||||
return response.json();
|
||||
return {}
|
||||
}).then(json => {
|
||||
let lang = Object.keys(json)[0] || '';
|
||||
i18next.init({
|
||||
lng: lang,
|
||||
resources: json
|
||||
}, () => {
|
||||
store.dispatch(set_i18n(i18next));
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
import React from 'react';
|
||||
import {Form, Button, Input, Segment} from 'semantic-ui-react';
|
||||
|
||||
class ActionSelect extends React.Component{
|
||||
state = {
|
||||
showTemp: false,
|
||||
temp: '0'
|
||||
}
|
||||
|
||||
checkShowTemp = (cmd = '') => {
|
||||
let c = cmd;
|
||||
let cs = c.split(' ');
|
||||
let showTemp = false;
|
||||
if(cs[0] == 2) {
|
||||
showTemp = true;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
showTemp
|
||||
});
|
||||
}
|
||||
|
||||
updateTemp = (temp) => {
|
||||
this.setState({
|
||||
temp
|
||||
})
|
||||
}
|
||||
|
||||
render(){
|
||||
let {i18n,list, unit, getList, addAction} = this.props;
|
||||
let actlist = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.action_list') : [];
|
||||
return (
|
||||
<Form.Field>
|
||||
<label>加入動作</label>
|
||||
<Segment color="green" className="clearfix">
|
||||
<Form.Group inline>
|
||||
<Form.Field>
|
||||
<label>選擇裝置</label>
|
||||
<select ref="devType" onChange={e=>{
|
||||
getList(unit, e.target.value);
|
||||
}}>
|
||||
<option value="">選擇裝置類型</option>
|
||||
<option value="do">DigitOutput</option>
|
||||
<option value="leone">LeOne</option>
|
||||
<option value="iogroup">IOGroup</option>
|
||||
</select>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<select ref="devName">
|
||||
<option value="">選擇裝置</option>
|
||||
{
|
||||
list.map((t,idx)=>(<option key={idx} value={t.id}>{t.name}</option>))
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
</Form.Group>
|
||||
<Form.Group inline>
|
||||
<Form.Field>
|
||||
<label>選擇動作</label>
|
||||
<select ref="act" onChange={e=>{
|
||||
this.checkShowTemp(e.target.value);
|
||||
}}>
|
||||
<option value="">選擇動作</option>
|
||||
{
|
||||
actlist.map((t,idx) => (
|
||||
<option key={idx} value={t.cmd}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
{
|
||||
this.state.showTemp ?
|
||||
(
|
||||
<Form.Field>
|
||||
<Input size="mini" placeholder="請輸入溫度" value={this.state.temp} onChange={(e,d) => {
|
||||
this.updateTemp(d.value);
|
||||
}} />
|
||||
</Form.Field>
|
||||
) : null
|
||||
}
|
||||
</Form.Group>
|
||||
<Button floated="right" content="加入動作" size="tiny" basic color="orange" onClick={()=>{
|
||||
let type = this.refs.devType.value;
|
||||
let dev = this.refs.devName.value;
|
||||
let devName = this.refs.devName.options[this.refs.devName.selectedIndex].innerHTML;
|
||||
let act = this.refs.act.value;
|
||||
let actName = this.refs.act.options[this.refs.act.selectedIndex].innerHTML;
|
||||
let temp = this.state.temp;
|
||||
let prefix = '';
|
||||
|
||||
switch(type){
|
||||
case 'do':
|
||||
prefix = 'do';
|
||||
break;
|
||||
case 'leone':
|
||||
prefix = 'le';
|
||||
break;
|
||||
case 'iogroup':
|
||||
prefix = 'iogroup';
|
||||
break;
|
||||
default:
|
||||
return addAction(null);
|
||||
}
|
||||
|
||||
if(!act) return addAction(null);
|
||||
if(act == 2) {
|
||||
act = `${act} ${temp}`;
|
||||
actName += ` ${temp}`;
|
||||
}
|
||||
|
||||
let data = {
|
||||
id: `${prefix}${dev}`,
|
||||
act,
|
||||
actName,
|
||||
devName
|
||||
};
|
||||
|
||||
return addAction(data);
|
||||
|
||||
}} />
|
||||
</Segment>
|
||||
</Form.Field>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ActionSelect;
|
||||
@@ -1,279 +0,0 @@
|
||||
import React from 'react';
|
||||
import {Grid, Form, Segment, Input} from 'semantic-ui-react';
|
||||
|
||||
const ops = [
|
||||
{
|
||||
"code": "0",
|
||||
"name": "等於"
|
||||
}, {
|
||||
"code": "1",
|
||||
"name": "大於"
|
||||
}, {
|
||||
"code": "2",
|
||||
"name": "小於"
|
||||
}, {
|
||||
"code": "3",
|
||||
"name": "大於等於"
|
||||
}, {
|
||||
"code": "4",
|
||||
"name": "小於等於"
|
||||
}, {
|
||||
"code": "5",
|
||||
"name": "不等於"
|
||||
}, {
|
||||
"code": "8",
|
||||
"name": "AND"
|
||||
}, {
|
||||
"code": "9",
|
||||
"name": "OR"
|
||||
}
|
||||
]
|
||||
|
||||
const stype = {
|
||||
di: {
|
||||
prefix: 'di',
|
||||
dev: '',
|
||||
op: '',
|
||||
value: '',
|
||||
mode: 'di_status'
|
||||
},
|
||||
leone: {
|
||||
prefix: 'le',
|
||||
dev: '',
|
||||
op: '',
|
||||
value: '',
|
||||
mode: ''
|
||||
},
|
||||
unit: {
|
||||
dev: ''
|
||||
},
|
||||
time: {
|
||||
op: '',
|
||||
dev: 'dt0',
|
||||
mode: 'mode0',
|
||||
year: '-',
|
||||
week: '-',
|
||||
month: '-',
|
||||
day: '-',
|
||||
hour: '-',
|
||||
min: '-'
|
||||
}
|
||||
}
|
||||
|
||||
class UnitItem extends React.Component {
|
||||
|
||||
state = {
|
||||
st: '',
|
||||
data:{}
|
||||
}
|
||||
|
||||
handleDataChange = (tag, value) => {
|
||||
let {data} = this.state;
|
||||
let {updateData} = this.props;
|
||||
if(tag in data) {
|
||||
data[tag] = value;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
data
|
||||
}, () => {
|
||||
let {data} = this.state
|
||||
let d = {...this.props.data.data}
|
||||
let {st} = this.props.data;
|
||||
|
||||
if(st == 'di' || st == 'leone'){
|
||||
d.id = `${data.prefix}${data.dev},${data.mode}`;
|
||||
d.op = data.op;
|
||||
d.value = data.value;
|
||||
}
|
||||
if(st == 'unit') {
|
||||
d.dev = data.dev;
|
||||
}
|
||||
if(st == 'time') {
|
||||
d.id = `${data.dev},${data.mode}`;
|
||||
d.op = data.op;
|
||||
d.value = `${data.min}|${data.hour}|${data.day}|${data.month}|${data.week}|${data.year}`;
|
||||
}
|
||||
|
||||
updateData(this.props.unit, d);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillReceiveProps(np) {
|
||||
let data = {...this.state.data};
|
||||
|
||||
if(np.data.st != this.state.st){
|
||||
|
||||
if(np.data.st in stype) {
|
||||
data = {...stype[np.data.st]};
|
||||
}else {
|
||||
data = {}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.setState({
|
||||
data,
|
||||
st: np.data.st
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
let {unit, data, getList} = this.props;
|
||||
|
||||
return (
|
||||
<Grid.Column>
|
||||
<Segment>
|
||||
<Form.Field>
|
||||
<label>選擇元件</label>
|
||||
<select
|
||||
value={data.st}
|
||||
onChange={e => {
|
||||
getList(unit, e.target.value);
|
||||
}}>
|
||||
<option value="">請選擇元件</option>
|
||||
<option value="leone">LeOne</option>
|
||||
<option value="di">DigitInput</option>
|
||||
<option value="time">時間</option>
|
||||
<option value="unit">已建立群組</option>
|
||||
</select>
|
||||
</Form.Field>
|
||||
{
|
||||
!data.st
|
||||
? null
|
||||
: (<UnitPanel data={data} state={this.state.data} dataChange={this.handleDataChange}/>)
|
||||
}
|
||||
</Segment>
|
||||
</Grid.Column>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const UnitPanel = ({data, state, dataChange}) => {
|
||||
if (data.st == 'di') {
|
||||
return (
|
||||
<div>
|
||||
<select value={state.dev} onChange={(e) => {
|
||||
dataChange('dev', e.target.value);
|
||||
}}>
|
||||
<option value="">選擇裝置</option>
|
||||
{
|
||||
data.list.map((t, idx) => (
|
||||
<option key={idx} value={t.id}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
<select value={state.op} onChange={e => {
|
||||
dataChange('op', e.target.value);
|
||||
}}>
|
||||
<option value="">選擇條件</option>
|
||||
{
|
||||
ops.map((t,idx) => {
|
||||
if(t.code == 8 || t.code == 9) return ;
|
||||
return (<option key={idx} value={t.code}>{t.name}</option>)
|
||||
})
|
||||
}
|
||||
</select>
|
||||
<select value={state.value} onChange={e => {
|
||||
dataChange('value', e.target.value);
|
||||
}}>
|
||||
<option value="">選擇狀態</option>
|
||||
<option value="0">0</option>
|
||||
<option value="1">1</option>
|
||||
</select>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if(data.st == 'leone') {
|
||||
return (
|
||||
<div>
|
||||
<select value={state.dev} onChange={e => {
|
||||
dataChange('dev', e.target.value);
|
||||
}}>
|
||||
<option value="">選擇裝置</option>
|
||||
{
|
||||
data.list.map((t, idx) => (
|
||||
<option key={idx} value={t.id}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
<select value={state.mode} onChange={e => {
|
||||
dataChange('mode', e.target.value);
|
||||
}}>
|
||||
<option value="">選擇感測器</option>
|
||||
<option value="leone_ttrigger1">溫度</option>
|
||||
<option value="leone_htrigger1">濕度</option>
|
||||
</select>
|
||||
<select value={state.op} onChange={e => {
|
||||
dataChange('op', e.target.value);
|
||||
}}>
|
||||
<option value="">選擇條件</option>
|
||||
{
|
||||
ops.map((t,idx) => {
|
||||
if(t.code == 8 || t.code == 9) return ;
|
||||
return (<option key={idx} value={t.code}>{t.name}</option>)
|
||||
})
|
||||
}
|
||||
</select>
|
||||
<Input size="mini" placeholder="請輸入數值" value={state.value} onChange={(e,d) => {
|
||||
dataChange('value', d.value);
|
||||
}} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if(data.st == 'unit') {
|
||||
return (
|
||||
<div>
|
||||
<select value={state.dev} onChange={e => {
|
||||
dataChange('dev', e.target.value);
|
||||
}}>
|
||||
<option value="">選擇群組</option>
|
||||
{
|
||||
data.list.map((t,idx) => (
|
||||
<option key={idx} value={t.id}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if(data.st == 'time') {
|
||||
return (
|
||||
<div>
|
||||
<select value={state.op} onChange={e => {
|
||||
dataChange('op', e.target.value);
|
||||
}}>
|
||||
<option value="">選擇條件</option>
|
||||
{
|
||||
ops.map((t,idx) => {
|
||||
if(t.code == 8 || t.code == 9) return ;
|
||||
return (<option key={idx} value={t.code}>{t.name}</option>)
|
||||
})
|
||||
}
|
||||
</select>
|
||||
<Input size="mini" placeholder="年(不指定請留空)" value={state.year == '-' ? '' : state.year} onChange={(e,d) => {
|
||||
dataChange('year', d.value.length == 0 ? '-' : d.value);
|
||||
}} />
|
||||
<Input size="mini" placeholder="週(不指定請留空)" value={state.week == '-' ? '' : state.week} onChange={(e,d) => {
|
||||
dataChange('week', d.value.length == 0 ? '-' : d.value);
|
||||
}} />
|
||||
<Input size="mini" placeholder="月(不指定請留空)" value={state.month == '-' ? '' : state.month} onChange={(e,d) => {
|
||||
dataChange('month', d.value.length == 0 ? '-' : d.value);
|
||||
}} />
|
||||
<Input size="mini" placeholder="日(不指定請留空)" value={state.day == '-' ? '' : state.day} onChange={(e,d) => {
|
||||
dataChange('day', d.value.length == 0 ? '-' : d.value);
|
||||
}} />
|
||||
<Input size="mini" placeholder="時(不指定請留空)" value={state.hour == '-' ? '' : state.hour} onChange={(e,d) => {
|
||||
dataChange('hour', d.value.length == 0 ? '-' : d.value);
|
||||
}} />
|
||||
<Input size="mini" placeholder="分(不指定請留空)" value={state.min == '-' ? '' : state.min} onChange={(e,d) => {
|
||||
dataChange('min', d.value.length == 0 ? '-' : d.value);
|
||||
}} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export default UnitItem;
|
||||
@@ -1,41 +0,0 @@
|
||||
import React from 'react';
|
||||
import {Modal, Form, Button} from 'semantic-ui-react';
|
||||
|
||||
const ViewTree = ({i18n, open, data, closeView, removeNode}) => {
|
||||
let seNode = null;
|
||||
let nodeKey = Object.keys(data);
|
||||
return (
|
||||
<Modal open={open} onClose={()=>{closeView()}} >
|
||||
<Modal.Header content="連動群組資料" />
|
||||
<Modal.Content>
|
||||
<Form as="div">
|
||||
<Form.Group inline>
|
||||
<Form.Field>
|
||||
<label>刪除節點</label>
|
||||
<select ref={node=>seNode=node}>
|
||||
{
|
||||
nodeKey.map((t,idx)=>(
|
||||
<option key={idx} value={t}>{data[t].name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Button type="button" basic size="tiny" content="刪除節點" onClick={()=>{
|
||||
if(!seNode) return ;
|
||||
removeNode(seNode.value);
|
||||
}} />
|
||||
</Form.Field>
|
||||
</Form.Group>
|
||||
</Form>
|
||||
<pre>
|
||||
{
|
||||
JSON.stringify(data, null, 4)
|
||||
}
|
||||
</pre>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default ViewTree;
|
||||
@@ -1,353 +0,0 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Container,
|
||||
Segment,
|
||||
Form,
|
||||
Input,
|
||||
Button,
|
||||
Checkbox,
|
||||
Grid,
|
||||
Menu,
|
||||
List
|
||||
} from 'semantic-ui-react';
|
||||
import {getRequest} from '../../../actions';
|
||||
import UnitItem from './UnitItem';
|
||||
import ActionSelect from './ActionSelect';
|
||||
import ActionItem from './ActionItem';
|
||||
import ViewTree from './ViewTreeModal';
|
||||
|
||||
const defState = () => ({
|
||||
gidx: 0,
|
||||
groups: {},
|
||||
active: false,
|
||||
edit: {
|
||||
name: '',
|
||||
type: 'ln',
|
||||
op: '',
|
||||
id1: {
|
||||
st: '',
|
||||
list: [],
|
||||
data: {}
|
||||
},
|
||||
id2: {
|
||||
st: '',
|
||||
list: [],
|
||||
data: {}
|
||||
}
|
||||
},
|
||||
actDevlist: [],
|
||||
items: [],
|
||||
showTree: false
|
||||
})
|
||||
const gtype = {
|
||||
lc: {
|
||||
type: 'lc',
|
||||
id: '',
|
||||
op: '',
|
||||
value: ''
|
||||
},
|
||||
ln: {
|
||||
type: 'ln',
|
||||
dev: ''
|
||||
}
|
||||
}
|
||||
|
||||
class ActionLinkAdd extends React.Component {
|
||||
state = {
|
||||
...defState()
|
||||
}
|
||||
|
||||
getSelectList = (unit, type = '') => {
|
||||
if (!unit) {
|
||||
return;
|
||||
}
|
||||
if(unit != 'act'){
|
||||
let edit = {
|
||||
...this.state.edit
|
||||
};
|
||||
if (!(unit in edit)) {
|
||||
return;
|
||||
}
|
||||
edit[unit].st = type;
|
||||
edit[unit].data = {
|
||||
...gtype.lc
|
||||
}
|
||||
if (type != 'di' && type != 'leone' && type != 'unit') {
|
||||
return this.setState({edit});
|
||||
}
|
||||
|
||||
if (type == 'di' || type == 'leone') {
|
||||
this.props.toggleLoading(1);
|
||||
let json = {
|
||||
type
|
||||
};
|
||||
fetch('/api/system/getselectlist', getRequest(json))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
if (json.status != 1)
|
||||
return this.props.showDialog(json.message);
|
||||
edit[unit].list = json.data.record || [];
|
||||
this.setState({edit}, () => {
|
||||
this.props.toggleLoading(0);
|
||||
});
|
||||
});
|
||||
}
|
||||
if(type == 'unit') {
|
||||
let list = [];
|
||||
for(let i in this.state.groups){
|
||||
list.push({id: i, name: this.state.groups[i].name});
|
||||
}
|
||||
edit[unit].list = list;
|
||||
edit[unit].data = {
|
||||
...gtype.ln
|
||||
}
|
||||
this.setState({edit})
|
||||
}
|
||||
}else{
|
||||
let actDevlist = [];
|
||||
if(!type) {
|
||||
this.setState({
|
||||
actDevlist
|
||||
});
|
||||
return ;
|
||||
}
|
||||
this.props.toggleLoading(1);
|
||||
fetch('/api/system/getselectlist', getRequest({type}))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
if (json.status != 1)
|
||||
return this.props.showDialog(json.message);
|
||||
actDevlist = json.data.record || []
|
||||
this.setState({
|
||||
actDevlist
|
||||
}, ()=>{
|
||||
this.props.toggleLoading(0);
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
updateData = (unit, data) => {
|
||||
let {edit} = this.state;
|
||||
if(!(unit in edit)) return ;
|
||||
edit[unit].data = data;
|
||||
|
||||
this.setState({
|
||||
edit
|
||||
})
|
||||
}
|
||||
|
||||
updateEditData = (tag, value) => {
|
||||
let {edit} = this.state;
|
||||
if(tag in edit){
|
||||
edit[tag] = value;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
edit
|
||||
})
|
||||
}
|
||||
|
||||
updateActive = (active = false) => {
|
||||
this.setState({
|
||||
active: active ? 1 : 0
|
||||
})
|
||||
}
|
||||
|
||||
joinUnit = () => {
|
||||
let {edit} = this.state;
|
||||
let {i18n} = this.props;
|
||||
if(!edit.name || edit.op.length == 0 || Object.keys(edit.id1.data).length == 0 || Object.keys(edit.id2.data).length == 0) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
if(edit.id1.data.type == 'lc' && (edit.id1.data.id.length == 0 || edit.id1.data.op.length == 0 || edit.id1.data.value.length == 0)) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
if(edit.id2.data.type == 'lc' && (edit.id2.data.id.length == 0 || edit.id2.data.op.length == 0 || edit.id2.data.value.length == 0)) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
if(edit.id1.data.type == 'ln' && edit.id1.data.dev.length == 0) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
if(edit.id2.data.type == 'ln' && edit.id2.data.dev.length == 0) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
|
||||
let unitKey = [];
|
||||
if(edit.id1.data.type == 'lc'){
|
||||
edit.id1 = {
|
||||
...edit.id1.data
|
||||
}
|
||||
}else if(edit.id1.data.type == 'ln'){
|
||||
unitKey.push(edit.id1.data.dev)
|
||||
edit.id1 = {
|
||||
...this.state.groups[edit.id1.data.dev]
|
||||
}
|
||||
}
|
||||
if(edit.id2.data.type == 'lc'){
|
||||
edit.id2 = {
|
||||
...edit.id2.data
|
||||
}
|
||||
}else if(edit.id2.data.type == 'ln'){
|
||||
unitKey.push(edit.id2.data.dev)
|
||||
edit.id2 = {
|
||||
...this.state.groups[edit.id2.data.dev]
|
||||
}
|
||||
}
|
||||
let groups = {...this.state.groups};
|
||||
for(let i in unitKey){
|
||||
if(unitKey[i] in groups) delete groups[unitKey[i]];
|
||||
}
|
||||
|
||||
groups[`unit${this.state.gidx}`] = {
|
||||
...edit
|
||||
}
|
||||
|
||||
this.setState({
|
||||
gidx: this.state.gidx+1,
|
||||
groups: {...groups}
|
||||
}, ()=>{
|
||||
this.resetEdit()
|
||||
})
|
||||
}
|
||||
|
||||
resetEdit = () => {
|
||||
this.setState({
|
||||
edit:{
|
||||
...defState().edit
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
addAction = (item) => {
|
||||
if(!item) return this.props.showDialog('動作請選擇完整');
|
||||
let cmds = item.act.split(' ');
|
||||
if(cmds.length != 2) return this.props.showDialog('動作選擇錯誤');
|
||||
if(cmds[0] == 2 && (cmds[1] < 16 || cmds[1] > 30)) return this.props.showDialog('溫度範圍錯誤(16-30)');
|
||||
|
||||
this.setState({
|
||||
items: [...this.state.items, item]
|
||||
})
|
||||
}
|
||||
|
||||
removeAction = (idx) => {
|
||||
let items = [...this.state.items];
|
||||
items.splice(idx, 1);
|
||||
this.setState({
|
||||
items
|
||||
})
|
||||
}
|
||||
|
||||
toggleView = (sw = false) => {
|
||||
this.setState({
|
||||
showTree: sw ? true : false
|
||||
})
|
||||
}
|
||||
|
||||
removeNode = (node) => {
|
||||
if(!node) return ;
|
||||
let groups = {...this.state.groups};
|
||||
if(node in groups){
|
||||
delete groups[node];
|
||||
this.setState({
|
||||
groups: {...groups}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
saveLink = () => {
|
||||
if(Object.keys(this.state.groups).length == 0) return this.props.showDialog('請先建立群組');
|
||||
if(Object.keys(this.state.groups).length > 1) return this.props.showDialog('根節點數量大於一');
|
||||
if(this.state.items.length == 0) return this.props.showDialog('請選擇動作');
|
||||
let json = {
|
||||
active: this.state.active,
|
||||
link: this.state.groups[Object.keys(this.state.groups)[0]],
|
||||
action: ''
|
||||
}
|
||||
|
||||
let acts = this.state.items.map(t => {
|
||||
return `${t.id},${t.act.replace(' ', ',')},0`
|
||||
})
|
||||
|
||||
json.action = acts.join('|')
|
||||
|
||||
this.props.toggleLoading(1);
|
||||
fetch('/api/link/addlink', getRequest(json))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
this.props.toggleLoading(0);
|
||||
if(json.status != 1) return this.props.showDialog(json.message);
|
||||
this.resetAll();
|
||||
})
|
||||
}
|
||||
|
||||
resetAll = () => {
|
||||
this.setState({
|
||||
...defState()
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n} = this.props;
|
||||
return (
|
||||
<Container>
|
||||
<Menu >
|
||||
<Menu.Menu position="right">
|
||||
<Menu.Item content="ShowTree" onClick={()=>{
|
||||
this.toggleView(1)
|
||||
}}/>
|
||||
<Menu.Item content="Save" onClick={()=>{
|
||||
this.saveLink();
|
||||
}}/>
|
||||
</Menu.Menu>
|
||||
</Menu>
|
||||
<Form as={Segment}>
|
||||
<Form.Field>
|
||||
<Checkbox label="啟用連動" checked={this.state.active == 1} onChange={(e,d) =>{
|
||||
this.updateActive(d.checked ? 1 : 0);
|
||||
}}/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>建立條件群組</label>
|
||||
<Segment color="red">
|
||||
<Form.Field>
|
||||
<Input label="節點名稱" value={this.state.edit.name} onChange={(e,d) => {
|
||||
this.updateEditData('name', d.value);
|
||||
}}/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>觸發條件</label>
|
||||
<select value={this.state.edit.op} onChange={(e) => {
|
||||
this.updateEditData('op', e.target.value);
|
||||
}}>
|
||||
<option value="">請選擇觸發條件</option>
|
||||
<option value="8">AND</option>
|
||||
<option value="9">OR</option>
|
||||
</select>
|
||||
</Form.Field>
|
||||
<Grid columns={2} padded>
|
||||
<UnitItem unit="id1" data={this.state.edit.id1} getList={this.getSelectList} updateData={this.updateData}/>
|
||||
<UnitItem unit="id2" data={this.state.edit.id2} getList={this.getSelectList} updateData={this.updateData}/>
|
||||
</Grid>
|
||||
<div
|
||||
style={{
|
||||
textAlign: 'right'
|
||||
}}>
|
||||
<Button type="button" basic size="tiny" color="blue" content="加入" onClick={()=>{
|
||||
this.joinUnit();
|
||||
}}/>
|
||||
<Button type="button" basic size="tiny" color="green" content="清除" onClick={()=>{this.resetEdit()}}/>
|
||||
</div>
|
||||
</Segment>
|
||||
</Form.Field>
|
||||
<ActionSelect i18n={i18n} unit="act" list={this.state.actDevlist} getList={this.getSelectList} addAction={this.addAction} />
|
||||
<Form.Field>
|
||||
<label>裝置動作列表</label>
|
||||
<Segment color="blue">
|
||||
<List>
|
||||
{
|
||||
this.state.items.map((t,idx) => (
|
||||
<ActionItem key={idx} i18n={i18n} data={t} idx={idx} removeAction={this.removeAction}/>
|
||||
))
|
||||
}
|
||||
</List>
|
||||
</Segment>
|
||||
</Form.Field>
|
||||
</Form>
|
||||
<ViewTree i18n={i18n} data={this.state.groups} open={this.state.showTree} closeView={this.toggleView} removeNode={this.removeNode} />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ActionLinkAdd;
|
||||
+3
-3
@@ -1,17 +1,17 @@
|
||||
import React from 'react';
|
||||
import {List, Label, Button} from 'semantic-ui-react';
|
||||
|
||||
const ActionItem = ({i18n, data, idx, removeAction}) => {
|
||||
const ListItem = ({ i18n, data, idx, removeAction }) => {
|
||||
|
||||
return (
|
||||
<List.Item>
|
||||
<Label basic content={`裝置名稱`} /><span>{data.devName}</span>
|
||||
<Label basic content={`動作`} /><span>{data.actName}</span>
|
||||
<Button floated="right" color="red" basic size="tiny" content="Delete" type="button" onClick={()=>{
|
||||
removeAction(idx);
|
||||
removeAction(idx)
|
||||
}}/>
|
||||
</List.Item>
|
||||
)
|
||||
}
|
||||
|
||||
export default ActionItem;
|
||||
export default ListItem;
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import {Segment, List} from 'semantic-ui-react';
|
||||
import ListItem from './ListItem';
|
||||
|
||||
const ActionList = ({ i18n, list, removeAction }) => {
|
||||
|
||||
return (
|
||||
<Segment color="blue">
|
||||
<List divided>
|
||||
{
|
||||
list.map((t,idx) => (
|
||||
<ListItem key={idx} i18n={i18n} data={t} idx={idx} removeAction={removeAction} />
|
||||
))
|
||||
}
|
||||
</List>
|
||||
</Segment>
|
||||
)
|
||||
}
|
||||
|
||||
export default ActionList;
|
||||
@@ -0,0 +1,74 @@
|
||||
import React from 'react';
|
||||
import {Modal, Input, Button, Form, Grid} from 'semantic-ui-react';
|
||||
|
||||
const CalModal = ({ i18n, onClose, onSubmit }) => {
|
||||
|
||||
return (
|
||||
<Modal open={true}>
|
||||
<Modal.Header content="數值換算" />
|
||||
<Modal.Content>
|
||||
<Form onSubmit={(e,d) => {
|
||||
e.preventDefault();
|
||||
onSubmit(d.formData);
|
||||
}} serializer={e=>{
|
||||
let json = {
|
||||
r1: '',
|
||||
r2: '',
|
||||
s1: '',
|
||||
s2: '',
|
||||
val: ''
|
||||
}
|
||||
|
||||
let r1 = e.querySelector('input[name="r1"]');
|
||||
if(r1 && 'value' in r1) json.r1 = r1.value;
|
||||
let r2 = e.querySelector('input[name="r2"]');
|
||||
if(r2 && 'value' in r2) json.r2 = r2.value;
|
||||
let s1 = e.querySelector('input[name="s1"]');
|
||||
if(s1 && 'value' in s1) json.s1 = s1.value;
|
||||
let s2 = e.querySelector('input[name="s2"]');
|
||||
if(s2 && 'value' in s2) json.s2 = s2.value;
|
||||
let val = e.querySelector('input[name="val"]');
|
||||
if(val && 'value' in val) json.val = val.value;
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Form.Field>
|
||||
<label>Range</label>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Input label="RangeMin" name="r1" />
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Input label="RangeMax" name="r2" />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>Scale</label>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Input label="ScaleMin" name="s1" />
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Input label="ScaleMax" name="s2" />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input label="輸入數值" name="val" />
|
||||
</Form.Field>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Button fluid content="送出" basic />
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button fluid type="button" content="取消" basic onClick={()=>{onClose()}} />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default CalModal;
|
||||
@@ -0,0 +1,84 @@
|
||||
import React from 'react';
|
||||
import {Form, Input} from 'semantic-ui-react';
|
||||
|
||||
class StdAction extends React.Component{
|
||||
state = {
|
||||
name: '',
|
||||
act: '',
|
||||
temp: ''
|
||||
}
|
||||
|
||||
changeState = (tag, value) => {
|
||||
let data = {...this.state};
|
||||
if(tag == 'act'){
|
||||
data.name = value.name || '';
|
||||
data.act = value.act || '';
|
||||
}
|
||||
if(tag == 'temp'){
|
||||
data.temp = value;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
...data
|
||||
}, () => {
|
||||
this.updateAct();
|
||||
})
|
||||
}
|
||||
|
||||
showTemp = () => {
|
||||
if(this.state.act == '2'){
|
||||
return (
|
||||
<Form.Field>
|
||||
<Input label="請輸入溫度"
|
||||
placeholder="溫度請介於16-30間"
|
||||
value={this.state.temp}
|
||||
onChange={(e,d) => {this.changeState('temp', d.value)}} />
|
||||
</Form.Field>
|
||||
)
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
updateAct = ()=>{
|
||||
let {updateAct} = this.props;
|
||||
let act = this.state.act;
|
||||
let temp = this.state.temp;
|
||||
|
||||
if(act == '2') act = `${act},${temp}`;
|
||||
updateAct(act, this.state.name)
|
||||
}
|
||||
|
||||
render(){
|
||||
let {i18n} = this.props;
|
||||
let actlist = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.action_list') : [];
|
||||
return (
|
||||
<div>
|
||||
<Form.Field>
|
||||
<label>選擇動作</label>
|
||||
<select value={this.state.act} onChange={e=>{
|
||||
let el = e.target;
|
||||
let json = {
|
||||
name: '',
|
||||
act: ''
|
||||
}
|
||||
json.act = el.value;
|
||||
json.name = el.options[el.selectedIndex].innerHTML;
|
||||
|
||||
this.changeState('act', json);
|
||||
}}>
|
||||
<option value="">選擇動作</option>
|
||||
{
|
||||
actlist.map((t,idx) => (
|
||||
<option key={idx} value={t.cmd.replace(' ', ',')}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
{this.showTemp()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default StdAction;
|
||||
@@ -0,0 +1,98 @@
|
||||
import React from 'react';
|
||||
import {Form, Input} from 'semantic-ui-react';
|
||||
import { getRequest } from '../../../../actions';
|
||||
import StdAction from './StdAction';
|
||||
|
||||
class UnitLeone extends React.Component {
|
||||
state = {
|
||||
list: [],
|
||||
data: {
|
||||
dev: '',
|
||||
devName: '',
|
||||
act: '',
|
||||
actName: ''
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let { showDialog } = this.props;
|
||||
fetch('/api/system/getselectlist', getRequest({ type: 'do' }))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
if (json.status != 1) return showDialog(json.message);
|
||||
this.setState({
|
||||
list: json.data.record || []
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
changeState = (tag, value) =>{
|
||||
let data = {...this.state.data};
|
||||
|
||||
if(tag == 'act') {
|
||||
data.actName = value.name;
|
||||
data.act = value.act;
|
||||
}
|
||||
if(tag == 'dev'){
|
||||
data.dev = value.dev == '' ? '' : `do${value.dev}`;
|
||||
data.devName = value.name;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
data:{
|
||||
...data
|
||||
}
|
||||
}, ()=>{
|
||||
this.updateData()
|
||||
})
|
||||
}
|
||||
|
||||
updateData = () => {
|
||||
let data = {...this.state.data};
|
||||
data.type = 'do';
|
||||
|
||||
this.props.updateData(data);
|
||||
}
|
||||
|
||||
updateAct = (act, name) => {
|
||||
this.changeState('act', {act, name});
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n} = this.props;
|
||||
let dev = '';
|
||||
let m = this.state.data.dev.match(/(\d+)/);
|
||||
if(m!=null && m.length > 1){
|
||||
dev = m[1];
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<Form.Field>
|
||||
<label>選擇裝置</label>
|
||||
<select value={dev} onChange={e=>{
|
||||
let el = e.target;
|
||||
let json = {
|
||||
dev: '',
|
||||
name: ''
|
||||
};
|
||||
|
||||
json.dev = el.value;
|
||||
json.name = el.options[el.selectedIndex].innerHTML;
|
||||
|
||||
this.changeState('dev', json);
|
||||
}}>
|
||||
<option value="">選擇裝置</option>
|
||||
{
|
||||
this.state.list.map((t,idx) => (
|
||||
<option key={idx} value={t.id}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
<StdAction i18n={i18n} updateAct={this.updateAct} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default UnitLeone;
|
||||
@@ -0,0 +1,98 @@
|
||||
import React from 'react';
|
||||
import {Form, Input} from 'semantic-ui-react';
|
||||
import { getRequest } from '../../../../actions';
|
||||
import StdAction from './StdAction';
|
||||
|
||||
class UnitLeone extends React.Component {
|
||||
state = {
|
||||
list: [],
|
||||
data: {
|
||||
dev: '',
|
||||
devName: '',
|
||||
act: '',
|
||||
actName: ''
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let { showDialog } = this.props;
|
||||
fetch('/api/system/getselectlist', getRequest({ type: 'iogroup' }))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
if (json.status != 1) return showDialog(json.message);
|
||||
this.setState({
|
||||
list: json.data.record || []
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
changeState = (tag, value) =>{
|
||||
let data = {...this.state.data};
|
||||
|
||||
if(tag == 'act') {
|
||||
data.actName = value.name;
|
||||
data.act = value.act;
|
||||
}
|
||||
if(tag == 'dev'){
|
||||
data.dev = value.dev == '' ? '' : `iogroup${value.dev}`;
|
||||
data.devName = value.name;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
data:{
|
||||
...data
|
||||
}
|
||||
}, ()=>{
|
||||
this.updateData()
|
||||
})
|
||||
}
|
||||
|
||||
updateData = () => {
|
||||
let data = {...this.state.data};
|
||||
data.type = 'iogroup';
|
||||
|
||||
this.props.updateData(data);
|
||||
}
|
||||
|
||||
updateAct = (act, name) => {
|
||||
this.changeState('act', {act, name});
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n} = this.props;
|
||||
let dev = '';
|
||||
let m = this.state.data.dev.match(/(\d+)/);
|
||||
if(m!=null && m.length > 1){
|
||||
dev = m[1];
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<Form.Field>
|
||||
<label>選擇裝置</label>
|
||||
<select value={dev} onChange={e=>{
|
||||
let el = e.target;
|
||||
let json = {
|
||||
dev: '',
|
||||
name: ''
|
||||
};
|
||||
|
||||
json.dev = el.value;
|
||||
json.name = el.options[el.selectedIndex].innerHTML;
|
||||
|
||||
this.changeState('dev', json);
|
||||
}}>
|
||||
<option value="">選擇裝置</option>
|
||||
{
|
||||
this.state.list.map((t,idx) => (
|
||||
<option key={idx} value={t.id}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
<StdAction i18n={i18n} updateAct={this.updateAct} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default UnitLeone;
|
||||
@@ -0,0 +1,98 @@
|
||||
import React from 'react';
|
||||
import {Form, Input} from 'semantic-ui-react';
|
||||
import { getRequest } from '../../../../actions';
|
||||
import StdAction from './StdAction';
|
||||
|
||||
class UnitLeone extends React.Component {
|
||||
state = {
|
||||
list: [],
|
||||
data: {
|
||||
dev: '',
|
||||
devName: '',
|
||||
act: '',
|
||||
actName: ''
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let { showDialog } = this.props;
|
||||
fetch('/api/system/getselectlist', getRequest({ type: 'leone' }))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
if (json.status != 1) return showDialog(json.message);
|
||||
this.setState({
|
||||
list: json.data.record || []
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
changeState = (tag, value) =>{
|
||||
let data = {...this.state.data};
|
||||
|
||||
if(tag == 'act') {
|
||||
data.actName = value.name;
|
||||
data.act = value.act;
|
||||
}
|
||||
if(tag == 'dev'){
|
||||
data.dev = value.dev == '' ? '' : `le${value.dev}`;
|
||||
data.devName = value.name;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
data:{
|
||||
...data
|
||||
}
|
||||
}, ()=>{
|
||||
this.updateData()
|
||||
})
|
||||
}
|
||||
|
||||
updateData = () => {
|
||||
let data = {...this.state.data};
|
||||
data.type = 'leone';
|
||||
|
||||
this.props.updateData(data);
|
||||
}
|
||||
|
||||
updateAct = (act, name) => {
|
||||
this.changeState('act', {act, name});
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n} = this.props;
|
||||
let dev = '';
|
||||
let m = this.state.data.dev.match(/(\d+)/);
|
||||
if(m!=null && m.length > 1){
|
||||
dev = m[1];
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<Form.Field>
|
||||
<label>選擇裝置</label>
|
||||
<select value={dev} onChange={e=>{
|
||||
let el = e.target;
|
||||
let json = {
|
||||
dev: '',
|
||||
name: ''
|
||||
};
|
||||
|
||||
json.dev = el.value;
|
||||
json.name = el.options[el.selectedIndex].innerHTML;
|
||||
|
||||
this.changeState('dev', json);
|
||||
}}>
|
||||
<option value="">選擇裝置</option>
|
||||
{
|
||||
this.state.list.map((t,idx) => (
|
||||
<option key={idx} value={t.id}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
<StdAction i18n={i18n} updateAct={this.updateAct} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default UnitLeone;
|
||||
@@ -0,0 +1,185 @@
|
||||
import React from 'react';
|
||||
import {Form, Input} from 'semantic-ui-react';
|
||||
import { getRequest } from '../../../../actions';
|
||||
import CalModal from './CalModal';
|
||||
|
||||
class UnitLeone extends React.Component {
|
||||
state = {
|
||||
list: [],
|
||||
data: {
|
||||
dev: '',
|
||||
devName: '',
|
||||
func: '',
|
||||
funcName: '',
|
||||
addr: '',
|
||||
value: ''
|
||||
},
|
||||
modal: false
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let { showDialog } = this.props;
|
||||
fetch('/api/system/getselectlist', getRequest({ type: 'modbus' }))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
if (json.status != 1) return showDialog(json.message);
|
||||
this.setState({
|
||||
list: json.data.record || []
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
renderModal = () => {
|
||||
let {i18n} = this.props;
|
||||
return (
|
||||
this.state.modal ?
|
||||
(
|
||||
<CalModal i18n={i18n} onClose={this.closeModal} onSubmit={this.submitModal} />
|
||||
): null
|
||||
)
|
||||
}
|
||||
|
||||
closeModal = () => {
|
||||
this.setState({
|
||||
modal: false
|
||||
})
|
||||
}
|
||||
|
||||
submitModal = (data) => {
|
||||
if(!data) return ;
|
||||
let {showDialog} = this.props;
|
||||
let {r1, r2, s1, s2, val} = data;
|
||||
if(!isFinite(r1) || !isFinite(r2) || !isFinite(s1) || !isFinite(s2) || !isFinite(val)) return showDialog('請勿輸入數字以外的內容');
|
||||
|
||||
let value = Math.round(((val - r1) * (s2 - s1)) / (r2 - r1));
|
||||
|
||||
this.setState({
|
||||
data:{
|
||||
...this.state.data,
|
||||
value
|
||||
}
|
||||
}, ()=>{this.closeModal()})
|
||||
}
|
||||
|
||||
changeState = (tag, value) =>{
|
||||
let data = {...this.state.data};
|
||||
|
||||
if(tag == 'func') {
|
||||
data.funcName = value.name;
|
||||
data.func = value.func;
|
||||
}
|
||||
if(tag == 'dev'){
|
||||
data.dev = value.dev == '' ? '' : `mb${value.dev}`;
|
||||
data.devName = value.name;
|
||||
}
|
||||
if(tag == 'addr'){
|
||||
data.addr = value;
|
||||
}
|
||||
if(tag == 'value'){
|
||||
data.value = value;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
data:{
|
||||
...data
|
||||
}
|
||||
}, ()=>{
|
||||
this.updateData()
|
||||
})
|
||||
}
|
||||
|
||||
updateData = () => {
|
||||
let data = {...this.state.data};
|
||||
data.type = 'modbus';
|
||||
|
||||
data.act = `${data.func},${data.addr},${data.value}`;
|
||||
data.actName = `${data.funcName} Addr:${data.addr} Value:${data.value}`;
|
||||
|
||||
delete data.func;
|
||||
delete data.funcName;
|
||||
delete data.addr;
|
||||
delete data.value;
|
||||
|
||||
this.props.updateData(data);
|
||||
}
|
||||
|
||||
updateAct = (act, name) => {
|
||||
this.changeState('act', {act, name});
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n} = this.props;
|
||||
let dev = '';
|
||||
let m = this.state.data.dev.match(/(\d+)/);
|
||||
|
||||
if(m!=null && m.length > 1){
|
||||
dev = m[1];
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<Form.Field>
|
||||
<label>選擇裝置</label>
|
||||
<select value={dev} onChange={e=>{
|
||||
let el = e.target;
|
||||
let json = {
|
||||
dev: '',
|
||||
name: ''
|
||||
};
|
||||
|
||||
json.dev = el.value;
|
||||
json.name = el.options[el.selectedIndex].innerHTML;
|
||||
|
||||
this.changeState('dev', json);
|
||||
}}>
|
||||
<option value="">選擇裝置</option>
|
||||
{
|
||||
this.state.list.map((t,idx) => (
|
||||
<option key={idx} value={t.id}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>選擇輸出類型</label>
|
||||
<select value={this.state.data.func} onChange={e=>{
|
||||
let el = e.target;
|
||||
let json = {
|
||||
func: '',
|
||||
name: ''
|
||||
};
|
||||
|
||||
json.func = el.value;
|
||||
json.name = el.options[el.selectedIndex].innerHTML;
|
||||
|
||||
this.changeState('func', json);
|
||||
}}>
|
||||
<option value="">輸出類型</option>
|
||||
<option value="5">DigitalOutput</option>
|
||||
<option value="6">AnalogOutput</option>
|
||||
</select>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input label="輸入位址" value={this.state.data.addr} onChange={(e,d) => {this.changeState('addr', d.value)}} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input label="輸入數值"
|
||||
value={this.state.data.value}
|
||||
onChange={(e,d) => {this.changeState('value', d.value)}}
|
||||
action={{
|
||||
content:"數值換算",
|
||||
basic: true,
|
||||
onClick: ()=>{
|
||||
this.setState({
|
||||
modal: true
|
||||
})
|
||||
},
|
||||
type: 'button'
|
||||
}} />
|
||||
</Form.Field>
|
||||
{this.renderModal()}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default UnitLeone;
|
||||
@@ -0,0 +1,135 @@
|
||||
import React from 'react';
|
||||
import {Segment, Button, Form, Input} from 'semantic-ui-react';
|
||||
import UnitLeone from './UnitLeone';
|
||||
import UnitDigitalOutput from './UnitDigitalOutput';
|
||||
import UnitIOGroup from './UnitIOGroup';
|
||||
import UnitModbus from './UnitModbus';
|
||||
|
||||
const stateDefault = () => ({
|
||||
unit: '',
|
||||
act: {
|
||||
type: '',
|
||||
dev: '',
|
||||
devName: '',
|
||||
act: '',
|
||||
actName: ''
|
||||
}
|
||||
})
|
||||
|
||||
class ActionSelect extends React.Component {
|
||||
|
||||
state = {
|
||||
...stateDefault()
|
||||
}
|
||||
|
||||
changeUnit = (unit) => {
|
||||
this.setState({
|
||||
unit
|
||||
})
|
||||
}
|
||||
|
||||
getUnitComponent = () => {
|
||||
let {unit} = this.state;
|
||||
let {i18n, showDialog, toggleLoading} = this.props;
|
||||
|
||||
switch(unit){
|
||||
case 'leone':
|
||||
return (
|
||||
<UnitLeone i18n={i18n}
|
||||
data={this.state.act}
|
||||
showDialog={showDialog}
|
||||
toggleLoading={toggleLoading}
|
||||
updateData={this.updateData} />
|
||||
)
|
||||
case 'do':
|
||||
return (
|
||||
<UnitDigitalOutput i18n={i18n}
|
||||
data={this.state.act}
|
||||
showDialog={showDialog}
|
||||
toggleLoading={toggleLoading}
|
||||
updateData={this.updateData} />
|
||||
)
|
||||
case 'iogroup':
|
||||
return (
|
||||
<UnitIOGroup i18n={i18n}
|
||||
data={this.state.act}
|
||||
showDialog={showDialog}
|
||||
toggleLoading={toggleLoading}
|
||||
updateData={this.updateData} />
|
||||
)
|
||||
case 'modbus':
|
||||
return (
|
||||
<UnitModbus i18n={i18n}
|
||||
data={this.state.act}
|
||||
showDialog={showDialog}
|
||||
toggleLoading={toggleLoading}
|
||||
updateData={this.updateData} />
|
||||
)
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
updateData = (data) => {
|
||||
let {act} = this.state;
|
||||
for(let i in act){
|
||||
act[i] = data[i] || ''
|
||||
}
|
||||
this.setState({
|
||||
act
|
||||
})
|
||||
}
|
||||
|
||||
addAction = () => {
|
||||
let {dev, devName, act, actName, type} = this.state.act;
|
||||
let {showDialog} = this.props;
|
||||
if(!dev || !act) return showDialog('請選擇動作資料');
|
||||
if(type != 'modbus'){
|
||||
let acts = act.split(',');
|
||||
if(acts.length != 2 ) return showDialog('請選擇正確的動作');
|
||||
if(acts[0] == '2'){
|
||||
if(acts[1] < 16 || acts[1] > 30) return showDialog('冷氣溫度請介於16-30間');
|
||||
}
|
||||
}
|
||||
if(type == 'modbus'){
|
||||
let acts = act.split(',');
|
||||
if(acts.length != 3) return showDialog('請把動作資料填寫完成');
|
||||
if(acts[0] == '' || acts[1] == '' || acts[2] == '') return showDialog('請把動作資料填寫完成');
|
||||
}
|
||||
|
||||
this.props.addNewAction({
|
||||
dev,devName,act,actName,type
|
||||
}, this.clearField);
|
||||
}
|
||||
|
||||
clearField = () => {
|
||||
this.setState({
|
||||
...stateDefault()
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<Segment color="green">
|
||||
<Form.Field>
|
||||
<label>選擇裝置類型</label>
|
||||
<select value={this.state.unit} onChange={e=>{this.changeUnit(e.target.value)}}>
|
||||
<option value="">裝置類型</option>
|
||||
<option value="leone">LeOne</option>
|
||||
<option value="do">DigitalOutput</option>
|
||||
<option value="iogroup">IOGroup</option>
|
||||
<option value="modbus">Modbus</option>
|
||||
</select>
|
||||
</Form.Field>
|
||||
{this.getUnitComponent()}
|
||||
<div style={{textAlign:'right', marginTop: '20px'}}>
|
||||
<Button content="加入" basic size="mini" color="blue" onClick={()=>{ this.addAction() }} />
|
||||
<Button content="清除" basic size="mini" color="red" onClick={()=>{this.clearField()}} />
|
||||
</div>
|
||||
</Segment>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ActionSelect;
|
||||
@@ -0,0 +1,105 @@
|
||||
import React from 'react';
|
||||
import {Input} from 'semantic-ui-react';
|
||||
import {getRequest} from '../../../../../actions';
|
||||
|
||||
class UnitDigitalInput extends React.Component {
|
||||
state = {
|
||||
list: [],
|
||||
data: {
|
||||
id: '',
|
||||
op: '',
|
||||
value: ''
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
let {showDialog, toggleLoading} = this.props;
|
||||
|
||||
toggleLoading(1);
|
||||
fetch('/api/system/getselectlist', getRequest({type: 'di'}))
|
||||
.then(response=>response.json())
|
||||
.then(json=>{
|
||||
toggleLoading(0);
|
||||
if(json.status != 1) return showDialog(json.message);
|
||||
this.setState({
|
||||
list: json.data.record || []
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
componentWillReceiveProps(np) {
|
||||
let data = {...this.state.data};
|
||||
if(np.data.id != data.id) data.id = np.data.id;
|
||||
if(np.data.op != data.op) data.op = np.data.op;
|
||||
if(np.data.value != data.value) data.value = np.data.op;
|
||||
|
||||
this.setState({
|
||||
data: {...data}
|
||||
})
|
||||
}
|
||||
|
||||
changeState = (key, value) => {
|
||||
let data = {
|
||||
...this.state.data
|
||||
}
|
||||
if(key == 'dev') {
|
||||
data.id = value == '' ? '' : `di${value},di_status`;
|
||||
}
|
||||
if(key == 'op'){
|
||||
data.op = value;
|
||||
}
|
||||
if(key == 'value') {
|
||||
data.value = value;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
data: {...data}
|
||||
}, ()=>{ this.sendUpdate() });
|
||||
}
|
||||
|
||||
sendUpdate = () => {
|
||||
this.props.updateData({...this.props.data, ...this.state.data});
|
||||
}
|
||||
|
||||
render() {
|
||||
let {ops} = this.props;
|
||||
let id = '';
|
||||
if(this.state.data.id != '') {
|
||||
let m = this.state.data.id.match(/(\d+)/);
|
||||
if(m != null && m.length > 1){
|
||||
id = m[1];
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<select value={id} onChange={e => {this.changeState('dev', e.target.value)}}>
|
||||
<option value="">選擇裝置</option>
|
||||
{
|
||||
this.state.list.map((t,idx) => (
|
||||
<option key={idx} value={t.id}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
<select value={this.state.data.op} onChange={e => {this.changeState('op', e.target.value)}}>
|
||||
<option value="">選擇條件</option>
|
||||
{
|
||||
ops.map((t,idx) => {
|
||||
if(t.code != 8 && t.code != 9) {
|
||||
return (
|
||||
<option value={t.code} key={idx}>{t.name}</option>
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
</select>
|
||||
<select value={this.state.data.value} onChange={e => {this.changeState('value', e.target.value)}}>
|
||||
<option value="">選擇狀態</option>
|
||||
<option value="0">0</option>
|
||||
<option value="1">1</option>
|
||||
</select>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default UnitDigitalInput;
|
||||
@@ -0,0 +1,26 @@
|
||||
import React from 'react';
|
||||
import {Input} from 'semantic-ui-react';
|
||||
import {getRequest} from '../../../../../actions';
|
||||
|
||||
class UnitGroups extends React.Component {
|
||||
|
||||
render() {
|
||||
let {groups, data, updateData } = this.props;
|
||||
return (
|
||||
<div>
|
||||
<select value={data.dev} onChange={e => {
|
||||
updateData({...data, dev: e.target.value});
|
||||
}}>
|
||||
<option value="">選擇群組</option>
|
||||
{
|
||||
Object.keys(groups).map((t,idx) => (
|
||||
<option key={idx} value={t}>{groups[t].name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default UnitGroups;
|
||||
@@ -0,0 +1,117 @@
|
||||
import React from 'react';
|
||||
import {Input} from 'semantic-ui-react';
|
||||
import {getRequest} from '../../../../../actions';
|
||||
|
||||
class UnitLeone extends React.Component {
|
||||
state = {
|
||||
list: [],
|
||||
data: {
|
||||
id: '',
|
||||
op: '',
|
||||
mode: '',
|
||||
value: ''
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
let {showDialog, toggleLoading} = this.props;
|
||||
|
||||
toggleLoading(1);
|
||||
fetch('/api/system/getselectlist', getRequest({type: 'leone'}))
|
||||
.then(response=>response.json())
|
||||
.then(json=>{
|
||||
toggleLoading(0);
|
||||
if(json.status != 1) return showDialog(json.message);
|
||||
this.setState({
|
||||
list: json.data.record || []
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
componentWillReceiveProps(np) {
|
||||
let data = {...this.state.data};
|
||||
if(np.data.op != data.op) data.op = np.data.op;
|
||||
if(np.data.value != data.value) data.value = np.data.op;
|
||||
|
||||
let id = np.data.id.split(',')[0];
|
||||
let mode = np.data.id.split(',')[1];
|
||||
if(id != data.id) data.id = id;
|
||||
if(mode != data.mode) data.mode = mode;
|
||||
|
||||
this.setState({
|
||||
data: {...data}
|
||||
})
|
||||
}
|
||||
|
||||
changeState = (key, value) => {
|
||||
let data = {
|
||||
...this.state.data
|
||||
}
|
||||
if(key == 'dev') {
|
||||
data.id = value == '' ? '' : `le${value}`;
|
||||
}
|
||||
if(key == 'mode'){
|
||||
data.mode = value;
|
||||
}
|
||||
if(key == 'op'){
|
||||
data.op = value;
|
||||
}
|
||||
if(key == 'value') {
|
||||
data.value = value;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
data: {...data}
|
||||
}, ()=>{ this.sendUpdate() });
|
||||
}
|
||||
|
||||
sendUpdate = () => {
|
||||
let data = {...this.state.data};
|
||||
data.id = `${data.id},${data.mode}`;
|
||||
delete data.mode;
|
||||
this.props.updateData({...this.props.data, ...data});
|
||||
}
|
||||
|
||||
render() {
|
||||
let {ops} = this.props;
|
||||
let id = '';
|
||||
if(this.state.data.id != '') {
|
||||
let m = this.state.data.id.match(/(\d+)/);
|
||||
if(m != null && m.length > 1){
|
||||
id = m[1];
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<select value={id} onChange={e => {this.changeState('dev', e.target.value)}}>
|
||||
<option value="">選擇裝置</option>
|
||||
{
|
||||
this.state.list.map((t,idx) => (
|
||||
<option key={idx} value={t.id}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
<select value={this.state.data.mode} onChange={e=>{this.changeState('mode', e.target.value)}}>
|
||||
<option value="">選擇感測器</option>
|
||||
<option value="leone_ttrigger1">溫度</option>
|
||||
<option value="leone_htrigger1">濕度</option>
|
||||
</select>
|
||||
<select value={this.state.data.op} onChange={e=>{this.changeState('op', e.target.value)}}>
|
||||
<option value="">選擇條件</option>
|
||||
{
|
||||
ops.map((t,idx) => {
|
||||
if(t.code != 8 && t.code != 9) {
|
||||
return (
|
||||
<option value={t.code} key={idx}>{t.name}</option>
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
</select>
|
||||
<Input placeholder="請輸入數值" value={this.state.data.value} onChange={(e, d)=>{this.changeState('value', d.value)}} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default UnitLeone;
|
||||
@@ -0,0 +1,200 @@
|
||||
import React from 'react';
|
||||
import {Input} from 'semantic-ui-react';
|
||||
import {getRequest} from '../../../../../actions';
|
||||
|
||||
class UnitDigitalInput extends React.Component {
|
||||
state = {
|
||||
list: [],
|
||||
typelist: [],
|
||||
portlist: [],
|
||||
data: {
|
||||
id: '',
|
||||
op: '',
|
||||
type: '',
|
||||
port: '',
|
||||
value: ''
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
let {showDialog, toggleLoading} = this.props;
|
||||
|
||||
toggleLoading(1);
|
||||
fetch('/api/system/getselectlist', getRequest({type: 'modbus'}))
|
||||
.then(response=>response.json())
|
||||
.then(json=>{
|
||||
toggleLoading(0);
|
||||
if(json.status != 1) return showDialog(json.message);
|
||||
this.setState({
|
||||
list: json.data.record || []
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
componentWillReceiveProps(np) {
|
||||
let data = {...this.state.data};
|
||||
// if(np.data.id != data.id) data.id = np.data.id;
|
||||
if(np.data.op != data.op) data.op = np.data.op;
|
||||
if(np.data.value != data.value) data.value = np.data.op;
|
||||
|
||||
let id = (np.data.id || '').split(',')[0];
|
||||
let type = ((np.data.id || '').split(',')[1] || '').split('|')[0] || '';
|
||||
let port = ((np.data.id || '').split(',')[1] || '').split('|')[1] || '';
|
||||
|
||||
if(data.id != id ) data.id = id;
|
||||
if(data.type != type ) data.type = type;
|
||||
if(data.port != port ) data.port = port;
|
||||
|
||||
this.setState({
|
||||
data: {...data}
|
||||
})
|
||||
}
|
||||
|
||||
getDevTypes = (id) => {
|
||||
if(!id) return ;
|
||||
let {i18n, showDialog} = this.props;
|
||||
let typelist = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.porttype') : [];
|
||||
fetch('/api/modbus/getmodbustype', getRequest({id}))
|
||||
.then(response=>response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return showDialog(json.message);
|
||||
let arr = json.data.record || [];
|
||||
for(let i in arr){
|
||||
for(let j in typelist) {
|
||||
if(arr[i].type == typelist[j].code){
|
||||
arr[i].name = typelist[j].name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({
|
||||
typelist: arr,
|
||||
portlist: [],
|
||||
data: {
|
||||
...this.state.data,
|
||||
type: '',
|
||||
port: ''
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getDevPorts = (id, type) => {
|
||||
if(!id || !type) return ;
|
||||
let {i18n, showDialog} = this.props;
|
||||
let mid = '';
|
||||
let m = id.match(/(\d+)/);
|
||||
if(m != null && m.length>1) mid = m[1];
|
||||
fetch('/api/modbus/getmodbusport', getRequest({id: mid, type}))
|
||||
.then(response=>response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return showDialog(json.message);
|
||||
let arr = json.data.record || [];
|
||||
|
||||
this.setState({
|
||||
portlist: arr,
|
||||
data: {
|
||||
...this.state.data,
|
||||
port: ''
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
changeState = (key, value) => {
|
||||
let data = {
|
||||
...this.state.data
|
||||
}
|
||||
if(key == 'dev') {
|
||||
data.id = value == '' ? '' : `mb${value}`;
|
||||
}
|
||||
if(key == 'op'){
|
||||
data.op = value;
|
||||
}
|
||||
if(key == 'type') {
|
||||
data.type = value
|
||||
}
|
||||
if(key == 'port') {
|
||||
data.port = value
|
||||
}
|
||||
if(key == 'value') {
|
||||
data.value = value;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
data: {...data}
|
||||
}, ()=>{
|
||||
if(key == 'dev'){
|
||||
this.getDevTypes(value);
|
||||
}
|
||||
if(key == 'type'){
|
||||
this.getDevPorts(this.state.data.id, this.state.data.type)
|
||||
}
|
||||
this.sendUpdate()
|
||||
});
|
||||
}
|
||||
|
||||
sendUpdate = () => {
|
||||
let data = {...this.state.data};
|
||||
data.id = `${data.id},${data.type}|${data.port}`;
|
||||
delete data.type;
|
||||
delete data.port;
|
||||
delete data.dev;
|
||||
this.props.updateData({...this.props.data, ...data});
|
||||
}
|
||||
|
||||
render() {
|
||||
let {ops, i18n} = this.props;
|
||||
let id = '';
|
||||
if(this.state.data.id != '') {
|
||||
let m = this.state.data.id.match(/(\d+)/);
|
||||
if(m != null && m.length > 1){
|
||||
id = m[1];
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<select value={id} onChange={e => {this.changeState('dev', e.target.value)}}>
|
||||
<option value="">選擇裝置</option>
|
||||
{
|
||||
this.state.list.map((t,idx) => (
|
||||
<option key={idx} value={t.id}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
<select value={this.state.data.type} onChange={e => {this.changeState('type', e.target.value)}}>
|
||||
<option value="">接口類型</option>
|
||||
{
|
||||
this.state.typelist.map((t,idx) => (
|
||||
<option key={idx} value={t.type}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
<select value={this.state.data.port} onChange={e => {this.changeState('port', e.target.value)}}>
|
||||
<option value="">接口</option>
|
||||
{
|
||||
this.state.portlist.map((t,idx) => (
|
||||
<option key={idx} value={t.portnum}>{`Port ${t.portnum} ${t.name ? ` - ${t.name}` : '' }`}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
<select value={this.state.data.op} onChange={e => {this.changeState('op', e.target.value)}}>
|
||||
<option value="">選擇條件</option>
|
||||
{
|
||||
ops.map((t,idx) => {
|
||||
if(t.code != 8 && t.code != 9) {
|
||||
return (
|
||||
<option value={t.code} key={idx}>{t.name}</option>
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
</select>
|
||||
<Input label="請輸入數值" value={this.state.data.value} onChange={(e,d)=>{this.changeState('value', d.value)}} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default UnitDigitalInput;
|
||||
@@ -0,0 +1,119 @@
|
||||
import React from 'react';
|
||||
import {Input} from 'semantic-ui-react';
|
||||
import {getRequest} from '../../../../../actions';
|
||||
|
||||
class UnitTime extends React.Component {
|
||||
state = {
|
||||
list: [],
|
||||
data: {
|
||||
op: '',
|
||||
id: 'dt0,mode0',
|
||||
year: '-',
|
||||
week: '-',
|
||||
month: '-',
|
||||
day: '-',
|
||||
hour: '-',
|
||||
min: '-'
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(np) {
|
||||
let data = {...this.state.data};
|
||||
if(np.data.op != data.op) data.op = np.data.op;
|
||||
|
||||
let year = np.data.value.split('|')[5] || '-';
|
||||
let week = np.data.value.split('|')[4] || '-';
|
||||
let month = np.data.value.split('|')[3] || '-';
|
||||
let day = np.data.value.split('|')[2] || '-';
|
||||
let hour = np.data.value.split('|')[1] || '-';
|
||||
let min = np.data.value.split('|')[0] || '-';
|
||||
|
||||
if(year != data.year) data.year = year;
|
||||
if(week != data.week) data.week = week;
|
||||
if(month != data.month) data.month = month;
|
||||
if(day != data.day) data.day = day;
|
||||
if(hour != data.hour) data.hour = hour;
|
||||
if(min != data.min) data.min = min;
|
||||
|
||||
this.setState({
|
||||
data: {...data}
|
||||
})
|
||||
}
|
||||
|
||||
changeState = (key, value) => {
|
||||
let data = {
|
||||
...this.state.data
|
||||
}
|
||||
if(key == 'op'){
|
||||
data.op = value;
|
||||
}
|
||||
if(key == 'year') {
|
||||
data.year = value == '' ? '-' : value;
|
||||
}
|
||||
if(key == 'week') {
|
||||
data.week = value == '' ? '-' : value;
|
||||
}
|
||||
if(key == 'month') {
|
||||
data.month = value == '' ? '-' : value;
|
||||
}
|
||||
if(key == 'day') {
|
||||
data.day = value == '' ? '-' : value;
|
||||
}
|
||||
if(key == 'hour') {
|
||||
data.hour = value == '' ? '-' : value;
|
||||
}
|
||||
if(key == 'min') {
|
||||
data.min = value == '' ? '-' : value;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
data: {...data}
|
||||
}, ()=>{ this.sendUpdate() });
|
||||
}
|
||||
|
||||
sendUpdate = () => {
|
||||
let data = {...this.state.data};
|
||||
data.value = `${data.min}|${data.hour}|${data.day}|${data.month}|${data.week}|${data.year}`;
|
||||
delete data.year;
|
||||
delete data.week;
|
||||
delete data.month;
|
||||
delete data.day;
|
||||
delete data.hour;
|
||||
delete data.min;
|
||||
this.props.updateData({...this.props.data, ...data});
|
||||
}
|
||||
|
||||
render() {
|
||||
let {ops} = this.props;
|
||||
return (
|
||||
<div>
|
||||
<select value={this.state.data.op} onChange={e=>{this.changeState('op', e.target.value)}}>
|
||||
<option value="">選擇條件</option>
|
||||
{
|
||||
ops.map((t,idx) => {
|
||||
if(t.code != 8 && t.code != 9) {
|
||||
return (
|
||||
<option value={t.code} key={idx}>{t.name}</option>
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
</select>
|
||||
<Input size="mini" placeholder="年(不指定請留空)" value={this.state.data.year == '-' ? '' : this.state.data.year}
|
||||
onChange={(e,d) => {this.changeState('year', d.value)}} />
|
||||
<Input size="mini" placeholder="週(不指定請留空)" value={this.state.data.week == '-' ? '' : this.state.data.week}
|
||||
onChange={(e,d) => {this.changeState('week', d.value)}} />
|
||||
<Input size="mini" placeholder="月(不指定請留空)" value={this.state.data.month == '-' ? '' : this.state.data.month}
|
||||
onChange={(e,d) => {this.changeState('month', d.value)}} />
|
||||
<Input size="mini" placeholder="日(不指定請留空)" value={this.state.data.day == '-' ? '' : this.state.data.day}
|
||||
onChange={(e,d) => {this.changeState('day', d.value)}} />
|
||||
<Input size="mini" placeholder="時(不指定請留空)" value={this.state.data.hour == '-' ? '' : this.state.data.hour}
|
||||
onChange={(e,d) => {this.changeState('hour', d.value)}} />
|
||||
<Input size="mini" placeholder="分(不指定請留空)" value={this.state.data.min == '-' ? '' : this.state.data.min}
|
||||
onChange={(e,d) => {this.changeState('min', d.value)}} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default UnitTime;
|
||||
@@ -0,0 +1,63 @@
|
||||
import React from 'react';
|
||||
import {Segment, Input, Form} from 'semantic-ui-react';
|
||||
import UnitLeone from './UnitLeone';
|
||||
import UnitDigitalInput from './UnitDigitalInput';
|
||||
import UnitTime from './UnitTime';
|
||||
import UnitGroups from './UnitGroups';
|
||||
import UnitModbus from './UnitModbus';
|
||||
|
||||
class Unit extends React.Component {
|
||||
|
||||
handleChangeUnit = (val) => {
|
||||
this.props.changeUnitType(this.props.id, val);
|
||||
}
|
||||
|
||||
getUnitComponent = () => {
|
||||
|
||||
let {data, ops, i18n, showDialog, toggleLoading, groups} = this.props;
|
||||
|
||||
switch(data.unit){
|
||||
case 'leone':
|
||||
return <UnitLeone ops={ops} data={data.data} i18n={i18n} showDialog={showDialog} toggleLoading={toggleLoading} updateData={this.updateData} />
|
||||
case 'di':
|
||||
return <UnitDigitalInput ops={ops} data={data.data} i18n={i18n} showDialog={showDialog} toggleLoading={toggleLoading} updateData={this.updateData} />
|
||||
case 'modbus':
|
||||
return <UnitModbus ops={ops} data={data.data} i18n={i18n} showDialog={showDialog} toggleLoading={toggleLoading} updateData={this.updateData} />
|
||||
case 'time':
|
||||
return <UnitTime ops={ops} data={data.data} i18n={i18n} showDialog={showDialog} toggleLoading={toggleLoading} updateData={this.updateData} />
|
||||
case 'unit':
|
||||
return <UnitGroups i18n={i18n} data={data.data} groups={groups} updateData={this.updateData} />
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
updateData = (data) => {
|
||||
console.log(data);
|
||||
this.props.updateData(this.props.id, data);
|
||||
}
|
||||
|
||||
render() {
|
||||
let {ops, id} = this.props;
|
||||
return (
|
||||
<Segment>
|
||||
<Form.Field>
|
||||
<label>選擇元件</label>
|
||||
<select value={this.props.data.unit} onChange={e => {
|
||||
this.handleChangeUnit(e.target.value);
|
||||
}}>
|
||||
<option value="">請選擇元件</option>
|
||||
<option value="leone">LeOne</option>
|
||||
<option value="di">DigitalInput</option>
|
||||
<option value="modbus">Modbus</option>
|
||||
<option value="time">時間</option>
|
||||
<option value="unit">已建立群組</option>
|
||||
</select>
|
||||
</Form.Field>
|
||||
{this.getUnitComponent()}
|
||||
</Segment>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Unit;
|
||||
@@ -0,0 +1,225 @@
|
||||
import React from 'react';
|
||||
import { Segment, Input, Button, Form, Grid } from 'semantic-ui-react';
|
||||
import Unit from './Unit';
|
||||
|
||||
const ops = [
|
||||
{
|
||||
"code": "0",
|
||||
"name": "等於"
|
||||
}, {
|
||||
"code": "1",
|
||||
"name": "大於"
|
||||
}, {
|
||||
"code": "2",
|
||||
"name": "小於"
|
||||
}, {
|
||||
"code": "3",
|
||||
"name": "大於等於"
|
||||
}, {
|
||||
"code": "4",
|
||||
"name": "小於等於"
|
||||
}, {
|
||||
"code": "5",
|
||||
"name": "不等於"
|
||||
}, {
|
||||
"code": "8",
|
||||
"name": "AND"
|
||||
}, {
|
||||
"code": "9",
|
||||
"name": "OR"
|
||||
}
|
||||
];
|
||||
|
||||
const stateDefault = () => ({
|
||||
id1: {
|
||||
unit: '',
|
||||
data: {}
|
||||
},
|
||||
id2: {
|
||||
unit: '',
|
||||
data: {}
|
||||
},
|
||||
name: '',
|
||||
op: ''
|
||||
})
|
||||
|
||||
const lcDef = () => ({
|
||||
type: 'lc',
|
||||
id: '',
|
||||
op: '',
|
||||
value: ''
|
||||
})
|
||||
|
||||
const lnDef = () => ({
|
||||
type: 'ln',
|
||||
dev: ''
|
||||
})
|
||||
|
||||
class ConditionField extends React.Component {
|
||||
state = {
|
||||
...stateDefault()
|
||||
}
|
||||
|
||||
changeUnitType = (id, type) => {
|
||||
let st = this.state;
|
||||
if(id in st){
|
||||
st[id].unit = type;
|
||||
if(type == ''){
|
||||
st[id].data = {}
|
||||
}else if(type == 'unit'){
|
||||
st[id].data = {...lnDef()}
|
||||
}else {
|
||||
st[id].data = {...lcDef()}
|
||||
}
|
||||
this.setState({
|
||||
...st
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
updateData = (id, data) => {
|
||||
let st = this.state;
|
||||
if(id in st) {
|
||||
st[id].data = data;
|
||||
this.setState({
|
||||
...st
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
clearField = () => {
|
||||
this.setState({
|
||||
...stateDefault()
|
||||
})
|
||||
}
|
||||
|
||||
joinGroup = () => {
|
||||
let id1 = {...this.state.id1};
|
||||
let id2 = {...this.state.id2};
|
||||
let {showDialog, addNewGroup} = this.props;
|
||||
if(!('type' in id1.data)){
|
||||
showDialog('請選擇元件');
|
||||
}else{
|
||||
if(id1.data.type == 'lc') {
|
||||
let chk = this.checkLC(id1.data);
|
||||
if(chk.status != 1) return showDialog(chk.message);
|
||||
}else{
|
||||
let chk = this.checkLN(id1.data);
|
||||
if(chk.status != 1) return showDialog(chk.message);
|
||||
}
|
||||
}
|
||||
|
||||
if(!('type' in id2.data)){
|
||||
showDialog('請選擇元件');
|
||||
}else{
|
||||
if(id2.data.type == 'lc') {
|
||||
let chk = this.checkLC(id2.data);
|
||||
if(chk.status != 1) return showDialog(chk.message);
|
||||
}else{
|
||||
let chk = this.checkLN(id2.data);
|
||||
if(chk.status != 1) return showDialog(chk.message);
|
||||
}
|
||||
}
|
||||
|
||||
if(!this.state.op) return showDialog('請選擇條件');
|
||||
if(!this.state.name) return showDialog('請輸入名稱');
|
||||
|
||||
addNewGroup({
|
||||
name: this.state.name,
|
||||
op: this.state.op,
|
||||
type: 'ln',
|
||||
id1: id1.data,
|
||||
id2: id2.data
|
||||
}, this.clearField);
|
||||
}
|
||||
|
||||
changeState = (tag, value) => {
|
||||
if(!tag) return ;
|
||||
if(tag == 'name'){
|
||||
this.setState({
|
||||
name: value
|
||||
})
|
||||
}
|
||||
if(tag == 'op'){
|
||||
this.setState({
|
||||
op: value
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
checkLC = (data) => {
|
||||
let json = {
|
||||
status: 0,
|
||||
message: ''
|
||||
};
|
||||
if(typeof data != 'object' || Object.keys(data).length == 0) return {...json, message: '請選擇元件'};
|
||||
if(!data.id) return {...json, message: '請選擇裝置'};
|
||||
if(!('op' in data) || data.op == '') return {...json, message: '請選擇條件'};
|
||||
if(!('value' in data) || data.value == '') return {...json, message: '請輸入數值'};
|
||||
return {...json, status: 1}
|
||||
}
|
||||
|
||||
checkLN = (data) => {
|
||||
let json = {
|
||||
status: 0,
|
||||
message: ''
|
||||
};
|
||||
if(typeof data != 'object' || Object.keys(data).length == 0) return {...json, message: '請選擇元件'};
|
||||
if(!data.dev) return {...json, message: '請選擇群組'};
|
||||
return {...json, status: 1};
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n, showDialog, toggleLoading} = this.props;
|
||||
return (
|
||||
<Segment color="red">
|
||||
<Form.Field>
|
||||
<Input label="節點名稱" value={this.state.name} onChange={(e,d)=>{ this.changeState('name', d.value) }} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>觸發條件</label>
|
||||
<select value={this.state.op} onChange={e=>{this.changeState('op', e.target.value)}}>
|
||||
<option value="">請選擇觸發條件</option>
|
||||
{
|
||||
ops.map((t,idx) => {
|
||||
if(t.code == 8 || t.code == 9) {
|
||||
return (
|
||||
<option key={idx} value={t.code}>{t.name}</option>
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
<Grid columns={2} padded>
|
||||
<Grid.Column>
|
||||
<Unit i18n={i18n} id="id1"
|
||||
data={this.state.id1}
|
||||
groups={this.props.groups}
|
||||
ops={ops}
|
||||
toggleLoading={toggleLoading}
|
||||
showDialog={showDialog}
|
||||
updateData={this.updateData}
|
||||
changeUnitType={this.changeUnitType}/>
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Unit i18n={i18n} id="id2"
|
||||
data={this.state.id2}
|
||||
groups={this.props.groups}
|
||||
ops={ops}
|
||||
toggleLoading={toggleLoading}
|
||||
showDialog={showDialog}
|
||||
updateData={this.updateData}
|
||||
changeUnitType={this.changeUnitType}/>
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
<div style={{textAlign: 'right'}}>
|
||||
<Button content="加入" basic size="mini" color="blue" onClick={()=>{this.joinGroup()}} />
|
||||
<Button content="清除" basic size="mini" color="red" onClick={()=>{this.clearField()}} />
|
||||
</div>
|
||||
</Segment>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ConditionField;
|
||||
@@ -0,0 +1,47 @@
|
||||
import React from 'react';
|
||||
import { Modal, Header, Button, Form } from 'semantic-ui-react';
|
||||
|
||||
const ShowTree = ({ i18n, open, data, onClose, delItem }) => {
|
||||
|
||||
return (
|
||||
<Modal open={open} onClose={()=>{onClose(0)}}>
|
||||
<Modal.Header content="連動群組資料" />
|
||||
<Modal.Content>
|
||||
<Form onSubmit={(e,d)=>{
|
||||
e.preventDefault();
|
||||
delItem(d.formData.key);
|
||||
}} serializer={e=>{
|
||||
let json = {key:''};
|
||||
let key = e.querySelector('select[name="key"]');
|
||||
if(key && 'value' in key) json.key = key.value;
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Form.Group inline>
|
||||
<Form.Field>
|
||||
<label>選擇要刪除的群組</label>
|
||||
<select name="key">
|
||||
<option value="">選擇群組</option>
|
||||
{
|
||||
Object.keys(data).map((t,idx) => (
|
||||
<option key={idx} value={t}>{data[t].name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Button type="submit" basic size="mini" content="刪除群組" />
|
||||
</Form.Field>
|
||||
</Form.Group>
|
||||
</Form>
|
||||
<pre>
|
||||
{
|
||||
JSON.stringify(data, null, 4)
|
||||
}
|
||||
</pre>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default ShowTree;
|
||||
@@ -0,0 +1,175 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Container,
|
||||
Segment,
|
||||
Form,
|
||||
Input,
|
||||
Button,
|
||||
Checkbox,
|
||||
Grid,
|
||||
Menu,
|
||||
List
|
||||
} from 'semantic-ui-react';
|
||||
import {getRequest} from '../../../actions';
|
||||
import ConditionField from './Condition';
|
||||
import ActionSelect from './ActionSelect';
|
||||
import ActionList from './ActionList';
|
||||
import ShowTree from './ShowTree';
|
||||
|
||||
const stateDefault = ()=>({
|
||||
groups: {},
|
||||
idx: 0,
|
||||
active: 0,
|
||||
actions: [],
|
||||
showTree: false
|
||||
})
|
||||
|
||||
class ActionLinkAdd extends React.Component {
|
||||
state = {
|
||||
...stateDefault()
|
||||
}
|
||||
|
||||
changeState = (tag, value) => {
|
||||
if(tag == 'active'){
|
||||
this.setState({
|
||||
active: value?1:0
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
addNewGroup = (data, cb = null) => {
|
||||
let devs = [];
|
||||
let {groups} = this.state
|
||||
if(data.id1.type == 'ln') devs.push(data.id1.dev)
|
||||
if(data.id2.type == 'ln') devs.push(data.id2.dev)
|
||||
|
||||
data.id1 = {...data.id1, ...groups[data.id1.dev]}
|
||||
data.id2 = {...data.id2, ...groups[data.id2.dev]}
|
||||
delete data.id1.dev;
|
||||
delete data.id2.dev;
|
||||
|
||||
for(let i in devs){
|
||||
if(devs[i] in groups) delete groups[devs[i]];
|
||||
}
|
||||
|
||||
let idx = this.state.idx + 1;
|
||||
groups[`unit${idx}`] = data;
|
||||
|
||||
this.setState({
|
||||
groups,
|
||||
idx
|
||||
}, ()=>{
|
||||
if(cb && typeof cb == 'function') cb();
|
||||
})
|
||||
}
|
||||
|
||||
addNewAction = (data, cb=null) => {
|
||||
this.setState({
|
||||
actions: [...this.state.actions, data]
|
||||
}, ()=>{
|
||||
if(cb && typeof cb == 'function') cb();
|
||||
})
|
||||
}
|
||||
|
||||
removeAction = (idx) => {
|
||||
let {actions} = this.state;
|
||||
actions.splice(idx, 1);
|
||||
this.setState({
|
||||
actions
|
||||
})
|
||||
}
|
||||
|
||||
toggleShowTree = (flag) => {
|
||||
this.setState({
|
||||
showTree: flag ? true : false
|
||||
})
|
||||
}
|
||||
|
||||
delGroup = (key) => {
|
||||
if(!key) return ;
|
||||
let {groups} = this.state;
|
||||
if(key in groups) delete groups[key];
|
||||
|
||||
this.setState({
|
||||
groups
|
||||
})
|
||||
}
|
||||
|
||||
saveLink = () => {
|
||||
let {showDialog, toggleLoading} = this.props;
|
||||
if(this.state.actions.length == 0) return showDialog('請至少加入一個動作');
|
||||
if(Object.keys(this.state.groups).length == 0) return showDialog('請建立群組');
|
||||
if(Object.keys(this.state.groups).length > 1) return showDialog('根群組數量大於一,請合併或刪除');
|
||||
|
||||
let data = {
|
||||
active: this.state.active,
|
||||
action: '',
|
||||
link: {}
|
||||
}
|
||||
|
||||
let act = [];
|
||||
for(let i in this.state.actions) {
|
||||
let tmp = this.state.actions[i];
|
||||
act.push(`${tmp.dev},${tmp.act},0`);
|
||||
}
|
||||
|
||||
data.action = act.join('|');
|
||||
|
||||
data.link = this.state.groups[Object.keys(this.state.groups)[0]];
|
||||
|
||||
fetch('/api/link/addlink', getRequest(data))
|
||||
.then(response=>response.json())
|
||||
.then(json=>{
|
||||
if(json.status != 1) return showDialog(json.message);
|
||||
showDialog('新增完成');
|
||||
this.resetData()
|
||||
})
|
||||
}
|
||||
|
||||
resetData = ()=>{
|
||||
this.setState({
|
||||
...stateDefault()
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n, showDialog, toggleLoading} = this.props;
|
||||
return (
|
||||
<Container>
|
||||
<Menu>
|
||||
<Menu.Menu position="right">
|
||||
<Menu.Item content="ShowTree" onClick={()=>{ this.toggleShowTree(1) }}/>
|
||||
<Menu.Item content="Save" onClick={()=>{this.saveLink()}}/>
|
||||
</Menu.Menu>
|
||||
</Menu>
|
||||
<Form as={Segment}>
|
||||
<Form.Field>
|
||||
<Checkbox label="啟用連動" checked={this.state.active == 1} onChange={(e,d)=>{this.changeState('active', d.checked)}} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>建立條件群組</label>
|
||||
<ConditionField i18n={i18n}
|
||||
showDialog={showDialog}
|
||||
toggleLoading={toggleLoading}
|
||||
groups={this.state.groups}
|
||||
addNewGroup={this.addNewGroup} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>加入動作</label>
|
||||
<ActionSelect i18n={i18n}
|
||||
showDialog={showDialog}
|
||||
toggleLoading={toggleLoading}
|
||||
addNewAction={this.addNewAction} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>已選擇動作</label>
|
||||
<ActionList i18n={i18n} list={this.state.actions} removeAction={this.removeAction} />
|
||||
</Form.Field>
|
||||
</Form>
|
||||
<ShowTree i18n={i18n} open={this.state.showTree} data={this.state.groups} onClose={this.toggleShowTree} delItem={this.delGroup} />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ActionLinkAdd;
|
||||
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import {} from 'semantic-ui-react';
|
||||
|
||||
class IPCamPage extends React.Component{
|
||||
|
||||
render(){
|
||||
|
||||
return (
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default IPCamPage;
|
||||
@@ -5,7 +5,8 @@ const AIOForm = ({i18n, open, type, data, onSubmit, onClose}) => {
|
||||
if(!open) return null;
|
||||
let input = {
|
||||
name: data.name || '',
|
||||
portnum: data.portnum || '',
|
||||
portnum: data.portnum,
|
||||
type: data.type,
|
||||
scale_min: data.scale_min || 0,
|
||||
scale_max: data.scale_max || 0,
|
||||
range_min: data.range_min || 0,
|
||||
@@ -14,7 +15,8 @@ const AIOForm = ({i18n, open, type, data, onSubmit, onClose}) => {
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell><Input name="name" onChange={(e,d)=>{input.name = d.value}} defaultValue={data.name || ''}/></Table.Cell>
|
||||
<Table.Cell><Input name="portnum" onChange={(e,d)=>{input.portnum = d.value}} defaultValue={data.portnum || ''}/></Table.Cell>
|
||||
<Table.Cell><Input name="portnum" onChange={(e,d)=>{input.portnum = d.value}} defaultValue={data.portnum}/></Table.Cell>
|
||||
<Table.Cell><Input name="type" onChange={(e,d)=>{input.type = d.value}} defaultValue={data.type}/></Table.Cell>
|
||||
<Table.Cell>
|
||||
<Input name="range_min" size="small" label="Min" onChange={(e,d)=>{input.range_min = d.value}} defaultValue={data.range_min || '0'}/>
|
||||
<Input name="range_max" size="small" label="Max" onChange={(e,d)=>{input.range_max = d.value}} defaultValue={data.range_max || '0'}/>
|
||||
|
||||
@@ -6,7 +6,8 @@ const AIOListItem = ({i18n, data, editAIO, delAIO}) => {
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>{data.name || ''}</Table.Cell>
|
||||
<Table.Cell>{data.portnum || ''}</Table.Cell>
|
||||
<Table.Cell>{data.portnum}</Table.Cell>
|
||||
<Table.Cell>{data.type}</Table.Cell>
|
||||
<Table.Cell>{data.range_min || 0} ~ {data.range_max || 0}</Table.Cell>
|
||||
<Table.Cell>{data.scale_min || 0} ~ {data.scale_max || 0}</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
@@ -47,6 +47,7 @@ class AIOModal extends React.Component {
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>名稱</Table.HeaderCell>
|
||||
<Table.HeaderCell>接口號碼</Table.HeaderCell>
|
||||
<Table.HeaderCell>資料類型</Table.HeaderCell>
|
||||
<Table.HeaderCell>Range(Min-Max)</Table.HeaderCell>
|
||||
<Table.HeaderCell>Scale(Min-Max)</Table.HeaderCell>
|
||||
<Table.HeaderCell>操作</Table.HeaderCell>
|
||||
|
||||
@@ -5,13 +5,16 @@ const DeviceListItem = ({i18n, idx, data, delModbus, editModbus, showDev, select
|
||||
|
||||
return (
|
||||
<List.Item active={data.uid == showDev}>
|
||||
<span style={{cursor: 'pointer'}} onClick={() => {
|
||||
selectDevToShow(data.uid);
|
||||
}}>
|
||||
{data.name} / Node:{data.node}
|
||||
</span>
|
||||
<Icon style={{cursor: 'pointer'}} name="trash" onClick={()=>{delModbus(data.uid || '')}}/>
|
||||
<Icon style={{cursor: 'pointer'}} name="write" onClick={()=>{editModbus(1, data)}}/>
|
||||
<Icon style={{cursor: 'pointer'}} name="trash" title="Delete" onClick={()=>{delModbus(data.uid || '')}}/>
|
||||
<Icon style={{cursor: 'pointer'}} name="write" title="Edit" onClick={()=>{editModbus(1, data)}}/>
|
||||
<List.Content style={{cursor: 'pointer'}} onClick={() => {
|
||||
selectDevToShow(data.uid);
|
||||
}}>
|
||||
<List.Header>
|
||||
{data.name}
|
||||
</List.Header>
|
||||
Node: {data.node} / Type: {data.type}
|
||||
</List.Content>
|
||||
</List.Item>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ const IOModal = ({i18n, open, type, data, onSubmit, onClose}) => {
|
||||
id: data.uid || '',
|
||||
addr: '',
|
||||
num: '',
|
||||
datalen: '',
|
||||
type: ''
|
||||
};
|
||||
|
||||
@@ -26,6 +27,8 @@ const IOModal = ({i18n, open, type, data, onSubmit, onClose}) => {
|
||||
if(num && 'value' in num) json.num = num.value;
|
||||
let type = e.querySelector('select[name="io_type"]');
|
||||
if(type && 'value' in type) json.type = type.value;
|
||||
let len = e.querySelector('input[name="datalen"]');
|
||||
if(len && 'value' in len) json.datalen = len.value;
|
||||
|
||||
return json;
|
||||
}}>
|
||||
@@ -41,10 +44,13 @@ const IOModal = ({i18n, open, type, data, onSubmit, onClose}) => {
|
||||
</select>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input name="addr" label="起始位址" defaultValue={data.addr || ''} />
|
||||
<Input name="addr" label="起始位址" defaultValue={data.addr} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input name="num" label="數量" defaultValue={data.num || ''} />
|
||||
<Input name="num" label="數量" defaultValue={data.num} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input name="datalen" label="資料長度" defaultValue={data.datalen} placeholder="長度不填則預設2"/>
|
||||
</Form.Field>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
|
||||
@@ -41,10 +41,10 @@ class IOPanel extends React.Component {
|
||||
return (
|
||||
<div>
|
||||
<Menu attached="top" tabular>
|
||||
<Menu.Item content="DigitOutput" name="1" active={this.state.tabIdx == "1"} onClick={this.tabItemClick} />
|
||||
<Menu.Item content="DigitInput" name="2" active={this.state.tabIdx == "2"} onClick={this.tabItemClick} />
|
||||
<Menu.Item content="AnalogyOutput" name="3" active={this.state.tabIdx == "3"} onClick={this.tabItemClick} />
|
||||
<Menu.Item content="AnalogyInput" name="4" active={this.state.tabIdx == "4"} onClick={this.tabItemClick} />
|
||||
<Menu.Item content="DigitalOutput" name="1" active={this.state.tabIdx == "1"} onClick={this.tabItemClick} />
|
||||
<Menu.Item content="DigitalInput" name="2" active={this.state.tabIdx == "2"} onClick={this.tabItemClick} />
|
||||
<Menu.Item content="AnalogOutput" name="3" active={this.state.tabIdx == "3"} onClick={this.tabItemClick} />
|
||||
<Menu.Item content="AnalogInput" name="4" active={this.state.tabIdx == "4"} onClick={this.tabItemClick} />
|
||||
<Menu.Menu position="right">
|
||||
<Menu.Item content="AddIO" icon="plus" onClick={()=>{ioModal(0)}}/>
|
||||
</Menu.Menu>
|
||||
@@ -54,7 +54,8 @@ class IOPanel extends React.Component {
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>起始位置</Table.HeaderCell>
|
||||
<Table.HeaderCell>接口數量</Table.HeaderCell>
|
||||
<Table.HeaderCell>讀取數量</Table.HeaderCell>
|
||||
<Table.HeaderCell>資料長度</Table.HeaderCell>
|
||||
<Table.HeaderCell>操作</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
@@ -72,6 +73,7 @@ class IOPanel extends React.Component {
|
||||
{
|
||||
ss.map((t,idx) => (
|
||||
<div key={idx}>
|
||||
<Label basic color="olive" content={`SetName:${t.name}`} />
|
||||
<Label basic color="blue" content={`PortNum:${t.port}`}/>
|
||||
<Label basic color="blue" content={`原始數值:${t.value}`}/>
|
||||
<Label basic color="blue" content={`轉換數值:${t.value2}`}/>
|
||||
|
||||
@@ -5,8 +5,9 @@ const IOPanelListItem = ({i18n, data, ioModal, delIOList, showAIOSet}) => {
|
||||
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>{data.addr || ''}</Table.Cell>
|
||||
<Table.Cell>{data.num || ''}</Table.Cell>
|
||||
<Table.Cell>{data.addr}</Table.Cell>
|
||||
<Table.Cell>{data.num}</Table.Cell>
|
||||
<Table.Cell>{data.datalen}</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Button type="button" basic content="修改" onClick={()=>{ioModal(1, data)}}/>
|
||||
<Button type="button" basic content="刪除" onClick={()=>{delIOList(data.uid || '')}}/>
|
||||
|
||||
@@ -15,6 +15,7 @@ const ModbusModal = ({i18n, open, type, data, onSubmit, onClose}) => {
|
||||
let json = {
|
||||
name: '',
|
||||
node: '',
|
||||
type: '',
|
||||
id: data.uid || '',
|
||||
original_node: data.node || ''
|
||||
};
|
||||
@@ -23,6 +24,8 @@ const ModbusModal = ({i18n, open, type, data, onSubmit, onClose}) => {
|
||||
if(n && 'value' in n) json.name = n.value;
|
||||
let nn = e.querySelector('input[name="node"]');
|
||||
if(nn && 'value' in nn) json.node = nn.value;
|
||||
let type = e.querySelector('input[name="type"]');
|
||||
if(type && 'value' in type) json.type = type.value;
|
||||
|
||||
return json ;
|
||||
}}>
|
||||
@@ -30,7 +33,10 @@ const ModbusModal = ({i18n, open, type, data, onSubmit, onClose}) => {
|
||||
<Input name="name" defaultValue={data.name || ''} label="Name"/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input name="node" defaultValue={data.node || ''} label="Node"/>
|
||||
<Input name="node" defaultValue={data.node} label="Node"/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input name="type" defaultValue={data.type} label="Type" placeholder="預設請留空"/>
|
||||
</Form.Field>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
|
||||
@@ -101,6 +101,7 @@ class ModbusPage extends React.Component {
|
||||
submitIOModal = (type, data) => {
|
||||
let {i18n} = this.props;
|
||||
if((type == 1 && !data.id) || !('addr' in data) || !('num' in data) || !('type' in data)) return this.props.showDialog(i18n.t('tip.input_empty'));
|
||||
if(data.datalen == 0) return this.props.showDialog('資料長度不能為0');
|
||||
|
||||
data.devuid = this.state.showDev;
|
||||
if(type == 1){
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import React from 'react';
|
||||
import {Modal, Input, Button, Form, Grid} from 'semantic-ui-react';
|
||||
|
||||
const CalModal = ({ i18n, onClose, onSubmit }) => {
|
||||
|
||||
return (
|
||||
<Modal open={true}>
|
||||
<Modal.Header content="數值換算" />
|
||||
<Modal.Content>
|
||||
<Form onSubmit={(e,d) => {
|
||||
e.preventDefault();
|
||||
onSubmit(d.formData);
|
||||
}} serializer={e=>{
|
||||
let json = {
|
||||
r1: '',
|
||||
r2: '',
|
||||
s1: '',
|
||||
s2: '',
|
||||
val: ''
|
||||
}
|
||||
|
||||
let r1 = e.querySelector('input[name="r1"]');
|
||||
if(r1 && 'value' in r1) json.r1 = r1.value;
|
||||
let r2 = e.querySelector('input[name="r2"]');
|
||||
if(r2 && 'value' in r2) json.r2 = r2.value;
|
||||
let s1 = e.querySelector('input[name="s1"]');
|
||||
if(s1 && 'value' in s1) json.s1 = s1.value;
|
||||
let s2 = e.querySelector('input[name="s2"]');
|
||||
if(s2 && 'value' in s2) json.s2 = s2.value;
|
||||
let val = e.querySelector('input[name="val"]');
|
||||
if(val && 'value' in val) json.val = val.value;
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Form.Field>
|
||||
<label>Range</label>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Input label="RangeMin" name="r1" />
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Input label="RangeMax" name="r2" />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>Scale</label>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Input label="ScaleMin" name="s1" />
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Input label="ScaleMax" name="s2" />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input label="輸入數值" name="val" />
|
||||
</Form.Field>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Button fluid content="送出" basic />
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button fluid type="button" content="取消" basic onClick={()=>{onClose()}} />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default CalModal;
|
||||
@@ -0,0 +1,132 @@
|
||||
import React from 'react';
|
||||
import {Container, Segment, Input, Form, Button} from 'semantic-ui-react';
|
||||
import {getRequest} from '../../../actions';
|
||||
import CalModal from './CalModal';
|
||||
|
||||
class ModbusCmdPage extends React.Component {
|
||||
|
||||
state = {
|
||||
res: '',
|
||||
value: '',
|
||||
modal: false
|
||||
}
|
||||
|
||||
handleSubmit = (data) => {
|
||||
let {i18n} = this.props;
|
||||
if(data.ip == '' || data.node == '' || data.func == '' || data.addr == '' || data.value == '') return this.props.showDialog(i18n&&i18n.t?i18n.t('tip.input_empty'):'');
|
||||
this.props.toggleLoading(1);
|
||||
this.setState({res:''})
|
||||
fetch('/api/modbus/modbuscmd', getRequest(data))
|
||||
.then(response=>response.json())
|
||||
.then(json=>{
|
||||
this.props.toggleLoading(0);
|
||||
if(json.status != 1) return this.props.showDialog(json.message);
|
||||
this.setState({
|
||||
res: json.data.record[0].msg || ''
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
renderModal = () => {
|
||||
let {i18n} = this.props;
|
||||
return (
|
||||
this.state.modal ?
|
||||
(
|
||||
<CalModal i18n={i18n} onClose={this.closeModal} onSubmit={this.submitModal} />
|
||||
): null
|
||||
)
|
||||
}
|
||||
|
||||
closeModal = () => {
|
||||
this.setState({
|
||||
modal: false
|
||||
})
|
||||
}
|
||||
|
||||
submitModal = (data) => {
|
||||
if(!data) return ;
|
||||
let {showDialog} = this.props;
|
||||
let {r1, r2, s1, s2, val} = data;
|
||||
if(!isFinite(r1) || !isFinite(r2) || !isFinite(s1) || !isFinite(s2) || !isFinite(val)) return showDialog('請勿輸入數字以外的內容');
|
||||
|
||||
let value = Math.round(((val - r1) * (s2 - s1)) / (r2 - r1));
|
||||
|
||||
this.setState({
|
||||
value
|
||||
}, ()=>{this.closeModal()})
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<Segment>
|
||||
<Form onSubmit={(e,d)=>{
|
||||
e.preventDefault();
|
||||
this.handleSubmit(d.formData);
|
||||
}} serializer={e=>{
|
||||
let json = {
|
||||
ip: '',
|
||||
node: '',
|
||||
func: '',
|
||||
addr: '',
|
||||
value: ''
|
||||
};
|
||||
|
||||
let ip = e.querySelector('input[name="ip"]');
|
||||
if(ip && 'value' in ip) json.ip = ip.value;
|
||||
let node = e.querySelector('input[name="node"]');
|
||||
if(node && 'value' in node) json.node = node.value;
|
||||
let func = e.querySelector('input[name="func"]');
|
||||
if(func && 'value' in func) json.func = func.value;
|
||||
let addr = e.querySelector('input[name="addr"]');
|
||||
if(addr && 'value' in addr) json.addr = addr.value;
|
||||
let val = e.querySelector('input[name="val"]');
|
||||
if(val && 'value' in val) json.value = val.value;
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Form.Field>
|
||||
<Input name="ip" label="請輸入IP" defaultValue="127.0.0.1" />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input name="node" label="請輸入節點" />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input name="func" label="請輸入FunctionCode" />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input name="addr" label="請輸入位址" />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input name="val"
|
||||
label="請輸入數值"
|
||||
action={{
|
||||
content: "數值換算",
|
||||
basic: true,
|
||||
type: 'button',
|
||||
onClick: ()=>{
|
||||
this.setState({
|
||||
modal: true
|
||||
})
|
||||
}
|
||||
}}
|
||||
value={this.state.value}
|
||||
onChange={(e,d) => {this.setState({value: d.value})}} />
|
||||
</Form.Field>
|
||||
<Button type="submit" content="送出" fluid />
|
||||
</Form>
|
||||
</Segment>
|
||||
<Segment>
|
||||
{
|
||||
this.state.res.split(/\n/).map((t,idx) => (
|
||||
<div key={idx}>{t}</div>
|
||||
))
|
||||
}
|
||||
</Segment>
|
||||
{this.renderModal()}
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ModbusCmdPage;
|
||||
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
import {Menu, Header} from 'semantic-ui-react';
|
||||
import ListItem from './DeviceListItem';
|
||||
|
||||
const DeviceList = ({i18n, list, selected, toggleSelect}) => {
|
||||
|
||||
return (
|
||||
<Menu vertical={true}>
|
||||
<Menu.Item>
|
||||
<Menu.Header content="裝置列表" />
|
||||
<Menu.Menu>
|
||||
{
|
||||
list.map((t, idx) => {
|
||||
return (
|
||||
<ListItem key={idx}
|
||||
i18n={i18n}
|
||||
data={t}
|
||||
toggleSelect={toggleSelect}
|
||||
checked={selected.indexOf(t.uid) == -1 ? false : true} />
|
||||
)
|
||||
})
|
||||
}
|
||||
</Menu.Menu>
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
}
|
||||
|
||||
export default DeviceList;
|
||||
@@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
import {Menu, Checkbox} from 'semantic-ui-react';
|
||||
|
||||
const ListItem = ({i18n, data, checked, toggleSelect}) => {
|
||||
|
||||
return (
|
||||
<Menu.Item>
|
||||
<Checkbox label={data.name} checked={checked} onChange={(e,d)=>{ toggleSelect(data.uid) }}/>
|
||||
</Menu.Item>
|
||||
)
|
||||
}
|
||||
|
||||
export default ListItem;
|
||||
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import {Table} from 'semantic-ui-react';
|
||||
import {convertTime} from '../../../tools'
|
||||
|
||||
const ListItem = ({i18n, data}) => {
|
||||
let iotype = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.porttype') : [];
|
||||
|
||||
let t = '';
|
||||
for(let i in iotype) {
|
||||
if(data.type == iotype[i].code) t = iotype[i].name;
|
||||
}
|
||||
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>{data.devname}</Table.Cell>
|
||||
<Table.Cell>{data.aioname}</Table.Cell>
|
||||
<Table.Cell>{data.port}</Table.Cell>
|
||||
<Table.Cell>{t}</Table.Cell>
|
||||
<Table.Cell>{data.value}</Table.Cell>
|
||||
<Table.Cell>{convertTime(data.tst)}</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default ListItem;
|
||||
@@ -0,0 +1,35 @@
|
||||
import React from 'react';
|
||||
import {Table, Segment} from 'semantic-ui-react';
|
||||
import ListItem from './LogListItem';
|
||||
|
||||
const LogPanel = ({i18n, log}) => {
|
||||
|
||||
return (
|
||||
<Segment>
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>裝置名稱</Table.HeaderCell>
|
||||
<Table.HeaderCell>接口名稱</Table.HeaderCell>
|
||||
<Table.HeaderCell>接口號碼</Table.HeaderCell>
|
||||
<Table.HeaderCell>接口類型</Table.HeaderCell>
|
||||
<Table.HeaderCell>數值</Table.HeaderCell>
|
||||
<Table.HeaderCell>時間</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{
|
||||
log.map((t,idx)=>{
|
||||
return (
|
||||
<ListItem key={idx} i18n={i18n}
|
||||
data={t} />
|
||||
)
|
||||
})
|
||||
}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</Segment>
|
||||
)
|
||||
}
|
||||
|
||||
export default LogPanel;
|
||||
@@ -0,0 +1,101 @@
|
||||
import React from 'react';
|
||||
import {Container, Menu, Grid, Button, Input, Segment, Table} from 'semantic-ui-react';
|
||||
import DeviceList from './DeviceList';
|
||||
import {convertTime} from '../../../tools';
|
||||
import Datetime from 'react-datetime';
|
||||
import LogPanel from './LogPanel';
|
||||
|
||||
let getDayTime = () => {
|
||||
let date = new Date();
|
||||
date.setHours(0,0,0,0);
|
||||
return date.getTime();
|
||||
}
|
||||
|
||||
class ModbusLogPage extends React.Component {
|
||||
state = {
|
||||
selected: [],
|
||||
stime: getDayTime(),
|
||||
etime: Date.now()
|
||||
}
|
||||
|
||||
toggleSelect = (id) => {
|
||||
let selected = [...this.state.selected];
|
||||
let idx = selected.indexOf(id);
|
||||
if(idx == -1) selected.push(id);
|
||||
else selected.splice(idx, 1);
|
||||
|
||||
this.setState({
|
||||
selected
|
||||
})
|
||||
}
|
||||
|
||||
getLogList = () => {
|
||||
let ids = [...this.state.selected];
|
||||
let data = {
|
||||
ids,
|
||||
stime: Math.floor(this.state.stime /1000),
|
||||
etime: Math.floor(this.state.etime)
|
||||
}
|
||||
|
||||
if(ids.length == 0) return this.props.showDialog('請選擇裝置');
|
||||
|
||||
this.props.getMBLog(data);
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
this.props.getList();
|
||||
|
||||
this.props.router.setRouteLeaveHook(this.props.route, () => {
|
||||
this.props.clearList();
|
||||
});
|
||||
}
|
||||
|
||||
render(){
|
||||
let {i18n, list, log} = this.props;
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Menu>
|
||||
<Menu.Item>
|
||||
<Input label="起始時間" input={
|
||||
<Datetime dateFormat="YYYY-MM-DD"
|
||||
timeFormat="HH:mm"
|
||||
value={convertTime(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={convertTime(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.getLogList()}} />
|
||||
</Menu.Item>
|
||||
</Menu.Menu>
|
||||
</Menu>
|
||||
<Grid>
|
||||
<Grid.Column width={4}>
|
||||
<DeviceList i18n={i18n}
|
||||
list={list}
|
||||
selected={this.state.selected}
|
||||
toggleSelect={this.toggleSelect}
|
||||
/>
|
||||
</Grid.Column>
|
||||
<Grid.Column width={12}>
|
||||
<LogPanel i18n={i18n}
|
||||
log={log} />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ModbusLogPage;
|
||||
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import {Grid, Segment, Header, List} from 'semantic-ui-react';
|
||||
import StatusItem from './StatusItem';
|
||||
|
||||
const DevField = ({ i18n, data }) => {
|
||||
|
||||
return (
|
||||
<Grid.Column>
|
||||
<Header as="h4" content={`Name: ${data.name} / Node: ${data.node}`} />
|
||||
<Segment style={{height: '400px', overflow: 'auto'}}>
|
||||
<List divided>
|
||||
{
|
||||
data.list.map((t,idx) => (
|
||||
<StatusItem key={idx} i18n={i18n} data={t} />
|
||||
))
|
||||
}
|
||||
</List>
|
||||
</Segment>
|
||||
</Grid.Column>
|
||||
)
|
||||
}
|
||||
|
||||
export default DevField;
|
||||
@@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
import { List, Label } from 'semantic-ui-react';
|
||||
import {convertTime} from '../../../tools'
|
||||
|
||||
const StatusItem = ({ i18n, data }) => {
|
||||
let iotype = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.porttype') : [];
|
||||
let iot = {};
|
||||
for(let i in iotype){
|
||||
iot[iotype[i].code] = iotype[i].name;
|
||||
}
|
||||
let tc = {
|
||||
"1": "orange",
|
||||
"2": "green",
|
||||
"3": "violet",
|
||||
"4": "brown"
|
||||
}
|
||||
return (
|
||||
<List.Item>
|
||||
<Label basic size="small" color="teal" content={`Port: ${data.port}`} />
|
||||
<Label basic size="small" color={tc[data.type] || 'blue'} content={`Type: ${iot[data.type]}`} />
|
||||
{
|
||||
data.type == 3 || data.type == 4 ?
|
||||
(<Label basic size="small" color="teal" content={`Name: ${data.name}`} />) :
|
||||
null
|
||||
}
|
||||
<Label basic size="small" color="blue" content={`數值: ${data.value2}`}/>
|
||||
<List.Description style={{textAlign: 'right'}}>
|
||||
{`最後更新於: ${convertTime(data.tst, true)}`}
|
||||
</List.Description>
|
||||
</List.Item>
|
||||
)
|
||||
}
|
||||
|
||||
export default StatusItem;
|
||||
@@ -0,0 +1,64 @@
|
||||
import React from 'react';
|
||||
import {Container, Segment, Grid, List, Label} from 'semantic-ui-react';
|
||||
import DevField from './DeviceField';
|
||||
|
||||
class ModbusPreview extends React.Component {
|
||||
state = {
|
||||
list: []
|
||||
}
|
||||
|
||||
tick = null
|
||||
|
||||
componentDidMount(){
|
||||
this.getList()
|
||||
this.tick = setInterval(this.runTick, 10000);
|
||||
}
|
||||
|
||||
componentWillUnmount(){
|
||||
clearInterval(this.tick);
|
||||
}
|
||||
|
||||
runTick = () => {
|
||||
this.getList();
|
||||
}
|
||||
|
||||
getList = () => {
|
||||
let {getRequest, showDialog} = this.props;
|
||||
fetch('/api/modbus/getalliostatus', getRequest())
|
||||
.then(response=>response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return showDialog(json.message);
|
||||
let dev = json.data.rt.device || [];
|
||||
let status = json.data.record || [];
|
||||
for(let i in dev) {
|
||||
dev[i].list = [];
|
||||
for(let j in status){
|
||||
if(status[j].node == dev[i].node){
|
||||
dev[i].list.push(status[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({
|
||||
list: dev
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n} = this.props;
|
||||
return (
|
||||
<Container fluid style={{paddingLeft: '10px', paddingRight: '10px'}}>
|
||||
<Grid columns={3}>
|
||||
{
|
||||
this.state.list.map((t,idx) => (
|
||||
<DevField key={idx} i18n={i18n} data={t} />
|
||||
))
|
||||
}
|
||||
</Grid>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ModbusPreview;
|
||||
@@ -0,0 +1,117 @@
|
||||
import React from 'react';
|
||||
import {Form, Input, Button, Label, Message} from 'semantic-ui-react';
|
||||
import {getRequest} from '../../../actions';
|
||||
|
||||
class TimezoneForm extends React.Component {
|
||||
state = {
|
||||
zones: [],
|
||||
zone: '',
|
||||
loc: '',
|
||||
selZone: null,
|
||||
selLoc: null
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
this.getZones();
|
||||
this.getZoneSet();
|
||||
}
|
||||
|
||||
getZones = () => {
|
||||
fetch('/api/system/gettimezonelist', getRequest())
|
||||
.then(response=>response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return this.props.showDialog(json.message);
|
||||
this.setState({
|
||||
zones: json.data.record || []
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getZoneSet = () => {
|
||||
fetch('/api/system/gettimezoneset', getRequest())
|
||||
.then(response=>response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return this.props.showDialog(json.message);
|
||||
let tz = (json.data.record[0].value || '').split('/');
|
||||
this.setState({
|
||||
zone: tz[0] || '',
|
||||
loc: tz[1] || ''
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
zonesChange = (data) => {
|
||||
this.setState({
|
||||
selZone: data == '' ? null : data
|
||||
})
|
||||
}
|
||||
|
||||
handleSubmit = () => {
|
||||
if(this.state.selZone == null || this.state.selLoc == null ) return this.props.showDialog('請選擇區域與城市');
|
||||
let zone = this.state.zones[this.state.selZone].name;
|
||||
let loc = this.state.zones[this.state.selZone].location[this.state.selLoc];
|
||||
|
||||
fetch('/api/system/settimezone', getRequest({timezone: `${zone}/${loc}`}))
|
||||
.then(response=>response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return this.props.showDialog(json.message);
|
||||
this.setState({
|
||||
selZone: null,
|
||||
selLoc: null
|
||||
}, () => {
|
||||
this.getZoneSet();
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
render(){
|
||||
return (
|
||||
<Form onSubmit={(e,d) => {
|
||||
e.preventDefault();
|
||||
this.handleSubmit();
|
||||
}} serializer={e=>{
|
||||
return {};
|
||||
}}>
|
||||
<Form.Field inline>
|
||||
{/*<Input label="系統Timezone"
|
||||
value={`${this.state.zone}${this.state.zone.length > 0 ? '/' : ''}${this.state.loc}`}
|
||||
disabled />*/}
|
||||
<label>系統Timezone</label>
|
||||
<Label content={`${this.state.zone}${this.state.zone.length > 0 ? '/' : ''}${this.state.loc}`} basic/>
|
||||
</Form.Field>
|
||||
<Form.Group inline>
|
||||
<Form.Field>
|
||||
<label>設定Timezone</label>
|
||||
<select value={this.state.selZone == null ? '' : this.state.selZone} onChange={e=>{ this.zonesChange(e.target.value); }}>
|
||||
<option value="">選擇區域</option>
|
||||
{
|
||||
this.state.zones.map((t,idx)=>(
|
||||
<option key={idx} value={idx}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
{
|
||||
this.state.selZone == null ? null :
|
||||
(
|
||||
<Form.Field>
|
||||
<select value={this.state.selLoc == null ? '' : this.state.selLoc}
|
||||
onChange={e => { this.setState({selLoc: e.target.value == '' ? null : e.target.value}) }}>
|
||||
<option value="">選擇城市</option>
|
||||
{
|
||||
this.state.zones[this.state.selZone].location.map((t,idx) => (
|
||||
<option key={idx} value={idx}>{t}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
)
|
||||
}
|
||||
</Form.Group>
|
||||
<Button type="submit" fluid content="更新Timezone" />
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default TimezoneForm;
|
||||
@@ -4,6 +4,7 @@ import Datetime from 'react-datetime';
|
||||
import {Container, Segment, Form, Header, Menu, Grid, Table, Input} from 'semantic-ui-react';
|
||||
import NetForm from './NetForm';
|
||||
import TimeForm from './TimeForm';
|
||||
import TimezoneForm from './TimezoneForm';
|
||||
import {convertTime,padding} from '../../../tools';
|
||||
|
||||
class SysInfo extends React.Component {
|
||||
@@ -37,6 +38,11 @@ class SysInfo extends React.Component {
|
||||
dispatch(set_system_time(dstr));
|
||||
}
|
||||
|
||||
showDialog = (msg) => {
|
||||
let {dispatch} = this.props;
|
||||
dispatch(add_dialog_msg(msg));
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n, network, time} = this.props;
|
||||
return (
|
||||
@@ -45,6 +51,10 @@ class SysInfo extends React.Component {
|
||||
<Header as="h2" content={i18n && 't' in i18n ? i18n.t('page.system_info.title.sysinfo') : ''} />
|
||||
<NetForm i18n={i18n} network={network} onSubmit={this.netSubmit}/>
|
||||
</Segment>
|
||||
<Segment>
|
||||
<Header as="h2" content="Time Zone" />
|
||||
<TimezoneForm i18n={i18n} showDialog={this.showDialog} />
|
||||
</Segment>
|
||||
<Segment style={{marginBottom: '100px'}}>
|
||||
<Header as="h2" content={i18n && 't' in i18n ? i18n.t('page.system_info.title.timeinfo') : ''} />
|
||||
<TimeForm i18n={i18n} time={time} onSubmit={this.timeSubmit}/>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import {Table} from 'semantic-ui-react';
|
||||
import {convertTime, padding} from '../../../../tools';
|
||||
|
||||
const ListItem = ({i18n, data}) => {
|
||||
|
||||
return (
|
||||
<Table.Row style={{color: data.loss != 0 ? '#f00' : 'inherit'}}>
|
||||
<Table.Cell>{data.wristband}</Table.Cell>
|
||||
<Table.Cell>{data.name}</Table.Cell>
|
||||
<Table.Cell>{data.locname}</Table.Cell>
|
||||
<Table.Cell>{data.val3 ? parseInt(data.val3, 16) : ''}</Table.Cell>
|
||||
<Table.Cell>{data.val4 ? `${parseInt(data.val4, 16)}%` : ''}</Table.Cell>
|
||||
<Table.Cell>{data.val2 ? `${parseInt(data.val2, 16)}` : ''}</Table.Cell>
|
||||
<Table.Cell>{data.val5 ? `${parseInt(data.val5, 16)}` : ''}</Table.Cell>
|
||||
<Table.Cell>{data.val6 ? `${parseInt(data.val6, 16)}` : ''}</Table.Cell>
|
||||
<Table.Cell>{data.val7 ? `${parseInt(data.val7, 16)}` : ''}</Table.Cell>
|
||||
<Table.Cell>{data.val9 ? `${parseInt(data.val9, 16)}` : ''}</Table.Cell>
|
||||
<Table.Cell>{data.timestamp ? convertTime(data.timestamp, true) : ''}</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default ListItem;
|
||||
@@ -0,0 +1,172 @@
|
||||
import React from 'react';
|
||||
import {Container, Segment, Table, Label, Checkbox, Icon} from 'semantic-ui-react';
|
||||
import {getRequest} from '../../../../actions';
|
||||
import ListItem from './ListItem';
|
||||
|
||||
const sort_icon = {
|
||||
"asc": "caret down",
|
||||
"desc": "caret up"
|
||||
}
|
||||
|
||||
class LocStatus extends React.Component{
|
||||
state = {
|
||||
autoRefresh: true,
|
||||
list: [],
|
||||
sort: {
|
||||
field: '',
|
||||
order: ''
|
||||
}
|
||||
}
|
||||
tick = null
|
||||
|
||||
componentDidMount(){
|
||||
this.getList();
|
||||
this.checkRefresh();
|
||||
}
|
||||
|
||||
componentWillUnmount(){
|
||||
clearInterval(this.tick);
|
||||
}
|
||||
|
||||
changeRefresh = () => {
|
||||
this.setState({
|
||||
autoRefresh: !this.state.autoRefresh
|
||||
}, ()=>{
|
||||
this.checkRefresh();
|
||||
})
|
||||
}
|
||||
|
||||
checkRefresh = () => {
|
||||
if(this.state.autoRefresh) {
|
||||
this.tick = setInterval(this.runTick, 5000);
|
||||
}else{
|
||||
clearInterval(this.tick);
|
||||
}
|
||||
}
|
||||
|
||||
runTick = () => {
|
||||
this.getList();
|
||||
}
|
||||
|
||||
getList = () => {
|
||||
let {toggleLoading, showDialog} = this.props;
|
||||
let json = {
|
||||
sort: this.state.sort
|
||||
};
|
||||
|
||||
fetch('/api/wristband/getstatus', getRequest(json))
|
||||
.then(response=>response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return showDialog(json.message);
|
||||
this.setState({
|
||||
list: [...(json.data.record || [])]
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
handlerSort = (tag) => {
|
||||
if(!tag) return ;
|
||||
let sort = this.state.sort;
|
||||
if(tag == sort.field){
|
||||
if(sort.order == 'asc') sort.order = 'desc';
|
||||
else sort.order = 'asc';
|
||||
}else{
|
||||
sort.field = tag;
|
||||
sort.order = 'asc';
|
||||
}
|
||||
|
||||
this.setState({
|
||||
sort
|
||||
}, () => {
|
||||
this.getList();
|
||||
})
|
||||
}
|
||||
|
||||
renderSortIcon = (tag) => {
|
||||
if(this.state.sort.field == tag)
|
||||
return (<Icon size="large" name={sort_icon[this.state.sort.order]} />);
|
||||
return null;
|
||||
}
|
||||
|
||||
render (){
|
||||
let {i18n} = this.props;
|
||||
console.log(this.state.list);
|
||||
return (
|
||||
<Container fluid>
|
||||
<Segment className="clearfix">
|
||||
<Checkbox toggle checked={this.state.autoRefresh} onChange={(e,d) => {this.changeRefresh()}} label="自動更新" />
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell className="pointer" onClick={()=>{ this.handlerSort('mac') }}>
|
||||
手環ID
|
||||
{
|
||||
this.renderSortIcon('mac')
|
||||
}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell className="pointer" onClick={()=>{ this.handlerSort('name') }}>
|
||||
手環名稱
|
||||
{
|
||||
this.renderSortIcon('name')
|
||||
}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell className="pointer" onClick={()=>{this.handlerSort('loc')}}>
|
||||
地點
|
||||
{this.renderSortIcon('loc')}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell className="pointer" onClick={()=>{this.handlerSort('val3')}}>
|
||||
步數
|
||||
{
|
||||
this.renderSortIcon('val3')
|
||||
}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell className="pointer" onClick={()=>{this.handlerSort('val4')}}>
|
||||
剩餘電量
|
||||
{
|
||||
this.renderSortIcon('val4')
|
||||
}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell className="pointer" onClick={()=>{this.handlerSort('val2')}}>
|
||||
HR
|
||||
{this.renderSortIcon('val2')}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell className="pointer" onClick={()=>{this.handlerSort('val5')}}>
|
||||
SBP
|
||||
{this.renderSortIcon('val5')}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell className="pointer" onClick={()=>{this.handlerSort('val6')}}>
|
||||
DBP
|
||||
{this.renderSortIcon('val6')}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell className="pointer" onClick={()=>{this.handlerSort('val7')}}>
|
||||
卡路里
|
||||
{this.renderSortIcon('val7')}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell className="pointer" onClick={()=>{this.handlerSort('val9')}}>
|
||||
SOS
|
||||
{this.renderSortIcon('val9')}
|
||||
</Table.HeaderCell>
|
||||
<Table.HeaderCell className="pointer" onClick={()=>{this.handlerSort('time')}}>
|
||||
更新時間
|
||||
{this.renderSortIcon('time')}
|
||||
</Table.HeaderCell>
|
||||
{/*<Table.HeaderCell></Table.HeaderCell>*/}
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{
|
||||
this.state.list.map((t,idx)=>(
|
||||
<ListItem key={idx}
|
||||
i18n={i18n}
|
||||
data={t} />
|
||||
))
|
||||
}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</Segment>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default LocStatus;
|
||||
@@ -0,0 +1,120 @@
|
||||
import React from 'react';
|
||||
import {Grid, Header, Container, Segment, List, Label} from 'semantic-ui-react';
|
||||
import {getRequest} from '../../../../actions';
|
||||
import {padding} from '../../../../tools'
|
||||
|
||||
class LocStatusWloc extends React.Component {
|
||||
state = {
|
||||
loc: [],
|
||||
ui: {
|
||||
colLoading: false
|
||||
}
|
||||
}
|
||||
tick = null
|
||||
|
||||
componentDidMount() {
|
||||
this.getLocList();
|
||||
}
|
||||
componentWillUnmount(){
|
||||
clearInterval(this.tick);
|
||||
}
|
||||
|
||||
runTick = ()=>{
|
||||
this.getStatus();
|
||||
}
|
||||
|
||||
getLocList = ()=>{
|
||||
let {toggleLoading, showDialog} = this.props;
|
||||
toggleLoading(1);
|
||||
fetch('/api/wristband/getlocationlist', getRequest())
|
||||
.then(response=>response.json())
|
||||
.then(json=>{
|
||||
toggleLoading(0);
|
||||
if(json.status != 1) return showDialog(json.message);
|
||||
this.setState({
|
||||
loc: json.data.record || []
|
||||
}, ()=>{
|
||||
this.setState({
|
||||
ui:{
|
||||
colLoading: true
|
||||
}}, ()=>{})
|
||||
this.getStatus();
|
||||
this.tick = setInterval(this.runTick, 5000);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getStatus = () => {
|
||||
let {toggleLoading, showDialog} = this.props;
|
||||
|
||||
fetch('/api/wristband/getstatus', getRequest({
|
||||
sort: {
|
||||
field: 'time',
|
||||
order: 'desc'
|
||||
}
|
||||
}))
|
||||
.then(response=>response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return showDialog(json.message);
|
||||
let record = json.data.record || [];
|
||||
let locs = this.state.loc;
|
||||
for(let i in locs){
|
||||
locs[i].list = [];
|
||||
}
|
||||
for(let i in record) {
|
||||
let tmp = record[i];
|
||||
if(!tmp.locid) continue;
|
||||
for(let j in locs) {
|
||||
if(locs[j].serialnumber == tmp.locid) {
|
||||
locs[j].list.push(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({
|
||||
loc: locs,
|
||||
ui:{
|
||||
colLoading: false
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<Container fluid>
|
||||
<Grid columns={3}>
|
||||
{
|
||||
this.state.loc.map((t,idx) => (
|
||||
<Grid.Column key={idx} className="clearfix" >
|
||||
<Header as="h5" content={t.name} />
|
||||
<Segment style={{height: '400px', overflow: 'auto'}} loading={this.state.ui.colLoading}>
|
||||
<List>
|
||||
{
|
||||
t.list ?
|
||||
t.list.map((tt, idx) => {
|
||||
let isExpire = tt.loss == 1 ? true : false;
|
||||
return (<List.Item key={idx}>
|
||||
{
|
||||
tt.name ? (
|
||||
<Label basic color={isExpire ? 'red' : 'blue'} size="tiny" content={tt.name}/>
|
||||
) : null
|
||||
}
|
||||
<Label basic color={isExpire ? 'red' : 'teal'} size="tiny" content={tt.mac}/>
|
||||
</List.Item>)
|
||||
})
|
||||
: null
|
||||
}
|
||||
</List>
|
||||
</Segment>
|
||||
</Grid.Column>
|
||||
))
|
||||
}
|
||||
</Grid>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default LocStatusWloc;
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
import { Table, Button } from 'semantic-ui-react';
|
||||
|
||||
const ListItem = ({ i18n, data, delLocation, editLocation }) => {
|
||||
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Button content="Edit" basic onClick={()=>{editLocation(1, data)}} />
|
||||
<Button content="Delete" basic onClick={()=>{delLocation(data.uid)}} />
|
||||
</Table.Cell>
|
||||
<Table.Cell>{data.serialnumber}</Table.Cell>
|
||||
<Table.Cell>{data.name}</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default ListItem;
|
||||
@@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import { Modal, Form, Input, Button, Checkbox, Grid } from 'semantic-ui-react';
|
||||
|
||||
const WristbandModal = ({ i18n, open, type, data, closeModal, submitModal }) => {
|
||||
|
||||
return (
|
||||
<Modal open={open}>
|
||||
<Modal.Header content={type == 1 ? '修改資料' : '新增資料'} />
|
||||
<Modal.Content>
|
||||
<Form onSubmit={(e,d)=>{
|
||||
e.preventDefault();
|
||||
submitModal(type, d.formData);
|
||||
}} serializer={e => {
|
||||
let json = {
|
||||
name: '',
|
||||
sn: '',
|
||||
id: type == 1 ? data.uid : ''
|
||||
};
|
||||
|
||||
let name = e.querySelector('input[name="name"]');
|
||||
if(name && 'value' in name) json.name = name.value;
|
||||
let sn = e.querySelector('input[name="serialnumber"]');
|
||||
if(sn && 'value' in sn) json.sn = sn.value;
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Form.Field>
|
||||
<Input label="裝置序號" name="serialnumber" defaultValue={data.serialnumber} disabled={type == 1} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input label="名稱" name="name" defaultValue={data.name} />
|
||||
</Form.Field>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Button content="送出" fluid type="submit" />
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button content="取消" fluid type="button" onClick={()=>{ closeModal() }} />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default WristbandModal;
|
||||
@@ -0,0 +1,128 @@
|
||||
import React from 'react';
|
||||
import {Container, Segment, Button, Table} from 'semantic-ui-react';
|
||||
import {getRequest} from '../../../../actions';
|
||||
import ListItem from './ListItem';
|
||||
import LocationModal from './LocationModal';
|
||||
|
||||
const stateDefault = ()=>({
|
||||
list: [],
|
||||
modal: {
|
||||
open: false,
|
||||
type: 0,
|
||||
data: {}
|
||||
}
|
||||
})
|
||||
|
||||
class Location extends React.Component {
|
||||
|
||||
state = {
|
||||
...stateDefault()
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getList();
|
||||
}
|
||||
|
||||
getList = () => {
|
||||
let {showDialog, toggleLoading} = this.props;
|
||||
toggleLoading(1);
|
||||
fetch('/api/wristband/getlocationlist', getRequest())
|
||||
.then(response=>response.json())
|
||||
.then(json => {
|
||||
toggleLoading(0);
|
||||
if(json.status != 1) return showDialog(json.message);
|
||||
this.setState({
|
||||
list: json.data.record || []
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
openModal = (type, data = {}) =>{
|
||||
this.setState({
|
||||
modal: {
|
||||
open: true,
|
||||
type,
|
||||
data
|
||||
}
|
||||
})
|
||||
}
|
||||
closeModal = () => {
|
||||
this.setState({
|
||||
modal:{
|
||||
...stateDefault().modal
|
||||
}
|
||||
})
|
||||
}
|
||||
submitModal = (type, data) => {
|
||||
let {showDialog} = this.props;
|
||||
if(type == 1 && !data.id) return showDialog('資料取得失敗');
|
||||
if(type == 0 && !data.sn) return showDialog('請填寫裝置序號');
|
||||
|
||||
let url = type == 1 ? '/api/wristband/editlocation' : '/api/wristband/addlocation';
|
||||
fetch(url, getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return showDialog(json.message);
|
||||
this.setState({
|
||||
modal: {
|
||||
...stateDefault().modal
|
||||
}
|
||||
}, ()=>{
|
||||
this.getList();
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
delLocation = (id) => {
|
||||
if(!id) return ;
|
||||
let {showDialog, callConfirm} = this.props;
|
||||
callConfirm('確定要刪除這筆定位點資料?', ()=>{
|
||||
fetch('/api/wristband/dellocation', getRequest({id}))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return showDialog(json.message);
|
||||
this.getList();
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n} = this.props;
|
||||
return (
|
||||
<Container fluid>
|
||||
<Segment className="clearfix">
|
||||
<Button floated="right" basic color="green" style={{marginBottom: '15px'}} content="新增" icon="plus" onClick={()=>{this.openModal(0)}} />
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>操作</Table.HeaderCell>
|
||||
<Table.HeaderCell>裝置序號</Table.HeaderCell>
|
||||
<Table.HeaderCell>裝置名稱</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{
|
||||
this.state.list.map((t,idx) => (
|
||||
<ListItem key={idx}
|
||||
i18n={i18n}
|
||||
data={t}
|
||||
delLocation={this.delLocation}
|
||||
editLocation={this.openModal} />
|
||||
))
|
||||
}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</Segment>
|
||||
<LocationModal
|
||||
i18n={i18n}
|
||||
open={this.state.modal.open}
|
||||
type={this.state.modal.type}
|
||||
data={this.state.modal.data}
|
||||
closeModal={this.closeModal}
|
||||
submitModal={this.submitModal} />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Location;
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import { Table, Button } from 'semantic-ui-react';
|
||||
|
||||
const ListItem = ({ i18n, data, delWristband, editWristband, showPathInfo, showHealthInfo }) => {
|
||||
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Button content="Edit" basic onClick={()=>{editWristband(1, data)}} />
|
||||
<Button content="Delete" basic onClick={()=>{delWristband(data.uid)}} />
|
||||
<Button content="地點紀錄" basic onClick={()=>{showPathInfo(data.mac, data.name)}} />
|
||||
<Button content="生理資訊紀錄" basic onClick={()=>{showHealthInfo(data.mac, data.name)}} />
|
||||
</Table.Cell>
|
||||
<Table.Cell>{data.mac}</Table.Cell>
|
||||
<Table.Cell>{data.name}</Table.Cell>
|
||||
<Table.Cell>{data.identity}</Table.Cell>
|
||||
<Table.Cell>{data.monitor == 1 ? '啟用' : '停用'}</Table.Cell>
|
||||
<Table.Cell>{data.notify == 1 ? '啟用' : '停用'}</Table.Cell>
|
||||
<Table.Cell>{data.switch == 1 ? '啟用' : '停用'}</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default ListItem;
|
||||
@@ -0,0 +1,150 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Modal, List, Menu, Button, Input, Label, Table } 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: [],
|
||||
page: 1,
|
||||
maxPage: 1,
|
||||
stime: (getDayTime()),
|
||||
etime: (Date.now())
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
|
||||
}
|
||||
|
||||
closeView = () => {
|
||||
this.setState({
|
||||
list: [],
|
||||
page: 1,
|
||||
maxPage: 1,
|
||||
stime: (getDayTime()),
|
||||
etime: (Date.now())
|
||||
}, ()=>{
|
||||
this.props.closeModal();
|
||||
})
|
||||
}
|
||||
|
||||
getList = () => {
|
||||
let {mac, showDialog, getRequest} = this.props;
|
||||
fetch('/api/wristband/getwristbandhealthinfo', 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);
|
||||
let l = json.data.record || [];
|
||||
this.setState({
|
||||
list: l,
|
||||
page: 1,
|
||||
maxPage: Math.ceil(l.length / 20)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
nextPage = () => {
|
||||
let {page, maxPage} = this.state;
|
||||
this.setState({
|
||||
page: page >= maxPage ? maxPage : page+1
|
||||
})
|
||||
}
|
||||
|
||||
prevPage = () => {
|
||||
let {page} = this.state;
|
||||
this.setState({
|
||||
page: page <= 1 ? 1 : page-1
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
let {closeModal, open} = this.props;
|
||||
|
||||
let tmpList = this.state.list.slice((this.state.page - 1) * 20, ((this.state.page - 1) * 20 + 20))
|
||||
|
||||
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>
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<Button content="上一頁" size="small" labelPosition="left" basic={true} color="black" icon="arrow left" onClick={() => {this.prevPage()}} />
|
||||
<Label basic={true} color="blue" content={`${this.state.page || 1} / ${this.state.maxPage || 1}`} />
|
||||
<Button content="下一頁" size="small" labelPosition="right" basic={true} color="black" icon="arrow right" onClick={() => {this.nextPage()}} />
|
||||
</div>
|
||||
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>HR</Table.HeaderCell>
|
||||
<Table.HeaderCell>步數</Table.HeaderCell>
|
||||
<Table.HeaderCell>SBP</Table.HeaderCell>
|
||||
<Table.HeaderCell>DBP</Table.HeaderCell>
|
||||
<Table.HeaderCell>卡路里</Table.HeaderCell>
|
||||
<Table.HeaderCell>SOS</Table.HeaderCell>
|
||||
<Table.HeaderCell>更新時間</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{
|
||||
tmpList.map((t,idx) => {
|
||||
return (
|
||||
<Table.Row key={idx}>
|
||||
<Table.Cell>{parseInt(t.wphyloghr, 16)}</Table.Cell>
|
||||
<Table.Cell>{parseInt(t.wphylogsteps, 16)}</Table.Cell>
|
||||
<Table.Cell>{parseInt(t.wphylogsbp, 16)}</Table.Cell>
|
||||
<Table.Cell>{parseInt(t.wphylogdbp, 16)}</Table.Cell>
|
||||
<Table.Cell>{parseInt(t.wphylogcal, 16)}</Table.Cell>
|
||||
<Table.Cell>{parseInt(t.wphylogsos, 16)}</Table.Cell>
|
||||
<Table.Cell>{convertTime(t.wphylogtst, true)}</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default WristbandPathInfo;
|
||||
@@ -0,0 +1,70 @@
|
||||
import React from 'react';
|
||||
import { Modal, Form, Input, Button, Checkbox, Grid } from 'semantic-ui-react';
|
||||
|
||||
const WristbandModal = ({ i18n, open, type, data, closeModal, submitModal }) => {
|
||||
|
||||
return (
|
||||
<Modal open={open}>
|
||||
<Modal.Header content={type == 1 ? '修改資料' : '新增資料'} />
|
||||
<Modal.Content>
|
||||
<Form onSubmit={(e,d)=>{
|
||||
e.preventDefault();
|
||||
submitModal(type, d.formData);
|
||||
}} serializer={e => {
|
||||
let json = {
|
||||
name: '',
|
||||
identity: '',
|
||||
monitor: 0,
|
||||
notify: 0,
|
||||
id: type == 1 ? data.uid : '',
|
||||
mac: '',
|
||||
switch: 0
|
||||
};
|
||||
|
||||
let mac = e.querySelector('input[name="mac"]');
|
||||
if(mac && 'value' in mac) json.mac = mac.value;
|
||||
let name = e.querySelector('input[name="name"]');
|
||||
if(name && 'value' in name) json.name = name.value;
|
||||
let identity = e.querySelector('input[name="identity"]');
|
||||
if(identity && 'value' in identity) json.identity = identity.value;
|
||||
let monitor = e.querySelector('input[name="monitor"]');
|
||||
if(monitor && 'checked' in monitor) json.monitor = monitor.checked ? 1 : 0;
|
||||
let notify = e.querySelector('input[name="notify"]');
|
||||
if(notify && 'checked' in notify) json.notify = notify.checked ? 1 : 0;
|
||||
let sw = e.querySelector('input[name="switch"]');
|
||||
if(sw && 'checked' in sw) json.switch = sw.checked ? 1 : 0;
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Form.Field>
|
||||
<Input label="手環ID" name="mac" defaultValue={data.mac} disabled={type == 1} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input label="名稱" name="name" defaultValue={data.name} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input label="身份" name="identity" defaultValue={data.identity} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Checkbox label="監控" name="monitor" defaultChecked={data.monitor == 1} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Checkbox label="通知" name="notify" defaultChecked={data.notify == 1} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Checkbox label="啟用" name="switch" defaultChecked={data.switch == 1} />
|
||||
</Form.Field>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Button content="送出" fluid type="submit" />
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button content="取消" fluid type="button" onClick={()=>{ closeModal() }} />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default WristbandModal;
|
||||
@@ -0,0 +1,135 @@
|
||||
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: [],
|
||||
page: 1,
|
||||
maxPage: 1,
|
||||
stime: (getDayTime()),
|
||||
etime: (Date.now())
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
|
||||
}
|
||||
|
||||
closeView = () => {
|
||||
this.setState({
|
||||
list: [],
|
||||
page: 1,
|
||||
maxPage: 1,
|
||||
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);
|
||||
let l = json.data.record || [];
|
||||
this.setState({
|
||||
list: l,
|
||||
page: 1,
|
||||
maxPage: Math.ceil(l.length / 20)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
nextPage = () => {
|
||||
let {page, maxPage} = this.state;
|
||||
this.setState({
|
||||
page: page >= maxPage ? maxPage : page+1
|
||||
})
|
||||
}
|
||||
|
||||
prevPage = () => {
|
||||
let {page} = this.state;
|
||||
this.setState({
|
||||
page: page <= 1 ? 1 : page-1
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
let {closeModal, open} = this.props;
|
||||
|
||||
let tmpList = this.state.list.slice((this.state.page - 1) * 20, ((this.state.page - 1) * 20 + 20))
|
||||
|
||||
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>
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<Button content="上一頁" size="small" labelPosition="left" basic={true} color="black" icon="arrow left" onClick={() => {this.prevPage()}} />
|
||||
<Label basic={true} color="blue" content={`${this.state.page || 1} / ${this.state.maxPage || 1}`} />
|
||||
<Button content="下一頁" size="small" labelPosition="right" basic={true} color="black" icon="arrow right" onClick={() => {this.nextPage()}} />
|
||||
</div>
|
||||
|
||||
<List divided>
|
||||
{
|
||||
tmpList.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;
|
||||
@@ -0,0 +1,195 @@
|
||||
import React from 'react';
|
||||
import { Container, Segment, Table, Button } from 'semantic-ui-react';
|
||||
import {getRequest} from '../../../../actions';
|
||||
import ListItem from './ListItem';
|
||||
import WristbandModal from './WristbandModal';
|
||||
import WristbandPathInfo from './WristbandPathInfo';
|
||||
import WristbandHealthInfo from './WristbandHealthInfo';
|
||||
|
||||
const stateDefault = ()=>({
|
||||
list: [],
|
||||
modal: {
|
||||
open: false,
|
||||
type: 0,
|
||||
data: {}
|
||||
},
|
||||
pathinfo: {
|
||||
open: false,
|
||||
mac: '',
|
||||
name: ''
|
||||
},
|
||||
healthinfo: {
|
||||
open: false,
|
||||
mac: '',
|
||||
name: ''
|
||||
}
|
||||
})
|
||||
|
||||
class WristbandInfo extends React.Component {
|
||||
state = {
|
||||
...stateDefault()
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
this.getList();
|
||||
}
|
||||
|
||||
getList = () => {
|
||||
let {showDialog, toggleLoading} = this.props;
|
||||
toggleLoading(1);
|
||||
fetch('/api/wristband/getwristbandlist', getRequest())
|
||||
.then(response=>response.json())
|
||||
.then(json =>{
|
||||
toggleLoading(0);
|
||||
if(json.status != 1) return showDialog(json.message);
|
||||
this.setState({
|
||||
list: json.data.record || []
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
delWristband = (id) => {
|
||||
if(!id) return ;
|
||||
let {showDialog, callConfirm} = this.props;
|
||||
|
||||
callConfirm('確定要刪除這筆手環資料?', ()=>{
|
||||
fetch('/api/wristband/delwristband', getRequest({id}))
|
||||
.then(response=>response.json())
|
||||
.then(json=>{
|
||||
if(json.status!=1) return showDialog(json.message);
|
||||
this.getList();
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
openModal = (type, data = {}) => {
|
||||
this.setState({
|
||||
modal: {
|
||||
type,
|
||||
data,
|
||||
open: true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
closeModal = () => {
|
||||
this.setState({
|
||||
modal: {
|
||||
...stateDefault().modal
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
submitModal = (type, data = {}) => {
|
||||
let {showDialog, toggleLoading} = this.props;
|
||||
if(type == 1 && !data.id) return showDialog('資料取得失敗');
|
||||
if(type == 0 && !data.mac) return showDialog('請填寫手環ID');
|
||||
|
||||
let url = type == 1 ? '/api/wristband/editwristband' : '/api/wristband/addwristband';
|
||||
|
||||
fetch(url, getRequest(data))
|
||||
.then(response=>response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return showDialog(json.message);
|
||||
this.setState({
|
||||
modal: {...stateDefault().modal}
|
||||
}, ()=>{
|
||||
this.getList();
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
showPathInfo = (mac, name) => {
|
||||
if(!mac) return ;
|
||||
this.setState({
|
||||
pathinfo:{
|
||||
open: true,
|
||||
mac,
|
||||
name
|
||||
}
|
||||
})
|
||||
}
|
||||
closePathInfo = () => {
|
||||
this.setState({
|
||||
pathinfo: {
|
||||
...stateDefault().pathinfo
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
showHealthInfo = (mac, name) => {
|
||||
if(!mac) return ;
|
||||
this.setState({
|
||||
healthinfo:{
|
||||
open: true,
|
||||
mac,
|
||||
name
|
||||
}
|
||||
})
|
||||
}
|
||||
closeHealthInfo = () => {
|
||||
this.setState({
|
||||
healthinfo: {
|
||||
...stateDefault().healthinfo
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
let { i18n } = this.props;
|
||||
return (
|
||||
<Container fluid>
|
||||
<Segment className="clearfix">
|
||||
<Button basic color="green" icon="plus" content="新增" floated="right" onClick={()=>{this.openModal(0)}} style={{marginBottom: '15px'}} />
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>操作</Table.HeaderCell>
|
||||
<Table.HeaderCell>手環ID</Table.HeaderCell>
|
||||
<Table.HeaderCell>手環名稱</Table.HeaderCell>
|
||||
<Table.HeaderCell>身份</Table.HeaderCell>
|
||||
<Table.HeaderCell>監控</Table.HeaderCell>
|
||||
<Table.HeaderCell>通知</Table.HeaderCell>
|
||||
<Table.HeaderCell>啟用</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{
|
||||
this.state.list.map((t,idx) => (
|
||||
<ListItem key={idx} data={t}
|
||||
i18n={i18n}
|
||||
delWristband={this.delWristband}
|
||||
editWristband={this.openModal}
|
||||
showPathInfo={this.showPathInfo}
|
||||
showHealthInfo={this.showHealthInfo} />
|
||||
))
|
||||
}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</Segment>
|
||||
<WristbandModal i18n={i18n}
|
||||
open={this.state.modal.open}
|
||||
type={this.state.modal.type}
|
||||
data={this.state.modal.data}
|
||||
closeModal={this.closeModal}
|
||||
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} />
|
||||
<WristbandHealthInfo i18n={i18n}
|
||||
open={this.state.healthinfo.open}
|
||||
mac={this.state.healthinfo.mac}
|
||||
wbname={this.state.healthinfo.name}
|
||||
closeModal={this.closeHealthInfo}
|
||||
showDialog={this.props.showDialog}
|
||||
getRequest={getRequest} />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default WristbandInfo;
|
||||
@@ -0,0 +1,70 @@
|
||||
import React from 'react';
|
||||
import {Grid, Container, Segment, Menu, List} from 'semantic-ui-react';
|
||||
import LocStatus from '../../../containers/AdminPage/Wristband/LocStatus';
|
||||
import WristbandInfo from '../../../containers/AdminPage/Wristband/WristbandInfo';
|
||||
import Location from '../../../containers/AdminPage/Wristband/Location';
|
||||
import LocStatusWloc from '../../../containers/AdminPage/Wristband/LocStatusWloc';
|
||||
|
||||
class WristbandPage extends React.Component{
|
||||
state = {
|
||||
page: ''
|
||||
}
|
||||
|
||||
changePage = (page) => {
|
||||
this.setState({
|
||||
page
|
||||
})
|
||||
}
|
||||
|
||||
getRenderPage = () => {
|
||||
let {i18n} = this.props;
|
||||
switch(this.state.page) {
|
||||
case 'locstatus':
|
||||
return <LocStatus/>;
|
||||
case 'locstatus_wloc':
|
||||
return <LocStatusWloc />;
|
||||
case 'wristband':
|
||||
return <WristbandInfo />;
|
||||
case 'location':
|
||||
return <Location />
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
render(){
|
||||
let {i18n} = this.props;
|
||||
return (
|
||||
<Container fluid style={{paddingLeft: '10px', paddingRight: '10px'}}>
|
||||
<Grid>
|
||||
<Grid.Column width={4}>
|
||||
<Menu vertical={true} fluid>
|
||||
<Menu.Item>
|
||||
<Menu.Header>主選單</Menu.Header>
|
||||
<Menu.Menu>
|
||||
<Menu.Item active={this.state.page == 'wristband'} onClick={()=>{this.changePage('wristband')}}>
|
||||
手環名稱設定
|
||||
</Menu.Item>
|
||||
<Menu.Item active={this.state.page == 'location'} onClick={()=>{this.changePage('location')}}>
|
||||
定位點設定
|
||||
</Menu.Item>
|
||||
<Menu.Item active={this.state.page == 'locstatus'} onClick={()=>{ this.changePage('locstatus'); }}>
|
||||
即時資訊總覽
|
||||
</Menu.Item>
|
||||
<Menu.Item active={this.state.page == 'locstatus_wloc'} onClick={()=>{ this.changePage('locstatus_wloc'); }}>
|
||||
位置資訊
|
||||
</Menu.Item>
|
||||
</Menu.Menu>
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
</Grid.Column>
|
||||
<Grid.Column width={12}>
|
||||
{this.getRenderPage()}
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default WristbandPage;
|
||||
@@ -14,7 +14,7 @@ const DeviceSelect = ({i18n, querySelectList, page, permissions, devs, addSelect
|
||||
<option value="">{i18n&&i18n.t?i18n.t('select.dev_type') : ''}</option>
|
||||
{
|
||||
permissions.dio ?
|
||||
<option value="do">{i18n&&i18n.t ? i18n.t('select.digitoutput') : ''}</option> : null
|
||||
<option value="do">{i18n&&i18n.t ? i18n.t('select.digitaloutput') : ''}</option> : null
|
||||
}
|
||||
{
|
||||
permissions.leone ?
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
import {Modal, Button} from 'semantic-ui-react';
|
||||
|
||||
const ConfirmBox = ({obj, getNext}) => (
|
||||
<Modal open={obj && obj.msg != '' ? true : false} onClose={() => getNext()} style={{zIndex: "2001"}}>
|
||||
<Modal.Content>{obj && obj.msg ? obj.msg : ''}</Modal.Content>
|
||||
<Modal.Actions>
|
||||
<Button onClick={() => getNext(true, obj.act)} content="Submit" />
|
||||
<Button onClick={() => getNext()} content="Cancel" />
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
|
||||
export default ConfirmBox;
|
||||
@@ -6,14 +6,14 @@ const AlertItem = ({i18n, name, type}) => {
|
||||
return (
|
||||
<Grid.Row columns={3} color="red">
|
||||
<Grid.Column>
|
||||
<Label basic content={type == 'di' ? "DigitInput" : "LeOne"} />
|
||||
<Label basic content={type == 'di' ? "DigitalInput" : "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') ): ''}
|
||||
{i18n&&i18n.t ? ( type == 'di' ? i18n.t('dashboard.status.digitalinput') : i18n.t('dashboard.status.leone') ): ''}
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
)
|
||||
|
||||
@@ -15,7 +15,7 @@ const loginForm = ({i18n, page, onSubmit}) => {
|
||||
}}>
|
||||
<Segment stacked={true} >
|
||||
<Form.Field>
|
||||
<Input icon="user" iconPosition="left" name="acc" placeholder={typeof i18n.t == 'function' ? i18n.t(`${page}.input.placeholder.account`) : ''} />
|
||||
<Input icon="user" iconPosition="left" autoFocus={true} name="acc" placeholder={typeof i18n.t == 'function' ? i18n.t(`${page}.input.placeholder.account`) : ''} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input icon="lock" iconPosition="left" name="pass" type="password" placeholder={typeof i18n.t == 'function' ? i18n.t(`${page}.input.placeholder.password`) : ''} />
|
||||
|
||||
@@ -59,7 +59,8 @@ class Root extends React.Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
let lang = navigator
|
||||
let slang = sessionStorage.getItem('lang');
|
||||
let lang = slang || navigator
|
||||
.language
|
||||
.substring(0, 2);
|
||||
fetch(`/locales/${lang}.json`).then(response => {
|
||||
@@ -67,6 +68,7 @@ class Root extends React.Component {
|
||||
return response.json();
|
||||
return {}
|
||||
}).then(json => {
|
||||
let lang = Object.keys(json)[0] || '';
|
||||
i18next.init({
|
||||
lng: lang,
|
||||
resources: json
|
||||
|
||||
@@ -16,7 +16,12 @@ 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/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/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/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/ipcam" txt={i18n && 't' in i18n ? i18n.t('menu.item.ipcam') : ''} permission={permissions.ipcam} onClick={()=>toggleMenu()} />
|
||||
<MItem toLink="/admin/wristband" txt={i18n && 't' in i18n ? i18n.t('menu.item.wristband') : ''} permission={permissions.wristband} onClick={()=>toggleMenu()} />
|
||||
<MItem toLink="/admin" txt={i18n && 't' in i18n ? i18n.t('menu.item.logout') : ''} permission={true} onClick={()=>{
|
||||
sessionStorage.clear();
|
||||
location.replace('/');
|
||||
@@ -40,7 +45,7 @@ const MainMenu = ({i18n, show, toggleMenu, children, permissions, showDashboard,
|
||||
</Menu.Item>
|
||||
</Menu.Menu>
|
||||
</Menu>
|
||||
<Container style={{paddingTop: '45px', paddingBottom: '40px'}}>
|
||||
<Container style={{paddingTop: '45px', paddingBottom: '40px'}} fluid>
|
||||
{children}
|
||||
</Container>
|
||||
</Sidebar.Pusher>
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {add_dialog_msg, toggle_loading} from '../../actions';
|
||||
import ActionLinkAdd from '../../components/AdminPage/ActionLinkAdd';
|
||||
import { connect } from 'react-redux';
|
||||
import { add_dialog_msg, toggle_loading } from '../../actions';
|
||||
import ActionLinkAdd from '../../components/AdminPage/ActionLinkAddN';
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n
|
||||
i18n: state.i18n
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
toggleLoading: (active = false) => {
|
||||
dispatch(toggle_loading(active));
|
||||
}
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
toggleLoading: (active = false) => {
|
||||
dispatch(toggle_loading(active));
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ActionLinkAdd);
|
||||
@@ -0,0 +1,18 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {add_dialog_msg, toggle_loading} from '../../actions';
|
||||
import IPCamPage from '../../components/AdminPage/IPCam';
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
toggleLoading: (flag = false) => {
|
||||
dispatch(toggle_loading(flag));
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(IPCamPage);
|
||||
@@ -0,0 +1,18 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {add_dialog_msg, toggle_loading} from '../../actions';
|
||||
import ModbusCmdPage from '../../components/AdminPage/ModbusCmd';
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
toggleLoading: (flag = false) => {
|
||||
dispatch(toggle_loading(flag));
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ModbusCmdPage);
|
||||
@@ -0,0 +1,29 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {add_dialog_msg, toggle_loading, get_modbus_list, get_mb_log, clear_modbus} from '../../actions';
|
||||
import ModbusLogPage from '../../components/AdminPage/ModbusLog';
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n,
|
||||
list: state.lists.modbus.list,
|
||||
log: state.lists.modbus.log
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
toggleLoading: (flag = false) => {
|
||||
dispatch(toggle_loading(flag));
|
||||
},
|
||||
getList: () => {
|
||||
dispatch(get_modbus_list());
|
||||
},
|
||||
clearList: ()=>{
|
||||
dispatch(clear_modbus())
|
||||
},
|
||||
getMBLog: (data) => {
|
||||
dispatch(get_mb_log(data));
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ModbusLogPage);
|
||||
@@ -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);
|
||||
@@ -0,0 +1,19 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {add_dialog_msg, toggle_loading} from '../../../actions';
|
||||
import LocStatusPage from '../../../components/AdminPage/Wristband/LocStatus';
|
||||
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
toggleLoading: (flag = false) => {
|
||||
dispatch(toggle_loading(flag));
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(LocStatusPage);
|
||||
@@ -0,0 +1,19 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { add_dialog_msg, toggle_loading } from '../../../actions';
|
||||
import LocStatusPage from '../../../components/AdminPage/Wristband/LocStatusWloc';
|
||||
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
toggleLoading: (flag = false) => {
|
||||
dispatch(toggle_loading(flag));
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(LocStatusPage);
|
||||
@@ -0,0 +1,22 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { add_dialog_msg, toggle_loading, add_confirm } from '../../../actions';
|
||||
import LocationPage from '../../../components/AdminPage/Wristband/Location';
|
||||
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
toggleLoading: (flag = false) => {
|
||||
dispatch(toggle_loading(flag));
|
||||
},
|
||||
callConfirm: (msg, act = null) => {
|
||||
dispatch(add_confirm(msg, act))
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(LocationPage);
|
||||
@@ -0,0 +1,22 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { add_dialog_msg, toggle_loading, add_confirm } from '../../../actions';
|
||||
import WristbandInfo from '../../../components/AdminPage/Wristband/WristbandInfo';
|
||||
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
toggleLoading: (flag = false) => {
|
||||
dispatch(toggle_loading(flag));
|
||||
},
|
||||
callConfirm: (msg, act = null) => {
|
||||
dispatch(add_confirm(msg, act))
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(WristbandInfo);
|
||||
@@ -0,0 +1,19 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { add_dialog_msg, toggle_loading, add_confirm } from '../../../actions';
|
||||
import WristbandPage from '../../../components/AdminPage/Wristband';
|
||||
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
toggleLoading: (flag = false) => {
|
||||
dispatch(toggle_loading(flag));
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(WristbandPage);
|
||||
@@ -4,6 +4,7 @@ import Datetime from 'react-datetime';
|
||||
import MainMenu from '../../containers/MenuControl';
|
||||
import Loading from '../../containers/LoadingControl';
|
||||
import Dialog from '../DialogControl';
|
||||
import ConfirmBox from '../ConfirmControl';
|
||||
import Dashboard from '../../containers/DashBoard';
|
||||
import {toggle_dashboard} from '../../actions'
|
||||
|
||||
@@ -27,6 +28,7 @@ class AdmPage extends React.Component {
|
||||
<div style={{height: '100%'}}>
|
||||
<Loading />
|
||||
<Dialog />
|
||||
<ConfirmBox />
|
||||
<MainMenu i18n={i18n} >
|
||||
<Dashboard />
|
||||
{children}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user