re commit
This commit is contained in:
commit
8947715671
8
.babelrc
Normal file
8
.babelrc
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"presets":[
|
||||
"es2015",
|
||||
"react",
|
||||
"stage-1"
|
||||
],
|
||||
"plugins": []
|
||||
}
|
24
.eslintrc.json
Normal file
24
.eslintrc.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"commonjs": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
},
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"no-const-assign": "warn",
|
||||
"no-this-before-super": "warn",
|
||||
"no-undef": "warn",
|
||||
"no-unreachable": "warn",
|
||||
"no-unused-vars": "warn",
|
||||
"constructor-super": "warn",
|
||||
"valid-typeof": "warn"
|
||||
},
|
||||
"parser": "babel-eslint"
|
||||
}
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
node_modules
|
50
app.js
Normal file
50
app.js
Normal file
@ -0,0 +1,50 @@
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const cookieParser = require('cookie-parser');
|
||||
const session = require('express-session');
|
||||
const cors = require('cors');
|
||||
const logger = require('morgan');
|
||||
const path = require('path');
|
||||
const config = require('./config');
|
||||
const so = require('./includes/storeObject');
|
||||
|
||||
const app = express();
|
||||
|
||||
const api_route = require('./route/api');
|
||||
|
||||
// storeObject interval clear
|
||||
const clearStore = setInterval(() =>{
|
||||
so.clear();
|
||||
}, 30000)
|
||||
|
||||
app.set('port', process.env.PORT || config.system.port);
|
||||
|
||||
app.use(logger('short'));
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({ extended: false }));
|
||||
app.use(cookieParser());
|
||||
app.use(session({
|
||||
resave: false,
|
||||
saveUninitialized: true,
|
||||
secret: '6520833345e05e0dcfce'
|
||||
}));
|
||||
app.use(cors());
|
||||
|
||||
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')));
|
||||
|
||||
const server = app.listen(app.get('port'), () => {
|
||||
console.log(`Server start on port ${server.address().port}`);
|
||||
});
|
||||
|
||||
// use route
|
||||
app.use('/api', api_route);
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
res.sendFile(path.resolve(__dirname, 'views', 'index.html'));
|
||||
});
|
||||
|
||||
app.get(['/admin','/admin/*'], (req,res) => {
|
||||
res.sendFile(path.resolve(__dirname, 'views', 'admin.html'));
|
||||
});
|
44
config.json
Normal file
44
config.json
Normal file
@ -0,0 +1,44 @@
|
||||
{
|
||||
"system": {
|
||||
"port": 3000
|
||||
},
|
||||
"uni_token": "webiounitoken",
|
||||
"perpage": 10,
|
||||
"leone_limie": 40,
|
||||
"db": {
|
||||
"user": "webio",
|
||||
"pass": "16055536",
|
||||
"host": "192.168.98.227",
|
||||
"port": "3306",
|
||||
"db1": "jcwebioc",
|
||||
"db2": "jciocer",
|
||||
"db3": "jciochtr",
|
||||
"db4": "jcles",
|
||||
"db5": "jcmbset",
|
||||
"db6": "jcmbrt",
|
||||
"db7": "jcioclc",
|
||||
"db8": "jciocln"
|
||||
},
|
||||
"permission": {
|
||||
"dio": true,
|
||||
"log": true,
|
||||
"leone": true,
|
||||
"iogroup": true,
|
||||
"iocmd": true,
|
||||
"schedule": true,
|
||||
"modbus": true,
|
||||
"link": true
|
||||
},
|
||||
"cmdpath":{
|
||||
"manualip": "/home/www/cmd/manualip",
|
||||
"dhcpip": "/home/www/cmd/dhcpip",
|
||||
"sysinfo": "/home/www/sysinfo",
|
||||
"settime": "/home/www/cmd/chd",
|
||||
"scanleone": "/home/www/cmd/scanleone",
|
||||
"scanleone_end": "/home/www/scan_end",
|
||||
"iocmd": "/home/www/cmd/cmdio",
|
||||
"leonert": "/home/www/tmp/rtles",
|
||||
"htsrt": "/home/www/tmp/rthts",
|
||||
"version": "/factory/webioa_version"
|
||||
}
|
||||
}
|
87
includes/apiTool.js
Normal file
87
includes/apiTool.js
Normal file
@ -0,0 +1,87 @@
|
||||
const so = require('./storeObject');
|
||||
const config = require('../config');
|
||||
const fs = require('fs');
|
||||
|
||||
const checkPermission = (req) => {
|
||||
let id = req.headers['x-auth-token'];
|
||||
if (id) {
|
||||
let obj = so.get(id);
|
||||
if (config.uni_token.length > 0 && id == config.uni_token) return true;
|
||||
if (obj != null) {
|
||||
if ('user' in obj && obj.user.write_privilege == '1') return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const checkArray = (obj) => {
|
||||
if (Array.isArray(obj)) return obj;
|
||||
return [];
|
||||
}
|
||||
|
||||
const getLeoneRT = (cb) => {
|
||||
if (!cb || typeof cb != 'function') return;
|
||||
fs.exists(config.cmdpath.leonert, exists => {
|
||||
if (!exists) return cb([]);
|
||||
fs.readFile(config.cmdpath.leonert, (err, data) => {
|
||||
if (err) return cb([]);
|
||||
let str = data.toString();
|
||||
let tmp = str.split(/\n/);
|
||||
let rt = [];
|
||||
for (var i in tmp) {
|
||||
if (!tmp[i].trim()) continue;
|
||||
let arr = tmp[i].split(' ');
|
||||
if (arr.length != 5) continue;
|
||||
let [ip, ts, hs, mode, mtime] = arr;
|
||||
rt.push({ ip, ts, hs, mode, mtime });
|
||||
}
|
||||
return cb(rt);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const promiseQuery = (res, query, param, key = '') => {
|
||||
return new Promise((resolve, reject) => {
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return reject(err);
|
||||
resolve({ data: row, key });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const getMode = (req) => {
|
||||
let lngs = req.headers['accept-language'].split(',');
|
||||
let lng = null;
|
||||
if (lngs.length > 0) {
|
||||
lng = lngs[0].substring(0, 2);
|
||||
} else {
|
||||
lng = 'zh';
|
||||
}
|
||||
|
||||
if (!fs.existsSync(`../public/locales/${lng}.json`)) lng = 'zh';
|
||||
let json = require(`../public/locales/${lng}.json`);
|
||||
return json[lng].translation.leone_stats;
|
||||
}
|
||||
|
||||
const getCmd = (req) => {
|
||||
let lngs = req.headers['accept-language'].split(',');
|
||||
let lng = null;
|
||||
if (lngs.length > 0) {
|
||||
lng = lngs[0].substring(0, 2);
|
||||
} else {
|
||||
lng = 'zh';
|
||||
}
|
||||
|
||||
if (!fs.existsSync(`../public/locales/${lng}.json`)) lng = 'zh';
|
||||
let json = require(`../public/locales/${lng}.json`);
|
||||
return json[lng].translation.action_list;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
checkPermission,
|
||||
checkArray,
|
||||
getLeoneRT,
|
||||
promiseQuery,
|
||||
getCmd,
|
||||
getMode
|
||||
}
|
9
includes/errorManager.js
Normal file
9
includes/errorManager.js
Normal file
@ -0,0 +1,9 @@
|
||||
const manager = (errCode = '', lang = 'zh') => {
|
||||
if(typeof lang != 'string' || !lang.trim()) lang = 'zh';
|
||||
lang = lang.toLowerCase();
|
||||
let errors = require(`./language/${lang}.json`);
|
||||
if(errCode in errors) return errors[errCode];
|
||||
else return 'Error Code not found';
|
||||
}
|
||||
|
||||
module.exports = manager;
|
65
includes/language/zh.json
Normal file
65
includes/language/zh.json
Normal file
@ -0,0 +1,65 @@
|
||||
{
|
||||
"ERR0000": "資料輸入錯誤",
|
||||
"ERR0001": "PIN輸入錯誤",
|
||||
"ERR0002": "value輸入錯誤",
|
||||
"ERR0003": "DI資料查詢錯誤",
|
||||
"ERR0004": "DO資料查詢錯誤",
|
||||
"ERR0005": "DI資料輸入錯誤",
|
||||
"ERR0006": "DO資料輸入錯誤",
|
||||
"ERR0007": "DO資訊寫入失敗",
|
||||
"ERR0008": "DI資訊寫入失敗",
|
||||
"ERR0009": "類型輸入錯誤",
|
||||
"ERR0010": "IP輸入錯誤",
|
||||
"ERR0011": "Netmask輸入錯誤",
|
||||
"ERR0012": "Gateway輸入錯誤",
|
||||
"ERR0013": "DNS輸入錯誤",
|
||||
"ERR0014": "網路資訊取得失敗",
|
||||
"ERR0015": "時間輸入錯誤",
|
||||
"ERR0016": "帳號輸入錯誤",
|
||||
"ERR0017": "密碼輸入錯誤",
|
||||
"ERR0018": "使用者資料取得失敗",
|
||||
"ERR0019": "帳號或密碼錯誤",
|
||||
"ERR0020": "刪除使用者失敗",
|
||||
"ERR0021": "使用者資料更新失敗",
|
||||
"ERR0022": "使用者資料新增失敗",
|
||||
"ERR0023": "數量計算錯誤",
|
||||
"ERR0024": "數量取得失敗",
|
||||
"ERR0025": "IP格式錯誤",
|
||||
"ERR0026": "名稱輸入錯誤",
|
||||
"ERR0027": "此IP裝置已存在",
|
||||
"ERR0028": "ID輸入錯誤",
|
||||
"ERR0029": "裝置輸入錯誤",
|
||||
"ERR0030": "動作輸入錯誤",
|
||||
"ERR0031": "溫度請介於16-30間",
|
||||
"ERR0032": "啟用狀態輸入錯誤",
|
||||
"ERR0033": "分鐘輸入錯誤",
|
||||
"ERR0034": "小時輸入錯誤",
|
||||
"ERR0035": "日輸入錯誤",
|
||||
"ERR0036": "月輸入錯誤",
|
||||
"ERR0037": "admin 不能被刪除",
|
||||
"ERR0038": "裝置節點輸入錯誤",
|
||||
"ERR0039": "裝置Di數量輸入錯誤",
|
||||
"ERR0040": "裝置Di起始位址輸入錯誤",
|
||||
"ERR0041": "裝置Do數量輸入錯誤",
|
||||
"ERR0042": "裝置Do起始位址輸入錯誤",
|
||||
"ERR0043": "裝置Ai數量輸入錯誤",
|
||||
"ERR0044": "裝置Ai起始位址輸入錯誤",
|
||||
"ERR0045": "裝置Ao數量輸入錯誤",
|
||||
"ERR0046": "裝置Ao起始位址輸入錯誤",
|
||||
"ERR0047": "裝置節點編號已存在",
|
||||
"ERR0048": "位址輸入錯誤",
|
||||
"ERR0049": "數值輸入錯誤",
|
||||
"ERR0050": "最小值輸入錯誤",
|
||||
"ERR0051": "最大值輸入錯誤",
|
||||
"ERR0052": "ScaleMin輸入錯誤",
|
||||
"ERR0053": "ScaleMax輸入錯誤",
|
||||
"ERR0054": "此位址設定已存在",
|
||||
|
||||
"ERR7000": "命令執行失敗",
|
||||
|
||||
"ERR8000": "資料查詢失敗",
|
||||
"ERR8001": "資料新增失敗",
|
||||
"ERR8002": "資料更新失敗",
|
||||
"ERR8003": "資料刪除失敗",
|
||||
"ERR9000": "操作權限不足"
|
||||
}
|
68
includes/storeObject.js
Normal file
68
includes/storeObject.js
Normal file
@ -0,0 +1,68 @@
|
||||
const StoreObj = (() => {
|
||||
|
||||
let memStore = {};
|
||||
let maxAge = 3600000;
|
||||
|
||||
/**
|
||||
* @param {string} uuid
|
||||
* @param {object} obj
|
||||
*/
|
||||
const set = (uuid, obj) => {
|
||||
memStore[uuid] = {
|
||||
obj,
|
||||
age: Date.now() + maxAge
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} uuid
|
||||
*/
|
||||
const get = (uuid) => {
|
||||
if (uuid in memStore) {
|
||||
let s = memStore[uuid];
|
||||
if (Date.now() < s.age) {
|
||||
s.age = Date.now() + maxAge;
|
||||
return s.obj;
|
||||
} else {
|
||||
delete memStore[uuid];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} uuid
|
||||
*/
|
||||
const chkKey = (uuid) => {
|
||||
if (uuid in memStore) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} uuid
|
||||
*/
|
||||
const del = (uuid) => {
|
||||
if (uuid in memStore) delete memStore[uuid];
|
||||
}
|
||||
|
||||
const clear = () => {
|
||||
let t = Date.now();
|
||||
for (var i in memStore) {
|
||||
let s = memStore[i];
|
||||
if (s.age < t) delete memStore[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} uuid if not input return all
|
||||
*/
|
||||
const show = (uuid) => {
|
||||
if (uuid && uuid in memStore) return memStore[uuid];
|
||||
|
||||
return memStore;
|
||||
}
|
||||
|
||||
return {set, get, chkKey, clear, del, show };
|
||||
})()
|
||||
|
||||
module.exports = StoreObj;
|
36
libs/confLoader.js
Normal file
36
libs/confLoader.js
Normal file
@ -0,0 +1,36 @@
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
var confLoader = {
|
||||
_conf: null,
|
||||
_path: null,
|
||||
load: (p) => {
|
||||
var self = this;
|
||||
if (!p || p == undefined) {
|
||||
p = path.resolve(__dirname, '..', 'config.json');
|
||||
}
|
||||
self._path = p;
|
||||
if (!fs.existsSync(p)) {
|
||||
throw `Config file not exists , file location : ${p}`;
|
||||
}
|
||||
|
||||
var filecontent = fs.readFileSync(p);
|
||||
if (!filecontent) {
|
||||
throw `Config file read fail`;
|
||||
}
|
||||
filecontent = filecontent.toString();
|
||||
var conf = null;
|
||||
try {
|
||||
conf = JSON.parse(filecontent);
|
||||
self._conf = conf;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
return self._conf;
|
||||
},
|
||||
get: (key) => {
|
||||
return this._conf[key];
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = confLoader;
|
40
libs/confLoader_cls.js
Normal file
40
libs/confLoader_cls.js
Normal file
@ -0,0 +1,40 @@
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
class confLoader {
|
||||
constructor() {
|
||||
this._conf = null;
|
||||
this._path = null;
|
||||
}
|
||||
|
||||
load(p) {
|
||||
var self = this;
|
||||
if (!p || p == undefined) {
|
||||
p = path.resolve(__dirname, '..', 'config.json');
|
||||
}
|
||||
self._path = p;
|
||||
if (!fs.existsSync(p)) {
|
||||
throw `Config file not exists , file location : ${p}`;
|
||||
}
|
||||
|
||||
var filecontent = fs.readFileSync(p);
|
||||
if (!filecontent) {
|
||||
throw `Config file read fail`;
|
||||
}
|
||||
filecontent = filecontent.toString();
|
||||
var conf = null;
|
||||
try {
|
||||
conf = JSON.parse(filecontent);
|
||||
self._conf = conf;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
get(key) {
|
||||
return this._conf[key];
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = confLoader;
|
31
libs/crypto.js
Normal file
31
libs/crypto.js
Normal file
@ -0,0 +1,31 @@
|
||||
var crypto = require('crypto');
|
||||
|
||||
var random = (len = 32) => {
|
||||
var buf = crypto.randomBytes(len);
|
||||
return buf.toString("hex");
|
||||
}
|
||||
|
||||
var sha256 = (str) => {
|
||||
return crypto.createHash("sha256").update(str).digest('base64');
|
||||
}
|
||||
|
||||
var genPassHash = (str) => {
|
||||
var hash = random(16);
|
||||
var pass = sha256(str + hash);
|
||||
return `$${hash}$${pass}`;
|
||||
}
|
||||
|
||||
var comparePass = (plain, hash) => {
|
||||
var match = hash.match(/^\$(.+?)\$(.+)$/);
|
||||
if (match == null || match.length < 3 || !match[1] || !match[2]) return false;
|
||||
var pass = sha256(plain + match[1]);
|
||||
if (pass == match[2]) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
random: random,
|
||||
sha256: sha256,
|
||||
genPassHash: genPassHash,
|
||||
comparePass: comparePass
|
||||
}
|
30
libs/mysql.js
Normal file
30
libs/mysql.js
Normal file
@ -0,0 +1,30 @@
|
||||
var mysql = require('mysql');
|
||||
var config = require('./confLoader.js');
|
||||
|
||||
config.load();
|
||||
|
||||
var dbConf = config.get('db');
|
||||
|
||||
var database = function(){
|
||||
this.conf = dbConf;
|
||||
}
|
||||
|
||||
database.prototype.connect = function(){
|
||||
var self = this;
|
||||
self._con = mysql.createConnection(self.conf);
|
||||
}
|
||||
|
||||
database.prototype.formatQuery = function(str, arr){
|
||||
return mysql.format(str, arr);
|
||||
}
|
||||
|
||||
database.prototype.query = function(query, cb){
|
||||
var self = this;
|
||||
self._con.query(query,cb);
|
||||
}
|
||||
|
||||
database.prototype.close = function(){
|
||||
this._con.end();
|
||||
}
|
||||
|
||||
module.exports = database;
|
102
libs/mysql_cls.js
Normal file
102
libs/mysql_cls.js
Normal file
@ -0,0 +1,102 @@
|
||||
var mysql = require('mysql');
|
||||
|
||||
class database {
|
||||
constructor() {
|
||||
this._user = '';
|
||||
this._password = '';
|
||||
this._host = '';
|
||||
this._port = 3306;
|
||||
this._database = '';
|
||||
this._con = null;
|
||||
this.autoclose = false;
|
||||
}
|
||||
|
||||
connect() {
|
||||
if (!this._user || !this._host || !this._password || !this._database) throw 'mysql connect arg is empty';
|
||||
this._con = mysql.createConnection({
|
||||
user: this._user,
|
||||
password: this._password,
|
||||
host: this._host,
|
||||
database: this._database,
|
||||
port: this._port
|
||||
});
|
||||
}
|
||||
|
||||
checkConnect() {
|
||||
if (!this._con) {
|
||||
this.connect();
|
||||
}
|
||||
}
|
||||
|
||||
formatQuery(query, arg) {
|
||||
return mysql.format(query, arg);
|
||||
}
|
||||
|
||||
escape(val) {
|
||||
return mysql.escape(val);
|
||||
}
|
||||
|
||||
query(query, params, cb) {
|
||||
this.checkConnect();
|
||||
let self = this;
|
||||
if (typeof params == 'function') {
|
||||
cb = params;
|
||||
params = [];
|
||||
};
|
||||
if (typeof params == 'object' && !Array.isArray(params)) params = [];
|
||||
|
||||
this._con.query(query, params, (err, rows, field) => {
|
||||
if (self.autoclose) {
|
||||
self.close(() => {
|
||||
cb.apply(this, [err, rows, field]);
|
||||
});
|
||||
} else {
|
||||
cb.apply(this, [err, rows, field]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
close(cb) {
|
||||
let self = this;
|
||||
this._con.end((err) => {
|
||||
self._con = null;
|
||||
if (cb) cb();
|
||||
});
|
||||
}
|
||||
|
||||
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; }
|
||||
}
|
||||
|
||||
module.exports = database;
|
55
package.json
Normal file
55
package.json
Normal file
@ -0,0 +1,55 @@
|
||||
{
|
||||
"name": "ci3",
|
||||
"version": "1.0.0",
|
||||
"main": "app.js",
|
||||
"scripts": {
|
||||
"test": "node node_modules/webpack-dev-server/bin/webpack-dev-server",
|
||||
"build": "NODE_ENV=production webpack -p --progress --colors",
|
||||
"build-dev": "NODE_ENV=development webpack --watch --progress"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"body-parser": "^1.16.1",
|
||||
"cookie-parser": "^1.4.3",
|
||||
"cors": "^2.8.1",
|
||||
"express": "^4.14.1",
|
||||
"express-session": "^1.15.1",
|
||||
"i18next": "^7.0.0",
|
||||
"moment": "^2.17.1",
|
||||
"morgan": "^1.8.1",
|
||||
"mysql": "^2.13.0",
|
||||
"react": "^15.4.2",
|
||||
"react-datetime": "^2.8.8",
|
||||
"react-dom": "^15.4.2",
|
||||
"react-redux": "^5.0.2",
|
||||
"react-router": "^3.0.2",
|
||||
"redux": "^3.6.0",
|
||||
"redux-thunk": "^2.2.0",
|
||||
"semantic-ui-css": "^2.2.7",
|
||||
"semantic-ui-react": "^0.65.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.23.1",
|
||||
"babel-eslint": "^7.1.1",
|
||||
"babel-loader": "^6.3.1",
|
||||
"babel-preset-es2015": "^6.22.0",
|
||||
"babel-preset-react": "^6.23.0",
|
||||
"babel-preset-stage-1": "^6.22.0",
|
||||
"eslint": "^3.15.0",
|
||||
"eslint-config-airbnb": "^14.1.0",
|
||||
"eslint-loader": "^1.6.1",
|
||||
"eslint-plugin-import": "^2.2.0",
|
||||
"eslint-plugin-jsx-a11y": "^4.0.0",
|
||||
"eslint-plugin-react": "^6.9.0",
|
||||
"html-webpack-plugin": "^2.28.0",
|
||||
"webpack": "^2.2.1",
|
||||
"webpack-dev-server": "^2.3.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://git.trj.tw/jcnet/webio-node.git"
|
||||
},
|
||||
"description": ""
|
||||
}
|
24
public/css/main.css
Normal file
24
public/css/main.css
Normal file
@ -0,0 +1,24 @@
|
||||
html,
|
||||
body,
|
||||
div#app {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-grid {
|
||||
height: 100%;
|
||||
}
|
||||
.login-column {
|
||||
max-width: 450px;
|
||||
}
|
||||
|
||||
.clearfix:after {
|
||||
content: ".";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
}
|
||||
.hide-element {
|
||||
display: 'none' !important;
|
||||
}
|
90109
public/js/admin_bundle.js
Normal file
90109
public/js/admin_bundle.js
Normal file
File diff suppressed because it is too large
Load Diff
62361
public/js/index_bundle.js
Normal file
62361
public/js/index_bundle.js
Normal file
File diff suppressed because it is too large
Load Diff
356
public/locales/zh.json
Normal file
356
public/locales/zh.json
Normal file
@ -0,0 +1,356 @@
|
||||
{
|
||||
"zh": {
|
||||
"translation": {
|
||||
"page": {
|
||||
"login": {
|
||||
"input": {
|
||||
"placeholder": {
|
||||
"account": "請輸入帳號",
|
||||
"password": "請輸入密碼"
|
||||
},
|
||||
|
||||
"label": {
|
||||
|
||||
}
|
||||
},
|
||||
"button": {
|
||||
"login": "登入"
|
||||
}
|
||||
},
|
||||
"system_info": {
|
||||
"title": {
|
||||
"sysinfo": "系統資訊",
|
||||
"timeinfo": "時間資訊"
|
||||
},
|
||||
"form": {
|
||||
"input": {
|
||||
|
||||
},
|
||||
"label": {
|
||||
"ip": "IP",
|
||||
"netmask": "Netmask",
|
||||
"gateway": "Gateway",
|
||||
"dns": "DNS",
|
||||
"sysdate": "系統日期"
|
||||
},
|
||||
"button": {
|
||||
"dhcpip": "使用DHCP",
|
||||
"manualip": "手動設定",
|
||||
"update_network": "更新網路資訊",
|
||||
"update_time": "更新時間資訊"
|
||||
}
|
||||
}
|
||||
},
|
||||
"userlist": {
|
||||
"title": {
|
||||
"userlist": "使用者管理"
|
||||
},
|
||||
"table": {
|
||||
"account": "帳號",
|
||||
"privilege": "權限",
|
||||
"operate": "操作",
|
||||
"button": {
|
||||
"edit": "修改",
|
||||
"del": "刪除",
|
||||
"add": "新增使用者"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"title": {
|
||||
"add": "新增資料",
|
||||
"edit": "修改資料"
|
||||
},
|
||||
"label": {
|
||||
"account": "帳號",
|
||||
"password": "密碼",
|
||||
"read_privilege": "讀取權限",
|
||||
"write_privilege": "控制權限"
|
||||
},
|
||||
"button": {
|
||||
"submit": "送出",
|
||||
"cancel": "取消"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dio": {
|
||||
"title": {
|
||||
"di": "DigitInput",
|
||||
"do": "DigitOutput"
|
||||
},
|
||||
"form": {
|
||||
"label": {
|
||||
"logic": "邏輯",
|
||||
"do_ctrl": "DO控制",
|
||||
"di_status": "狀態",
|
||||
"di_triggered": "觸發",
|
||||
"di_not_triggered": "未觸發"
|
||||
},
|
||||
"button": {
|
||||
"update_setting": "更新IO設定"
|
||||
}
|
||||
}
|
||||
},
|
||||
"log": {
|
||||
"table": {
|
||||
"datetime": "時間",
|
||||
"username": "使用者",
|
||||
"status": "狀態",
|
||||
"event": "事件",
|
||||
"description": "說明",
|
||||
"button": {
|
||||
"prevpage": "上一頁",
|
||||
"nextpage": "下一頁"
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"dio": "$io_label$ $io_name$ 邏輯 $io_logic$ 在 $io_trigger_time$ 改變為 $io_trigger_status$",
|
||||
"leone": "$io_label$ $io_name$ 在 $io_trigger_time$ 執行 $io_trigger_status$",
|
||||
"iogroup": "$io_label$ $io_name$ 在 $io_trigger_time$ 執行 $io_trigger_status$"
|
||||
}
|
||||
},
|
||||
"leone": {
|
||||
"form": {
|
||||
"title": {
|
||||
"add": "新增資料",
|
||||
"edit": "修改資料",
|
||||
"select-dev": "選擇裝置"
|
||||
},
|
||||
"label": {
|
||||
"ip": "IP",
|
||||
"password": "密碼",
|
||||
"name": "名稱",
|
||||
"run_command": "執行命令",
|
||||
"temp": "請輸入溫度",
|
||||
"select_num": "已選數量"
|
||||
},
|
||||
"button": {
|
||||
"scan": "掃描",
|
||||
"submit": "送出",
|
||||
"cancel": "取消",
|
||||
"prevpage": "上一頁",
|
||||
"nextpage": "下一頁"
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"operate": "操作",
|
||||
"name": "名稱",
|
||||
"ip": "IP",
|
||||
"hsts": "溫度 / 濕度",
|
||||
"mode": "模式",
|
||||
"password": "密碼",
|
||||
"update_time": "更新時間",
|
||||
"control": "控制",
|
||||
"button": {
|
||||
"add": "新增",
|
||||
"edit": "修改",
|
||||
"del": "刪除"
|
||||
}
|
||||
},
|
||||
"loader": {
|
||||
"scan": "Scanning",
|
||||
"load": "Loading"
|
||||
}
|
||||
},
|
||||
"iogroup": {
|
||||
"table": {
|
||||
"operate": "操作",
|
||||
"name": "名稱",
|
||||
"groups": "群組內容",
|
||||
"button": {
|
||||
"showgroup": "顯示群組裝置",
|
||||
"add": "新增",
|
||||
"edit": "修改",
|
||||
"del": "刪除"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"title": {
|
||||
"add": "新增資料",
|
||||
"edit": "修改資料"
|
||||
},
|
||||
"label": {
|
||||
"name": "名稱",
|
||||
"select_device": "選擇裝置",
|
||||
"selected_device": "已選裝置列表"
|
||||
},
|
||||
"button": {
|
||||
"join": "加入",
|
||||
"remove": "移除",
|
||||
"submit": "送出",
|
||||
"cancel": "取消"
|
||||
}
|
||||
}
|
||||
},
|
||||
"iocmd": {
|
||||
"form": {
|
||||
"label": {
|
||||
"action": "動作",
|
||||
"select_device": "選擇裝置",
|
||||
"selected_device": "已選裝置列表",
|
||||
"temp": "請輸入溫度"
|
||||
},
|
||||
"button": {
|
||||
"join": "加入",
|
||||
"remove": "移除",
|
||||
"submit": "送出"
|
||||
}
|
||||
}
|
||||
},
|
||||
"schedule": {
|
||||
"table": {
|
||||
"operate": "操作",
|
||||
"name": "名稱",
|
||||
"schedule_time": "排程時間",
|
||||
"action": "動作",
|
||||
"active_status": "啟用狀態",
|
||||
"device": "裝置",
|
||||
"button": {
|
||||
"add": "新增",
|
||||
"del": "刪除",
|
||||
"edit": "修改",
|
||||
"enable": "啟用",
|
||||
"disable": "停用",
|
||||
"showgroup": "顯示群組裝置"
|
||||
}
|
||||
},
|
||||
"form": {
|
||||
"title": {
|
||||
"add": "新增資料",
|
||||
"edit": "修改資料"
|
||||
},
|
||||
"label": {
|
||||
"enable": "啟用排程",
|
||||
"name": "名稱",
|
||||
"action": "動作",
|
||||
"time": "時間",
|
||||
"date": "請輸入日期",
|
||||
"week": "請選擇週次",
|
||||
"select_device": "選擇裝置",
|
||||
"selected_device": "已選裝置列表",
|
||||
"datetype": "時間類型",
|
||||
"type_week": "週次",
|
||||
"type_date": "日期",
|
||||
"temp": "溫度"
|
||||
},
|
||||
"button": {
|
||||
"join": "加入",
|
||||
"remove": "移除",
|
||||
"submit": "送出",
|
||||
"cancel": "取消",
|
||||
"remove": "移除"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
"systime": "系統時間",
|
||||
"sysip": "系統IP",
|
||||
"sysinfo": "系統資訊",
|
||||
"hsts": "溫濕度資訊",
|
||||
"devstats": "裝置狀態",
|
||||
"label": {
|
||||
"status": "狀態",
|
||||
"name": "名稱"
|
||||
},
|
||||
"status": {
|
||||
"leone": "無回應(網路問題或是IP/密碼錯誤)",
|
||||
"digitinput": "觸發"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"title": "選單",
|
||||
"item": {
|
||||
"systeminfo": "系統資訊",
|
||||
"userlist": "使用者管理",
|
||||
"dio": "DIO控制面板",
|
||||
"log": "系統記錄",
|
||||
"leone": "LeOne",
|
||||
"iogroup": "IOGroup",
|
||||
"iocmd": "IO CMD",
|
||||
"schedule": "排程控制",
|
||||
"modbus": "Modbus",
|
||||
"link": "連動",
|
||||
"logout": "登出"
|
||||
}
|
||||
},
|
||||
"tip": {
|
||||
"input_empty": "輸入欄位請勿空白",
|
||||
"input_empty_password": "請輸入密碼",
|
||||
"input_empty_ip": "請輸入IP",
|
||||
"input_empty_temp": "請輸入溫度",
|
||||
"input_empty_groupname": "請填寫群組名稱",
|
||||
"input_empty_name": "請輸入名稱",
|
||||
"input_empty_time": "請輸入時間",
|
||||
"input_empty_date": "請輸入日期",
|
||||
"date_format": "日期格式錯誤 m-d",
|
||||
"date_range": "日期範圍輸入錯誤",
|
||||
"time_format": "時間格式錯誤 H:M",
|
||||
"time_range": "時間範圍輸入錯誤",
|
||||
"temp_format": "溫度請介於16-30間",
|
||||
"ip_format": "IP格式錯誤,數值請介於0-255間",
|
||||
"datetime_format": "請輸入時間日期 yyyy-mm-dd MM:ss",
|
||||
"update_success": "更新成功",
|
||||
"delete_success": "刪除完成",
|
||||
"userdata_get_fail": "使用者資料取得失敗",
|
||||
"select_action": "請選擇動作",
|
||||
"select_device": "請選擇裝置",
|
||||
"select_week": "請選擇週次",
|
||||
"device_parser_error": "裝置列表解析錯誤",
|
||||
"command_run_complete": "命令執行完成",
|
||||
"action_error": "動作輸入錯誤",
|
||||
"mb_io_type_dup": "相同類型已存在",
|
||||
"scan_empty": "無新增裝置"
|
||||
},
|
||||
"action_list": [
|
||||
{ "cmd": "0 0", "name": "關閉" },
|
||||
{ "cmd": "0 1", "name": "開啟" },
|
||||
{ "cmd": "1 1", "name": "冷氣功能 - 自動" },
|
||||
{ "cmd": "1 2", "name": "冷氣功能 - 冷氣" },
|
||||
{ "cmd": "1 3", "name": "冷氣功能 - 除濕" },
|
||||
{ "cmd": "1 4", "name": "冷氣功能 - 送風" },
|
||||
{ "cmd": "1 5", "name": "冷氣功能 - 暖氣" },
|
||||
{ "cmd": "2", "name": "冷氣溫度" }
|
||||
],
|
||||
"leone_stats": [
|
||||
{ "mode": "9999", "name": "無回應" },
|
||||
{ "mode": "1", "name": "自動" },
|
||||
{ "mode": "2", "name": "冷氣" },
|
||||
{ "mode": "3", "name": "除濕" },
|
||||
{ "mode": "4", "name": "送風" },
|
||||
{ "mode": "5", "name": "暖氣" },
|
||||
{ "mode": "99", "name": "關機" }
|
||||
],
|
||||
"time_unit": {
|
||||
"sec": "秒",
|
||||
"min": "分",
|
||||
"hour": "小時",
|
||||
"day": "天",
|
||||
"ago": "前"
|
||||
},
|
||||
"week": {
|
||||
"mon": "週一",
|
||||
"tue": "週二",
|
||||
"wed": "週三",
|
||||
"thu": "週四",
|
||||
"fri": "週五",
|
||||
"sat": "週六",
|
||||
"sun": "週日"
|
||||
},
|
||||
"porttype": [
|
||||
{"code": "1", "name":"DigitOutput"},
|
||||
{"code": "2", "name":"DigitInput"},
|
||||
{"code": "3", "name":"AnalogyOutput"},
|
||||
{"code": "4", "name":"AnalogyInput"}
|
||||
],
|
||||
"select": {
|
||||
"select_action": "請選擇動作",
|
||||
"dev_type": "請選擇裝置類型",
|
||||
"dev_name": "請選擇裝置",
|
||||
"action": "請選擇動作",
|
||||
"digitoutput": "DigitOutput",
|
||||
"leone": "LeOne",
|
||||
"iogroup": "IOGroup"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
36
route/ResTool.js
Normal file
36
route/ResTool.js
Normal file
@ -0,0 +1,36 @@
|
||||
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();
|
||||
|
||||
let lngs = req.headers['accept-language'].split(',');
|
||||
let lng = null;
|
||||
if (lngs.length > 0) {
|
||||
lng = lngs[0].substring(0, 2);
|
||||
}
|
||||
|
||||
let json = {};
|
||||
|
||||
if (!('api_res' in res)) {
|
||||
json = {
|
||||
errorCode: 'ERR9999',
|
||||
message: 'api not found',
|
||||
status: 0
|
||||
};
|
||||
} else if (typeof res.api_res != 'object') {
|
||||
json = {
|
||||
errorCode: res.api_res,
|
||||
message: errList(res.api_res, lng),
|
||||
status: 0
|
||||
};
|
||||
} else {
|
||||
json = {
|
||||
data: res.api_res,
|
||||
status: 1
|
||||
};
|
||||
}
|
||||
|
||||
res.send(json);
|
||||
}
|
||||
|
||||
module.exports = { send: send };
|
199
route/api/dio.js
Normal file
199
route/api/dio.js
Normal file
@ -0,0 +1,199 @@
|
||||
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 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 DIO Api' });
|
||||
})
|
||||
.post('/getio', (req, res, n) => {
|
||||
if (!config.permission.dio) return n('ERR9000');
|
||||
|
||||
res.api_res = {
|
||||
record: [],
|
||||
rt: {
|
||||
di: {},
|
||||
do: {}
|
||||
}
|
||||
};
|
||||
|
||||
let pdi = new Promise((resolve, reject) => {
|
||||
let id = 1;
|
||||
let dis = {};
|
||||
! function dichk(i) {
|
||||
if (i > 8) return resolve({ data: dis, key: 'di' });
|
||||
dis[i] = 0;
|
||||
exec(`ditchk ${i}`, (err, sout, serr) => {
|
||||
if (err) return dichk(++i);
|
||||
dis[i] = sout.replace(/\n/, '');
|
||||
dichk(++i);
|
||||
});
|
||||
}(id)
|
||||
});
|
||||
|
||||
let pdo = new Promise((resolve, reject) => {
|
||||
let id = 1;
|
||||
let dos = {};
|
||||
! function dochk(i) {
|
||||
if (i > 8) return resolve({ data: dos, key: 'do' });
|
||||
dos[i] = 0;
|
||||
exec(`dotchk ${i}`, (err, sout, serr) => {
|
||||
if (err) return dochk(++i);
|
||||
dos[i] = sout.replace(/\n/, '');
|
||||
dochk(++i);
|
||||
});
|
||||
}(id)
|
||||
});
|
||||
|
||||
Promise.all([pdi, pdo])
|
||||
.then(r => {
|
||||
for (let i in r) {
|
||||
if (r[i].key == 'di') {
|
||||
res.api_res.rt.di = r[i].data;
|
||||
} else if (r[i].key == 'do') {
|
||||
res.api_res.rt.do = r[i].data;
|
||||
}
|
||||
}
|
||||
return n();
|
||||
})
|
||||
.catch(e => n());
|
||||
})
|
||||
.post('/dotrun', (req, res, n) => {
|
||||
if (!config.permission.dio) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.pin) return n('ERR0001');
|
||||
if (!('value' in arr.data)) return n('ERR0002');
|
||||
|
||||
exec(`dotrun ${arr.data.pin} ${arr.data.value}`, (err, sout, serr) => {
|
||||
res.api_res = {
|
||||
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;
|
||||
|
||||
let query = "select * from ??.?? where `douid` = ?";
|
||||
let param = [config.db.db1, 'dolist', arr.data.pin];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err || row.length == 0) return n();
|
||||
let q = "insert into ??.?? (`eventtag`, `iolabel`, `ioname`, `iosetting1`, `iosetting2`, `iosetting3`, `ioevent`, `ioeventtst`) values ";
|
||||
let p = [config.db.db2, 'jciocert'];
|
||||
let doStat = sout.replace(/\n/, '') == 1 ? 1 : 0;
|
||||
let str = `('WEB', 'DO${row[0].douid}', '${row[0].doname}', '${row[0].dologic}', '${doStat}', '${u}', '${doStat}', unix_timestamp())`;
|
||||
res.db.query(q + str, p, (err, row) => 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');
|
||||
|
||||
res.api_res = {
|
||||
record:[],
|
||||
rt: {
|
||||
di: [],
|
||||
do: []
|
||||
}
|
||||
};
|
||||
|
||||
Promise.all([pdi,pdo])
|
||||
.then(r => {
|
||||
for(let i in r){
|
||||
if(r[i].key == 'di') res.api_res.rt.di = r[i].data;
|
||||
else if(r[i].key == 'do') res.api_res.rt.do = r[i].data;
|
||||
}
|
||||
return n();
|
||||
})
|
||||
.catch(e => n('ERR8000'));
|
||||
})
|
||||
.post('/setdioinfo', (req,res,n) => {
|
||||
if(!config.permission.dio) return n('ERR9000');
|
||||
// if(!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if(!arr.data) return n('ERR0000');
|
||||
if(!arr.data.di || typeof (arr.data.di) != 'object' || Object.keys(arr.data.di).length == 0) return n('ERR0005');
|
||||
if(!arr.data.do || typeof (arr.data.do) != 'object' || Object.keys(arr.data.do).length == 0) return n('ERR0006');
|
||||
|
||||
res.api_res = {
|
||||
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 = [];
|
||||
let dis = [];
|
||||
let di_logic = "";
|
||||
let di_name = "";
|
||||
let do_logic = "";
|
||||
let do_name = "";
|
||||
let where = " where ?? in (?)";
|
||||
for(let i=1; i<=8; i++){
|
||||
dos.push(`do${i}`);
|
||||
dis.push(`di${i}`);
|
||||
if(arr.data.do[`do${i}`] && 'logic' in arr.data.do[`do${i}`]){
|
||||
do_logic += ` when 'do${i}' then ${arr.data.do[`do${i}`].logic == 1 ? 1 : 0} `;
|
||||
}
|
||||
if(arr.data.do[`do${i}`] && 'name' in arr.data.do[`do${i}`]){
|
||||
do_name += ` when 'do${i}' then ${res.db.escape(arr.data.do[`do${i}`].name)} `;
|
||||
}
|
||||
if(arr.data.di[`di${i}`] && 'logic' in arr.data.di[`di${i}`]){
|
||||
di_logic += ` when 'di${i}' then ${arr.data.di[`di${i}`].logic == 1 ? 1 : 0} `;
|
||||
}
|
||||
if(arr.data.di[`di${i}`] && 'name' in arr.data.di[`di${i}`]){
|
||||
di_name += ` when 'di${i}' then ${res.db.escape(arr.data.di[`di${i}`].name)} `;
|
||||
}
|
||||
}
|
||||
do_logic += " end ";
|
||||
do_name += " end ";
|
||||
di_logic += " end ";
|
||||
di_name += " end ";
|
||||
|
||||
let diq = `${query} ${sub} ${di_logic} , ${sub} ${di_name} ${where}`;
|
||||
let doq = `${query} ${sub} ${do_logic} , ${sub} ${do_name} ${where}`;
|
||||
|
||||
let pdi = tool.promiseQuery(res, diq, [config.db.db1, 'dilist', 'di_modify_date', 'dilogic', 'diid', 'diname', 'diid', 'diid', dis]);
|
||||
let pdo = tool.promiseQuery(res, doq, [config.db.db1, 'dolist', 'do_modify_date', 'dologic', 'doid', 'doname', 'doid', 'doid', dos]);
|
||||
|
||||
Promise.all([pdi, pdo])
|
||||
.then(r => n())
|
||||
.catch(e => n('ERR8002'))
|
||||
})
|
||||
.all('*', rt.send);
|
||||
|
||||
module.exports = router;
|
35
route/api/index.js
Normal file
35
route/api/index.js
Normal file
@ -0,0 +1,35 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const errMng = require('../../includes/errorManager');
|
||||
|
||||
router
|
||||
.get('/', (req, res) => {
|
||||
res.send({ name: 'WebIO API System' });
|
||||
})
|
||||
.use('/system', require('./system.js'))
|
||||
.use('/log', require('./log.js'))
|
||||
.use('/leone', require('./leone.js'))
|
||||
.use('/iogroup', require('./iogroup.js'))
|
||||
.use('/iocmd', require('./iocmd.js'))
|
||||
.use('/schedule', require('./schedule.js'))
|
||||
.use('/dio', require('./dio.js'))
|
||||
.use('/link', require('./link.js'))
|
||||
.use('/modbus', require('./modbus.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();
|
||||
|
||||
let lngs = req.headers['accept-language'].split(',');
|
||||
let lng = null;
|
||||
if (lngs.length > 0) {
|
||||
lng = lngs[0].substring(0, 2);
|
||||
}
|
||||
res.send({
|
||||
errorCode: (typeof err != 'string' ? err.toString() : err),
|
||||
message: errMng(err, lng),
|
||||
status: 0
|
||||
});
|
||||
})
|
||||
|
||||
module.exports = router;
|
188
route/api/iocmd.js
Normal file
188
route/api/iocmd.js
Normal file
@ -0,0 +1,188 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const mysql = require('../../libs/mysql_cls');
|
||||
const tool = require('../../includes/apiTool');
|
||||
const exec = require('child_process').exec;
|
||||
const execSync = require('child_process').execSync;
|
||||
const so = require('../../includes/storeObject');
|
||||
|
||||
router
|
||||
.get('/', (req, res) => {
|
||||
res.send({ name: 'WebIO IOCmd API' });
|
||||
})
|
||||
.post('/iocmd', (req, res, n) => {
|
||||
if (!config.permission.iocmd) return n('ERR9000');
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.cmd) return n('ERR0030');
|
||||
if (!arr.data.devs) return n('ERR0029');
|
||||
|
||||
let cmds = arr.data.cmd.split(' ');
|
||||
if (cmds.length != 2) return n('ERR0030');
|
||||
if (cmds[0] == 2 && !(cmds[1] > 16 && cmds[1] < 30)) return n('ERR0031');
|
||||
|
||||
let cmd = `echo '${cmds[0]} ${cmds[1]} ${arr.data.devs}' > ${config.cmdpath.iocmd}`;
|
||||
exec(cmd, (err, sout, serr) => {
|
||||
let data = {};
|
||||
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 = [];
|
||||
let devs = arr.data.devs.split(',');
|
||||
let regex_do = /^do([0-9]+)$/;
|
||||
let regex_le = /^le([0-9]+)$/;
|
||||
let regex_io = /^iogroup([0-9]+)$/;
|
||||
for (let i in devs) {
|
||||
let s = devs[i];
|
||||
if (!s.trim()) continue;
|
||||
if (regex_do.test(s)) {
|
||||
dos.push(s.replace(regex_do, '$1'));
|
||||
} else if (regex_le.test(s)) {
|
||||
les.push(s.replace(regex_le, '$1'));
|
||||
} else if (regex_io.test(s)) {
|
||||
ios.push(s.replace(regex_io, '$1'));
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
let pros = [];
|
||||
|
||||
if (dos.length > 0) {
|
||||
let query = "select * from ??.?? where `douid` in (?)";
|
||||
let param = [config.db.db1, 'dolist', dos];
|
||||
pros.push(tool.promiseQuery(res, query, param, 'do'));
|
||||
}
|
||||
if (les.length > 0) {
|
||||
let query = "select * from ??.?? where `leonelistuid` in (?)";
|
||||
let param = [config.db.db1, 'leonelist', les];
|
||||
pros.push(tool.promiseQuery(res, query, param, 'leone'));
|
||||
}
|
||||
if (ios.length > 0) {
|
||||
let query = "select * from ??.?? where `iogroupuid` in (?)";
|
||||
let param = [config.db.db1, 'iogroup', ios];
|
||||
pros.push(tool.promiseQuery(res, query, param, 'iogroup'));
|
||||
}
|
||||
|
||||
Promise.all(pros)
|
||||
.then(r => {
|
||||
let c = r.length;
|
||||
let q = "insert into ??.?? (`eventtag`, `iolabel`, `ioname`, `iosetting1`, `iosetting2`, `iosetting3`, `ioevent`, `ioeventtst`) values ";
|
||||
let p = [config.db.db2, 'jciocert'];
|
||||
// for (let i in r) {
|
||||
! function runLog(json) {
|
||||
if (!json) return;
|
||||
if (json.key == 'do') {
|
||||
let d = json.data;
|
||||
let qs = [];
|
||||
for (let j in d) {
|
||||
let doStat = execSync(`dotchk ${d[j].douid}`) == 1 ? 'HIGH' : 'LOW';
|
||||
let str = `('WEB', 'DO${d[j].douid}', '${d[j].doname}', '${d[j].dologic}', '${doStat}', '${u}', '${doStat}', unix_timestamp())`;
|
||||
qs.push(str);
|
||||
}
|
||||
tool.promiseQuery(res, q + qs.join(','), p)
|
||||
.then(r => {
|
||||
c--;
|
||||
})
|
||||
.catch(err => {
|
||||
c--;
|
||||
});
|
||||
runLog(r.pop());
|
||||
} else if (json.key == 'leone') {
|
||||
let d = json.data;
|
||||
let qs = [];
|
||||
let mm = tool.getMode(req);
|
||||
let act = tool.getCmd(req);
|
||||
tool.getLeoneRT((rts) => {
|
||||
for (let j in d) {
|
||||
let st = '';
|
||||
for (var k in rts) {
|
||||
if (rts[k].ip == d[j].leoneip) {
|
||||
for (let o in mm) {
|
||||
if (rts[k].mode == mm[o].mode) {
|
||||
st = mm[o].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
let cn = '';
|
||||
for (let k in act) {
|
||||
if (act[k].cmd == `${cmds[0]} ${cmds[1]}`) {
|
||||
cn = act[k].name;
|
||||
break;
|
||||
} else if (act[k].cmd == cmds[0]) {
|
||||
cn = act[k].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
let str = `('WEB', 'LeOne', '${d[j].leonename}', '-', '${st}', '${u}', '${cn}', unix_timestamp())`;
|
||||
qs.push(str);
|
||||
}
|
||||
tool.promiseQuery(res, q + qs.join(','), p)
|
||||
.then(r => {
|
||||
c--;
|
||||
})
|
||||
.catch(err => {
|
||||
c--;
|
||||
});
|
||||
runLog(r.pop());
|
||||
});
|
||||
} else if (json.key == 'iogroup') {
|
||||
let d = json.data;
|
||||
let qs = [];
|
||||
let act = tool.getCmd(req);
|
||||
for (let j in d) {
|
||||
let cn = '';
|
||||
for (let k in act) {
|
||||
if (act[k].cmd == `${cmds[0]} ${cmds[1]}`) {
|
||||
cn = act[k].name;
|
||||
break;
|
||||
} else if (act[k].cmd == cmds[0]) {
|
||||
cn = act[k].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
let str = `('WEB', 'IOGroup', '${d[j].iogroupname}', '-', '-', '${u}', '${cn}', unix_timestamp())`;
|
||||
qs.push(str);
|
||||
}
|
||||
tool.promiseQuery(res, q + qs.join(','), p)
|
||||
.then(r => {
|
||||
c--;
|
||||
})
|
||||
.catch(err => {
|
||||
c--;
|
||||
});
|
||||
runLog(r.pop());
|
||||
}
|
||||
}(r.pop())
|
||||
|
||||
! function chkFin() {
|
||||
if (c <= 0) return n();
|
||||
setTimeout(chkFin, 1000);
|
||||
}()
|
||||
})
|
||||
.catch(err => {
|
||||
return n();
|
||||
});
|
||||
});
|
||||
})
|
||||
.all('*', rt.send);
|
||||
|
||||
module.exports = router;
|
183
route/api/iogroup.js
Normal file
183
route/api/iogroup.js
Normal file
@ -0,0 +1,183 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const mysql = require('../../libs/mysql_cls');
|
||||
const tool = require('../../includes/apiTool');
|
||||
|
||||
router
|
||||
.get('/', (req, res) => {
|
||||
res.send({ name: 'WebIO IOGroup API' });
|
||||
})
|
||||
.post(['/getiogrouplist', '/getiogroup'], (req, res, n) => {
|
||||
if (!config.permission.iogroup) return n('ERR9000');
|
||||
let s = false;
|
||||
let arr = req.body;
|
||||
if (req.url == '/getiogroup') {
|
||||
s = true;
|
||||
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 = "select * from ??.?? ";
|
||||
let order = " order by `iogroupuid` desc ";
|
||||
let param = [config.db.db1, 'iogroup'];
|
||||
if (s) {
|
||||
query += " where `iogroupuid` = ? ";
|
||||
param.push(arr.data.id);
|
||||
}
|
||||
|
||||
res.db.query(query + order, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
|
||||
let dos = [];
|
||||
let les = [];
|
||||
for (var i in row) {
|
||||
let str = row[i].iogroupid;
|
||||
let tmp = str.split(',');
|
||||
if (tmp.length == 0) continue;
|
||||
for (var j in tmp) {
|
||||
if (/^do([0-9]+)$/.test(tmp[j])) {
|
||||
let n = tmp[j].replace(/^do([0-9]+)$/, '$1');
|
||||
dos.push(n);
|
||||
} else if (/^le([0-9]+)$/.test(tmp[j])) {
|
||||
let n = tmp[j].replace(/^le([0-9]+)$/, '$1');
|
||||
les.push(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let doarr = [];
|
||||
let leonearr = [];
|
||||
|
||||
let pros = [];
|
||||
|
||||
if (dos.length > 0) {
|
||||
let query = "select * from ??.?? where `douid` in (?)";
|
||||
let param = [config.db.db1, 'dolist', dos];
|
||||
pros.push(tool.promiseQuery(res, query, param, 'do'));
|
||||
}
|
||||
if (les.length > 0) {
|
||||
let query = "select * from ??.?? where `leonelistuid` in (?)";
|
||||
let param = [config.db.db1, 'leonelist', les];
|
||||
pros.push(tool.promiseQuery(res, query, param, 'leone'));
|
||||
}
|
||||
|
||||
Promise.all(pros)
|
||||
.then(r => {
|
||||
for (var i in r) {
|
||||
if (r[i].key == 'do') doarr = r[i].data;
|
||||
else if (r[i].key == 'leone') leonearr = r[i].data;
|
||||
}
|
||||
|
||||
let data = {};
|
||||
data.record = tool.checkArray(row);
|
||||
data.rt = {};
|
||||
data.rt.do = tool.checkArray(doarr);
|
||||
data.rt.leone = tool.checkArray(leonearr);
|
||||
res.api_res = data;
|
||||
return n();
|
||||
})
|
||||
.catch(err => {
|
||||
if (err) return n('ERR8000');
|
||||
});
|
||||
});
|
||||
})
|
||||
.post('/addiogroup', (req, res, n) => {
|
||||
if (!config.permission.iogroup) 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.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');
|
||||
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/editiogroup', (req, res, n) => {
|
||||
if (!config.permission.iogroup) 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');
|
||||
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` = ?, \
|
||||
`iogroup_modify_date` = unix_timestamp() \
|
||||
where \
|
||||
`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');
|
||||
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/deliogroup', (req, res, n) => {
|
||||
if (!config.permission.iogroup) 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 = 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');
|
||||
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.all('*', rt.send);
|
||||
|
||||
module.exports = router;
|
284
route/api/leone.js
Normal file
284
route/api/leone.js
Normal file
@ -0,0 +1,284 @@
|
||||
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 tool = require('../../includes/apiTool');
|
||||
const exec = require('child_process').exec;
|
||||
|
||||
router
|
||||
.get('/', (req, res) => {
|
||||
res.send({name: 'WebIO Leone API'});
|
||||
})
|
||||
.post('/scanleone', (req, res, n) => {
|
||||
if (!config.permission.leone) return n('ERR9000');
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.ip || !/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/.test(arr.data.ip)) return n('ERR0010');
|
||||
if (!arr.data.password) return n('ERR0017');
|
||||
|
||||
let ips = arr.data.ip.trim().split('.');
|
||||
for (var i in ips) {
|
||||
if (ips[i] < 0 || ips[i] > 255) return n('ERR0025');
|
||||
}
|
||||
|
||||
if (fs.existsSync(config.cmdpath.scanleone)) {
|
||||
fs.unlinkSync(config.cmdpath.scanleone);
|
||||
}
|
||||
if (fs.existsSync(config.cmdpath.scanleone_end)) {
|
||||
fs.unlinkSync(config.cmdpath.scanleone_end);
|
||||
}
|
||||
|
||||
let cmd = `echo '${arr.data.ip} ${arr.data.password}' > ${config.cmdpath.scanleone}`;
|
||||
exec(cmd, (err, sout, serr) => {
|
||||
if (err) return n('ERR7000');
|
||||
|
||||
! 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');
|
||||
|
||||
let data = {};
|
||||
data.record = tool.checkArray(row);
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
}else{
|
||||
setTimeout(chkEnd, 1000);
|
||||
}
|
||||
});
|
||||
}()
|
||||
});
|
||||
})
|
||||
.post(['/getleonelist', '/getleone'], (req, res, n) => {
|
||||
if (!config.permission.leone) return n('ERR9000');
|
||||
let s = false;
|
||||
let arr = req.body;
|
||||
if (req.url == '/getleone') {
|
||||
s = true;
|
||||
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 = "select * from ??.?? where `temporary` = '0' ";
|
||||
let param = [config.db.db1, 'leonelist'];
|
||||
if (s) {
|
||||
query += " and `leonelistuid` = ? ";
|
||||
param.push(arr.data.id);
|
||||
}
|
||||
let order = " order by `leonelistuid` desc ";
|
||||
res.db.query(query + order, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
|
||||
tool.getLeoneRT(rts => {
|
||||
let data = {};
|
||||
data.record = tool.checkArray(row);
|
||||
data.rt = {};
|
||||
data.rt.status = tool.checkArray(rts);
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
});
|
||||
})
|
||||
.post('/addleone', (req, res, n) => {
|
||||
let arr = req.body;
|
||||
if (!config.permission.leone) return n('ERR9000');
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.name) return n('ERR0026');
|
||||
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');
|
||||
|
||||
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 (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');
|
||||
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
.post('/delleone', (req, res, n) => {
|
||||
if (!config.permission.leone) 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 = 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');
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/editleone', (req, res, n) => {
|
||||
if (!config.permission.leone) 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");
|
||||
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` = ?,\
|
||||
`leone_modify_date` = unix_timestamp() \
|
||||
where \
|
||||
`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');
|
||||
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
|
||||
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 (row.length == 0) return n();
|
||||
|
||||
let { leoneip, leonename, leonepassword } = row[0];
|
||||
let cmd = `sledn ${leonepassword} ${leoneip} "${leonename}"`;
|
||||
exec(cmd, (err, sout, serr) => {
|
||||
return n();
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
.post('/addscanleone', (req, res, n) => {
|
||||
if (!config.permission.leone) return n('ERR9000');
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
let arr = req.body;
|
||||
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];
|
||||
if (typeof t == 'string' && t.length == 0) continue;
|
||||
ids.push(t);
|
||||
}
|
||||
|
||||
if (ids.length == 0) {
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
}
|
||||
|
||||
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');
|
||||
|
||||
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');
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
});
|
||||
})
|
||||
.post('/clearscanleone', (req, res, n) => {
|
||||
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) => {
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.all('*', rt.send);
|
||||
|
||||
module.exports = router;
|
287
route/api/link.js
Normal file
287
route/api/link.js
Normal file
@ -0,0 +1,287 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const mysql = require('../../libs/mysql_cls');
|
||||
const tool = require('../../includes/apiTool');
|
||||
|
||||
router
|
||||
.get('/', (req, res) => {
|
||||
res.send({ name: 'WebIO Link API' });
|
||||
})
|
||||
.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 ( \
|
||||
select n2.jcioclntuid \
|
||||
from ??.?? n1 \
|
||||
left join \
|
||||
??.?? n2\
|
||||
on \
|
||||
n1.`lnlcid1` = concat('ln', n2.`jcioclntuid`) \
|
||||
or n1.`lnlcid2` = concat('ln', n2.`jcioclntuid`) \
|
||||
where n2.`jcioclntuid` is not null \
|
||||
)";
|
||||
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');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
};
|
||||
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/getlink', (req, res, n) => {
|
||||
if (!config.permission.link) 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.db8;
|
||||
res.db.connect();
|
||||
|
||||
res.api_res = {
|
||||
record: [{ root: arr.data.id }],
|
||||
rt: {
|
||||
ln: [],
|
||||
lc: []
|
||||
}
|
||||
}
|
||||
|
||||
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');
|
||||
|
||||
let ids = row[0].ids;
|
||||
let id = ids.split(',');
|
||||
id.splice(0, 1);
|
||||
|
||||
let ida = id.filter(t => {
|
||||
if (t != '') return t;
|
||||
});
|
||||
|
||||
let pros = [];
|
||||
|
||||
let lnq = "select * from ??.?? where `jcioclntuid` in (?)";
|
||||
let lnp = [config.db.db8, 'jcioclnt', ida];
|
||||
pros.push(tool.promiseQuery(res, lnq, lnp, 'ln'));
|
||||
|
||||
let lcq = "select c.* from ??.?? n \
|
||||
left join ??.?? c \
|
||||
on \
|
||||
c.`jcioclctuid` = substr(n.`lnlcid1`, 3) \
|
||||
or c.`jcioclctuid` = substr(n.`lnlcid2`, 3) \
|
||||
where \
|
||||
n.`jcioclntuid` in ( ? ) \
|
||||
and ( \
|
||||
substr(n.`lnlcid1`, 1,2) = 'lc' \
|
||||
or \
|
||||
substr(n.`lnlcid2`, 2,2) = 'lc' \
|
||||
) \
|
||||
and c.`jcioclctuid` is not null \
|
||||
group by c.`jcioclctuid`";
|
||||
let lcp = [config.db.db8, 'jcioclnt', config.db.db7, 'jcioclct', ida];
|
||||
pros.push(tool.promiseQuery(res, lcq, lcp, 'lc'));
|
||||
|
||||
Promise.all(pros)
|
||||
.then(r => {
|
||||
for (let i in r) {
|
||||
if (r[i].key == 'lc') res.api_res.rt.lc = r[i].data;
|
||||
if (r[i].key == 'ln') res.api_res.rt.ln = r[i].data;
|
||||
}
|
||||
return n();
|
||||
})
|
||||
.catch(err => n('ERR8000'));
|
||||
});
|
||||
})
|
||||
.post('/addlink', (req, res, n) => {
|
||||
if (!config.permission.link) return n('ERR9000');
|
||||
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 (!('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') {
|
||||
let p1 = new Promise((resolve, reject) => {
|
||||
runLoop(unit.id1, id => {
|
||||
resolve({ id, key: 'id1' });
|
||||
});
|
||||
});
|
||||
let p2 = new Promise((resolve, reject) => {
|
||||
runLoop(unit.id2, id => {
|
||||
resolve({ id, key: 'id2' });
|
||||
});
|
||||
});
|
||||
|
||||
Promise.all([p1, p2])
|
||||
.then(r => {
|
||||
let id1 = 0;
|
||||
let id2 = 0;
|
||||
for (let i in r) {
|
||||
if (r[i].key == 'id1') id1 = r[i].id;
|
||||
if (r[i].key == 'id2') id2 = r[i].id;
|
||||
}
|
||||
|
||||
let q = "insert into ??.?? \
|
||||
(`lnname`, `lnlcid1`, `lnlcid2`, `lnlcop`, `lnactive`, `lnaddtst`, `lnmodtst`) values (?,?,?,?,'1',unix_timestamp(),unix_timestamp())";
|
||||
let p = [config.db.db8, 'jcioclnt', unit.name, id1, id2, unit.op];
|
||||
|
||||
res.db.query(q, p, (err, row) => {
|
||||
if (err) return cb(0);
|
||||
return cb(`ln${row.insertId}`);
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
return cb(0);
|
||||
});
|
||||
} else if (unit.type == 'lc') {
|
||||
let q = "insert into ??.?? \
|
||||
(`lcname`, `lcioid`, `lciovalue`, `lcioop`, `lcactive`, `lcaddtst`, `lcmodtst`) values ('-', ?, ?, ?, '1', unix_timestamp(), unix_timestamp())";
|
||||
let p = [config.db.db7, 'jcioclct', unit.id, unit.value, unit.op];
|
||||
res.db.query(q, p, (err, row) => {
|
||||
if (err) return cb(0);
|
||||
return cb(`lc${row.insertId}`);
|
||||
});
|
||||
} else {
|
||||
return cb(0);
|
||||
}
|
||||
}(arr.data.link, (id) => {
|
||||
if (id == 0) return n('ERR8001');
|
||||
if (typeof id != 'string') id = id.toString();
|
||||
let query = "update ??.?? set \
|
||||
`lnactive` = ?, \
|
||||
`lnaction` = ? \
|
||||
where \
|
||||
`jcioclntuid` = ?";
|
||||
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');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
return n();
|
||||
});
|
||||
});
|
||||
})
|
||||
.post('/swlinkactive', (req, res, n) => {
|
||||
if (!config.permission.link) 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 = 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() \
|
||||
where \
|
||||
`jcioclntuid` = ?";
|
||||
let param = [config.db.db8, 'jcioclnt', arr.data.id];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8002');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
|
||||
return n();
|
||||
});
|
||||
|
||||
})
|
||||
.post('/dellink', (req, res, n) => {
|
||||
if (!config.permission.link) 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 = 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');
|
||||
let ids = row[0].ids;
|
||||
let id = ids.split(',');
|
||||
id.splice(0, 1);
|
||||
|
||||
let ida = id.filter(t => {
|
||||
if (t != '') return t;
|
||||
});
|
||||
|
||||
let query = "delete c,n from ??.?? n \
|
||||
left join ??.?? c \
|
||||
on \
|
||||
( \
|
||||
c.`jcioclctuid` = substr(n.`lnlcid1`, 3) \
|
||||
or c.`jcioclctuid` = substr(n.`lnlcid2`, 3)\
|
||||
) \
|
||||
and ( \
|
||||
substr(n.`lnlcid1`, 1,2) = 'lc' \
|
||||
or substr(n.`lnlcid2` ,1,2) = 'lc'\
|
||||
) \
|
||||
where \
|
||||
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');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
return n();
|
||||
});
|
||||
});
|
||||
})
|
||||
.all('*', rt.send);
|
||||
|
||||
module.exports = router;
|
46
route/api/log.js
Normal file
46
route/api/log.js
Normal file
@ -0,0 +1,46 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const rt = require('../ResTool');
|
||||
const config = require('../../config.json');
|
||||
const mysql = require('../../libs/mysql_cls');
|
||||
const tool = require('../../includes/apiTool');
|
||||
|
||||
router
|
||||
.get('/', (req, res) => {
|
||||
res.send({ name: 'WebIO Log API' })
|
||||
})
|
||||
.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);
|
||||
|
||||
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');
|
||||
let data = {};
|
||||
data.page = page;
|
||||
data.record = tool.checkArray(row);
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
})
|
||||
})
|
||||
.all('*', rt.send);
|
||||
|
||||
module.exports = router;
|
588
route/api/modbus.js
Normal file
588
route/api/modbus.js
Normal file
@ -0,0 +1,588 @@
|
||||
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 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('/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');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
};
|
||||
|
||||
return n();
|
||||
})
|
||||
})
|
||||
.post('/getmodbus', (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.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');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row),
|
||||
rt: {
|
||||
iolist: [],
|
||||
aioset: []
|
||||
}
|
||||
};
|
||||
|
||||
let pros = [];
|
||||
|
||||
let iq = "select * from ??.?? where `devuid` = ?";
|
||||
let ip = [config.db.db5, 'iolist', row[0].uid];
|
||||
pros.push(tool.promiseQuery(res, iq, ip, 'iolist'));
|
||||
|
||||
let aq = "select a.* from ??.?? a\
|
||||
left join ??.?? i\
|
||||
on \
|
||||
a.`iouid`= i.`uid` \
|
||||
where \
|
||||
i.`devuid` = ?";
|
||||
let ap = [config.db.db5, 'aioset', config.db.db5, 'iolist', row[0].uid];
|
||||
pros.push(tool.promiseQuery(res, aq, ap, 'aioset'));
|
||||
|
||||
Promise.all(pros)
|
||||
.then(r => {
|
||||
for (let i in r) {
|
||||
if (r[i].key == 'iolist') res.api_res.rt.iolist = r[i].data;
|
||||
if (r[i].key == 'aioset') res.api_res.rt.aioset = r[i].data;
|
||||
}
|
||||
return n();
|
||||
})
|
||||
.then(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');
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
};
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/addmodbus', (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.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 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];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8001');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/editmodbus', (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.id) return n('ERR0028');
|
||||
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 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 (row[0].num > 0) return n('ERR0047');
|
||||
|
||||
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` = ?, \
|
||||
`node` = ?, \
|
||||
`moduser` = ?, \
|
||||
`mtime` = unix_timestamp() \
|
||||
where \
|
||||
`uid` = ?";
|
||||
let param = [config.db.db5, 'device', arr.data.name, arr.data.node, u, arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8002');
|
||||
|
||||
let q = "delete from ??.?? where `node` in (?)";
|
||||
let p = [config.db.db6, 'jcmbrt', [arr.data.node, arr.data.original_node]];
|
||||
res.db.query(q, p, (err, row) => {
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
return n();
|
||||
});
|
||||
})
|
||||
})
|
||||
})
|
||||
.post('/delmodbus', (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.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 d,i,s,rt from ??.?? d \
|
||||
left join ??.?? i \
|
||||
on d.`uid` = i.`devuid` \
|
||||
left join ??.?? s \
|
||||
on i.`uid` = s.`iouid` \
|
||||
left join ??.?? rt \
|
||||
on d.`node` = rt.`node` \
|
||||
where \
|
||||
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');
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/getiostatus', (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');
|
||||
|
||||
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 \
|
||||
left join ??.?? d \
|
||||
on d.`node` = rt.`node` \
|
||||
left join ??.?? i \
|
||||
on i.`devuid` = d.`uid` and i.`type` = ? \
|
||||
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];
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
};
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.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');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
};
|
||||
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/addiolist', (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.id) return n('ERR0028');
|
||||
if (!arr.data.type) return n('ERR0009');
|
||||
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 query = "select count(*) as c from ??.?? \
|
||||
where \
|
||||
`devuid` = ? \
|
||||
and `type` = ? \
|
||||
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 (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];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8001');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
return n();
|
||||
});
|
||||
});
|
||||
})
|
||||
.post('/editiolist', (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.id) return n('ERR0028');
|
||||
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 query = "select count(*) sa c from ??.?? i \
|
||||
left join ??.?? i2 \
|
||||
on i2.`type` = i.`type` \
|
||||
and i2.`addr` = ? \
|
||||
and i2.`devuid` = i.`devuid` \
|
||||
and i2.`uid` != ? \
|
||||
where \
|
||||
i.`uid` = ? \
|
||||
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 (row[0].c > 0) return n('ERR0054');
|
||||
|
||||
let q = "update ??.?? set \
|
||||
`addr` = ?, \
|
||||
`num` = ?, \
|
||||
`mtime` = unix_timestamp() \
|
||||
where \
|
||||
`uid` = ?";
|
||||
let p = [config.db.db5, 'iolist', arr.data.addr, arr.data.num, arr.data.id];
|
||||
res.db.query(q, p, (err, row) => {
|
||||
if (err) return n('ERR8002');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
return n();
|
||||
});
|
||||
});
|
||||
})
|
||||
.post('/deliolist', (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.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 i, a from ??.?? i \
|
||||
left join ??.?? a \
|
||||
on a.`iouid` = i.`uid` \
|
||||
where \
|
||||
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');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/getaiosetlist', (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 a.* from ??.?? a \
|
||||
left join ??.?? i \
|
||||
on a.`iouid` = i.`uid` \
|
||||
where \
|
||||
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');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
};
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/getaioset', (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, 'aioset', arr.data.id];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row)
|
||||
};
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/delaioset', (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.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');
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/addaioset', (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.iouid) return n('ERR0028');
|
||||
if (!arr.data.name) return n('ERR0026');
|
||||
if (!('portnum' in arr.data)) return n('ERR0048');
|
||||
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 (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];
|
||||
res.db.query(q, p, (err, row) => {
|
||||
if (err) return n('ERR8001');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
|
||||
return n();
|
||||
});
|
||||
});
|
||||
})
|
||||
.post('/editaioset', (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.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 (!('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` = ? \
|
||||
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 (row[0].length > 0) return n('ERR0054');
|
||||
|
||||
let query = "update ??.?? set \
|
||||
`name` = ?, \
|
||||
`portnum` = ?, \
|
||||
`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];
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8002');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
return n();
|
||||
});
|
||||
});
|
||||
})
|
||||
.all('*', rt.send);
|
||||
|
||||
module.exports = router;
|
301
route/api/schedule.js
Normal file
301
route/api/schedule.js
Normal file
@ -0,0 +1,301 @@
|
||||
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 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 Schedule API' });
|
||||
})
|
||||
.post(['/getschedulelist', '/getschedule'], (req, res, n) => {
|
||||
if (!config.permission.schedule) return n('ERR9000');
|
||||
let s = false;
|
||||
let arr = req.body;
|
||||
if (req.url == '/getschedule') {
|
||||
s = true;
|
||||
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 = "select * from ??.?? ";
|
||||
let order = " order by `ioscheduleuid` desc ";
|
||||
let param = [config.db.db1, 'ioschedulet'];
|
||||
if (s) {
|
||||
query += " where `ioschedulet` = ? ";
|
||||
param.push(arr.data.id);
|
||||
}
|
||||
|
||||
res.db.query(query + order, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
|
||||
res.api_res = {
|
||||
record: tool.checkArray(row),
|
||||
rt: {
|
||||
'do': [],
|
||||
'leone': [],
|
||||
'iogroup': []
|
||||
}
|
||||
};
|
||||
|
||||
let dos = [];
|
||||
let les = [];
|
||||
let ios = [];
|
||||
let regex = {
|
||||
do: /^do([0-9]+)$/,
|
||||
leone: /^leone([0-9]+)$/,
|
||||
iogroup: /^iogroup([0-9]+)$/
|
||||
}
|
||||
for (let i in row) {
|
||||
let str = row[i].ioscheduleio;
|
||||
let t = str.split(',');
|
||||
if (t.length == 0) continue;
|
||||
for (let j in t) {
|
||||
if (regex.do.test(t[j])) {
|
||||
dos.push(t[j].replace(regex.do, '$1'));
|
||||
} else if (regex.leone.test(t[j])) {
|
||||
les.push(t[j].replace(regex.leone, '$1'));
|
||||
} else if (regex.iogroup.test(t[j])) {
|
||||
ios.push(t[j].replace(regex.iogroup, '$1'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let pros = [];
|
||||
if (dos.length > 0) {
|
||||
let query = "select * from ??.?? where `douid` in (?)";
|
||||
let param = [config.db.db1, 'dolist', dos];
|
||||
pros.push(tool.promiseQuery(res, query, param, 'do'));
|
||||
}
|
||||
if (les.length > 0) {
|
||||
let query = "select * from ??.?? where `leonelistuid` in (?)";
|
||||
let param = [config.db.db1, 'leonelist', les];
|
||||
pros.push(tool.promiseQuery(res, query, param, 'leone'));
|
||||
}
|
||||
if (ios.length > 0) {
|
||||
let query = "select * from ??.?? where `iogroupuid` in (?)";
|
||||
let param = [config.db.db1, 'iogroup', ios];
|
||||
pros.push(tool.promiseQuery(res, query, param, 'iogroup'));
|
||||
}
|
||||
|
||||
Promise.all(pros)
|
||||
.then(r => {
|
||||
for (let i in r) {
|
||||
if (r[i].key == 'do') {
|
||||
res.api_res.rt.do = r[i].data;
|
||||
} else if (r[i].key == 'leone') {
|
||||
res.api_res.rt.leone = r[i].data;
|
||||
} else if (r[i].key == 'iogroup') {
|
||||
res.api_res.rt.iogroup = r[i].data;
|
||||
}
|
||||
}
|
||||
return n();
|
||||
})
|
||||
.catch(err => {
|
||||
return n();
|
||||
})
|
||||
});
|
||||
})
|
||||
.post('/delschedule', (req, res, n) => {
|
||||
if (!config.permission.schedule) 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 = 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');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/swschedule', (req, res, n) => {
|
||||
if (!config.permission.schedule) 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 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');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/addschedule', (req, res, n) => {
|
||||
if (!config.permission.schedule) 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 (!('active' in arr.data)) return n('ERR0032');
|
||||
if (!arr.data.devs) return n('ERR0029');
|
||||
if (!arr.data.action) return n('ERR0030');
|
||||
if (!('min' in arr.data) || !isFinite(arr.data.min) || !(arr.data.min >= 0 && arr.data.min < 60)) return n('ERR0033');
|
||||
if (!('hour' in arr.data) || !isFinite(arr.data.hour) || !(arr.data.hour >= 0 && arr.data.hour < 24)) return n('ERR0034');
|
||||
if (!arr.data.week) {
|
||||
if (!arr.data.day || !isFinite(arr.data.day) || !(arr.data.day > 0 && arr.data.day <= 31)) return n('ERR0035');
|
||||
if (!arr.data.month || !isFinite(arr.data.month) || !(arr.data.month > 0 && arr.data.month <= 12)) return n('ERR0036');
|
||||
}
|
||||
|
||||
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 = '';
|
||||
let m = '';
|
||||
let w = '';
|
||||
if (arr.data.week) {
|
||||
w = arr.data.week;
|
||||
d = '-';
|
||||
m = '-';
|
||||
} else {
|
||||
w = '-';
|
||||
d = arr.data.day;
|
||||
m = arr.data.month;
|
||||
}
|
||||
|
||||
let query = "insert into ??.?? (\
|
||||
`ioschedulename`, \
|
||||
`ioscheduleactive`, \
|
||||
`ioscheduleio`, \
|
||||
`ioschedulecmd`, \
|
||||
`ioscheduleparam1`, \
|
||||
`ioscheduleparam2`, \
|
||||
`ioscheduleparam3`, \
|
||||
`ioscheduleparam4`, \
|
||||
`ioscheduleparam5`, \
|
||||
`ioschedule_add_date`) values (?,?,?,?,?,?,?,?,?,unix_timestamp())";
|
||||
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');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/editschedule', (req,res,n) => {
|
||||
if(!config.permission.schedule) 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');
|
||||
if (!('active' in arr.data)) return n('ERR0032');
|
||||
if (!arr.data.devs) return n('ERR0029');
|
||||
if (!arr.data.action) return n('ERR0030');
|
||||
if (!('min' in arr.data) || !isFinite(arr.data.min) || !(arr.data.min >= 0 && arr.data.min < 60)) return n('ERR0033');
|
||||
if (!('hour' in arr.data) || !isFinite(arr.data.hour) || !(arr.data.hour >= 0 && arr.data.hour < 24)) return n('ERR0034');
|
||||
if (!arr.data.week) {
|
||||
if (!arr.data.day || !isFinite(arr.data.day) || !(arr.data.day > 0 && arr.data.day <= 31)) return n('ERR0035');
|
||||
if (!arr.data.month || !isFinite(arr.data.month) || !(arr.data.month > 0 && arr.data.month <= 12)) return n('ERR0036');
|
||||
}
|
||||
|
||||
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 = '';
|
||||
let m = '';
|
||||
let w = '';
|
||||
if (arr.data.week) {
|
||||
w = arr.data.week;
|
||||
d = '-';
|
||||
m = '-';
|
||||
} else {
|
||||
w = '-';
|
||||
d = arr.data.day;
|
||||
m = arr.data.month;
|
||||
}
|
||||
|
||||
let query = "update ??.?? set \
|
||||
`ioschedulename` = ? , \
|
||||
`ioscheduleactive` = ? , \
|
||||
`ioscheduleio` = ? , \
|
||||
`ioschedulecmd` = ? , \
|
||||
`ioscheduleparam1` = ? , \
|
||||
`ioscheduleparam2` = ? , \
|
||||
`ioscheduleparam3` = ? , \
|
||||
`ioscheduleparam4` = ? , \
|
||||
`ioscheduleparam5` = ? , \
|
||||
`ioschedule_add_date` = unix_timestamp() \
|
||||
where \
|
||||
`ioscheduleuid` = ?";
|
||||
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');
|
||||
|
||||
res.api_res = {
|
||||
record: []
|
||||
};
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.all('*', rt.send);
|
||||
|
||||
module.exports = router;
|
452
route/api/system.js
Normal file
452
route/api/system.js
Normal file
@ -0,0 +1,452 @@
|
||||
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 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.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.send({ name: 'WebIO System API' });
|
||||
})
|
||||
.post('/getnetwork', (req, res, n) => {
|
||||
fs.exists(config.cmdpath.sysinfo, (exists) => {
|
||||
if (!exists) return n('ERR0014');
|
||||
fs.readFile(config.cmdpath.sysinfo, (err, d) => {
|
||||
if (err) return n('ERR0014');
|
||||
let str = d.toString().split(/\n/);
|
||||
let arr = {};
|
||||
for (var i in str) {
|
||||
if (!str[i].trim()) continue;
|
||||
let t = str[i].split(' ');
|
||||
if (t.langth < 2) continue;
|
||||
arr[t[0]] = t[1];
|
||||
}
|
||||
|
||||
let data = {};
|
||||
data.record = [arr];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
});
|
||||
})
|
||||
.post('/updatenetwork', (req, res, n) => {
|
||||
let arr = req.body;
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.type) return n('ERR0009');
|
||||
if (arr.data.type == 'manual') {
|
||||
if (!arr.data.ip) return n('ERR0010');
|
||||
if (!arr.data.netmask) return n('ERR0011');
|
||||
if (!arr.data.gateway) return n('ERR0012');
|
||||
if (!arr.data.dns) return n('ERR0013');
|
||||
}
|
||||
|
||||
let cmd = '';
|
||||
if (arr.data.type == 'manual') {
|
||||
cmd = `echo "${arr.data.ip}" "${arr.data.gateway}" "${arr.data.netmask}" "${arr.data.dns}" > ${config.cmdpath.manualip}`;
|
||||
} else {
|
||||
cmd = `touch ${config.cmdpath.dhcpip}`;
|
||||
}
|
||||
|
||||
if (cmd.length > 0) {
|
||||
exec(cmd, (err, sout, serr) => {
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
}
|
||||
})
|
||||
.post('/gettime', (req, res, n) => {
|
||||
let cmd = 'date +%s';
|
||||
exec(cmd, (err, sout, serr) => {
|
||||
let time = parseInt(sout);
|
||||
let data = {};
|
||||
data.record = [{ time }];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/updatetime', (req, res, n) => {
|
||||
let arr = req.body;
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.time || !/^[0-9]{12}$/.test(arr.data.time)) return n('ERR0015');
|
||||
|
||||
let cmd = `echo "${arr.data.time}" > ${config.cmdpath.settime}`;
|
||||
|
||||
exec(cmd, (err, sout, serr) => {
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/login', (req, res, n) => {
|
||||
let arr = req.body;
|
||||
if (!arr.data) return n('ERR0000');
|
||||
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 (row.length == 0) return n('ERR0019');
|
||||
delete row[0]['user_password'];
|
||||
|
||||
let token = '';
|
||||
while (true) {
|
||||
token = crypt.random(15);
|
||||
if (!so.chkKey(token)) break;
|
||||
}
|
||||
so.set(token, { user: row[0] });
|
||||
|
||||
let data = {};
|
||||
data.record = row;
|
||||
data.rt = {}
|
||||
data.rt.permission = [];
|
||||
|
||||
let tmp = {};
|
||||
for(let i in config.permission) {
|
||||
if(config.permission[i]){
|
||||
tmp[i] = true;
|
||||
}
|
||||
}
|
||||
data.rt.permission.push(tmp);
|
||||
|
||||
data.token = token;
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/logout', (req, res, n) => {
|
||||
let token = req.headers['x-auth-token'];
|
||||
if (token) {
|
||||
so.del(token);
|
||||
}
|
||||
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
})
|
||||
.post(['/getuserlist', '/getuser'], (req, res, n) => {
|
||||
let s = false;
|
||||
let arr = req.body;
|
||||
if (req.url == '/getuser') {
|
||||
s = true;
|
||||
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']
|
||||
|
||||
if (s) {
|
||||
query += " where `account` = ?";
|
||||
param.push(arr.data.account);
|
||||
}
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR8000');
|
||||
|
||||
for (var i in row) {
|
||||
delete row[i]['user_password'];
|
||||
}
|
||||
|
||||
let data = {};
|
||||
data.record = row;
|
||||
res.api_res = data;
|
||||
return n();
|
||||
})
|
||||
})
|
||||
.post('/deluser', (req, res, n) => {
|
||||
let arr = req.body;
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
if (!arr.data) return n('ERR0000');
|
||||
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');
|
||||
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/edituser', (req, res, n) => {
|
||||
let arr = req.body;
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.account) return n('ERR0016');
|
||||
|
||||
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;
|
||||
let pass = typeof arr.data.password == 'string' && arr.data.password.length > 0 ? arr.data.password : '';
|
||||
|
||||
if(arr.data.account == 'admin') {
|
||||
w = 1;
|
||||
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()];
|
||||
if (pass.length > 0) param.push(pass);
|
||||
param.push(arr.data.account);
|
||||
|
||||
res.db.query(query, param, (err, row) => {
|
||||
if (err) return n('ERR0021');
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/adduser', (req, res, n) => {
|
||||
let arr = req.body;
|
||||
if (!tool.checkPermission(req)) return n('ERR9000');
|
||||
if (!arr.data) return n('ERR0000');
|
||||
if (!arr.data.account) return n('ERR0016');
|
||||
if (!arr.data.password) return n('ERR0017');
|
||||
|
||||
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');
|
||||
|
||||
let data = {};
|
||||
data.record = [];
|
||||
res.api_res = data;
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.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: [],
|
||||
rt: {}
|
||||
};
|
||||
|
||||
data.rt['time'] = [{
|
||||
time: Date.now()
|
||||
}];
|
||||
|
||||
res.api_res = data;
|
||||
|
||||
let pros = [];
|
||||
pros.push(new Promise((resolve, reject) => {
|
||||
fs.exists(config.cmdpath.sysinfo, exists => {
|
||||
if (!exists) return resolve({ data: [], key: 'sysinfo' });
|
||||
fs.readFile(config.cmdpath.sysinfo, (err, d) => {
|
||||
if (err) return resolve({ data: [], key: 'sysinfo' });
|
||||
let s = d.toString();
|
||||
let tmp = s.split(/\n/);
|
||||
for (let i in tmp) {
|
||||
if (!tmp[i].trim()) continue;
|
||||
let tt = tmp[i].split(' ');
|
||||
if (tt.length > 1 && /^ip$/i.test(tt[0])) {
|
||||
return resolve({ data: [{ ip: tt[1] }], key: 'sysinfo' });
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
pros.push(new Promise((resolve, reject) => {
|
||||
fs.exists(config.cmdpath.version, exists => {
|
||||
if (!exists) return resolve({ data: [], key: 'version' });
|
||||
fs.readFile(config.cmdpath.version, (err, d) => {
|
||||
if (err) return resolve({ data: [], key: 'version' });
|
||||
return resolve({ data: [{ version: d.toString().replace(/\n/, '') }], key: 'version' });
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
if (config.permission.dio) {
|
||||
pros.push(new Promise((resolve, reject) => {
|
||||
let q = "select `diname`, `diid`, `diuid` from ??.?? ";
|
||||
let p = [config.db.db1, 'dilist'];
|
||||
res.db.query(q, p, (err, row) => {
|
||||
if (err) return resolve({ data: [], key: 'di' });
|
||||
let c = row.length;
|
||||
let td = [];
|
||||
! function chkdi(json) {
|
||||
if (!json) return;
|
||||
exec(`ditchk ${json.diid.replace(/^di([0-9]+)$/, '$1')}`, (err, sout, serr) => {
|
||||
if (err) {
|
||||
chkdi(row.pop());
|
||||
if (!--c) return resolve({ data: td, key: 'di' });
|
||||
return;
|
||||
}
|
||||
if (sout == 1) td.push(json);
|
||||
chkdi(row.pop());
|
||||
if (!--c) return resolve({ data: td, key: 'di' });
|
||||
return;
|
||||
});
|
||||
}(row.pop());
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
if (config.permission.leone) {
|
||||
pros.push(new Promise((resolve, reject) => {
|
||||
tool.getLeoneRT(rts => {
|
||||
let ips = []
|
||||
for (let i in rts) {
|
||||
if (rts[i].mode == '9999') {
|
||||
ips.push(rts[i].ip);
|
||||
}
|
||||
}
|
||||
let q = "select * from ??.?? where `leoneip` in (?) order by `leonelistuid` desc ";
|
||||
let p = [config.db.db1, 'leonelist', ips];
|
||||
res.db.query(q, p, (err, row) => {
|
||||
if (err) return resolve({ data: [], key: 'leone' });
|
||||
return resolve({ data: row, key: 'leone' });
|
||||
});
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
Promise.all(pros)
|
||||
.then(r => {
|
||||
for (let i in r) {
|
||||
if (r[i].key == 'di') {
|
||||
data.rt.di = r[i].data;
|
||||
} else if (r[i].key == 'leone') {
|
||||
data.rt.leone = r[i].data;
|
||||
} else if (r[i].key == 'sysinfo') {
|
||||
data.rt.ip = r[i].data;
|
||||
} else if (r[i].key == 'version') {
|
||||
data.rt.version = r[i].data;
|
||||
}
|
||||
}
|
||||
return n();
|
||||
})
|
||||
.catch(e => {
|
||||
return n();
|
||||
});
|
||||
})
|
||||
.post('/getselectlist', (req, res, n) => {
|
||||
let arr = req.body;
|
||||
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: []
|
||||
};
|
||||
|
||||
let pro = null;
|
||||
let q, p;
|
||||
switch (arr.data.type) {
|
||||
case 'do':
|
||||
q = "select `doname` as name, `douid` as id from ??.??";
|
||||
p = [config.db.db1, 'dolist'];
|
||||
pro = tool.promiseQuery(res, q, p, '');
|
||||
break;
|
||||
case 'di':
|
||||
q = "select `diname` as name, `diuid` as id from ??.??";
|
||||
p = [config.db.db1, 'dilist'];
|
||||
pro = tool.promiseQuery(res, q, p, '');
|
||||
break;
|
||||
case 'leone':
|
||||
q = "select `leonename` as name, `leonelistuid` as id from ??.??";
|
||||
p = [config.db.db1, 'leonelist'];
|
||||
pro = tool.promiseQuery(res, q, p, '');
|
||||
break;
|
||||
case 'iogroup':
|
||||
q = "select `iogroupname` as name, `iogroupuid` as id from ??.??";
|
||||
p = [config.db.db1, 'iogroup'];
|
||||
pro = tool.promiseQuery(res, q, p, '');
|
||||
break;
|
||||
default:
|
||||
return n();
|
||||
}
|
||||
|
||||
pro.then(r => {
|
||||
if('data' in r) {
|
||||
res.api_res.record = tool.checkArray(r.data);
|
||||
}
|
||||
return n();
|
||||
}).catch(e => {
|
||||
return n();
|
||||
})
|
||||
})
|
||||
.all('*', rt.send);
|
||||
|
||||
module.exports = router;
|
623
src/actions/index.js
Normal file
623
src/actions/index.js
Normal file
@ -0,0 +1,623 @@
|
||||
/**
|
||||
* add message to dialog queue
|
||||
* @param {string} msg
|
||||
* @param {function} act
|
||||
*/
|
||||
export const add_dialog_msg =(msg, act) => ({
|
||||
type: 'dialog_addmsg',
|
||||
msg: msg,
|
||||
act: act || null
|
||||
});
|
||||
|
||||
/**
|
||||
* remove dialog queue first message
|
||||
*/
|
||||
export const remove_dialog_msg = () => ({
|
||||
type: 'dialog_remove_first'
|
||||
});
|
||||
|
||||
/**
|
||||
* set i18next object
|
||||
* @param {object} i18n i18next object
|
||||
*/
|
||||
export const set_i18n = (i18n) => ({
|
||||
type: 'i18n_set_ctx',
|
||||
i18n: i18n
|
||||
});
|
||||
|
||||
/**
|
||||
* Toggle Menu open/close
|
||||
* @param {bool} flag switch menu open/close
|
||||
*/
|
||||
export const toggle_menu = (flag) => ({
|
||||
type: flag ? 'ui_show_menu' : 'ui_hide_menu'
|
||||
});
|
||||
|
||||
/**
|
||||
* ToGGle Loading open/close
|
||||
* @param {bool} flag
|
||||
*/
|
||||
export const toggle_loading = (flag) => ({
|
||||
type: flag ? 'ui_show_loading' : 'ui_hide_loading'
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {object} data
|
||||
*/
|
||||
export const getRequest = (data = {}) => {
|
||||
let json = {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
mode:'cors'
|
||||
};
|
||||
let token = sessionStorage.getItem('token');
|
||||
if(token) json.headers['x-auth-token'] = token;
|
||||
|
||||
json.body = JSON.stringify({data});
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
export const get_network_info = () => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
return fetch('/api/system/getnetwork', getRequest())
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1){
|
||||
return dispatch(add_dialog_msg(json.message));
|
||||
}
|
||||
let j = {};
|
||||
if('data' in json && 'record' in json.data && json.data.record.length > 0) j = json.data.record[0];
|
||||
return dispatch(network_info(j));
|
||||
});
|
||||
}
|
||||
|
||||
const network_info = (json) => ({
|
||||
type: 'network_info',
|
||||
network: json
|
||||
});
|
||||
|
||||
export const set_network_info = (dhcpMode, ip, netmask, gateway, dns) => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
let type = dhcpMode ? 'dhcp' : 'manual';
|
||||
let req = getRequest();
|
||||
let json = {
|
||||
data:{
|
||||
type,
|
||||
ip,
|
||||
netmask,
|
||||
gateway,
|
||||
dns
|
||||
}
|
||||
}
|
||||
req.body = JSON.stringify(json);
|
||||
return fetch('/api/system/updatenetwork', req)
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(get_network_info());
|
||||
});
|
||||
}
|
||||
|
||||
export const get_system_time = () => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
return fetch('/api/system/gettime', getRequest())
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1){
|
||||
return dispatch(add_dialog_msg(json.message));
|
||||
}
|
||||
let t = '';
|
||||
if('data' in json && 'record' in json.data && json.data.record.length > 0) t = json.data.record[0].time;
|
||||
return dispatch(system_time(t));
|
||||
});
|
||||
}
|
||||
|
||||
const system_time = (time) => ({
|
||||
type: 'system_time',
|
||||
time
|
||||
});
|
||||
|
||||
export const set_system_time = time => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
let req = getRequest({time});
|
||||
return fetch('/api/system/updatetime', req)
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(get_system_time());
|
||||
});
|
||||
}
|
||||
|
||||
export const get_user_list = () => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
let req = getRequest();
|
||||
return fetch('/api/system/getuserlist', req)
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(user_list(json.data.record));
|
||||
});
|
||||
}
|
||||
|
||||
const user_list = (user) => ({
|
||||
type: 'user_list',
|
||||
user
|
||||
})
|
||||
|
||||
const userApi = (url, data = {}) => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
let req = getRequest(data);
|
||||
return fetch(url, req)
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(get_user_list());
|
||||
});
|
||||
}
|
||||
|
||||
export const edit_user = (data) => dispatch => {
|
||||
return dispatch(userApi('/api/system/edituser', data));
|
||||
}
|
||||
|
||||
export const add_user = (data) => dispatch => {
|
||||
return dispatch(userApi('/api/system/adduser', data));
|
||||
}
|
||||
|
||||
export const del_user = (data) => dispatch => {
|
||||
return dispatch(userApi('/api/system/deluser', data));
|
||||
}
|
||||
|
||||
export const get_dio_info = () => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
return fetch('/api/dio/getdioinfo', getRequest())
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(dioinfo(json.data.rt.do || [], json.data.rt.di || []));
|
||||
});
|
||||
}
|
||||
|
||||
export const get_dio_status = () => dispatch => {
|
||||
return fetch('/api/dio/getio', getRequest())
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(diostatus(json.data.rt.do, json.data.rt.di));
|
||||
});
|
||||
}
|
||||
|
||||
export const set_do_status = (data) => dispatch => {
|
||||
return fetch('/api/dio/dotrun', getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
})
|
||||
}
|
||||
|
||||
export const set_dio_info = (data) => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
return fetch('/api/dio/setdioinfo', getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(get_dio_info());
|
||||
})
|
||||
}
|
||||
const diostatus = (doSt, diSt) => ({
|
||||
type: 'dio_status',
|
||||
doSt,
|
||||
diSt
|
||||
})
|
||||
const dioinfo = (dod, did) => ({
|
||||
type: 'dio_list',
|
||||
do: dod,
|
||||
di: did
|
||||
});
|
||||
|
||||
export const get_log_list = (p = 1) => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
return fetch('/api/log/getlog', getRequest({p}))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(loglist(json.data.record, json.data.page));
|
||||
});
|
||||
}
|
||||
|
||||
const loglist = (list, page) => ({
|
||||
type: 'log_list',
|
||||
list,
|
||||
page
|
||||
});
|
||||
|
||||
export const scan_leone = (data) => (dispatch, getState) => {
|
||||
dispatch(toggle_loading(1));
|
||||
dispatch(set_scanning());
|
||||
return fetch('/api/leone/scanleone', getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
let {i18n} = getState();
|
||||
if(json.data.record.length == 0) return dispatch(add_dialog_msg(i18n&&i18n.t? i18n.t('tip.scan_empty') : ''));
|
||||
return dispatch(show_scan_leone(json.data.record));
|
||||
})
|
||||
}
|
||||
|
||||
export const clear_scan_leone = (clrRemote = false) => dispatch => {
|
||||
dispatch(clear_scan());
|
||||
|
||||
return fetch('/api/leone/clearscanleone', getRequest())
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
return ;
|
||||
});
|
||||
}
|
||||
|
||||
export const add_scan_leone = (data) => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
|
||||
return fetch('/api/leone/addscanleone', getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
dispatch(clear_scan());
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(get_leone_list());
|
||||
})
|
||||
}
|
||||
|
||||
export const get_leone_list = (showLoading = true) => dispatch => {
|
||||
if(showLoading) dispatch(toggle_loading(1));
|
||||
return fetch('/api/leone/getleonelist', getRequest())
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(leone_list(json.data.record, json.data.rt.status));
|
||||
});
|
||||
}
|
||||
|
||||
export const del_leone = (data) => dispatch => {
|
||||
dispatch(leone_api('/api/leone/delleone', data));
|
||||
}
|
||||
|
||||
export const add_leone = data => dispatch => {
|
||||
dispatch(leone_api('/api/leone/addleone', data));
|
||||
}
|
||||
|
||||
export const edit_leone = data => dispatch => {
|
||||
dispatch(leone_api('/api/leone/editleone', data));
|
||||
}
|
||||
|
||||
const leone_api = (url, data) => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
return fetch(url, getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(get_leone_list());
|
||||
});
|
||||
}
|
||||
|
||||
const clear_scan = () => ({
|
||||
type: 'leone_clear_scan'
|
||||
})
|
||||
|
||||
const set_scanning = () => ({
|
||||
type: 'leone_scanning'
|
||||
})
|
||||
|
||||
const show_scan_leone = (list) => ({
|
||||
type: 'leone_scan',
|
||||
list
|
||||
});
|
||||
|
||||
const leone_list = (list, status) => ({
|
||||
type: 'leone_list',
|
||||
list,
|
||||
status
|
||||
})
|
||||
|
||||
export const io_cmd = (data, cb = null) => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
return fetch('/api/iocmd/iocmd', getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
if(cb && typeof cb == 'function') return cb();
|
||||
});
|
||||
}
|
||||
|
||||
export const get_iogroup_list = () => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
return fetch('/api/iogroup/getiogrouplist', getRequest())
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(iogroup_list(json.data.record, json.data.rt.do, json.data.rt.leone));
|
||||
});
|
||||
}
|
||||
|
||||
const iogroup_list = (list, doa, leone) => ({
|
||||
type: 'iogroup_list',
|
||||
list,
|
||||
do: doa,
|
||||
leone
|
||||
});
|
||||
|
||||
const group_api = (url, data) => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
return fetch(url, getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(get_iogroup_list());
|
||||
});
|
||||
}
|
||||
|
||||
export const del_iogroup = (data) => dispatch => {
|
||||
dispatch(group_api('/api/iogroup/deliogroup', data));
|
||||
}
|
||||
|
||||
export const add_iogroup = (data) => dispatch => {
|
||||
dispatch(group_api('/api/iogroup/addiogroup', data));
|
||||
}
|
||||
|
||||
export const edit_iogroup = (data) => dispatch => {
|
||||
dispatch(group_api('/api/iogroup/editiogroup', data));
|
||||
}
|
||||
|
||||
export const get_select_list = (data) => dispatch => {
|
||||
return fetch('/api/system/getselectlist', getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(select_list(json.data.record || []));
|
||||
})
|
||||
}
|
||||
|
||||
export const clear_select_list = () => ({
|
||||
type: 'clear_select_list'
|
||||
})
|
||||
const select_list = (list) => ({
|
||||
type: 'select_list',
|
||||
list
|
||||
})
|
||||
|
||||
const schedule_api = (url, data) => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
return fetch(url, getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(get_schedule_list());
|
||||
})
|
||||
}
|
||||
|
||||
const schedule_list = (list, dos, les, ios) => ({
|
||||
type: 'schedule_list',
|
||||
list,
|
||||
dos,
|
||||
les,
|
||||
ios
|
||||
});
|
||||
|
||||
export const get_schedule_list = () => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
return fetch('/api/schedule/getschedulelist', getRequest())
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
return dispatch(schedule_list(json.data.record || [], json.data.rt.do || [], json.data.rt.leone || [], json.data.rt.iogroup || []));
|
||||
})
|
||||
}
|
||||
|
||||
export const add_schedule = (data) => dispatch => {
|
||||
dispatch(schedule_api('/api/schedule/addschedule', data));
|
||||
}
|
||||
export const del_schedule = (data) => dispatch => {
|
||||
dispatch(schedule_api('/api/schedule/delschedule', data));
|
||||
}
|
||||
export const edit_schedule = (data) => dispatch => {
|
||||
dispatch(schedule_api('/api/schedule/editschedule', data));
|
||||
}
|
||||
export const sw_schedule = (data) => dispatch => {
|
||||
dispatch(schedule_api('/api/schedule/swschedule', data));
|
||||
}
|
||||
|
||||
export const clear_userlist = () => ({
|
||||
type: 'clear_userlist'
|
||||
});
|
||||
export const clear_dio = () => ({
|
||||
type: 'clear_dio'
|
||||
});
|
||||
export const clear_leone =() => ({
|
||||
type: 'clear_leone'
|
||||
});
|
||||
export const clear_log = () => ({
|
||||
type: 'clear_log'
|
||||
});
|
||||
export const clear_iogroup = () => ({
|
||||
type: 'clear_iogroup'
|
||||
});
|
||||
export const clear_schedule = () => ({
|
||||
type: 'clear_schedule'
|
||||
});
|
||||
|
||||
export const get_modbus_list = () => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
return fetch('/api/modbus/getmodbuslist', getRequest())
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1 ) return dispatch(add_dialog_msg(json.message));
|
||||
dispatch(modbus_list(json.data.record || []));
|
||||
});
|
||||
}
|
||||
|
||||
const modbus_list = list => ({
|
||||
type: 'modbus_list',
|
||||
list
|
||||
});
|
||||
|
||||
export const clear_modbus = () => ({
|
||||
type: 'clear_modbus'
|
||||
})
|
||||
|
||||
const modbus_api = (url, data) => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
return fetch(url, getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
dispatch(get_modbus_list());
|
||||
})
|
||||
}
|
||||
|
||||
export const del_modbus = (data) => dispatch => {
|
||||
dispatch(modbus_api('/api/modbus/delmodbus', data));
|
||||
}
|
||||
|
||||
export const add_modbus = data => dispatch => {
|
||||
dispatch(modbus_api('/api/modbus/addmodbus', data));
|
||||
}
|
||||
|
||||
export const edit_modbus = data => dispatch => {
|
||||
dispatch(modbus_api('/api/modbus/editmodbus', data));
|
||||
}
|
||||
|
||||
export const get_mb_data = data => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
return fetch('/api/modbus/getmodbus', getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
dispatch(mb_data(data.id, json.data.rt.iolist || [], json.data.rt.aioset || []));
|
||||
})
|
||||
}
|
||||
|
||||
const mb_data = (id, iolist, aioset) => ({
|
||||
type: 'mb_data',
|
||||
id,
|
||||
iolist,
|
||||
aioset
|
||||
})
|
||||
|
||||
export const get_mb_iostatus = data => dispatch => {
|
||||
return fetch('/api/modbus/getiostatus', getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
dispatch(mb_iostatus(data.id, data.type, json.data.record || []));
|
||||
})
|
||||
}
|
||||
|
||||
const mb_iostatus = (id, iotype, list) => ({
|
||||
type: 'mb_iostatus',
|
||||
id,
|
||||
iotype,
|
||||
list
|
||||
});
|
||||
|
||||
const mb_iolist_api = (url, data) => dispatch => {
|
||||
dispatch(toggle_loading(1))
|
||||
return fetch(url, getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
dispatch(get_mb_data({id: data.devuid}));
|
||||
});
|
||||
}
|
||||
|
||||
const mb_aio_api = (url, data) => dispatch => {
|
||||
dispatch(toggle_loading(1))
|
||||
return fetch(url, getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
dispatch(get_mb_data({id: data.devuid}));
|
||||
});
|
||||
}
|
||||
|
||||
export const edit_mb_iolist = data => dispatch => {
|
||||
return dispatch(mb_iolist_api('/api/modbus/editiolist', data));
|
||||
}
|
||||
export const add_mb_iolist = data => dispatch => {
|
||||
return dispatch(mb_iolist_api('/api/modbus/addiolist', data));
|
||||
}
|
||||
export const del_mb_iolist = data => dispatch => {
|
||||
return dispatch(mb_iolist_api('/api/modbus/deliolist', data));
|
||||
}
|
||||
|
||||
export const add_mb_aio = data => dispatch => {
|
||||
return dispatch(mb_aio_api('/api/modbus/addaioset', data));
|
||||
}
|
||||
export const edit_mb_aio = data => dispatch => {
|
||||
return dispatch(mb_aio_api('/api/modbus/editaioset', data));
|
||||
}
|
||||
export const del_mb_aio = data => dispatch => {
|
||||
return dispatch(mb_aio_api('/api/modbus/delaioset', data));
|
||||
}
|
||||
|
||||
export const get_link_list = () => dispatch => {
|
||||
dispatch(toggle_loading(1));
|
||||
return fetch('/api/link/getlinklist', getRequest())
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
dispatch(toggle_loading(0));
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
dispatch(link_list(json.data.record || []))
|
||||
})
|
||||
}
|
||||
|
||||
const link_list = (list) => ({
|
||||
type: 'link_list',
|
||||
list
|
||||
})
|
||||
export const clear_link = () => ({
|
||||
type: 'clear_link'
|
||||
})
|
||||
|
||||
const link_api = (url, data) => dispatch => {
|
||||
return fetch(url, getRequest(data))
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1) return dispatch(add_dialog_msg(json.message));
|
||||
dispatch(get_link_list());
|
||||
})
|
||||
}
|
||||
|
||||
export const add_link = (data) => dispatch => {
|
||||
dispatch(link_api('/api/link/addlink', data));
|
||||
}
|
||||
export const del_link = (data) => dispatch => {
|
||||
dispatch(link_api('/api/link/dellink', data));
|
||||
}
|
||||
export const sw_link_active = (data) => dispatch => {
|
||||
dispatch(link_api('/api/link/swlinkactive', data));
|
||||
}
|
66
src/admin.js
Normal file
66
src/admin.js
Normal file
@ -0,0 +1,66 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import {Router, Route, browserHistory, IndexRoute} from 'react-router';
|
||||
import {Provider} from 'react-redux';
|
||||
import {createStore, applyMiddleware, compose} from 'redux';
|
||||
import reducers from './reducers';
|
||||
import routes from './routes';
|
||||
import thunk from 'redux-thunk';
|
||||
import {set_i18n} from './actions';
|
||||
import i18next from 'i18next';
|
||||
|
||||
const middleware = [thunk];
|
||||
|
||||
const composeEnhancers =
|
||||
typeof window === 'object' &&
|
||||
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
|
||||
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
|
||||
// Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
|
||||
}) : compose;
|
||||
|
||||
const enhancer = composeEnhancers(
|
||||
applyMiddleware(...middleware),
|
||||
// other store enhancers if any
|
||||
);
|
||||
|
||||
let {NODE_ENV} = process.env;
|
||||
|
||||
const store = createStore(reducers, NODE_ENV && NODE_ENV == 'production' ? applyMiddleware(...middleware) : enhancer );
|
||||
|
||||
// store.subscribe(() => {
|
||||
// console.log(store.getState().dialog);
|
||||
// });
|
||||
|
||||
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));
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<Router history={browserHistory} routes={routes}/>
|
||||
</Provider>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<PageRoot />,
|
||||
document.getElementById('app')
|
||||
);
|
123
src/components/AdminPage/ActionLink/LinkInfoModal.js
Normal file
123
src/components/AdminPage/ActionLink/LinkInfoModal.js
Normal file
@ -0,0 +1,123 @@
|
||||
import React from 'react';
|
||||
import {Modal, Grid, Divider} from 'semantic-ui-react';
|
||||
|
||||
function randomColor() {
|
||||
var colors = [
|
||||
'red',
|
||||
'orange',
|
||||
'yellow',
|
||||
'olive',
|
||||
'green',
|
||||
'teal',
|
||||
'blue',
|
||||
'violet',
|
||||
'purple',
|
||||
'pink',
|
||||
'brown',
|
||||
'grey'
|
||||
];
|
||||
colors.sort(function () {
|
||||
return 0.5 - Math.random();
|
||||
});
|
||||
return colors.shift();
|
||||
}
|
||||
|
||||
function ParseTree(props) {
|
||||
let {root, ln, lc} = props;
|
||||
let ops = {
|
||||
"0": "等於",
|
||||
"1": "大於",
|
||||
"2": "小於",
|
||||
"3": "大於等於",
|
||||
"4": "小於等於",
|
||||
"5": "不等於",
|
||||
"8": "AND",
|
||||
"9": "OR"
|
||||
};
|
||||
|
||||
function GenLN(props) {
|
||||
let {data, isRoot} = props;
|
||||
return (
|
||||
<Grid.Column color={randomColor()} width={isRoot
|
||||
? 16
|
||||
: 8}>
|
||||
<div>{`ID:${data.jcioclntuid || ''} / Name:${data.lnname || ''} / Action:${data.lnaction || ''}`}</div>
|
||||
<Divider horizontal={true}>{ops[data.lnlcop]}</Divider>
|
||||
<GenNode ids={[data.lnlcid1, data.lnlcid2]}/>
|
||||
</Grid.Column>
|
||||
)
|
||||
}
|
||||
function GenLC(props) {
|
||||
let {data} = props;
|
||||
return (
|
||||
<Grid.Column color={randomColor()} width={8}>
|
||||
<div>{`ID:${data.jcioclctuid || ''} / Name:${data.lcname || ''} / Action:${data.lcaction || ''}`}</div>
|
||||
<hr/>
|
||||
<div>{`${data.lcioid} ${ops[data.lcioop]} ${data.lciovalue}`}</div>
|
||||
</Grid.Column>
|
||||
)
|
||||
}
|
||||
|
||||
function GenNode(props) {
|
||||
let {ids} = props;
|
||||
let isRoot = ids.length == 1 && ids[0].substr(2) == root
|
||||
? true
|
||||
: false;
|
||||
let arr = [];
|
||||
for (let i in ids) {
|
||||
let id = ids[i];
|
||||
if (/^ln/.test(id)) {
|
||||
let idn = id.match(/^ln(\d+)$/);
|
||||
if (!idn || idn.length < 1)
|
||||
continue;
|
||||
let num = idn[1];
|
||||
for (let j in ln) {
|
||||
if (ln[j].jcioclntuid == num) {
|
||||
arr.push(<GenLN key={`ln${ln[j].kcioclntuid}`} data={ln[j]} isRoot={isRoot}/>)
|
||||
}
|
||||
}
|
||||
} else if (/^lc/.test(id)) {
|
||||
let idn = id.match(/^lc(\d+)$/);
|
||||
if (!idn || idn.length < 1)
|
||||
continue;
|
||||
let num = idn[1];
|
||||
for (let j in lc) {
|
||||
if (lc[j].jcioclctuid == num) {
|
||||
arr.push(<GenLC key={`lc${lc[j].jcioclctuid}`} data={lc[j]}/>)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid>
|
||||
{arr.map(t => t)
|
||||
}
|
||||
</Grid>
|
||||
)
|
||||
}
|
||||
|
||||
return <GenNode ids={[`ln${root}`]}/>
|
||||
}
|
||||
|
||||
const LinkInfo = ({
|
||||
i18n,
|
||||
open,
|
||||
root,
|
||||
ln,
|
||||
lc,
|
||||
onClose
|
||||
}) => {
|
||||
|
||||
return (
|
||||
<Modal size="fullscreen" open={open} onClose={() => {
|
||||
onClose()
|
||||
}}>
|
||||
<Modal.Content>
|
||||
<ParseTree root={root} ln={ln} lc={lc}/>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default LinkInfo;
|
22
src/components/AdminPage/ActionLink/ListItem.js
Normal file
22
src/components/AdminPage/ActionLink/ListItem.js
Normal file
@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import {Table, Button} from 'semantic-ui-react';
|
||||
|
||||
const ListItem = ({i18n, data, swActive, delItem, showInfo}) => {
|
||||
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Button type="button" size="tiny" basic content="Delete" onClick={()=>{delItem(data.jcioclntuid || '')}}/>
|
||||
<Button type="button" size="tiny" basic content={data.lnactive == 1 ? 'Disable' : 'Enable'} onClick={()=>{swActive(data.jcioclntuid || '')}} />
|
||||
</Table.Cell>
|
||||
<Table.Cell>{data.jcioclntuid || ''}</Table.Cell>
|
||||
<Table.Cell>{data.lnname || ''}</Table.Cell>
|
||||
<Table.Cell>{data.lnactive == 1 ? '啟用' : '停用'}</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Button type="button" size="tiny" basic content="顯示資訊" onClick={()=>{showInfo(data.jcioclntuid)}} />
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default ListItem ;
|
100
src/components/AdminPage/ActionLink/index.js
Normal file
100
src/components/AdminPage/ActionLink/index.js
Normal file
@ -0,0 +1,100 @@
|
||||
import React from 'react';
|
||||
import {Container, Segment, Table, Button} from 'semantic-ui-react';
|
||||
import {getRequest} from '../../../actions';
|
||||
import {Link} from 'react-router';
|
||||
import ListItem from './ListItem';
|
||||
import LinkInfoModal from './LinkInfoModal';
|
||||
|
||||
const defState = {
|
||||
infoModal: {
|
||||
open: false,
|
||||
ln: [],
|
||||
lc: [],
|
||||
root: ''
|
||||
}
|
||||
}
|
||||
|
||||
class ActionLinkPage extends React.Component {
|
||||
state = {
|
||||
...defState
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
this.props.getList();
|
||||
|
||||
this.props.router.setRouteLeaveHook(this.props.route, () => {
|
||||
this.props.clearList();
|
||||
})
|
||||
}
|
||||
|
||||
swLinkActive = (id) => {
|
||||
if(!id) return ;
|
||||
this.props.swLink({id});
|
||||
}
|
||||
delLink = (id) => {
|
||||
if(!id) return ;
|
||||
this.props.delLink({id});
|
||||
}
|
||||
openInfoModal = (id) => {
|
||||
if(!id) return ;
|
||||
|
||||
fetch('/api/link/getlink', getRequest({id}))
|
||||
.then(response=>response.json())
|
||||
.then(json => {
|
||||
if(json.status != 1 ) return this.props.showDialog(json.message);
|
||||
this.setState({
|
||||
infoModal:{
|
||||
open: true,
|
||||
root: id,
|
||||
ln: json.data.rt.ln || [],
|
||||
lc: json.data.rt.lc || []
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
closeInfoModal = () => {
|
||||
this.setState({
|
||||
infoModal:{
|
||||
...defState.infoModal
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
render(){
|
||||
let {i18n, list} = this.props;
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Segment className="clearfix">
|
||||
<Button as={Link} to="/admin/addlink" basic color="green" floated="right" icon="plus" content="新增" style={{marginBottom: '10px'}} />
|
||||
<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.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{
|
||||
list.map((t,idx) => (
|
||||
<ListItem key={idx} i18n={i18n} data={t} swActive={this.swLinkActive} delItem={this.delLink} showInfo={this.openInfoModal} />
|
||||
))
|
||||
}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</Segment>
|
||||
<LinkInfoModal i18n={i18n}
|
||||
open={this.state.infoModal.open}
|
||||
root={this.state.infoModal.root}
|
||||
ln={this.state.infoModal.ln}
|
||||
lc={this.state.infoModal.lc}
|
||||
onClose={this.closeInfoModal} />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ActionLinkPage;
|
132
src/components/AdminPage/ActionLinkAdd/UnitItem.js
Normal file
132
src/components/AdminPage/ActionLinkAdd/UnitItem.js
Normal file
@ -0,0 +1,132 @@
|
||||
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"
|
||||
}
|
||||
]
|
||||
|
||||
class UnitItem extends React.Component {
|
||||
|
||||
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}/>)
|
||||
}
|
||||
</Segment>
|
||||
</Grid.Column>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const UnitPanel = ({data}) => {
|
||||
if (data.st == 'di') {
|
||||
return (
|
||||
<div>
|
||||
<LC_List data={data} />
|
||||
<select>
|
||||
<option value="">選擇狀態</option>
|
||||
<option value="0">0</option>
|
||||
<option value="1">1</option>
|
||||
</select>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if(data.st == 'leone') {
|
||||
return (
|
||||
<div>
|
||||
<LC_List data={data} />
|
||||
<select>
|
||||
<option value="">選擇感測器</option>
|
||||
<option value="leone_ttrigger1">溫度</option>
|
||||
<option value="leone_htrigger1">濕度</option>
|
||||
</select>
|
||||
<Input size="mini" placeholder="請輸入數值" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if(data.st == 'unit') {
|
||||
return (
|
||||
<div>
|
||||
<select>
|
||||
<option value="">選擇群組</option>
|
||||
{
|
||||
data.list.map((t,idx) => (
|
||||
<option key={idx} value={t.id}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
const LC_List = ({data}) => {
|
||||
return (
|
||||
<div>
|
||||
<select>
|
||||
<option value="">選擇裝置</option>
|
||||
{
|
||||
data.list.map((t, idx) => (
|
||||
<option key={idx} value={t.id}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
<select>
|
||||
<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>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default UnitItem;
|
138
src/components/AdminPage/ActionLinkAdd/index.js
Normal file
138
src/components/AdminPage/ActionLinkAdd/index.js
Normal file
@ -0,0 +1,138 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Container,
|
||||
Segment,
|
||||
Form,
|
||||
Input,
|
||||
Button,
|
||||
Checkbox,
|
||||
Grid
|
||||
} from 'semantic-ui-react';
|
||||
import {getRequest} from '../../../actions';
|
||||
import UnitItem from './UnitItem';
|
||||
|
||||
const defState = {
|
||||
groups: {},
|
||||
edit: {
|
||||
active: false,
|
||||
name: '',
|
||||
type: 'ln',
|
||||
op: '',
|
||||
id1: {
|
||||
st: '',
|
||||
list: [],
|
||||
data: {}
|
||||
},
|
||||
id2: {
|
||||
st: '',
|
||||
list: [],
|
||||
data: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
const gtype = {
|
||||
lc: {
|
||||
type: 'lc',
|
||||
id: '',
|
||||
op: '',
|
||||
value: ''
|
||||
},
|
||||
ln: {
|
||||
type: 'ln'
|
||||
}
|
||||
}
|
||||
|
||||
class ActionLinkAdd extends React.Component {
|
||||
state = {
|
||||
...defState
|
||||
}
|
||||
|
||||
getSelectList = (unit, type = '') => {
|
||||
if (!unit) {
|
||||
return;
|
||||
}
|
||||
let edit = {
|
||||
...this.state.edit
|
||||
};
|
||||
if (!(unit in edit)) {
|
||||
return;
|
||||
}
|
||||
edit[unit].st = type;
|
||||
edit[unit].data = {
|
||||
...gtype.lc
|
||||
}
|
||||
if (type != 'di' && type != 'leone') {
|
||||
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})
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Form as={Segment}>
|
||||
<Form.Field>
|
||||
<Checkbox label="啟用連動"/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>建立條件群組</label>
|
||||
<Segment color="red">
|
||||
<Form.Field>
|
||||
<Input label="節點名稱"/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>觸發條件</label>
|
||||
<select>
|
||||
<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}/>
|
||||
<UnitItem unit="id2" data={this.state.edit.id2} getList={this.getSelectList}/>
|
||||
</Grid>
|
||||
<div
|
||||
style={{
|
||||
textAlign: 'right'
|
||||
}}>
|
||||
<Button type="button" basic size="tiny" color="blue" content="加入"/>
|
||||
<Button type="button" basic size="tiny" color="green" content="清除"/>
|
||||
</div>
|
||||
</Segment>
|
||||
</Form.Field>
|
||||
</Form>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ActionLinkAdd;
|
28
src/components/AdminPage/DIO/DiItem.js
Normal file
28
src/components/AdminPage/DIO/DiItem.js
Normal file
@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
import {Table, Input, Checkbox, Label} from 'semantic-ui-react';
|
||||
|
||||
const DiItem = ({i18n, cusKey, data, onNameChange, onLogicChange, status}) => {
|
||||
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Label content={cusKey}/>
|
||||
</Table.Cell>
|
||||
<Table.Cell width={4}>
|
||||
<Input fluid name="diname" value={data.diname || ''} onChange={(e) => onNameChange(cusKey, e.target.value)} />
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Checkbox toggle={true} label={i18n&&i18n.t ? i18n.t('page.dio.form.label.logic') : ''} checked={data.dilogic == 1 ? true : false} onChange={(e, d) => onLogicChange(cusKey, d.checked)}/>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
<span>{i18n&&i18n.t ? i18n.t('page.dio.form.label.di_status') : ''} <Label color={status == 0 ? 'green' : 'red'} size="tiny" content={
|
||||
i18n&&i18n.t ?
|
||||
(status == 0 ? i18n.t('page.dio.form.label.di_not_triggered') : i18n.t('page.dio.form.label.di_triggered')) :
|
||||
"Loading..."
|
||||
}/></span>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default DiItem;
|
24
src/components/AdminPage/DIO/DoItem.js
Normal file
24
src/components/AdminPage/DIO/DoItem.js
Normal file
@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import {Table, Input, Checkbox, Label} from 'semantic-ui-react';
|
||||
|
||||
const DoItem = ({i18n, cusKey, data, onNameChange, onLogicChange, status, onDoRun}) => {
|
||||
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Label content={cusKey}/>
|
||||
</Table.Cell>
|
||||
<Table.Cell width={4}>
|
||||
<Input fluid name="doname" value={data.doname || ''} onChange={(e) => {onNameChange(cusKey, e.target.value)}} />
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Checkbox toggle={true} label={i18n&&i18n.t ? i18n.t('page.dio.form.label.logic') : ''} checked={data.dologic == 1 ? true : false } onChange={(e, d)=>{onLogicChange(cusKey, d.checked)}} />
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Checkbox toggle={true} label={i18n&&i18n.t ? i18n.t('page.dio.form.label.do_ctrl') : ''} checked={status == 1} onChange={(e,d) => { onDoRun(cusKey, d.checked) }} />
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default DoItem;
|
175
src/components/AdminPage/DIO/index.js
Normal file
175
src/components/AdminPage/DIO/index.js
Normal file
@ -0,0 +1,175 @@
|
||||
import React from 'react';
|
||||
import {Container, Grid, Segment, Header, CheckBox, Table, Input, Button} from 'semantic-ui-react';
|
||||
import DoItem from './DoItem';
|
||||
import DiItem from './DiItem';
|
||||
|
||||
class DIO extends React.Component {
|
||||
state = {
|
||||
do: [],
|
||||
di: [],
|
||||
doSt: {},
|
||||
diSt: {}
|
||||
}
|
||||
|
||||
tick = null
|
||||
|
||||
onNameChange = (key, name) => {
|
||||
let reg = new RegExp(`^${key}$`, 'i');
|
||||
if(/^do/i.test(key)) {
|
||||
let dos = [...this.state.do];
|
||||
for(let i in dos){
|
||||
if(reg.test(dos[i].doid)){
|
||||
dos[i].doname = name;
|
||||
this.setState({
|
||||
do: dos
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
let dis = [...this.state.di];
|
||||
for(let i in dis){
|
||||
if(reg.test(dis[i].diid)){
|
||||
dis[i].diname = name;
|
||||
this.setState({
|
||||
di: dis
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onLogicChange = (key, st) => {
|
||||
let reg = new RegExp(`^${key}$`, 'i');
|
||||
if(/^do/i.test(key)) {
|
||||
let dos = [...this.state.do];
|
||||
for(let i in dos){
|
||||
if(reg.test(dos[i].doid)){
|
||||
dos[i].dologic = st ? 1 : 0;
|
||||
this.setState({
|
||||
do: dos
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
let dis = [...this.state.di];
|
||||
for(let i in dis){
|
||||
if(reg.test(dis[i].diid)){
|
||||
dis[i].dilogic = st ? 1 : 0;
|
||||
this.setState({
|
||||
di: dis
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateSetting = () => {
|
||||
let dos = [...this.state.do];
|
||||
let dis = [...this.state.di];
|
||||
let json = {};
|
||||
json.do = {};
|
||||
json.di = {};
|
||||
for(let i in dos) {
|
||||
json.do[dos[i].doid] = {
|
||||
name: dos[i].doname,
|
||||
logic: dos[i].dologic
|
||||
}
|
||||
}
|
||||
for(let i in dis){
|
||||
json.di[dis[i].diid] ={
|
||||
name: dis[i].diname,
|
||||
logic: dis[i].dilogic
|
||||
}
|
||||
}
|
||||
|
||||
this.props.setDIOInfo(json);
|
||||
}
|
||||
|
||||
doRun = (key, val) => {
|
||||
let reg = /^do([0-9]+)$/i;
|
||||
let m = key.match(reg);
|
||||
if(!m || !m[1]) return ;
|
||||
let pin = m[1];
|
||||
if(pin in this.state.doSt){
|
||||
let tmp = {...this.state.doSt};
|
||||
tmp[pin] = val ? 1 : 0;
|
||||
this.setState({
|
||||
doSt: tmp
|
||||
})
|
||||
}
|
||||
this.props.dotRun(pin, val ? 1 : 0);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
this.setState({
|
||||
do: nextProps.dio.do,
|
||||
di: nextProps.dio.di,
|
||||
diSt: nextProps.dio.diSt,
|
||||
doSt: nextProps.dio.doSt
|
||||
});
|
||||
}
|
||||
|
||||
updateTick = () => {
|
||||
this.props.getIO();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.getDIOInfo();
|
||||
this.props.getIO();
|
||||
this.tick = setInterval(this.updateTick, 5000);
|
||||
|
||||
this.props.router.setRouteLeaveHook(this.props.route, () => {
|
||||
this.props.clearList();
|
||||
})
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.tick);
|
||||
}
|
||||
|
||||
render () {
|
||||
let {i18n} = this.props;
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Header as="h4" color="blue" content={i18n&&i18n.t ? i18n.t('page.dio.title.do'): ''}/>
|
||||
<Table>
|
||||
<Table.Body>
|
||||
{
|
||||
[1,2,3,4,5,6,7,8].map(t => {
|
||||
let tmp = this.state.do.filter(tt => tt.doid == `do${t}`);
|
||||
let dost = this.state.doSt[t] || 0;
|
||||
return <DoItem i18n={i18n} key={t} cusKey={`Do${t}`} data={tmp[0] || {}} onLogicChange={this.onLogicChange} onNameChange={this.onNameChange} status={dost} onDoRun={this.doRun}/>
|
||||
})
|
||||
}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Header as="h4" color="blue" content={i18n&&i18n.t ? i18n.t('page.dio.title.di'): ''}/>
|
||||
<Table>
|
||||
<Table.Body>
|
||||
{
|
||||
[1,2,3,4,5,6,7,8].map(t => {
|
||||
let tmp = this.state.di.filter(tt => tt.diid == `di${t}`);
|
||||
let dist = this.state.diSt[t] || 0;
|
||||
return <DiItem i18n={i18n} key={t} cusKey={`Di${t}`} data={tmp[0] || {}} onLogicChange={this.onLogicChange} onNameChange={this.onNameChange} status={dist} />
|
||||
})
|
||||
}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
<Button type="button" style={{marginTop: '10px'}} fluid content={i18n&&i18n.t ? i18n.t('page.dio.form.button.update_setting') : ''} onClick={() => {this.updateSetting()}} />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default DIO;
|
17
src/components/AdminPage/IOCmd/SelectedItem.js
Normal file
17
src/components/AdminPage/IOCmd/SelectedItem.js
Normal file
@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
import {List, Button, Label} from 'semantic-ui-react';
|
||||
|
||||
const SelectedItem = ({i18n, data, idx, removeSelect}) => {
|
||||
|
||||
return (
|
||||
<List.Item>
|
||||
<List.Content floated="right">
|
||||
<Button type="button" size="mini" content={i18n&&i18n.t ? i18n.t('page.iogroup.form.button.remove') : ''} onClick={() => {removeSelect(idx)}} />
|
||||
</List.Content>
|
||||
<Label content={data.type || ''} />
|
||||
{data.name || ''}
|
||||
</List.Item>
|
||||
)
|
||||
}
|
||||
|
||||
export default SelectedItem;
|
129
src/components/AdminPage/IOCmd/index.js
Normal file
129
src/components/AdminPage/IOCmd/index.js
Normal file
@ -0,0 +1,129 @@
|
||||
import React from 'react';
|
||||
import {Container, Segment, Form, Button, List, Input} from 'semantic-ui-react';
|
||||
import DeviceSelect from '../../Common/DeviceSelect';
|
||||
import SelectedItem from './SelectedItem';
|
||||
|
||||
class IOCmdPage extends React.Component {
|
||||
state = {
|
||||
showTemp: false,
|
||||
selectItem: []
|
||||
}
|
||||
|
||||
querySelectList = (type) => {
|
||||
this.props.clearSelectList();
|
||||
if(!type) return ;
|
||||
this.props.getSelectList({type});
|
||||
}
|
||||
|
||||
checkShowTemp = (cmd) => {
|
||||
this.setState({
|
||||
showTemp: cmd == 2 ? true : false
|
||||
})
|
||||
}
|
||||
|
||||
addSelect = (data) => {
|
||||
let tmp = this.state.selectItem.filter(t => t.id == data.id);
|
||||
if(tmp.length > 0) return ;
|
||||
this.setState({
|
||||
selectItem: [...this.state.selectItem, data]
|
||||
});
|
||||
}
|
||||
|
||||
removeSelect = (idx) => {
|
||||
this.state.selectItem.splice(idx, 1);
|
||||
this.setState({
|
||||
selectItem: this.state.selectItem
|
||||
})
|
||||
}
|
||||
|
||||
runCmd = (data) => {
|
||||
let {i18n} = this.props;
|
||||
if(!data.cmd) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.select_action') : '');
|
||||
if(data.cmd == 2){
|
||||
if(!data.temp) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty_temp') : '');
|
||||
if(!(data.temp > 16 && data.temp < 30)) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.temp_format') : '');
|
||||
|
||||
data.cmd = `${data.cmd} ${data.temp}`;
|
||||
}
|
||||
|
||||
let ids = this.state.selectItem.map(t => t.id);
|
||||
|
||||
let json = {
|
||||
...data,
|
||||
devs: ids.join(',')
|
||||
}
|
||||
|
||||
this.props.runCmd(json);
|
||||
|
||||
this.setState({
|
||||
showTemp: false,
|
||||
selectItem: []
|
||||
}, ()=>{
|
||||
this.props.clearSelectList();
|
||||
})
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.clearSelectList();
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n,permissions,devs} = this.props;
|
||||
let actlist = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.action_list') : [];
|
||||
return (
|
||||
<Container>
|
||||
<Segment>
|
||||
<Form onSubmit={(e,d) => {
|
||||
e.preventDefault();
|
||||
this.runCmd(d.formData);
|
||||
}} serializer={e => {
|
||||
let json = {
|
||||
cmd: '',
|
||||
temp: ''
|
||||
};
|
||||
let sel = e.querySelector('select[name="cmd"]');
|
||||
if(sel && 'value' in sel) json.cmd = sel.value;
|
||||
let temp = e.querySelector('input[name="temp"]');
|
||||
if(temp && 'value' in temp) json.temp = temp.value;
|
||||
|
||||
if(e.reset) e.reset();
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Form.Field>
|
||||
<label>{i18n&&i18n.t ? i18n.t('page.iocmd.form.label.action') : ''}</label>
|
||||
<select name="cmd" onChange={e => {
|
||||
this.checkShowTemp(e.target.value);
|
||||
}}>
|
||||
<option value="">{i18n&&i18n.t ? i18n.t('select.action') : ''}</option>
|
||||
{
|
||||
actlist.map((t,idx) => <option key={idx} value={t.cmd}>{t.name}</option>)
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
{
|
||||
this.state.showTemp ?
|
||||
(<Form.Field>
|
||||
<Input name="temp" label={i18n&&i18n.t ? i18n.t('page.iocmd.form.label.temp') : ''} />
|
||||
</Form.Field>) : null
|
||||
}
|
||||
<DeviceSelect i18n={i18n} devs={devs} page="iocmd" showGroup={true} permissions={permissions} querySelectList={this.querySelectList} addSelect={this.addSelect} />
|
||||
<Form.Field>
|
||||
<label>{i18n&&i18n.t ? i18n.t('page.iocmd.form.label.selected_device') : ''}</label>
|
||||
<Segment>
|
||||
<List divided relaxed={true}>
|
||||
{
|
||||
this.state.selectItem.map((t,idx) => <SelectedItem key={idx} i18n={i18n} data={t} idx={idx} removeSelect={this.removeSelect} />)
|
||||
}
|
||||
</List>
|
||||
</Segment>
|
||||
</Form.Field>
|
||||
<Button type="submit" fluid content={i18n&&i18n.t ? i18n.t('page.iocmd.form.button.submit') : ''} />
|
||||
</Form>
|
||||
</Segment>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default IOCmdPage;
|
51
src/components/AdminPage/IOGroup/GroupModal.js
Normal file
51
src/components/AdminPage/IOGroup/GroupModal.js
Normal file
@ -0,0 +1,51 @@
|
||||
import React from 'react';
|
||||
import {Modal, Form, Input, Segment, Grid, Button, Header, List} from 'semantic-ui-react';
|
||||
import SelectedItem from './SelectedItem';
|
||||
import DeviceSelect from '../../Common/DeviceSelect';
|
||||
|
||||
const GroupModal = ({i18n, open, type, data, devs, permissions, onClose, onSubmit, selected, removeSelect, addSelect, querySelectList}) => {
|
||||
|
||||
return (
|
||||
<Modal open={open}>
|
||||
<Modal.Header content={i18n&&i18n.t ? (type == 1 ? i18n.t('page.iogroup.form.title.edit') : i18n.t('page.iogroup.form.title.add')) : ''} />
|
||||
<Modal.Content>
|
||||
<Form onSubmit={(e,d) => {
|
||||
e.preventDefault();
|
||||
onSubmit(type, d.formData);
|
||||
}} serializer={e => {
|
||||
let json = {
|
||||
name: '',
|
||||
id: data.iogroupuid || 0
|
||||
};
|
||||
let n = e.querySelector('input[name="name"]');
|
||||
if(n && 'value' in n) json.name = n.value;
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Form.Field>
|
||||
<Input label={i18n&&i18n.t?i18n.t('page.iogroup.form.label.name') : ''} name="name" defaultValue={data.iogroupname || ''} />
|
||||
</Form.Field>
|
||||
<DeviceSelect i18n={i18n} devs={devs} page="iogroup" showGroup={false} permissions={permissions} addSelect={addSelect} querySelectList={querySelectList} />
|
||||
<Segment>
|
||||
<Header as="h4" content={i18n&&i18n.t ? i18n.t('page.iogroup.form.label.selected_device') : ''} />
|
||||
<List divided verticalAlign="middle">
|
||||
{
|
||||
selected.map((t, idx) => <SelectedItem i18n={i18n} key={idx} data={t} idx={idx} removeSelect={removeSelect}/>)
|
||||
}
|
||||
</List>
|
||||
</Segment>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Button fluid type="submit" content={i18n&&i18n.t?i18n.t('page.leone.form.button.submit'):''}/>
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button fluid type="button" content={i18n&&i18n.t?i18n.t('page.leone.form.button.cancel'):''} onClick={() => {onClose()}}/>
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default GroupModal;
|
55
src/components/AdminPage/IOGroup/ListItem.js
Normal file
55
src/components/AdminPage/IOGroup/ListItem.js
Normal file
@ -0,0 +1,55 @@
|
||||
import React from 'react';
|
||||
import {Table, Button, Label, Item} from 'semantic-ui-react';
|
||||
|
||||
const ListItem = ({i18n, data, dos, les, openItemModal, onDelete, openModal}) => {
|
||||
let devs = data.iogroupid || '';
|
||||
let dev = devs.split(',');
|
||||
let items = [];
|
||||
if(dev.length > 0){
|
||||
for(let i in dev){
|
||||
if(/^do/i.test(dev[i])){
|
||||
for(let j in dos){
|
||||
if(`do${dos[j].douid}` == dev[i]) {
|
||||
items.push({
|
||||
type: 'DigitOutput',
|
||||
name: dos[j].doname,
|
||||
id: dev[i]
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else if(/^le/i.test(dev[i])){
|
||||
for(let j in les){
|
||||
if(`le${les[j].leonelistuid}` == dev[i]) {
|
||||
items.push({
|
||||
type: 'LeOne',
|
||||
name: les[j].leonename,
|
||||
id: dev[i]
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Button type="button" basic size="tiny" color="red" content={i18n&&i18n.t ? i18n.t('page.iogroup.table.button.del') : ''} onClick={()=>{onDelete(data.iogroupuid)}} />
|
||||
<Button type="button" basic size="tiny" color="blue" content={i18n&&i18n.t ? i18n.t('page.iogroup.table.button.edit') : ''} onClick={() => {openModal(1, data, items)}}/>
|
||||
</Table.Cell>
|
||||
<Table.Cell>{data.iogroupname}</Table.Cell>
|
||||
<Table.Cell>
|
||||
{
|
||||
items.length > 0 ?
|
||||
(items.length == 1 ?
|
||||
<Item><Label content={items[0].type} />{items[0].name}</Item>:
|
||||
<Button size="tiny" basic content={i18n&&i18n.t ? i18n.t('page.iogroup.table.button.showgroup') : ''} onClick={()=>{openItemModal(items)}}/> ) :
|
||||
''
|
||||
}
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default ListItem;
|
17
src/components/AdminPage/IOGroup/SelectedItem.js
Normal file
17
src/components/AdminPage/IOGroup/SelectedItem.js
Normal file
@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
import {List, Button, Label} from 'semantic-ui-react';
|
||||
|
||||
const SelectedItem = ({i18n, data, idx, removeSelect}) => {
|
||||
|
||||
return (
|
||||
<List.Item>
|
||||
<List.Content floated="right">
|
||||
<Button type="button" size="mini" content={i18n&&i18n.t ? i18n.t('page.iogroup.form.button.remove') : ''} onClick={() => {removeSelect(idx)}} />
|
||||
</List.Content>
|
||||
<Label content={data.type || ''} />
|
||||
{data.name || ''}
|
||||
</List.Item>
|
||||
)
|
||||
}
|
||||
|
||||
export default SelectedItem;
|
152
src/components/AdminPage/IOGroup/index.js
Normal file
152
src/components/AdminPage/IOGroup/index.js
Normal file
@ -0,0 +1,152 @@
|
||||
import React from 'react';
|
||||
import {Container, Table, Button, Segment, Modal, Item, Label} from 'semantic-ui-react';
|
||||
import ListItem from './ListItem';
|
||||
import GroupModal from './GroupModal';
|
||||
|
||||
class IOGroupPage extends React.Component {
|
||||
state = {
|
||||
modal: false,
|
||||
modalType: 0,
|
||||
modalData: {},
|
||||
modalSelect: [],
|
||||
showItem: false,
|
||||
items: []
|
||||
}
|
||||
|
||||
showGroupItems = (items = []) => {
|
||||
|
||||
this.setState({
|
||||
showItem: true,
|
||||
items
|
||||
})
|
||||
}
|
||||
closeItemModal = () => {
|
||||
this.setState({
|
||||
showItem: false,
|
||||
items: []
|
||||
})
|
||||
}
|
||||
|
||||
openModal = (type, data= {}, items=[]) => {
|
||||
this.props.clearSelectList();
|
||||
this.setState({
|
||||
modal: true,
|
||||
modalType: type,
|
||||
modalData: data,
|
||||
modalSelect: items
|
||||
})
|
||||
}
|
||||
closeModal = () => {
|
||||
this.setState({
|
||||
modal: false,
|
||||
modalData: {},
|
||||
modalSelect: []
|
||||
})
|
||||
}
|
||||
submitModal = (type, data ={}) => {
|
||||
let {i18n} = this.props;
|
||||
if(!data.name || (type == 1 && !data.id)) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
|
||||
let ids = this.state.modalSelect.map(t => t.id);
|
||||
|
||||
let json = {
|
||||
...data,
|
||||
devs: ids.join(',')
|
||||
};
|
||||
|
||||
if(type == 1) {
|
||||
this.props.editIOGroup(json);
|
||||
}else {
|
||||
this.props.addIOGroup(json);
|
||||
}
|
||||
|
||||
this.closeModal()
|
||||
}
|
||||
|
||||
querySelectList = (type) => {
|
||||
this.props.clearSelectList();
|
||||
if(!type) return ;
|
||||
this.props.getSelectList({type});
|
||||
}
|
||||
|
||||
removeSelect = (idx) => {
|
||||
this.state.modalSelect.splice(idx, 1);
|
||||
this.setState({
|
||||
modalSelect: this.state.modalSelect
|
||||
})
|
||||
}
|
||||
|
||||
addSelect = (data = {}) => {
|
||||
let tmp = this.state.modalSelect.filter(t => t.id == data.id);
|
||||
if(tmp.length > 0) return ;
|
||||
this.setState({
|
||||
modalSelect: [...this.state.modalSelect, data]
|
||||
})
|
||||
}
|
||||
|
||||
delIOGroup = (id) => {
|
||||
if(!id) return ;
|
||||
this.props.delIOGroup({id});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.getIOGroupList();
|
||||
|
||||
this.props.router.setRouteLeaveHook(this.props.route, () => {
|
||||
this.props.clearList();
|
||||
})
|
||||
}
|
||||
|
||||
render () {
|
||||
let {i18n, list, dos, leones, permissions, devs} = this.props;
|
||||
return (
|
||||
<Container>
|
||||
<Segment className="clearfix">
|
||||
<Button basic type="button" color="green" floated="right" style={{marginBottom: '15px'}} icon="plus" content={i18n&&i18n.t ? i18n.t('page.iogroup.table.button.add') : ''} onClick={() => {this.openModal(0)}} />
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.iogroup.table.operate') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.iogroup.table.name') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.iogroup.table.groups') : ''}</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{
|
||||
list.map((t, idx) => <ListItem i18n={i18n} key={idx} data={t} dos={dos} les={leones} openItemModal={this.showGroupItems} onDelete={this.delIOGroup} openModal={this.openModal}/>)
|
||||
}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</Segment>
|
||||
<ShowGroupItem open={this.state.showItem} items={this.state.items} onClose={this.closeItemModal} />
|
||||
<GroupModal i18n={i18n}
|
||||
open={this.state.modal}
|
||||
data={this.state.modalData}
|
||||
type={this.state.modalType}
|
||||
onClose={this.closeModal}
|
||||
onSubmit={this.submitModal}
|
||||
permissions={permissions}
|
||||
devs={devs}
|
||||
selected={this.state.modalSelect}
|
||||
removeSelect={this.removeSelect}
|
||||
addSelect={this.addSelect}
|
||||
querySelectList={this.querySelectList} />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const ShowGroupItem = ({i18n,open,items, onClose}) => {
|
||||
|
||||
return (
|
||||
<Modal open={open} onClose={() => {onClose()}} size="small">
|
||||
<Modal.Content>
|
||||
{
|
||||
items.map((t, idx) => <Item key={idx}><Label content={t.type}/>{t.name}</Item>)
|
||||
}
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default IOGroupPage;
|
52
src/components/AdminPage/LeOne/CmdModal.js
Normal file
52
src/components/AdminPage/LeOne/CmdModal.js
Normal file
@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import {Modal, Form, Header, Grid, Button, Input} from 'semantic-ui-react';
|
||||
|
||||
const CmdModal = ({i18n, open, id, devname, cmd, onSubmit, onClose}) => {
|
||||
let actlist = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.action_list') : [];
|
||||
let act = actlist.filter(t => t.cmd == cmd);
|
||||
|
||||
return (
|
||||
<Modal open={open} closeOnDimmerClick={false}>
|
||||
<Modal.Content>
|
||||
<Form onSubmit={(e, d) => {
|
||||
e.preventDefault();
|
||||
onSubmit(d.formData);
|
||||
}} serializer={e => {
|
||||
let json = {
|
||||
devs: `le${id}`
|
||||
};
|
||||
|
||||
json.cmd = cmd;
|
||||
if(json.cmd == 2){
|
||||
let el = e.querySelector('input[name="temp"]');
|
||||
if(el && 'value' in el){
|
||||
json.cmd = `${json.cmd} ${el.value}`
|
||||
}
|
||||
}
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Header as="h4" content={devname || ''}/>
|
||||
<Header as="h4" content={`${i18n&&i18n.t?i18n.t('page.leone.form.label.run_command'):''} ${act[0] ? act[0].name : ''}`} />
|
||||
{
|
||||
cmd && cmd == '2' ?
|
||||
(<Form.Field>
|
||||
<Input fluid name="temp" label={i18n&&i18n.t ? i18n.t('page.leone.form.label.temp') : ''}/>
|
||||
</Form.Field>) :
|
||||
null
|
||||
}
|
||||
<Grid columns={2} style={{marginTop: '15px'}}>
|
||||
<Grid.Column>
|
||||
<Button fluid type="submit" content={i18n&&i18n.t?i18n.t('page.leone.form.button.submit'):''}/>
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button fluid type="button" content={i18n&&i18n.t?i18n.t('page.leone.form.button.cancel'):''} onClick={() => {onClose()}}/>
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default CmdModal;
|
46
src/components/AdminPage/LeOne/LeOneModal.js
Normal file
46
src/components/AdminPage/LeOne/LeOneModal.js
Normal file
@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import {Modal, Form, Input, Grid, Button} from 'semantic-ui-react';
|
||||
|
||||
const LeOneModal = ({i18n, open, type, data, onSubmit, onClose}) => {
|
||||
|
||||
return (
|
||||
<Modal open={open}>
|
||||
<Modal.Header content={i18n&&i18n.t ? (type == 1 ? i18n.t('page.leone.form.title.edit') : i18n.t('page.leone.form.title.add')) : '' } />
|
||||
<Modal.Content>
|
||||
<Form onSubmit={(e,d) => {
|
||||
e.preventDefault();
|
||||
onSubmit(type, d.formData);
|
||||
}} serializer={e => {
|
||||
let json = {
|
||||
id: data.leonelistuid || 0,
|
||||
name: e.querySelector('input[name="name"]').value,
|
||||
ip: e.querySelector('input[name="ip"]').value,
|
||||
password: e.querySelector('input[name="password"]').value
|
||||
};
|
||||
|
||||
return json ;
|
||||
}}>
|
||||
<Form.Field>
|
||||
<Input label={i18n&&i18n.t?i18n.t('page.leone.form.label.name'):''} name="name" defaultValue={data.leonename || ''} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input label={i18n&&i18n.t?i18n.t('page.leone.form.label.ip'):''} name="ip" disabled={type == 1} defaultValue={data.leoneip || ''} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input label={i18n&&i18n.t?i18n.t('page.leone.form.label.password'):''} name="password" defaultValue={data.leonepassword || ''} />
|
||||
</Form.Field>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Button fluid type="submit" content={i18n&&i18n.t?i18n.t('page.leone.form.button.submit'):''}/>
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button fluid type="button" content={i18n&&i18n.t?i18n.t('page.leone.form.button.cancel'):''} onClick={() => {onClose()}}/>
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default LeOneModal;
|
46
src/components/AdminPage/LeOne/ListItem.js
Normal file
46
src/components/AdminPage/LeOne/ListItem.js
Normal file
@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import {Table, Button} from 'semantic-ui-react';
|
||||
|
||||
const ListItem = ({i18n, data, status, delLeone, editLeone, runCmd}) => {
|
||||
let stats = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.leone_stats') : [];
|
||||
let actlist = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.action_list') : [];
|
||||
let st = stats.filter(t => t.mode == status.mode);
|
||||
let tunit = i18n&&i18n.t ? [i18n.t('time_unit.sec'), i18n.t('time_unit.min'), i18n.t('time_unit.hour'), i18n.t('time_unit.day')] : [];
|
||||
let idx = 0;
|
||||
let mtime = Math.floor(Date.now() / 1000) - status.mtime;
|
||||
while(idx < 3){
|
||||
if(mtime >= 60){
|
||||
mtime = Math.floor(mtime / 60);
|
||||
idx++;
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Button type="button" basic size="tiny" color="red" content={i18n&&i18n.t ? i18n.t('page.leone.table.button.del') : ''} onClick={() => {delLeone(data.leonelistuid)}} />
|
||||
<Button type="button" basic size="tiny" color="blue" content={i18n&&i18n.t ? i18n.t('page.leone.table.button.edit') : ''} onClick={() => {editLeone(1, data)}} />
|
||||
</Table.Cell>
|
||||
<Table.Cell>{data.leonename}</Table.Cell>
|
||||
<Table.Cell>{data.leoneip}</Table.Cell>
|
||||
<Table.Cell>{`${status.ts == '9999' || !isFinite(status.ts) ? '-' : `${status.ts} ${String.fromCharCode(8451)}`} / ${status.hs == '9999' || !isFinite(status.hs) ? '-' : `${status.hs} %`}`}</Table.Cell>
|
||||
<Table.Cell>{st[0]&&st[0].name ? st[0].name : status.mode}</Table.Cell>
|
||||
<Table.Cell>{data.leonepassword}</Table.Cell>
|
||||
<Table.Cell>{`${mtime}${tunit[idx]}${i18n&&i18n.t? i18n.t('time_unit.ago') : ''}`}</Table.Cell>
|
||||
<Table.Cell>
|
||||
<select onChange={(e)=>{
|
||||
runCmd(data.leonelistuid, data.leonename, e.target.value);
|
||||
e.target.selectedIndex = 0;
|
||||
}}>
|
||||
<option value="">{i18n&&i18n.t ? i18n.t('tip.select_action') : ''}</option>
|
||||
{
|
||||
actlist.map((t, idx) => <option key={idx} value={t.cmd}>{t.name}</option>)
|
||||
}
|
||||
</select>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default ListItem;
|
52
src/components/AdminPage/LeOne/ScanForm.js
Normal file
52
src/components/AdminPage/LeOne/ScanForm.js
Normal file
@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import {Container, Table, Segment, Form, Grid, Button, Input} from 'semantic-ui-react';
|
||||
|
||||
const ScanForm = ({i18n, onSubmit}) => {
|
||||
|
||||
return (
|
||||
<Form onSubmit={(e, data) => {
|
||||
e.preventDefault();
|
||||
onSubmit(data.formData);
|
||||
}} serializer={e => {
|
||||
let json = {
|
||||
ip1: e.querySelector('input[name="ip1"]').value,
|
||||
ip2: e.querySelector('input[name="ip2"]').value,
|
||||
ip3: e.querySelector('input[name="ip3"]').value,
|
||||
password: e.querySelector('input[name="pass"]').value
|
||||
};
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Grid verticalAlign="middle">
|
||||
<Grid.Column computer={8} mobile={16}>
|
||||
<Form.Group inline={true}>
|
||||
<Form.Field>
|
||||
<label>{i18n&&i18n.t ? i18n.t('page.leone.form.label.ip') : ''}</label>
|
||||
<Input style={{width: '60px'}} defaultValue="192" name="ip1"/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input style={{width: '60px'}} defaultValue="168" name="ip2"/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input style={{width: '60px'}} defaultValue="1" name="ip3"/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input style={{width: '60px'}} defaultValue="*" disabled/>
|
||||
</Form.Field>
|
||||
</Form.Group>
|
||||
<Form.Group inline={true}>
|
||||
<Form.Field>
|
||||
<label>{i18n&&i18n.t ? i18n.t('page.leone.form.label.password') : ''}</label>
|
||||
<Input name="pass" />
|
||||
</Form.Field>
|
||||
</Form.Group>
|
||||
</Grid.Column>
|
||||
<Grid.Column computer={8} mobile={16}>
|
||||
<Button type="submit" fluid icon="search" content={i18n&&i18n.t ? i18n.t('page.leone.form.button.scan') : ''} />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
||||
export default ScanForm;
|
123
src/components/AdminPage/LeOne/SelectScan.js
Normal file
123
src/components/AdminPage/LeOne/SelectScan.js
Normal file
@ -0,0 +1,123 @@
|
||||
import React from 'react';
|
||||
import {Modal, Grid, Label, Button, Table, Checkbox} from 'semantic-ui-react';
|
||||
import ScanItem from './SelectScanItem';
|
||||
|
||||
class SelectScan extends React.Component {
|
||||
|
||||
state = {
|
||||
list: [],
|
||||
page: 1,
|
||||
per: 10,
|
||||
totalpage: 1
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if(this.state.list.length !== nextProps.list) {
|
||||
let totalpage = Math.ceil( nextProps.list.length / this.state.per ) || 1;
|
||||
this.setState({
|
||||
list: nextProps.list,
|
||||
totalpage
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onItemSelect = (idx, checked) => {
|
||||
let list = [...this.state.list];
|
||||
if(list[idx]){
|
||||
list[idx].checked = checked;
|
||||
this.setState({
|
||||
list
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
changePage = (p = 1) => {
|
||||
p = p < 1 ? 1 : p;
|
||||
p = p > this.state.totalpage ? this.state.totalpage : p;
|
||||
this.setState({
|
||||
page: p
|
||||
});
|
||||
}
|
||||
|
||||
calSelect = () => {
|
||||
let a = this.state.list.filter(t => t.checked);
|
||||
return a.length;
|
||||
}
|
||||
|
||||
checkAllSelect = (s, e) => {
|
||||
let arr = this.state.list.slice(s,e);
|
||||
let tmp = arr.filter(t => !t.checked);
|
||||
if(tmp.length > 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
changeAllCheck = (s, e, chk) => {
|
||||
let arr = [...this.state.list];
|
||||
for(let i=s; i<e; i++){
|
||||
arr[i].checked = chk;
|
||||
}
|
||||
this.setState({
|
||||
list: arr
|
||||
});
|
||||
}
|
||||
|
||||
submitData = () => {
|
||||
let json = {
|
||||
id: []
|
||||
};
|
||||
for(let i in this.state.list) {
|
||||
if(this.state.list[i].leonelistuid) json.id.push(this.state.list[i].leonelistuid)
|
||||
}
|
||||
|
||||
this.props.onSubmit(json);
|
||||
}
|
||||
|
||||
render () {
|
||||
let {i18n, onClose} = this.props;
|
||||
|
||||
let sIdx = this.state.per * (this.state.page - 1);
|
||||
let eIdx = sIdx + this.state.per;
|
||||
eIdx = eIdx > this.state.list.length ? this.state.list.length : eIdx;
|
||||
let arr = this.state.list.slice(sIdx, eIdx);
|
||||
|
||||
return (
|
||||
<Modal open={this.state.list.length > 0 ? true : false} closeOnDimmerClick={false} >
|
||||
<Modal.Header content={i18n&&i18n.t ? i18n.t('page.leone.form.title.select-dev') : ''} />
|
||||
<Modal.Content>
|
||||
<div className="clearfix">
|
||||
<Label content={`${i18n&&i18n.t?i18n.t('page.leone.form.label.select_num') : ''} ${this.calSelect()}`} basic color="blue"/>
|
||||
<div style={{float: 'right'}}>
|
||||
<Button type="button" content={i18n&&i18n.t?i18n.t('page.leone.form.button.prevpage') : ''} onClick={() => {this.changePage(this.state.page - 1)}} size="tiny" basic color="blue"/>
|
||||
<Label basic content={`${this.state.page} / ${this.state.totalpage}`}/>
|
||||
<Button type="button" content={i18n&&i18n.t?i18n.t('page.leone.form.button.nextpage') : ''} onClick={() => {this.changePage(this.state.page + 1)}} size="tiny" basic color="blue"/>
|
||||
</div>
|
||||
</div>
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell><Checkbox checked={this.checkAllSelect(sIdx, eIdx)} onChange={(e,d)=>{ this.changeAllCheck(sIdx, eIdx, d.checked) }} /></Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.form.label.name') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.form.label.name') : ''}</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{
|
||||
arr.map((t, idx) => <ScanItem key={idx} i18n={i18n} data={t} idx={idx} onChange={this.onItemSelect}/>)
|
||||
}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Button content={i18n&&i18n.t ? i18n.t('page.leone.form.button.submit') : ''} fluid onClick={() => {this.submitData()}}/>
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button content={i18n&&i18n.t ? i18n.t('page.leone.form.button.cancel') : ''} fluid onClick={() => {onClose()}} />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default SelectScan;
|
12
src/components/AdminPage/LeOne/SelectScanItem.js
Normal file
12
src/components/AdminPage/LeOne/SelectScanItem.js
Normal file
@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
import {Table, Checkbox} from 'semantic-ui-react';
|
||||
|
||||
const ScanItem = ({i18n, data, idx, onChange}) => (
|
||||
<Table.Row>
|
||||
<Table.Cell><Checkbox onChange={(e,d) => {onChange(idx, d.checked)}} checked={data.checked} /></Table.Cell>
|
||||
<Table.Cell>{data.leonename}</Table.Cell>
|
||||
<Table.Cell>{data.leoneip}</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
|
||||
export default ScanItem;
|
174
src/components/AdminPage/LeOne/index.js
Normal file
174
src/components/AdminPage/LeOne/index.js
Normal file
@ -0,0 +1,174 @@
|
||||
import React from 'react';
|
||||
import {Container, Table, Segment, Form, Grid, Button} from 'semantic-ui-react';
|
||||
import ScanForm from './ScanForm';
|
||||
import {add_dialog_msg} from '../../../actions';
|
||||
import SelectScan from './SelectScan';
|
||||
import ListItem from './ListItem';
|
||||
import LeOneModal from './LeOneModal';
|
||||
import CmdModal from './CmdModal';
|
||||
|
||||
class LeOnePage extends React.Component {
|
||||
state = {
|
||||
modal: false,
|
||||
modalType: 0,
|
||||
modalData: {},
|
||||
cmd: false,
|
||||
cmdData: {
|
||||
id: 0,
|
||||
name: '',
|
||||
cmd: ''
|
||||
}
|
||||
}
|
||||
|
||||
scanSubmit = (data) => {
|
||||
let {i18n} = this.props;
|
||||
|
||||
if(!data.ip1.trim() || !data.ip2.trim() || !data.ip3.trim() || !data.password.trim())
|
||||
return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
|
||||
// send to scan
|
||||
let json = {
|
||||
ip: `${data.ip1}.${data.ip2}.${data.ip3}`,
|
||||
password: data.password
|
||||
};
|
||||
|
||||
this.props.scanLeOne(json);
|
||||
}
|
||||
|
||||
doDelLeOne = (id) => {
|
||||
let {i18n} = this.props;
|
||||
if(!id) return;
|
||||
this.props.delLeOne({id});
|
||||
}
|
||||
|
||||
openModal = (type, data = {}) => {
|
||||
this.setState({
|
||||
modal: true,
|
||||
modalType: type == 1 ? 1 : 0,
|
||||
modalData: data
|
||||
});
|
||||
}
|
||||
|
||||
closeModal = () => {
|
||||
this.setState({
|
||||
modal: false,
|
||||
modalData: {}
|
||||
});
|
||||
}
|
||||
|
||||
submitModal = (type, data ={}) => {
|
||||
let {i18n} = this.props;
|
||||
if((type == 1 && !data.id) || !data.name || !data.password || (type == 0 && !data.ip)) return this.props.showDialog(i18n&&i18n.t?i18n.t('tip.input_empty') : '')
|
||||
|
||||
if(type == 0){
|
||||
this.props.addLeOne(data);
|
||||
}else{
|
||||
this.props.editLeOne(data);
|
||||
}
|
||||
|
||||
this.closeModal();
|
||||
}
|
||||
|
||||
openCmdModal = (id, name, cmd) => {
|
||||
this.setState({
|
||||
cmd: true,
|
||||
cmdData: {
|
||||
id,name,cmd
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
closeCmdModal = () => {
|
||||
this.setState({
|
||||
cmd: false,
|
||||
cmdData: {
|
||||
id: 0,
|
||||
name: '',
|
||||
cmd: ''
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
submitCmdModal = (data) => {
|
||||
let {i18n} = this.props;
|
||||
if(!data.devs || !data.cmd) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
if(data.cmd.trim() == 2) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty_temp') : '');
|
||||
|
||||
let cmds = data.cmd.split(' ');
|
||||
if(cmds.length != 2) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
if(cmds[0] == 2 && (cmds[1] <16 || cmds[1] > 30) ) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.temp_format') : '');
|
||||
this.props.runCmd(data);
|
||||
this.closeCmdModal()
|
||||
}
|
||||
|
||||
tick = null;
|
||||
|
||||
runTick = () => {
|
||||
if(!this.props.scanning){
|
||||
this.props.getLeOneList(0);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.getLeOneList();
|
||||
this.tick = setInterval(this.runTick, 10000);
|
||||
this.props.router.setRouteLeaveHook(this.props.route, () => {
|
||||
this.props.clearList();
|
||||
})
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearInterval(this.tick);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
|
||||
}
|
||||
|
||||
render () {
|
||||
let {i18n, scanList, clearScan, addScanLeOne, list, status} = this.props;
|
||||
return (
|
||||
<Container>
|
||||
<Segment>
|
||||
<ScanForm i18n={i18n} onSubmit={this.scanSubmit} />
|
||||
</Segment>
|
||||
<Segment className="clearfix">
|
||||
<Button type="button" basic color="green" content={i18n&&i18n.t ? i18n.t('page.leone.table.button.add') : ''} style={{marginBottom: '10px'}} icon="plus" floated="right" onClick={() => {this.openModal(0)}} />
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.operate') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.name') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.ip') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.hsts') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.mode') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.password') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.update_time') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.leone.table.control') : ''}</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{
|
||||
list.map(t => {
|
||||
let st = {};
|
||||
for(let i in status){
|
||||
if(status[i].ip == t.leoneip) {
|
||||
st = status[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return <ListItem i18n={i18n} key={t.leonelistuid} status={st} data={t} delLeone={this.doDelLeOne} editLeone={this.openModal} runCmd={this.openCmdModal}/>
|
||||
})
|
||||
}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</Segment>
|
||||
<SelectScan i18n={i18n} list={scanList} onClose={clearScan} onSubmit={addScanLeOne}/>
|
||||
<LeOneModal i18n={i18n} open={this.state.modal} type={this.state.modalType} data={this.state.modalData} onSubmit={this.submitModal} onClose={this.closeModal} />
|
||||
<CmdModal i18n={i18n} open={this.state.cmd} id={this.state.cmdData.id} devname={this.state.cmdData.name} cmd={this.state.cmdData.cmd} onSubmit={this.submitCmdModal} onClose={this.closeCmdModal} />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default LeOnePage;
|
32
src/components/AdminPage/Log/LogItem.js
Normal file
32
src/components/AdminPage/Log/LogItem.js
Normal file
@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import {Table} from 'semantic-ui-react';
|
||||
import {convertTime} from '../../../tools';
|
||||
|
||||
const LogItem = ({i18n, data}) => {
|
||||
if(!(i18n && i18n.t)) return null;
|
||||
let defMsg = '';
|
||||
if(/^(do|di)/i.test(data.iolabel)){
|
||||
defMsg = i18n.t('page.log.description.dio');
|
||||
}else if(/^leone/i.test(data.iolabel)){
|
||||
defMsg = i18n.t('page.log.description.leone');
|
||||
}else if(/^iogroup/i.test(data.iolabel)){
|
||||
defMsg = i18n.t('page.log.description.iogroup');
|
||||
}
|
||||
let msg = defMsg
|
||||
.replace(/\$io_label\$/, data.iolabel)
|
||||
.replace(/\$io_name\$/, data.ioname)
|
||||
.replace(/\$io_logic\$/, data.iosetting1)
|
||||
.replace(/\$io_trigger_time\$/, convertTime(data.ioeventtst))
|
||||
.replace(/\$io_trigger_status\$/, data.ioevent);
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>{convertTime(data.ioeventtst)}</Table.Cell>
|
||||
<Table.Cell>{data.iosetting3}</Table.Cell>
|
||||
<Table.Cell>{data.iosetting2}</Table.Cell>
|
||||
<Table.Cell>{data.ioevent}</Table.Cell>
|
||||
<Table.Cell>{msg}</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default LogItem;
|
46
src/components/AdminPage/Log/index.js
Normal file
46
src/components/AdminPage/Log/index.js
Normal file
@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import {Container, Table, Button, Label} from 'semantic-ui-react';
|
||||
import LogItem from './LogItem';
|
||||
|
||||
class LogPage extends React.Component {
|
||||
|
||||
componentDidMount(){
|
||||
this.props.getList();
|
||||
this.props.router.setRouteLeaveHook(this.props.route, () => {
|
||||
this.props.clearList();
|
||||
})
|
||||
}
|
||||
|
||||
loadPage = (p = 1) => {
|
||||
this.props.getList(p);
|
||||
}
|
||||
|
||||
render () {
|
||||
let {i18n, list, page} = this.props;
|
||||
return (
|
||||
<Container>
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.log.table.datetime') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.log.table.username') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.log.table.status') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.log.table.event') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.log.table.description') : ''}</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{ list.map(t => <LogItem key={t.jciocertuid} i18n={i18n} data={t} />) }
|
||||
</Table.Body>
|
||||
</Table>
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<Button content={i18n&&i18n.t ? i18n.t('page.log.table.button.prevpage') : ''} size="small" labelPosition="left" basic={true} color="black" icon="arrow left" onClick={() => {this.loadPage(page.prevpage)}} />
|
||||
<Label basic={true} color="blue" content={`${page.page || 1} / ${page.totalpage || 1}`} />
|
||||
<Button content={i18n&&i18n.t ? i18n.t('page.log.table.button.nextpage') : ''} size="small" labelPosition="right" basic={true} color="black" icon="arrow right" onClick={() => {this.loadPage(page.nextpage)}} />
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default LogPage;
|
40
src/components/AdminPage/Modbus/AIOForm.js
Normal file
40
src/components/AdminPage/Modbus/AIOForm.js
Normal file
@ -0,0 +1,40 @@
|
||||
import React from 'react';
|
||||
import {Table, Input, Form, Button} from 'semantic-ui-react';
|
||||
|
||||
const AIOForm = ({i18n, open, type, data, onSubmit, onClose}) => {
|
||||
if(!open) return null;
|
||||
let input = {
|
||||
name: data.name || '',
|
||||
portnum: data.portnum || '',
|
||||
scale_min: data.scale_min || 0,
|
||||
scale_max: data.scale_max || 0,
|
||||
range_min: data.range_min || 0,
|
||||
range_max: data.range_max || 0
|
||||
}
|
||||
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="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'}/>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Input name="scale_min" size="small" label="Min" onChange={(e,d)=>{input.scale_min = d.value}} defaultValue={data.scale_min || '0'}/>
|
||||
<Input name="scale_max" size="small" label="Max" onChange={(e,d)=>{input.scale_max = d.value}} defaultValue={data.scale_max || '0'}/>
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Button basic size="tiny" content="Submit" type="button" onClick={()=>{
|
||||
let json = {
|
||||
...input,
|
||||
id: data.uid || ''
|
||||
}
|
||||
onSubmit(type, json);
|
||||
}} />
|
||||
<Button basic size="tiny" content="Cancel" type="button" onClick={()=>{onClose()}} />
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default AIOForm;
|
20
src/components/AdminPage/Modbus/AIOListItem.js
Normal file
20
src/components/AdminPage/Modbus/AIOListItem.js
Normal file
@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import {Table, Button} from 'semantic-ui-react';
|
||||
|
||||
const AIOListItem = ({i18n, data, editAIO, delAIO}) => {
|
||||
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>{data.name || ''}</Table.Cell>
|
||||
<Table.Cell>{data.portnum || ''}</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>
|
||||
<Button type="button" basic size="tiny" content="Edit" onClick={()=>{editAIO(1, data)}} />
|
||||
<Button type="button" basic size="tiny" content="Delete" onClick={()=>{delAIO(data.uid || '')}} />
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default AIOListItem;
|
72
src/components/AdminPage/Modbus/AIOModal.js
Normal file
72
src/components/AdminPage/Modbus/AIOModal.js
Normal file
@ -0,0 +1,72 @@
|
||||
import React from 'react';
|
||||
import {Modal, Table, Button, Input, Form} from 'semantic-ui-react';
|
||||
import ListItem from './AIOListItem';
|
||||
import AIOForm from './AIOForm';
|
||||
|
||||
class AIOModal extends React.Component {
|
||||
state = {
|
||||
editMode: false,
|
||||
data: {},
|
||||
type: 0
|
||||
}
|
||||
|
||||
openEditField = (type, data = {}) => {
|
||||
this.closeEditField(()=>{
|
||||
this.setState({
|
||||
editMode: true,
|
||||
data,
|
||||
type
|
||||
});
|
||||
});
|
||||
}
|
||||
closeEditField = (cb) => {
|
||||
this.setState({
|
||||
editMode: false,
|
||||
data: {}
|
||||
}, ()=>{
|
||||
if(cb && typeof cb == 'function') cb()
|
||||
});
|
||||
}
|
||||
submitAIO = (type, data) => {
|
||||
data.iouid = this.props.iouid;
|
||||
this.props.onSubmit(type, data);
|
||||
this.closeEditField();
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n, iouid, open, list, onClose, delAIO} = this.props;
|
||||
|
||||
return (
|
||||
<Modal size="large" open={open} onClose={()=>{onClose()}}>
|
||||
<Modal.Content className="clearfix">
|
||||
<Button basic size="tiny" color="green" floated="right" style={{marginBottom: '10px'}} icon="plus" content="Add Set" onClick={()=>{
|
||||
this.openEditField(0);
|
||||
}}/>
|
||||
<Table size="small">
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<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>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{
|
||||
list.map((t,idx) => (
|
||||
<ListItem key={idx} i18n={i18n} data={t} editAIO={this.openEditField} delAIO={delAIO}/>
|
||||
))
|
||||
}
|
||||
</Table.Body>
|
||||
<Table.Footer>
|
||||
<AIOForm i18n={i18n} open={this.state.editMode} type={this.state.type} data={this.state.data} onSubmit={this.submitAIO} onClose={this.closeEditField}/>
|
||||
</Table.Footer>
|
||||
</Table>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default AIOModal;
|
25
src/components/AdminPage/Modbus/DeviceList.js
Normal file
25
src/components/AdminPage/Modbus/DeviceList.js
Normal file
@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import {Menu, Header} from 'semantic-ui-react';
|
||||
import DevListItem from './DeviceListItem';
|
||||
|
||||
const DeviceList = ({i18n, list, delModbus, editModbus, showDev, selectDevToShow}) => {
|
||||
|
||||
return (
|
||||
<Menu vertical={true}>
|
||||
<Menu.Item>
|
||||
<Menu.Header content="裝置列表" />
|
||||
<Menu.Menu>
|
||||
{
|
||||
list.map((t, idx) => {
|
||||
return (
|
||||
<DevListItem key={idx} i18n={i18n} idx={idx} data={t} delModbus={delModbus} editModbus={editModbus} showDev={showDev} selectDevToShow={selectDevToShow}/>
|
||||
)
|
||||
})
|
||||
}
|
||||
</Menu.Menu>
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
}
|
||||
|
||||
export default DeviceList;
|
19
src/components/AdminPage/Modbus/DeviceListItem.js
Normal file
19
src/components/AdminPage/Modbus/DeviceListItem.js
Normal file
@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
import {List, Button, Icon} from 'semantic-ui-react';
|
||||
|
||||
const DeviceListItem = ({i18n, idx, data, delModbus, editModbus, showDev, selectDevToShow}) =>{
|
||||
|
||||
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)}}/>
|
||||
</List.Item>
|
||||
)
|
||||
}
|
||||
|
||||
export default DeviceListItem;
|
63
src/components/AdminPage/Modbus/IOModal.js
Normal file
63
src/components/AdminPage/Modbus/IOModal.js
Normal file
@ -0,0 +1,63 @@
|
||||
import React from 'react';
|
||||
import {Modal, Form, Button, Grid, Input } from 'semantic-ui-react';
|
||||
|
||||
const IOModal = ({i18n, open, type, data, onSubmit, onClose}) => {
|
||||
|
||||
let iotype = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.porttype') : [];
|
||||
|
||||
return (
|
||||
<Modal open={open}>
|
||||
<Modal.Header content={type == 1 ? '修改資料' : '新增資料'} />
|
||||
<Modal.Content>
|
||||
<Form onSubmit={(e,d)=>{
|
||||
e.preventDefault();
|
||||
onSubmit(type, d.formData);
|
||||
}} serializer={e=>{
|
||||
let json = {
|
||||
id: data.uid || '',
|
||||
addr: '',
|
||||
num: '',
|
||||
type: ''
|
||||
};
|
||||
|
||||
let addr = e.querySelector('input[name="addr"]');
|
||||
if(addr && 'value' in addr) json.addr = addr.value;
|
||||
let num = e.querySelector('input[name="num"]');
|
||||
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;
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Form.Field>
|
||||
<label>接口類型</label>
|
||||
<select name="io_type" defaultValue={data.type || ''} disabled={type == 1}>
|
||||
<option value="">請選擇類型</option>
|
||||
{
|
||||
iotype.map((t,idx) => (
|
||||
<option key={idx} value={t.code}>{t.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input name="addr" label="起始位址" defaultValue={data.addr || ''} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input name="num" label="數量" defaultValue={data.num || ''} />
|
||||
</Form.Field>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Button type="submit" fluid content="Submit" />
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button type="button" fluid content="Cancel" onClick={()=>{onClose()}}/>
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default IOModal ;
|
89
src/components/AdminPage/Modbus/IOPanel.js
Normal file
89
src/components/AdminPage/Modbus/IOPanel.js
Normal file
@ -0,0 +1,89 @@
|
||||
import React from 'react';
|
||||
import {Menu, Segment, Table, Header, Label} from 'semantic-ui-react';
|
||||
import {convertTime} from '../../../tools';
|
||||
import IOPanelListItem from './IOPanelListItem';
|
||||
|
||||
class IOPanel extends React.Component {
|
||||
state = {
|
||||
tabIdx: '1'
|
||||
}
|
||||
|
||||
tabItemClick = (e, el) => {
|
||||
this.setState({
|
||||
tabIdx: el.name
|
||||
}, ()=>{
|
||||
this.props.getStatus({id: this.props.data.uid || '', type: this.state.tabIdx});
|
||||
});
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nprops) {
|
||||
if(nprops.data && nprops.data.uid) {
|
||||
if(this.props.data && this.props.data.uid){
|
||||
if(this.props.data.uid != nprops.data.uid) {
|
||||
this.props.getStatus({id: nprops.data.uid, type: this.state.tabIdx});
|
||||
}
|
||||
}else{
|
||||
this.props.getStatus({id: nprops.data.uid, type: this.state.tabIdx});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render(){
|
||||
let {i18n, show, data, ioModal, delIOList, showAIOSet} = this.props;
|
||||
if(!show) return null;
|
||||
|
||||
let iolist = data.iolist || [];
|
||||
let ios = iolist.filter(t => {
|
||||
if(t.type == this.state.tabIdx) return t;
|
||||
});
|
||||
let status = data.status || {};
|
||||
let ss = status[this.state.tabIdx] || [];
|
||||
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.Menu position="right">
|
||||
<Menu.Item content="AddIO" icon="plus" onClick={()=>{ioModal(0)}}/>
|
||||
</Menu.Menu>
|
||||
</Menu>
|
||||
<Segment attached="bottom">
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>起始位置</Table.HeaderCell>
|
||||
<Table.HeaderCell>接口數量</Table.HeaderCell>
|
||||
<Table.HeaderCell>操作</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{
|
||||
ios.map((t,idx) => (
|
||||
<IOPanelListItem key={idx} i18n={i18n} data={t} ioModal={ioModal} delIOList={delIOList} showAIOSet={showAIOSet} />
|
||||
))
|
||||
}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
<Segment>
|
||||
<Header as="h3" content="接口資訊"/>
|
||||
{
|
||||
ss.map((t,idx) => (
|
||||
<div key={idx}>
|
||||
<Label basic color="blue" content={`PortNum:${t.port}`}/>
|
||||
<Label basic color="blue" content={`原始數值:${t.value}`}/>
|
||||
<Label basic color="blue" content={`轉換數值:${t.value2}`}/>
|
||||
<Label basic color="green" content={`最後更新於:${convertTime(t.tst, true)}`}/>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</Segment>
|
||||
</Segment>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default IOPanel;
|
24
src/components/AdminPage/Modbus/IOPanelListItem.js
Normal file
24
src/components/AdminPage/Modbus/IOPanelListItem.js
Normal file
@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import {Table, Button} from 'semantic-ui-react';
|
||||
|
||||
const IOPanelListItem = ({i18n, data, ioModal, delIOList, showAIOSet}) => {
|
||||
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>{data.addr || ''}</Table.Cell>
|
||||
<Table.Cell>{data.num || ''}</Table.Cell>
|
||||
<Table.Cell>
|
||||
<Button type="button" basic content="修改" onClick={()=>{ioModal(1, data)}}/>
|
||||
<Button type="button" basic content="刪除" onClick={()=>{delIOList(data.uid || '')}}/>
|
||||
{
|
||||
data.type == 3 || data.type == 4 ?
|
||||
(
|
||||
<Button type="button" basic content="顯示設定" onClick={()=>{showAIOSet(data.uid)}} />
|
||||
):null
|
||||
}
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default IOPanelListItem;
|
49
src/components/AdminPage/Modbus/ModbusModal.js
Normal file
49
src/components/AdminPage/Modbus/ModbusModal.js
Normal file
@ -0,0 +1,49 @@
|
||||
import React from 'react';
|
||||
import {Modal, Form, Input, Grid, Button} from 'semantic-ui-react';
|
||||
|
||||
const ModbusModal = ({i18n, open, type, data, onSubmit, onClose}) => {
|
||||
if(!i18n || Object.keys(i18n).length == 0) return null;
|
||||
|
||||
return (
|
||||
<Modal open={open}>
|
||||
<Modal.Header content={type == 1 ? '修改裝置' : '新增裝置'} />
|
||||
<Modal.Content>
|
||||
<Form onSubmit={(e, d) => {
|
||||
e.preventDefault();
|
||||
onSubmit(type, d.formData);
|
||||
}} serializer={e => {
|
||||
let json = {
|
||||
name: '',
|
||||
node: '',
|
||||
id: data.uid || '',
|
||||
original_node: data.node || ''
|
||||
};
|
||||
|
||||
let n = e.querySelector('input[name="name"]');
|
||||
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;
|
||||
|
||||
return json ;
|
||||
}}>
|
||||
<Form.Field>
|
||||
<Input name="name" defaultValue={data.name || ''} label="Name"/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input name="node" defaultValue={data.node || ''} label="Node"/>
|
||||
</Form.Field>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Button content="Submit" fluid type="submit" />
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button content="Cancel" fluid type="button" onClick={()=>{onClose()}} />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default ModbusModal;
|
210
src/components/AdminPage/Modbus/index.js
Normal file
210
src/components/AdminPage/Modbus/index.js
Normal file
@ -0,0 +1,210 @@
|
||||
import React from 'react';
|
||||
import {Container, Segment, List, Menu, Item, Grid} from 'semantic-ui-react';
|
||||
import DeviceList from './DeviceList';
|
||||
import ModbusModal from './ModbusModal';
|
||||
import IOPanel from './IOPanel';
|
||||
import IOModal from './IOModal';
|
||||
import AIOModal from './AIOModal';
|
||||
|
||||
const defIOModalState = {
|
||||
open: false,
|
||||
data: {},
|
||||
type: 0
|
||||
}
|
||||
const defAIOModalState = {
|
||||
open: false,
|
||||
list: [],
|
||||
iouid: 0
|
||||
}
|
||||
|
||||
class ModbusPage extends React.Component {
|
||||
state = {
|
||||
mbModal: false,
|
||||
mbType: 0,
|
||||
mbData: {},
|
||||
showDev: "",
|
||||
ioModal:{
|
||||
...defIOModalState
|
||||
},
|
||||
aioModal:{
|
||||
...defAIOModalState
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.getList();
|
||||
|
||||
this.props.router.setRouteLeaveHook(this.props.route, () => {
|
||||
this.props.clearList();
|
||||
});
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nprop) {
|
||||
if(this.state.aioModal.open) {
|
||||
this.openAIOModal(this.state.aioModal.iouid, nprop.list);
|
||||
}
|
||||
}
|
||||
|
||||
delModbus = id => {
|
||||
if(!id) return ;
|
||||
this.props.delModbus({id});
|
||||
}
|
||||
|
||||
openModbusModal = (type, data = {}) => {
|
||||
this.setState({
|
||||
mbModal: true,
|
||||
mbType: type,
|
||||
mbData: data
|
||||
});
|
||||
}
|
||||
closeModbusModal = () => {
|
||||
this.setState({
|
||||
mbModal: false,
|
||||
mbData: {}
|
||||
})
|
||||
}
|
||||
submitModbusModal = (type, data = {}) => {
|
||||
let {i18n} = this.props;
|
||||
if(type == 1 && (!data.id)) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
if(!data.name || !('node' in data) || data.node.length == 0) return this.props.showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
|
||||
if(type == 1){
|
||||
this.props.editModbus(data);
|
||||
}else{
|
||||
this.props.addModbus(data);
|
||||
}
|
||||
this.closeModbusModal();
|
||||
}
|
||||
selectDevToShow = (uid) => {
|
||||
this.setState({
|
||||
showDev: uid
|
||||
});
|
||||
this.props.getMBData({id: uid});
|
||||
}
|
||||
|
||||
openIOModal = (type, data = {}) => {
|
||||
this.setState({
|
||||
ioModal: {
|
||||
open: true,
|
||||
type,
|
||||
data
|
||||
}
|
||||
});
|
||||
}
|
||||
closeIOModal = () =>{
|
||||
this.setState({
|
||||
ioModal: {
|
||||
...defIOModalState
|
||||
}
|
||||
})
|
||||
}
|
||||
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'));
|
||||
|
||||
data.devuid = this.state.showDev;
|
||||
if(type == 1){
|
||||
this.props.editIOList(data);
|
||||
}else{
|
||||
data.id = this.state.showDev;
|
||||
this.props.addIOList(data);
|
||||
}
|
||||
this.closeIOModal();
|
||||
}
|
||||
delIOList = (id) => {
|
||||
if(!id) return ;
|
||||
this.props.delIOList({id, devuid: this.state.showDev});
|
||||
}
|
||||
openAIOModal = (id, nlist = []) => {
|
||||
if(!id) return ;
|
||||
let slist = nlist.length == 0 ? this.props.list : nlist;
|
||||
let dev = slist.filter(t => {
|
||||
if(t.uid == this.state.showDev) return t;
|
||||
});
|
||||
if(dev.length == 0) return ;
|
||||
let aio = dev[0].aioset || [];
|
||||
let list = aio.filter(t => {
|
||||
if(t.iouid == id) return t;
|
||||
});
|
||||
this.setState({
|
||||
aioModal:{
|
||||
open: true,
|
||||
list,
|
||||
iouid: id
|
||||
}
|
||||
});
|
||||
}
|
||||
closeAIOModal = () => {
|
||||
this.setState({
|
||||
aioModal:{
|
||||
...defAIOModalState
|
||||
}
|
||||
});
|
||||
}
|
||||
submitAIO = (type, data) => {
|
||||
data.devuid = this.state.showDev;
|
||||
if(type == 1){
|
||||
this.props.editAIO(data);
|
||||
}else{
|
||||
this.props.addAIO(data);
|
||||
}
|
||||
// this.closeAIOModal();
|
||||
}
|
||||
delAIO = (id) => {
|
||||
if(!id) return ;
|
||||
this.props.delAIO({id, devuid: this.state.showDev});
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n, list} = this.props;
|
||||
|
||||
let dev = list.filter(t => {
|
||||
if(t.uid == this.state.showDev) return t;
|
||||
});
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Menu>
|
||||
<Menu.Menu position="right">
|
||||
<Menu.Item name="新增裝置" icon="plus" onClick={()=>{this.openModbusModal(0)}}/>
|
||||
</Menu.Menu>
|
||||
</Menu>
|
||||
<Grid>
|
||||
<Grid.Column width={4}>
|
||||
<DeviceList i18n={i18n}
|
||||
list={list}
|
||||
delModbus={this.delModbus}
|
||||
editModbus={this.openModbusModal}
|
||||
showDev={this.state.showDev}
|
||||
selectDevToShow={this.selectDevToShow}/>
|
||||
</Grid.Column>
|
||||
<Grid.Column width={12}>
|
||||
<IOPanel i18n={i18n}
|
||||
show={dev.length > 0}
|
||||
data={dev[0]}
|
||||
ioModal={this.openIOModal}
|
||||
delIOList={this.delIOList}
|
||||
getStatus={this.props.getMBIOStatus}
|
||||
showAIOSet={this.openAIOModal} />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
<ModbusModal i18n={i18n} open={this.state.mbModal} data={this.state.mbData} type={this.state.mbType} onSubmit={this.submitModbusModal} onClose={this.closeModbusModal} />
|
||||
<IOModal i18n={i18n}
|
||||
open={this.state.ioModal.open}
|
||||
type={this.state.ioModal.type}
|
||||
data={this.state.ioModal.data}
|
||||
onClose={this.closeIOModal}
|
||||
onSubmit={this.submitIOModal} />
|
||||
<AIOModal i18n={i18n}
|
||||
open={this.state.aioModal.open}
|
||||
iouid={this.state.aioModal.iouid}
|
||||
list={this.state.aioModal.list}
|
||||
onSubmit={this.submitAIO}
|
||||
delAIO={this.delAIO}
|
||||
onClose={this.closeAIOModal} />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ModbusPage;
|
120
src/components/AdminPage/Schedule/ListItem.js
Normal file
120
src/components/AdminPage/Schedule/ListItem.js
Normal file
@ -0,0 +1,120 @@
|
||||
import React from 'react';
|
||||
import {Table, Button, Item, Label} from 'semantic-ui-react';
|
||||
|
||||
const ListItem = ({i18n, idx, data, dos, les, ios, changeActive, openModal, delItem, showGroup}) => {
|
||||
let actlist = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.action_list') : [];
|
||||
let weekArr = i18n&&i18n.t ? [
|
||||
i18n.t('week.mon'),
|
||||
i18n.t('week.tue'),
|
||||
i18n.t('week.wed'),
|
||||
i18n.t('week.thu'),
|
||||
i18n.t('week.fri'),
|
||||
i18n.t('week.sat'),
|
||||
i18n.t('week.sun')
|
||||
] : [];
|
||||
|
||||
let timeStr = '';
|
||||
let min = data.ioscheduleparam1 || '';
|
||||
let hour = data.ioscheduleparam2 || '';
|
||||
let day = data.ioscheduleparam3 || '';
|
||||
let month = data.ioscheduleparam4 || '';
|
||||
let week = data.ioscheduleparam5 || '';
|
||||
if(week != '-'){
|
||||
let w = week.split(',');
|
||||
let ws = [];
|
||||
w.sort();
|
||||
for(let i in w){
|
||||
ws.push(weekArr[w[i] - 1] || '');
|
||||
}
|
||||
timeStr = `${ws.join(',')} ${hour}:${min}`;
|
||||
}else{
|
||||
timeStr = `${month}/${day} ${hour}:${min}`;
|
||||
}
|
||||
|
||||
let act = data.ioschedulecmd || '';
|
||||
act = act.split(',');
|
||||
let actcmd = '';
|
||||
let actname = '';
|
||||
if(act.length == 2){
|
||||
if(act[0] == 2){
|
||||
actcmd = '2'
|
||||
}else{
|
||||
actcmd = act.join(' ');
|
||||
}
|
||||
}
|
||||
if(actcmd.length > 0){
|
||||
for(let i in actlist){
|
||||
if(actlist[i].cmd == actcmd){
|
||||
actname = actlist[i].name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let devs = data.ioscheduleio || '';
|
||||
let dev = devs.split(',');
|
||||
let items = [];
|
||||
if(dev.length > 0){
|
||||
for(let i in dev){
|
||||
if(/^do/i.test(dev[i])){
|
||||
for(let j in dos){
|
||||
if(`do${dos[j].douid}` == dev[i]) {
|
||||
items.push({
|
||||
type: 'DigitOutput',
|
||||
name: dos[j].doname,
|
||||
id: dev[i]
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else if(/^le/i.test(dev[i])){
|
||||
for(let j in les){
|
||||
if(`le${les[j].leonelistuid}` == dev[i]) {
|
||||
items.push({
|
||||
type: 'LeOne',
|
||||
name: les[j].leonename,
|
||||
id: dev[i]
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else if(/^iogroup/i.test(dev[i])){
|
||||
for(let j in ios){
|
||||
if(`iogroup${ios[j].iogroupuid}` == dev[i]){
|
||||
items.push({
|
||||
type: 'IOGroup',
|
||||
name: ios[j].iogroupname,
|
||||
id: dev[i]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
<Button basic size="tiny" color={data.ioscheduleactive == 1 ? 'orange' : 'olive'}
|
||||
content={i18n&&i18n.t ? (data.ioscheduleactive == 1 ? i18n.t('page.schedule.table.button.disable') : i18n.t('page.schedule.table.button.enable')) : ''}
|
||||
onClick={()=>{ changeActive(data.ioscheduleuid || ''); }} />
|
||||
<Button basic size="tiny" color="red" content={i18n&&i18n.t ? i18n.t('page.schedule.table.button.del') : ''} onClick={() => {delItem(data.ioscheduleuid || '')}} />
|
||||
<Button basic size="tiny" color="blue" content={i18n&&i18n.t ? i18n.t('page.schedule.table.button.edit') : ''} onClick={() => {openModal(1, data, items);}} />
|
||||
</Table.Cell>
|
||||
<Table.Cell>{data.ioschedulename || ''}</Table.Cell>
|
||||
<Table.Cell>{timeStr}</Table.Cell>
|
||||
<Table.Cell>{actname}</Table.Cell>
|
||||
<Table.Cell>{i18n&&i18n.t ? (data.ioscheduleactive == 1 ? i18n.t('page.schedule.table.button.enable') : i18n.t('page.schedule.table.button.disable')) : ''}</Table.Cell>
|
||||
<Table.Cell>
|
||||
{
|
||||
items.length > 0 ?
|
||||
(items.length == 1 ?
|
||||
<Item><Label content={items[0].type} />{items[0].name}</Item>:
|
||||
<Button size="tiny" basic content={i18n&&i18n.t ? i18n.t('page.schedule.table.button.showgroup') : ''} onClick={()=>{showGroup(items)}}/> ) :
|
||||
''
|
||||
}
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default ListItem;
|
158
src/components/AdminPage/Schedule/ScheduleModal.js
Normal file
158
src/components/AdminPage/Schedule/ScheduleModal.js
Normal file
@ -0,0 +1,158 @@
|
||||
import React from 'react';
|
||||
import {Modal, Form, Checkbox, Input, Radio, Segment, Header, List, Grid, Button} from 'semantic-ui-react';
|
||||
import DateTime from 'react-datetime';
|
||||
import DeviceSelect from '../../Common/DeviceSelect';
|
||||
import SelectedItem from './SelectedItem';
|
||||
|
||||
class ScheduleModal extends React.Component {
|
||||
|
||||
render(){
|
||||
let {i18n, open, data, type, devs, permissions, querySelectList, onSubmit, onClose} = this.props;
|
||||
let {showTemp, week, cmd, temp, dateType, selected, addSelect, removeSelected, changeDateType, checkShowTemp, changeWeek} = this.props;
|
||||
let actlist = i18n&&i18n.getResource&&i18n.language ? i18n.getResource(i18n.language + '.translation.action_list') : [];
|
||||
|
||||
let act = data.ioschedulecmd || '';
|
||||
act = act.split(',');
|
||||
let defcmd = '';
|
||||
let deftemp = '';
|
||||
if(act.length == 2){
|
||||
if(act[0] == '2') {
|
||||
defcmd = act[0];
|
||||
deftemp = act[1];
|
||||
}else {
|
||||
defcmd = act.join(' ');
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal open={open}>
|
||||
<Modal.Header content={i18n&&i18n.t ? (type == 1 ? i18n.t('page.schedule.form.title.edut') : i18n.t('page.schedule.form.title.add')) : ''}/>
|
||||
<Modal.Content>
|
||||
<Form onSubmit={(e, d) => {
|
||||
e.preventDefault();
|
||||
onSubmit(type, d.formData);
|
||||
}} serializer={e => {
|
||||
let json = {
|
||||
active: false,
|
||||
name: '',
|
||||
cmd: '',
|
||||
temp: '',
|
||||
time: '',
|
||||
date: '',
|
||||
id: data.ioscheduleuid || ''
|
||||
};
|
||||
|
||||
let active = e.querySelector('input[name="active"]');
|
||||
if(active && 'checked' in active) json.active = active.checked;
|
||||
let name = e.querySelector('input[name="name"]');
|
||||
if(name && 'value' in name) json.name = name.value;
|
||||
let cmd = e.querySelector('select[name="act"]');
|
||||
if(cmd && 'value' in cmd) json.cmd = cmd.value;
|
||||
let time = e.querySelector('#timeDiv input');
|
||||
if(time && 'value' in time) json.time = time.value;
|
||||
let date = e.querySelector('#dateDiv input');
|
||||
if(date && 'value' in date) json.date = date.value;
|
||||
let temp = e.querySelector('input[name="temp"]');
|
||||
if(temp && 'value' in temp) json.temp = temp.value;
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Form.Field>
|
||||
{/*<label>{i18n&&i18n.t ? i18n.t('page.schedule.form.label.enable') : ''}</label>*/}
|
||||
<Checkbox defaultChecked={data.ioscheduleactive == 1 ? true : false} name="active" label={i18n&&i18n.t ? i18n.t('page.schedule.form.label.enable') : ''} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input label={i18n&&i18n.t ? i18n.t('page.schedule.form.label.name') : ''} name="name" defaultValue={data.ioschedulename} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>{i18n&&i18n.t?i18n.t('page.schedule.form.label.action') : ''}</label>
|
||||
<select name="act" value={cmd} onChange={(e) => { checkShowTemp(e.target.value); }}>
|
||||
<option value="">{i18n&&i18n.t ? i18n.t('select.select_action') : ''}</option>
|
||||
{
|
||||
actlist.map((t, idx) => {
|
||||
{/*let selected = defcmd == t.cmd ? 'selected' : 'false';*/}
|
||||
return (
|
||||
<option key={idx} value={t.cmd} >{t.name}</option>
|
||||
)
|
||||
})
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
{
|
||||
showTemp ?
|
||||
(<Form.Field>
|
||||
<Input label={i18n&&i18n.t ? i18n.t('page.schedule.form.label.temp') : ''} name="temp" defaultValue={temp} />
|
||||
</Form.Field>)
|
||||
: null
|
||||
}
|
||||
<Form.Field id="timeDiv">
|
||||
<label>{i18n&&i18n.t?i18n.t('page.schedule.form.label.time') : ''}</label>
|
||||
<DateTime dateFormat={false} timeFormat="HH:mm" defaultValue={data.ioscheduleparam1&&data.ioscheduleparam2 ? `${data.ioscheduleparam2}:${data.ioscheduleparam1}` : ''} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<label>{i18n&&i18n.t ? i18n.t('page.schedule.form.label.datetype') : ''}</label>
|
||||
<Radio label={i18n&&i18n.t ? i18n.t('page.schedule.form.label.type_week') : ''} name="dtRadio" value="w" checked={dateType == 'w'} onChange={(e, {value}) => {changeDateType(value)}} />
|
||||
<Radio label={i18n&&i18n.t ? i18n.t('page.schedule.form.label.type_date') : ''} name="dtRadio" value="d" checked={dateType == 'd'} onChange={(e, {value}) => {changeDateType(value)}} />
|
||||
</Form.Field>
|
||||
{
|
||||
dateType == 'w' ?
|
||||
(
|
||||
<Form.Group inline>
|
||||
<label>{i18n&&i18n.t ? i18n.t('page.schedule.form.label.week') : ''}</label>
|
||||
<Form.Field>
|
||||
<Checkbox label={i18n&&i18n.t ? i18n.t('week.mon') : ''} value="1" checked={week.find(t => t == 1) ? true : false} onChange={(e, {value, checked}) => {changeWeek(checked, value)}}/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Checkbox label={i18n&&i18n.t ? i18n.t('week.tue') : ''} value="2" checked={week.find(t => t == 2) ? true : false} onChange={(e, {value, checked}) => {changeWeek(checked, value)}}/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Checkbox label={i18n&&i18n.t ? i18n.t('week.wed') : ''} value="3" checked={week.find(t => t == 3) ? true : false} onChange={(e, {value, checked}) => {changeWeek(checked, value)}}/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Checkbox label={i18n&&i18n.t ? i18n.t('week.thu') : ''} value="4" checked={week.find(t => t == 4) ? true : false} onChange={(e, {value, checked}) => {changeWeek(checked, value)}}/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Checkbox label={i18n&&i18n.t ? i18n.t('week.fri') : ''} value="5" checked={week.find(t => t == 5) ? true : false} onChange={(e, {value, checked}) => {changeWeek(checked, value)}}/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Checkbox label={i18n&&i18n.t ? i18n.t('week.sat') : ''} value="6" checked={week.find(t => t == 6) ? true : false} onChange={(e, {value, checked}) => {changeWeek(checked, value)}}/>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Checkbox label={i18n&&i18n.t ? i18n.t('week.sun') : ''} value="7" checked={week.find(t => t == 7) ? true : false} onChange={(e, {value, checked}) => {changeWeek(checked, value)}}/>
|
||||
</Form.Field>
|
||||
</Form.Group>
|
||||
) :
|
||||
(
|
||||
<Form.Field id="dateDiv">
|
||||
<label>{i18n&&i18n.t?i18n.t('page.schedule.form.label.date'):''}</label>
|
||||
<DateTime timeFormat={false} dateFormat="MM-DD" defaultValue={`${data.ioscheduleparam4}-${data.ioscheduleparam3}`} />
|
||||
</Form.Field>
|
||||
)
|
||||
}
|
||||
<DeviceSelect i18n={i18n} devs={devs} addSelect={addSelect} showGroup={true} permissions={permissions} querySelectList={querySelectList} page="schedule" />
|
||||
<Segment>
|
||||
<Header as="h4" content={i18n&&i18n.t ? i18n.t('page.schedule.form.label.selected_device') : ''} />
|
||||
<List verticalAlign="middle" divided>
|
||||
{
|
||||
selected.map((t, idx) => (
|
||||
<SelectedItem key={idx} i18n={i18n} data={t} idx={idx} removeSelected={removeSelected} />
|
||||
))
|
||||
}
|
||||
</List>
|
||||
</Segment>
|
||||
<Grid columns={2}>
|
||||
<Grid.Column>
|
||||
<Button fluid type="submit" content={i18n&&i18n.t?i18n.t('page.leone.form.button.submit'):''}/>
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<Button fluid type="button" content={i18n&&i18n.t?i18n.t('page.leone.form.button.cancel'):''} onClick={() => {onClose()}}/>
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ScheduleModal;
|
17
src/components/AdminPage/Schedule/SelectedItem.js
Normal file
17
src/components/AdminPage/Schedule/SelectedItem.js
Normal file
@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
import {List, Button, Label} from 'semantic-ui-react';
|
||||
|
||||
const SelectedItem = ({i18n, idx, data, removeSelected}) => {
|
||||
|
||||
return(
|
||||
<List.Item>
|
||||
<List.Content floated="right">
|
||||
<Button type="button" size="mini" content={i18n&&i18n.t ? i18n.t('page.schedule.form.button.remove') : ''} onClick={() => {removeSelected(idx)}} />
|
||||
</List.Content>
|
||||
<Label content={data.type || ''} />
|
||||
{data.name || ''}
|
||||
</List.Item>
|
||||
)
|
||||
}
|
||||
|
||||
export default SelectedItem;
|
297
src/components/AdminPage/Schedule/index.js
Normal file
297
src/components/AdminPage/Schedule/index.js
Normal file
@ -0,0 +1,297 @@
|
||||
import React from 'react';
|
||||
import {Container, Segment, Table, Button, Modal, Item, Label} from 'semantic-ui-react';
|
||||
import ListItem from './ListItem';
|
||||
import ScheduleModal from './ScheduleModal';
|
||||
|
||||
class SchedulePage extends React.Component {
|
||||
|
||||
state ={
|
||||
modal: false,
|
||||
modalType: 0,
|
||||
modalData: {},
|
||||
modalWeek: [],
|
||||
modalShowTemp: false,
|
||||
modalDateType: 'w',
|
||||
modalSelected: [],
|
||||
modalCmd: '',
|
||||
modalTemp: '',
|
||||
itemModal: false,
|
||||
itemModalData: []
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.getScheduleList();
|
||||
this.props.router.setRouteLeaveHook(this.props.route, () => {
|
||||
this.props.clearList();
|
||||
})
|
||||
}
|
||||
|
||||
changeActive = (id) => {
|
||||
if(!id) return ;
|
||||
this.props.swSchedule({id});
|
||||
}
|
||||
|
||||
delItem = (id) => {
|
||||
if(!id) return ;
|
||||
this.props.delSchedule({id});
|
||||
}
|
||||
|
||||
openModal = (type, data = {}, items = []) => {
|
||||
let json = {
|
||||
modal: true,
|
||||
modalType: type,
|
||||
modalData: data,
|
||||
modalSelected: [...items]
|
||||
}
|
||||
if(type == 1){
|
||||
let dtype = '';
|
||||
if(data.ioscheduleparam5 && data.ioscheduleparam5 != '-'){
|
||||
let ws = data.ioscheduleparam5.split(',');
|
||||
let arr = [];
|
||||
dtype = 'w';
|
||||
for(let i in ws){
|
||||
if(isFinite(ws[i]) && ws[i] >= 1 && ws[i] <= 7){
|
||||
arr = [...arr, ws[i]];
|
||||
}
|
||||
}
|
||||
json = {
|
||||
...json,
|
||||
modalWeek: [...arr]
|
||||
};
|
||||
// this.setState({
|
||||
// week: [...arr]
|
||||
// });
|
||||
}else{
|
||||
dtype = 'd';
|
||||
}
|
||||
|
||||
let act = data.ioschedulecmd || '';
|
||||
act = act.split(',');
|
||||
if(act.length == 2){
|
||||
if(act[0] == '2') {
|
||||
json = {
|
||||
...json,
|
||||
modalShowTemp: true,
|
||||
modalCmd: act[0],
|
||||
modalTemp: act[1]
|
||||
}
|
||||
}else {
|
||||
json ={
|
||||
...json,
|
||||
modalShowTemp: false,
|
||||
modalCmd: act.join(' '),
|
||||
modalTemp: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json = {
|
||||
...json,
|
||||
modalDateType: dtype
|
||||
}
|
||||
// this.setState({
|
||||
// modalDateType: dtype
|
||||
// })
|
||||
}
|
||||
this.setState({
|
||||
...json
|
||||
});
|
||||
}
|
||||
|
||||
closeModal = () => {
|
||||
this.setState({
|
||||
modal: false,
|
||||
modalType: 0,
|
||||
modalData: {},
|
||||
modalWeek: [],
|
||||
modalShowTemp: false,
|
||||
modalDateType: 'w',
|
||||
modalSelected: [],
|
||||
modalCmd: '',
|
||||
modalTemp: ''
|
||||
})
|
||||
}
|
||||
|
||||
submitModal = (type, data) => {
|
||||
let {i18n, showDialog} = this.props;
|
||||
let json = {};
|
||||
if(type == 1 && !data.id) return showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
if(!data.name || !data.time || !data.cmd || (data.cmd == 2 && !data.temp) || (this.state.modalDateType == 'd' && !data.date))
|
||||
return showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
|
||||
if((this.state.modalDateType == 'w' && this.state.modalWeek.length == 0)) return showDialog(i18n&&i18n.t ? i18n.t('tip.select_week') : '');
|
||||
|
||||
json.name = data.name;
|
||||
json.active = data.active ? 1 : 0;
|
||||
|
||||
if(!/^\d{1,2}:\d{1,2}$/.test(data.time)) return showDialog(i18n&&i18n.t ? i18n.t('tip.input_format') : '');
|
||||
let tarr = data.time.split(':');
|
||||
if(tarr[0] < 0 || tarr[0] > 23 || tarr[1] < 0 || tarr[1] > 59) return showDialog(i18n&&i18n.t ? i18n.t('tip.time_range') : '');
|
||||
json.min = tarr[1];
|
||||
json.hour = tarr[0];
|
||||
|
||||
if(this.state.modalDateType == 'w'){
|
||||
json.week = this.state.modalWeek.join(',');
|
||||
}else{
|
||||
json.day = '';
|
||||
json.month = '';
|
||||
if(!/^\d{1,2}\-\d{1,2}$/.test(data.date)) return showDialog(i18n&&i18n.t ? i18n.t('tip.date_format') : '');
|
||||
let darr = data.date.split('-');
|
||||
if(darr[0] < 1 || darr[0] > 12 || darr[1] < 1 || darr[1] > 31) return showDialog(i18n&&i18n.t ? i18n.t('tip.date_range') : '');
|
||||
json.day = darr[1];
|
||||
json.month = darr[0];
|
||||
}
|
||||
|
||||
let tmp = this.state.modalSelected.map(t => t.id);
|
||||
json.devs = tmp.join(',');
|
||||
|
||||
if(data.cmd == 2){
|
||||
if(!data.temp) return showDialog(i18n&&i18n.t ? i18n.t('tip.input_empty_temp') : '');
|
||||
if(!(data.temp >= 16 && data.temp <= 30)) return showDialog(i18n&&i18n.t ? i18n.t('tip.temp_format') : '');
|
||||
json.action = `${data.cmd},${data.temp}`;
|
||||
}else{
|
||||
json.action = data.cmd.replace(' ', ',');
|
||||
}
|
||||
|
||||
json.id = data.id;
|
||||
|
||||
if(type == 0){
|
||||
this.props.addSchedule(json);
|
||||
}else{
|
||||
this.props.editSchedule(json);
|
||||
}
|
||||
|
||||
this.closeModal();
|
||||
}
|
||||
|
||||
showGroup = (items) => {
|
||||
this.setState({
|
||||
itemModal: true,
|
||||
itemModalData: [...items]
|
||||
});
|
||||
}
|
||||
closeGroupModal = () => {
|
||||
this.setState({
|
||||
itemModal: false,
|
||||
itemModalData: []
|
||||
});
|
||||
}
|
||||
|
||||
querySelectList = (type) => {
|
||||
this.props.getSelectList({type});
|
||||
}
|
||||
|
||||
// ================================
|
||||
|
||||
addSelect = (data) => {
|
||||
if(!data) return;
|
||||
this.setState({
|
||||
modalSelected: [...this.state.modalSelected, data]
|
||||
})
|
||||
}
|
||||
|
||||
removeSelected = (idx) => {
|
||||
let items = [...this.state.modalSelected];
|
||||
items.splice(idx, 1);
|
||||
this.setState({
|
||||
modalSelected: [...items]
|
||||
});
|
||||
}
|
||||
|
||||
checkShowTemp = (val) => {
|
||||
this.setState({
|
||||
modalShowTemp: val == 2 ? true : false,
|
||||
modalCmd: val
|
||||
});
|
||||
}
|
||||
|
||||
changeDateType = (type) => {
|
||||
if(!type) return;
|
||||
this.setState({
|
||||
modalDateType: type
|
||||
})
|
||||
}
|
||||
|
||||
changeWeek = (checked, value) => {
|
||||
let week = this.state.modalWeek;
|
||||
if(checked){
|
||||
if(week.indexOf(value) == -1){
|
||||
week.push(value);
|
||||
}
|
||||
}else{
|
||||
if(week.indexOf(value) != -1){
|
||||
week.splice(week.indexOf(value), 1);
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
modalWeek: [...week]
|
||||
});
|
||||
}
|
||||
|
||||
// ================================
|
||||
|
||||
render() {
|
||||
let {i18n, devs, list, dos, les, ios, permissions} = this.props;
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Segment className="clearfix">
|
||||
<Button type="button" floated="right" icon="plus" basic color="green" content={i18n&&i18n.t ? i18n.t('page.schedule.table.button.add') : ''} style={{marginBottom: '15px'}} onClick={() => {this.openModal(0)}}/>
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.schedule.table.operate') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.schedule.table.name') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.schedule.table.schedule_time') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.schedule.table.action') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.schedule.table.active_status') : ''}</Table.HeaderCell>
|
||||
<Table.HeaderCell>{i18n&&i18n.t ? i18n.t('page.schedule.table.device') : ''}</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{
|
||||
list.map((t,idx) => (<ListItem key={idx} i18n={i18n} data={t} idx={idx} dos={dos} ios={ios} les={les} openModal={this.openModal} changeActive={this.changeActive} delItem={this.delItem} showGroup={this.showGroup} />))
|
||||
}
|
||||
</Table.Body>
|
||||
</Table>
|
||||
</Segment>
|
||||
<ShowGroupItem i18n={i18n} open={this.state.itemModal} items={this.state.itemModalData} onClose={this.closeGroupModal} />
|
||||
<ScheduleModal i18n={i18n}
|
||||
open={this.state.modal}
|
||||
data={this.state.modalData}
|
||||
type={this.state.modalType}
|
||||
querySelectList={this.querySelectList}
|
||||
permissions={permissions}
|
||||
devs={devs}
|
||||
selected={this.state.modalSelected}
|
||||
week={this.state.modalWeek}
|
||||
showTemp={this.state.modalShowTemp}
|
||||
dateType={this.state.modalDateType}
|
||||
cmd={this.state.modalCmd}
|
||||
temp={this.state.modalTemp}
|
||||
addSelect={this.addSelect}
|
||||
checkShowTemp={this.checkShowTemp}
|
||||
removeSelected={this.removeSelected}
|
||||
changeDateType={this.changeDateType}
|
||||
changeWeek={this.changeWeek}
|
||||
onClose={this.closeModal}
|
||||
onSubmit={this.submitModal} />
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const ShowGroupItem = ({i18n,open,items, onClose}) => {
|
||||
|
||||
return (
|
||||
<Modal open={open} onClose={() => {onClose()}} size="small">
|
||||
<Modal.Content>
|
||||
{
|
||||
items.map((t, idx) => <Item key={idx}><Label content={t.type}/>{t.name}</Item>)
|
||||
}
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default SchedulePage;
|
159
src/components/AdminPage/SystemInfo/NetForm.js
Normal file
159
src/components/AdminPage/SystemInfo/NetForm.js
Normal file
@ -0,0 +1,159 @@
|
||||
import React from 'react';
|
||||
import {} from '../../../actions';
|
||||
import Datetime from 'react-datetime';
|
||||
import {Container, Segment, Form, Header, Menu, Grid, Table, Input, Button} from 'semantic-ui-react';
|
||||
|
||||
class NetForm extends React.Component {
|
||||
state = {
|
||||
input: this.props.network && 'NETWORKMODE' in this.props.network && this.props.network['NETWORKMODE'] == 1 ? false : true,
|
||||
ip: '',
|
||||
netmask: '',
|
||||
gateway: '',
|
||||
dns: ''
|
||||
}
|
||||
|
||||
changeActive = (active) => {
|
||||
this.setState({input: active});
|
||||
}
|
||||
|
||||
setInputState = (name, val) => {
|
||||
let json = {};
|
||||
json[name] = val;
|
||||
this.setState(json);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// if(this.props.network['IP'] != nextProps.network['IP']){
|
||||
// this.setState({ip: nextProps.network.ip});
|
||||
this.setInputState('ip', nextProps.network['IP']);
|
||||
// }
|
||||
// if(this.props.network['NETMASK'] != nextProps.network['NETMASK']){
|
||||
// this.setState({netmask: nextProps.network.netmask});
|
||||
this.setInputState('netmask', nextProps.network['NETMASK']);
|
||||
// }
|
||||
// if(this.props.network['GATEWAY'] != nextProps.network['GATEWAY']){
|
||||
// this.setState({gateway: nextProps.network['GATEWAY]});
|
||||
this.setInputState('gateway', nextProps.network['GATEWAY']);
|
||||
// }
|
||||
// if(this.props.network['DNS'] !== nextProps.network['DNS']){
|
||||
// this.setState({dns: nextProps.network['DNS]});
|
||||
this.setInputState('dns', nextProps.network['DNS']);
|
||||
// }
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n, network, onSubmit} = this.props;
|
||||
return (
|
||||
<div>
|
||||
<Menu widths={2}>
|
||||
<Menu.Item active={this.state.input} content={i18n && 't' in i18n ? i18n.t('page.system_info.form.button.dhcpip') : ''} onClick={()=>{this.changeActive(true)}}/>
|
||||
<Menu.Item active={!this.state.input} content={i18n && 't' in i18n ? i18n.t('page.system_info.form.button.manualip') : ''} onClick={()=>{this.changeActive(false)}}/>
|
||||
</Menu>
|
||||
<Form onSubmit={(e,data) => {
|
||||
e.preventDefault();
|
||||
onSubmit(data.formData);
|
||||
}} serializer={e => {
|
||||
let json = {
|
||||
ip: e.querySelector('input[name="ip"]').value,
|
||||
netmask: e.querySelector('input[name="netmask"]').value,
|
||||
gateway: e.querySelector('input[name="gateway"]').value,
|
||||
dns: e.querySelector('input[name="dns"]').value,
|
||||
dhcpMode: this.state.input
|
||||
}
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Table>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell width={8} content={i18n && 't' in i18n ? i18n.t('page.system_info.form.label.ip') : ''} textAlign="center"/>
|
||||
<Table.Cell width={8} textAlign="center" >
|
||||
<Input fluid name="ip" value={this.state.ip} disabled={this.state.input} onChange={e=>{this.setInputState('ip', e.target.value)}}/>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell width={8} content={i18n && 't' in i18n ? i18n.t('page.system_info.form.label.netmask') : ''} textAlign="center"/>
|
||||
<Table.Cell width={8} textAlign="center" >
|
||||
<Input fluid name="netmask" value={this.state.netmask} disabled={this.state.input} onChange={e=>{this.setInputState('netmask', e.target.value)}}/>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell width={8} content={i18n && 't' in i18n ? i18n.t('page.system_info.form.label.gateway') : ''} textAlign="center"/>
|
||||
<Table.Cell width={8} textAlign="center" >
|
||||
<Input fluid name="gateway" value={this.state.gateway} disabled={this.state.input} onChange={e=>{this.setInputState('gateway', e.target.value)}}/>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell width={8} content={i18n && 't' in i18n ? i18n.t('page.system_info.form.label.dns') : ''} textAlign="center"/>
|
||||
<Table.Cell width={8} textAlign="center" >
|
||||
<Input fluid name="dns" value={this.state.dns} disabled={this.state.input} onChange={e=>{this.setInputState('dns', e.target.value)}}/>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
<Table.Footer>
|
||||
<Table.Row>
|
||||
<Table.Cell colSpan="2">
|
||||
<Button type="submit" fluid content={i18n && 't' in i18n ? i18n.t('page.system_info.form.button.update_network') :''}/>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Footer>
|
||||
</Table>
|
||||
</Form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/*const NetForm = ({i18n, onSubmit, network}) => (
|
||||
<Form onSubmit={(e,data) => {
|
||||
e.preventDefault();
|
||||
onSubmit(data.formData);
|
||||
}} serializer={e => {
|
||||
let json = {
|
||||
ip: e.querySelector('input[name="ip"]').value,
|
||||
netmask: e.querySelector('input[name="netmask"]').value,
|
||||
gateway: e.querySelector('input[name="gateway"]').value,
|
||||
dns: e.querySelector('input[name="dns"]').value
|
||||
}
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Table>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell width={8} content={i18n && 't' in i18n ? i18n.t('page.system_info.form.label.ip') : ''} textAlign="center"/>
|
||||
<Table.Cell width={8} textAlign="center" >
|
||||
<Input fluid name="ip" value={network['IP'] || ''} />
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell width={8} content={i18n && 't' in i18n ? i18n.t('page.system_info.form.label.netmask') : ''} textAlign="center"/>
|
||||
<Table.Cell width={8} textAlign="center" >
|
||||
<Input fluid name="netmask" value={network['NETMASK'] || ''} />
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell width={8} content={i18n && 't' in i18n ? i18n.t('page.system_info.form.label.gateway') : ''} textAlign="center"/>
|
||||
<Table.Cell width={8} textAlign="center" >
|
||||
<Input fluid name="gateway" value={network['GATEWAY'] || ''} />
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell width={8} content={i18n && 't' in i18n ? i18n.t('page.system_info.form.label.dns') : ''} textAlign="center"/>
|
||||
<Table.Cell width={8} textAlign="center" >
|
||||
<Input fluid name="dns" value={network['DNS'] || ''} />
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
<Table.Footer>
|
||||
<Table.Row>
|
||||
<Table.Cell colSpan="2">
|
||||
<Button type="submit" fluid content={i18n && 't' in i18n ? i18n.t('page.system_info.form.button.update_network') :''}/>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Footer>
|
||||
</Table>
|
||||
</Form>
|
||||
)*/
|
||||
|
||||
export default NetForm;
|
40
src/components/AdminPage/SystemInfo/TimeForm.js
Normal file
40
src/components/AdminPage/SystemInfo/TimeForm.js
Normal file
@ -0,0 +1,40 @@
|
||||
import React from 'react';
|
||||
import {} from '../../../actions';
|
||||
import Datetime from 'react-datetime';
|
||||
import {Container, Segment, Form, Header, Menu, Grid, Table, Input, Button} from 'semantic-ui-react';
|
||||
import {convertTime} from '../../../tools';
|
||||
|
||||
const TimeForm = ({i18n, time, onSubmit}) => {
|
||||
return (
|
||||
<Form onSubmit={(e,data) => {
|
||||
e.preventDefault();
|
||||
onSubmit(data.formData);
|
||||
}} serializer={e => {
|
||||
let json = {};
|
||||
|
||||
json.time = e.querySelector('input').value || '';
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Table>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell width={8} content={i18n && 't' in i18n ? i18n.t('page.system_info.form.label.sysdate') : ''} textAlign="center"/>
|
||||
<Table.Cell width={8} textAlign="center" >
|
||||
<Datetime dateFormat="YYYY-MM-DD" timeFormat="HH:mm" value={convertTime(time)} input={true} />
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
<Table.Footer>
|
||||
<Table.Row>
|
||||
<Table.Cell colSpan="2">
|
||||
<Button type="submit" fluid content={i18n && 't' in i18n ? i18n.t('page.system_info.form.button.update_time') :''} />
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Footer>
|
||||
</Table>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
|
||||
export default TimeForm;
|
57
src/components/AdminPage/SystemInfo/index.js
Normal file
57
src/components/AdminPage/SystemInfo/index.js
Normal file
@ -0,0 +1,57 @@
|
||||
import React from 'react';
|
||||
import {toggle_loading, get_network_info, get_system_time, add_dialog_msg,set_network_info, set_system_time} from '../../../actions';
|
||||
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 {convertTime,padding} from '../../../tools';
|
||||
|
||||
class SysInfo extends React.Component {
|
||||
|
||||
componentDidMount(){
|
||||
let {dispatch} = this.props;
|
||||
// get network
|
||||
dispatch(get_network_info());
|
||||
//get time
|
||||
dispatch(get_system_time());
|
||||
}
|
||||
|
||||
netSubmit = (data) => {
|
||||
let {dispatch, i18n} = this.props;
|
||||
if(!data.dhcpMode){
|
||||
if(!data.ip || !data.netmask || !data.gateway || !data.dns) return dispatch(add_dialog_msg(i18n && 't' in i18n ? i18n.t('tip.input_empty') : ''));
|
||||
}
|
||||
|
||||
dispatch(set_network_info(data.dhcpMode, data.ip, data.netmask, data.gateway, data.dns));
|
||||
}
|
||||
|
||||
timeSubmit = (data) => {
|
||||
let {dispatch, i18n} = this.props;
|
||||
let regex_date = /^([0-9]{4})\-([0-9]{2})\-([0-9]{2})\s([0-9]{1,2}):([0-9]{1,2})$/;
|
||||
if(!('time' in data) || !data.time.trim() || !regex_date.test(data.time.trim())) return dispatch(add_dialog_msg(i18n && 't' in i18n ? i18n.t('tip.datetime_format') : ''));
|
||||
let m = data.time.trim().match(regex_date);
|
||||
if(!m) return dispatch(add_dialog_msg(i18n && 't' in i18n ? i18n.t('tip.datetime_format') : ''));
|
||||
// MMDDHHmmYYYY
|
||||
let dstr = `${m[2]}${m[3]}${padding(m[4], 2)}${padding(m[5], 2)}${m[1]}`;
|
||||
|
||||
dispatch(set_system_time(dstr));
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n, network, time} = this.props;
|
||||
return (
|
||||
<Container>
|
||||
<Segment>
|
||||
<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 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}/>
|
||||
</Segment>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default SysInfo;
|
26
src/components/AdminPage/UserList/ListItem.js
Normal file
26
src/components/AdminPage/UserList/ListItem.js
Normal file
@ -0,0 +1,26 @@
|
||||
import React from 'react';
|
||||
import {Table, Button} from 'semantic-ui-react';
|
||||
|
||||
const ListItem = ({i18n, user, openModal, delUser}) => {
|
||||
let write = sessionStorage.getItem('write_privilege');
|
||||
let account = sessionStorage.getItem('account');
|
||||
|
||||
return (
|
||||
<Table.Row>
|
||||
<Table.Cell>{user.account}</Table.Cell>
|
||||
<Table.Cell>
|
||||
{user.write_privilege == 1 ? 'W' : ''}{user.write_privilege == 1 && user.read_privilege == 1 ? ' / ' : ''}{user.read_privilege == 1 ? 'R' : ''}
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
{
|
||||
(write == 1 && (user.account != 'admin' || (account == 'admin') ) ) || account == user.account ?
|
||||
<Button type="button" content={i18n && i18n.t ? i18n.t('page.userlist.table.button.edit') : ''} onClick={() => openModal(user.account)}/> :
|
||||
null
|
||||
}
|
||||
{write == 1 && user.account != 'admin' ? <Button type="button" content={i18n && i18n.t ? i18n.t('page.userlist.table.button.del') : ''} onClick={()=>delUser(user.account)}/> : null }
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default ListItem;
|
50
src/components/AdminPage/UserList/UserModal.js
Normal file
50
src/components/AdminPage/UserList/UserModal.js
Normal file
@ -0,0 +1,50 @@
|
||||
import React from 'react';
|
||||
import {Modal, Form, Input, Grid, Button, Checkbox} from 'semantic-ui-react';
|
||||
|
||||
|
||||
const UModal = ({i18n, open, type, data, closeModal, onSubmit}) => {
|
||||
return (
|
||||
<Modal closeOnDimmerClick={false} open={open}>
|
||||
<Modal.Content>
|
||||
<Form onSubmit={(e, data) => {
|
||||
e.preventDefault();
|
||||
onSubmit(data.formData);
|
||||
}}
|
||||
serializer={e=>{
|
||||
let json = {
|
||||
type,
|
||||
account: e.querySelector('input[name="account"]').value,
|
||||
password: e.querySelector('input[name="password"]').value,
|
||||
read_privilege: e.querySelector('input[name="read_privilege"]').checked ? 1 : 0,
|
||||
write_privilege: e.querySelector('input[name="write_privilege"]').checked ? 1 : 0
|
||||
};
|
||||
|
||||
return json;
|
||||
}}>
|
||||
<Form.Field>
|
||||
<Input label={i18n && i18n.t ? i18n.t('page.userlist.form.label.account') : ''} name="account" disabled={type == 1} defaultValue={type == 1 ? data.account : ''} />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Input type="password" label={i18n && i18n.t ? i18n.t('page.userlist.form.label.password') : ''} name="password" />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Checkbox label={i18n && i18n.t ? i18n.t('page.userlist.form.label.read_privilege') : ''} defaultChecked={data.read_privilege == 1} name="read_privilege" />
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Checkbox label={i18n && i18n.t ? i18n.t('page.userlist.form.label.write_privilege') : ''} defaultChecked={data.write_privilege == 1} name="write_privilege" />
|
||||
</Form.Field>
|
||||
<Grid>
|
||||
<Grid.Column width={8}>
|
||||
<Button type="submit" fluid content={i18n && i18n.t ? i18n.t('page.userlist.form.button.submit') : ''} />
|
||||
</Grid.Column>
|
||||
<Grid.Column width={8}>
|
||||
<Button type="button" fluid content={i18n && i18n.t ? i18n.t('page.userlist.form.button.cancel') : ''} onClick={() => closeModal()} />
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</Form>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default UModal;
|
89
src/components/AdminPage/UserList/index.js
Normal file
89
src/components/AdminPage/UserList/index.js
Normal file
@ -0,0 +1,89 @@
|
||||
import React from 'react';
|
||||
import {Container, Segment, Header, Table, Button, Modal} from 'semantic-ui-react';
|
||||
import ListItem from './ListItem';
|
||||
import {get_user_list, add_dialog_msg, edit_user, add_user, del_user} from '../../../actions';
|
||||
import UModal from './UserModal';
|
||||
|
||||
class UList extends React.Component {
|
||||
|
||||
state ={
|
||||
edit: false,
|
||||
// 0 is add , 1 is edit
|
||||
editType: 0,
|
||||
editData: {}
|
||||
}
|
||||
|
||||
openModal = (acc) => {
|
||||
if(!acc) return this.setState({edit: true, editType: 0});
|
||||
let {users} = this.props;
|
||||
let user = users.filter(t => t.account == acc);
|
||||
this.setState({
|
||||
edit: true,
|
||||
editType: 1,
|
||||
editData: user[0] || {}
|
||||
});
|
||||
}
|
||||
|
||||
closeModal = () => {
|
||||
this.setState({edit: false, editData: {}});
|
||||
}
|
||||
|
||||
onModalSubmit = (data) => {
|
||||
let {i18n} = this.props;
|
||||
if(data.type == 0 && (!data.account || !data.password)) return this.props.showDialog(i18n && i18n.t ? i18n.t('tip.input_empty') : '');
|
||||
this.setState({edit: false, editData: {}});
|
||||
if(data.type == 1){
|
||||
this.props.editUser(data);
|
||||
}else{
|
||||
this.props.addUser(data);
|
||||
}
|
||||
}
|
||||
|
||||
delUser = (acc) => {
|
||||
if(!acc) return ;
|
||||
this.props.delUser({account: acc});
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
this.props.getList();
|
||||
|
||||
this.props.router.setRouteLeaveHook(this.props.route, () => {
|
||||
this.props.clearList();
|
||||
})
|
||||
}
|
||||
|
||||
render () {
|
||||
let {i18n, users} = this.props;
|
||||
return (
|
||||
<Container>
|
||||
<Segment>
|
||||
<Header as="h2" content={i18n && 't' in i18n ? i18n.t('page.userlist.title.userlist') : ''} />
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell width={6} content={i18n && i18n.t ? i18n.t('page.userlist.table.account') : ''} />
|
||||
<Table.HeaderCell width={6} content={i18n && i18n.t ? i18n.t('page.userlist.table.privilege') : ''} />
|
||||
<Table.HeaderCell width={4} content={i18n && i18n.t ? i18n.t('page.userlist.table.operate') : ''} />
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
{
|
||||
users.map(t => <ListItem key={t.account} i18n={i18n} user={t} openModal={this.openModal} delUser={this.delUser}/>)
|
||||
}
|
||||
</Table.Body>
|
||||
<Table.Footer>
|
||||
<Table.Row>
|
||||
<Table.Cell colSpan="3">
|
||||
<Button type="button" fluid content={i18n && i18n.t ? i18n.t('page.userlist.table.button.add') : ''} onClick={()=>this.openModal()}/>
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Footer>
|
||||
</Table>
|
||||
</Segment>
|
||||
<UModal i18n={i18n} open={this.state.edit} type={this.state.editType} data={this.state.editData} closeModal={this.closeModal} onSubmit={this.onModalSubmit}/>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default UList;
|
64
src/components/Common/DeviceSelect.js
Normal file
64
src/components/Common/DeviceSelect.js
Normal file
@ -0,0 +1,64 @@
|
||||
import React from 'react';
|
||||
import {Form, Button} from 'semantic-ui-react';
|
||||
|
||||
const DeviceSelect = ({i18n, querySelectList, page, permissions, devs, addSelect, showGroup}) => {
|
||||
let devName = null;
|
||||
let devType = null;
|
||||
return (
|
||||
<Form.Group inline>
|
||||
<Form.Field>
|
||||
<label>{i18n&&i18n.t?i18n.t(`page.${page || ''}.form.label.select_device`) : ''}</label>
|
||||
<select ref={node => devType = node} onChange={(e) => {
|
||||
querySelectList(e.target.value);
|
||||
}}>
|
||||
<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
|
||||
}
|
||||
{
|
||||
permissions.leone ?
|
||||
<option value="leone">{i18n&&i18n.t ? i18n.t('select.leone') : ''}</option> : null
|
||||
}
|
||||
{
|
||||
permissions.iogroup && showGroup ?
|
||||
<option value="iogroup">{i18n&&i18n.t ? i18n.t('select.iogroup') : ''}</option> : null
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<select ref={node => devName = node}>
|
||||
{
|
||||
devs.map((t, idx) => <option key={idx} value={t.id || ''}>{t.name || ''}</option>)
|
||||
}
|
||||
</select>
|
||||
</Form.Field>
|
||||
<Form.Field>
|
||||
<Button type="button" basic size="mini" content={i18n&&i18n.t?i18n.t(`page.${page || ''}.form.button.join`) : ''} onClick={()=>{
|
||||
let type = '';
|
||||
let devname = '';
|
||||
let devid = '';
|
||||
let typev = '';
|
||||
if(devType != null) {
|
||||
type = devType.options[devType.selectedIndex].innerHTML;
|
||||
typev = devType.value == 'leone' ? 'le' : devType.value;
|
||||
}
|
||||
if(devName != null) {
|
||||
if(devName.options.length == 0) return ;
|
||||
devname = devName.options[devName.selectedIndex].innerHTML;
|
||||
devid = `${typev}${devName.value}`;
|
||||
}
|
||||
let json = {
|
||||
type,
|
||||
name: devname,
|
||||
id: devid
|
||||
};
|
||||
if(!devType.value || !type || !devname) return ;
|
||||
addSelect(json);
|
||||
}} />
|
||||
</Form.Field>
|
||||
</Form.Group>
|
||||
)
|
||||
}
|
||||
|
||||
export default DeviceSelect;
|
14
src/components/Dialog.js
Normal file
14
src/components/Dialog.js
Normal file
@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import {Modal, Button} from 'semantic-ui-react';
|
||||
|
||||
const Dialog = ({obj, getNext}) => (
|
||||
<Modal open={obj && obj.msg != '' ? true : false} onClose={() => getNext(obj.act)} style={{zIndex: "2001"}}>
|
||||
<Modal.Content>{obj && obj.msg ? obj.msg : ''}</Modal.Content>
|
||||
<Modal.Actions>
|
||||
<Button onClick={() => getNext(obj.act)} content="OK" />
|
||||
</Modal.Actions>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
|
||||
export default Dialog;
|
10
src/components/Loading.js
Normal file
10
src/components/Loading.js
Normal file
@ -0,0 +1,10 @@
|
||||
import React from 'react';
|
||||
import {Loader, Dimmer} from 'semantic-ui-react';
|
||||
|
||||
const Loading = ({active}) => (
|
||||
<Dimmer active={active} style={{zIndex: '2000'}}>
|
||||
<Loader size="large" />
|
||||
</Dimmer>
|
||||
)
|
||||
|
||||
export default Loading;
|
29
src/components/Login/Form.js
Normal file
29
src/components/Login/Form.js
Normal file
@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
import {Form, Segment, Input, Button} from 'semantic-ui-react';
|
||||
|
||||
const loginForm = ({i18n, page, onSubmit}) => {
|
||||
let account;
|
||||
let password;
|
||||
return (
|
||||
<Form size="large" onSubmit={(e, data) => {
|
||||
e.preventDefault();
|
||||
onSubmit(data.formData);
|
||||
}} serializer={e => {
|
||||
let acc = e.querySelector('input[name="acc"]').value;
|
||||
let pass = e.querySelector('input[name="pass"]').value;
|
||||
return {account: acc, password: pass};
|
||||
}}>
|
||||
<Segment stacked={true} >
|
||||
<Form.Field>
|
||||
<Input icon="user" iconPosition="left" 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`) : ''} />
|
||||
</Form.Field>
|
||||
<Button type="submit" color="teal" size="large" fluid={true} content={typeof i18n.t == 'function' ? i18n.t(`${page}.button.login`) : ''} />
|
||||
</Segment>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
||||
export default loginForm;
|
99
src/components/Login/index.js
Normal file
99
src/components/Login/index.js
Normal file
@ -0,0 +1,99 @@
|
||||
import React from 'react';
|
||||
import i18next from 'i18next';
|
||||
import {Grid, Header} from 'semantic-ui-react';
|
||||
import LoginForm from './Form.js';
|
||||
import Dialog from '../../containers/DialogControl';
|
||||
import {add_dialog_msg, toggle_loading} from '../../actions';
|
||||
import {connect} from 'react-redux';
|
||||
import Loading from '../../containers/LoadingControl';
|
||||
|
||||
class Root extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
i18n: {}
|
||||
};
|
||||
}
|
||||
|
||||
handleSubmit = (data) => {
|
||||
let {i18n} = this.state;
|
||||
if (typeof data.account != 'string' || !data.account.trim() || typeof data.password != 'string' || !data.password.trim()) {
|
||||
// show dialog
|
||||
this.props.dispatch(add_dialog_msg(i18n && 't' in i18n ? i18n.t('tip.input_empty') : ''));
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.dispatch(toggle_loading(1));
|
||||
fetch('/api/system/login', {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({data})
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(json => {
|
||||
this.props.dispatch(toggle_loading(0));
|
||||
if(json.status != 1) {
|
||||
this.props.dispatch(add_dialog_msg(json.message));
|
||||
return ;
|
||||
}
|
||||
|
||||
sessionStorage.setItem('write_privilege', json.data.record[0].write_privilege);
|
||||
sessionStorage.setItem('read_privilege', json.data.record[0].read_privilege);
|
||||
sessionStorage.setItem('account', json.data.record[0].account);
|
||||
|
||||
sessionStorage.setItem('token', json.data.token);
|
||||
if(json.data.rt.permission && json.data.rt.permission.length > 0) {
|
||||
sessionStorage.setItem('permissions', JSON.stringify(json.data.rt.permission[0]));
|
||||
}
|
||||
|
||||
// this.props.dispatch(add_dialog_msg('登入成功', () => {
|
||||
location.replace('/admin');
|
||||
// }))
|
||||
})
|
||||
.catch(err => this.props.dispatch(add_dialog_msg('登入失敗')));
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
}, () => {
|
||||
this.setState({i18n: i18next});
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const {i18n} = this.state;
|
||||
const page = 'page.login';
|
||||
return (
|
||||
<div style={{
|
||||
height: '100%'
|
||||
}}>
|
||||
<Loading />
|
||||
<Dialog/>
|
||||
<Grid verticalAlign="middle" centered className="login-grid">
|
||||
<Grid.Column className="login-column">
|
||||
<Header textAlign="center" content={'JCNet WebIO'} as="h2" color="teal"/>
|
||||
<LoginForm i18n={this.state.i18n} page={page} onSubmit={this.handleSubmit}/>
|
||||
</Grid.Column>
|
||||
</Grid>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default connect()(Root)
|
14
src/components/MainMenu/Item.js
Normal file
14
src/components/MainMenu/Item.js
Normal file
@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import {Sidebar, Menu, Segment, Icon} from 'semantic-ui-react';
|
||||
import {Link} from 'react-router';
|
||||
|
||||
const MItem = ({toLink, txt, onClick, permission}) => {
|
||||
if(permission == 1) {
|
||||
return (
|
||||
<Menu.Item as={Link} to={toLink} content={txt} onClick={onClick} />
|
||||
)
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export default MItem;
|
40
src/components/MainMenu/index.js
Normal file
40
src/components/MainMenu/index.js
Normal file
@ -0,0 +1,40 @@
|
||||
import React from 'react';
|
||||
import {Sidebar, Menu, Segment, Icon, Container} from 'semantic-ui-react';
|
||||
import {Link} from 'react-router';
|
||||
import MItem from './Item';
|
||||
|
||||
const MainMenu = ({i18n, show, toggleMenu, children, permissions}) => (
|
||||
<div style={{height: '100%'}}>
|
||||
<Sidebar.Pushable as={Segment} style={{zIndex: 100}}>
|
||||
<Sidebar as={Menu} animation="push" width="thin" visible={show} icon="labeled" vertical inverted>
|
||||
<MItem toLink="/admin" txt={i18n && 't' in i18n ? i18n.t('menu.item.systeminfo') : ''} permission={true} onClick={() => toggleMenu()} />
|
||||
<MItem toLink="/admin/user" txt={i18n && 't' in i18n ? i18n.t('menu.item.userlist') : ''} permission={true} onClick={() => toggleMenu()} />
|
||||
<MItem toLink="/admin/dio" txt={i18n && 't' in i18n ? i18n.t('menu.item.dio') : ''} permission={permissions.dio} onClick={() => toggleMenu()} />
|
||||
<MItem toLink="/admin/log" txt={i18n && 't' in i18n ? i18n.t('menu.item.log') : ''} permission={permissions.log} onClick={()=>toggleMenu()} />
|
||||
<MItem toLink="/admin/leone" txt={i18n && 't'in i18n ? i18n.t('menu.item.leone') : ''} permission={permissions.leone} onClick={()=>toggleMenu()} />
|
||||
<MItem toLink="/admin/iogroup" txt={i18n && 't' in i18n ? i18n.t('menu.item.iogroup') : ''} permission={permissions.iogroup} onClick={()=>toggleMenu()} />
|
||||
<MItem toLink="/admin/iocmd" txt={i18n && 't' in i18n ? i18n.t('menu.item.iocmd') : ''} permission={permissions.iocmd} onClick={()=>toggleMenu()} />
|
||||
<MItem toLink="/admin/schedule" txt={i18n && 't' in i18n ? i18n.t('menu.item.schedule') : ''} permission={permissions.schedule} onClick={()=>toggleMenu()} />
|
||||
<MItem toLink="/admin/modbus" txt={i18n && 't' in i18n ? i18n.t('menu.item.modbus') : ''} 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" txt={i18n && 't' in i18n ? i18n.t('menu.item.logout') : ''} permission={true} onClick={()=>{
|
||||
sessionStorage.clear();
|
||||
location.replace('/');
|
||||
}} />
|
||||
</Sidebar>
|
||||
<Sidebar.Pusher style={{backgroundColor: '#eee'}}>
|
||||
<Menu fixed="top" >
|
||||
<Menu.Item onClick={() => toggleMenu(show ? false : true)} >
|
||||
<Icon name="sidebar" />
|
||||
{i18n && 't' in i18n ? i18n.t('menu.title') : ''}
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
<Container style={{paddingTop: '45px', paddingBottom: '40px'}}>
|
||||
{children}
|
||||
</Container>
|
||||
</Sidebar.Pusher>
|
||||
</Sidebar.Pushable>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default MainMenu;
|
34
src/containers/AdminPage/ActionLink.js
Normal file
34
src/containers/AdminPage/ActionLink.js
Normal file
@ -0,0 +1,34 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {add_dialog_msg, toggle_loading, get_link_list, clear_link, add_link, del_link, sw_link_active} from '../../actions';
|
||||
import ActionLinkPage from '../../components/AdminPage/ActionLink';
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n,
|
||||
list: state.lists.link.list || []
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
toggleLoading: (active = false) => {
|
||||
dispatch(toggle_loading(active));
|
||||
},
|
||||
getList: () => {
|
||||
dispatch(get_link_list());
|
||||
},
|
||||
clearList: () => {
|
||||
dispatch(clear_link());
|
||||
},
|
||||
delLink: (data) => {
|
||||
dispatch(del_link(data));
|
||||
},
|
||||
addLink: (data) => {
|
||||
dispatch(add_link(data));
|
||||
},
|
||||
swLink: (data) => {
|
||||
dispatch(sw_link_active(data));
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ActionLinkPage);
|
18
src/containers/AdminPage/ActionLinkAdd.js
Normal file
18
src/containers/AdminPage/ActionLinkAdd.js
Normal file
@ -0,0 +1,18 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {add_dialog_msg, toggle_loading} from '../../actions';
|
||||
import ActionLinkAdd from '../../components/AdminPage/ActionLinkAdd';
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
toggleLoading: (active = false) => {
|
||||
dispatch(toggle_loading(active));
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ActionLinkAdd);
|
31
src/containers/AdminPage/DIO.js
Normal file
31
src/containers/AdminPage/DIO.js
Normal file
@ -0,0 +1,31 @@
|
||||
import {connect} from 'react-redux';
|
||||
import DIO from '../../components/AdminPage/DIO';
|
||||
import {get_dio_info, get_dio_status, set_do_status, set_dio_info, clear_dio} from '../../actions';
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
dio: state.lists.dio,
|
||||
i18n: state.i18n
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
clearList: () => {
|
||||
dispatch(clear_dio());
|
||||
},
|
||||
getDIOInfo: () => {
|
||||
dispatch(get_dio_info());
|
||||
},
|
||||
getIO: () => {
|
||||
dispatch(get_dio_status());
|
||||
},
|
||||
dotRun: (pin, value) => {
|
||||
dispatch(set_do_status({
|
||||
pin,
|
||||
value
|
||||
}));
|
||||
},
|
||||
setDIOInfo: (data) => {
|
||||
dispatch(set_dio_info(data));
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(DIO);
|
36
src/containers/AdminPage/IOCmd.js
Normal file
36
src/containers/AdminPage/IOCmd.js
Normal file
@ -0,0 +1,36 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {add_dialog_msg, get_select_list, clear_select_list, io_cmd} from '../../actions';
|
||||
import IOCmdPage from '../../components/AdminPage/IOCmd'
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n,
|
||||
permissions: (function() {
|
||||
let p = sessionStorage.getItem('permissions');
|
||||
if (!p) return {};
|
||||
let json = {};
|
||||
try {
|
||||
json = JSON.parse(p);
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
return json
|
||||
}()),
|
||||
devs: state.lists.selectdev
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
getSelectList: (data) => {
|
||||
dispatch(get_select_list(data));
|
||||
},
|
||||
clearSelectList: () => {
|
||||
dispatch(clear_select_list());
|
||||
},
|
||||
runCmd: (data) => {
|
||||
dispatch(io_cmd(data))
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(IOCmdPage);
|
51
src/containers/AdminPage/IOGroup.js
Normal file
51
src/containers/AdminPage/IOGroup.js
Normal file
@ -0,0 +1,51 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {add_dialog_msg, get_iogroup_list, del_iogroup, edit_iogroup, add_iogroup, get_select_list,clear_iogroup, clear_select_list} from '../../actions';
|
||||
import IOGroupPage from '../../components/AdminPage/IOGroup';
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n,
|
||||
list: state.lists.iogroup.list,
|
||||
dos: state.lists.iogroup.do,
|
||||
leones: state.lists.iogroup.leone,
|
||||
permissions: (function() {
|
||||
let p = sessionStorage.getItem('permissions');
|
||||
if (!p) return {};
|
||||
let json = {};
|
||||
try {
|
||||
json = JSON.parse(p);
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
return json
|
||||
}()),
|
||||
devs: state.lists.selectdev
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
clearList: () => {
|
||||
dispatch(clear_iogroup());
|
||||
},
|
||||
getIOGroupList: () => {
|
||||
dispatch(get_iogroup_list());
|
||||
},
|
||||
addIOGroup: (data) => {
|
||||
dispatch(add_iogroup(data));
|
||||
},
|
||||
editIOGroup: (data) => {
|
||||
dispatch(edit_iogroup(data));
|
||||
},
|
||||
delIOGroup: (data) => {
|
||||
dispatch(del_iogroup(data));
|
||||
},
|
||||
getSelectList: (data) => {
|
||||
dispatch(get_select_list(data));
|
||||
},
|
||||
clearSelectList: () => {
|
||||
dispatch(clear_select_list());
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(IOGroupPage);
|
46
src/containers/AdminPage/LeOne.js
Normal file
46
src/containers/AdminPage/LeOne.js
Normal file
@ -0,0 +1,46 @@
|
||||
import {connect} from 'react-redux';
|
||||
import LeOnePage from '../../components/AdminPage/LeOne';
|
||||
import {add_dialog_msg, scan_leone, clear_scan_leone, get_leone_list,add_scan_leone,del_leone, add_leone, edit_leone, io_cmd, clear_leone} from '../../actions';
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n,
|
||||
scanList: state.lists.leone.scanList,
|
||||
list: state.lists.leone.list,
|
||||
status: state.lists.leone.status,
|
||||
scanning: state.lists.leone.scanning
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg = '') => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
clearList: () => {
|
||||
dispatch(clear_leone);
|
||||
},
|
||||
scanLeOne: (data) => {
|
||||
dispatch(scan_leone(data));
|
||||
},
|
||||
clearScan: () => {
|
||||
dispatch(clear_scan_leone())
|
||||
},
|
||||
addScanLeOne: (data) => {
|
||||
dispatch(add_scan_leone(data));
|
||||
},
|
||||
getLeOneList: (showLoading = true) => {
|
||||
dispatch(get_leone_list(showLoading));
|
||||
},
|
||||
delLeOne: (data) => {
|
||||
dispatch(del_leone(data));
|
||||
},
|
||||
addLeOne: (data) => {
|
||||
dispatch(add_leone(data));
|
||||
},
|
||||
editLeOne: (data) => {
|
||||
dispatch(edit_leone(data));
|
||||
},
|
||||
runCmd: (data) => {
|
||||
dispatch(io_cmd(data));
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(LeOnePage);
|
20
src/containers/AdminPage/Log.js
Normal file
20
src/containers/AdminPage/Log.js
Normal file
@ -0,0 +1,20 @@
|
||||
import {connect} from 'react-redux';
|
||||
import LogPage from '../../components/AdminPage/Log';
|
||||
import {get_log_list, clear_log} from '../../actions';
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n,
|
||||
list: state.lists.log.list || [],
|
||||
page: state.lists.log.page || []
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
getList: (p = 1) => {
|
||||
dispatch(get_log_list(p));
|
||||
},
|
||||
clearList: () => {
|
||||
dispatch(clear_log());
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(LogPage);
|
68
src/containers/AdminPage/Modbus.js
Normal file
68
src/containers/AdminPage/Modbus.js
Normal file
@ -0,0 +1,68 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {add_dialog_msg,
|
||||
clear_modbus,
|
||||
get_modbus_list,
|
||||
del_modbus,
|
||||
add_modbus,
|
||||
edit_modbus,
|
||||
get_mb_data,
|
||||
get_mb_iostatus,
|
||||
del_mb_iolist,
|
||||
add_mb_iolist,
|
||||
edit_mb_iolist,
|
||||
add_mb_aio,
|
||||
edit_mb_aio,
|
||||
del_mb_aio} from '../../actions';
|
||||
import ModbusPage from '../../components/AdminPage/Modbus';
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n,
|
||||
list: state.lists.modbus.list || []
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
clearList: () => {
|
||||
dispatch(clear_modbus());
|
||||
},
|
||||
getList: () => {
|
||||
dispatch(get_modbus_list());
|
||||
},
|
||||
delModbus: (data) => {
|
||||
dispatch(del_modbus(data));
|
||||
},
|
||||
addModbus: data => {
|
||||
dispatch(add_modbus(data));
|
||||
},
|
||||
editModbus: data=>{
|
||||
dispatch(edit_modbus(data));
|
||||
},
|
||||
getMBData: data => {
|
||||
dispatch(get_mb_data(data));
|
||||
},
|
||||
getMBIOStatus: data => {
|
||||
dispatch(get_mb_iostatus(data));
|
||||
},
|
||||
addIOList: data => {
|
||||
dispatch(add_mb_iolist(data));
|
||||
},
|
||||
editIOList: data=>{
|
||||
dispatch(edit_mb_iolist(data));
|
||||
},
|
||||
delIOList: data => {
|
||||
dispatch(del_mb_iolist(data));
|
||||
},
|
||||
addAIO: data => {
|
||||
dispatch(add_mb_aio(data));
|
||||
},
|
||||
editAIO: data => {
|
||||
dispatch(edit_mb_aio(data));
|
||||
},
|
||||
delAIO: data => {
|
||||
dispatch(del_mb_aio(data));
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(ModbusPage);
|
55
src/containers/AdminPage/Schedule.js
Normal file
55
src/containers/AdminPage/Schedule.js
Normal file
@ -0,0 +1,55 @@
|
||||
import {connect} from 'react-redux';
|
||||
import {add_dialog_msg, get_select_list, clear_select_list, get_schedule_list, add_schedule, del_schedule, edit_schedule, sw_schedule, clear_schedule} from '../../actions';
|
||||
import SchedulePage from '../../components/AdminPage/Schedule';
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n,
|
||||
devs: state.lists.selectdev,
|
||||
list: state.lists.schedule.list,
|
||||
dos: state.lists.schedule.do,
|
||||
les: state.lists.schedule.leone,
|
||||
ios: state.lists.schedule.iogroup,
|
||||
permissions: (function() {
|
||||
let p = sessionStorage.getItem('permissions');
|
||||
if (!p) return {};
|
||||
let json = {};
|
||||
try {
|
||||
json = JSON.parse(p);
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
return json
|
||||
}())
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
clearList: () => {
|
||||
dispatch(clear_schedule());
|
||||
},
|
||||
getSelectList: (data) => {
|
||||
dispatch(get_select_list(data));
|
||||
},
|
||||
clearSelectList: () => {
|
||||
dispatch(clear_select_list());
|
||||
},
|
||||
getScheduleList: () => {
|
||||
dispatch(get_schedule_list());
|
||||
},
|
||||
addSchedule: (data) => {
|
||||
dispatch(add_schedule(data));
|
||||
},
|
||||
editSchedule: (data) => {
|
||||
dispatch(edit_schedule(data));
|
||||
},
|
||||
delSchedule: (data) => {
|
||||
dispatch(del_schedule(data));
|
||||
},
|
||||
swSchedule: (data) => {
|
||||
dispatch(sw_schedule(data));
|
||||
}
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(SchedulePage);
|
11
src/containers/AdminPage/SystemInfo.js
Normal file
11
src/containers/AdminPage/SystemInfo.js
Normal file
@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import SysInfo from '../../components/AdminPage/SystemInfo'
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n,
|
||||
network: 'network' in state.sysinfo ? state.sysinfo.network : {},
|
||||
time: 'time' in state.sysinfo ? state.sysinfo.time : 0
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps)(SysInfo);
|
32
src/containers/AdminPage/UserList.js
Normal file
32
src/containers/AdminPage/UserList.js
Normal file
@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import UList from '../../components/AdminPage/UserList';
|
||||
import {add_dialog_msg, edit_user, get_user_list, add_user, del_user,clear_userlist} from '../../actions';
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n,
|
||||
users: state.lists.user || []
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
showDialog: (msg) => {
|
||||
dispatch(add_dialog_msg(msg));
|
||||
},
|
||||
clearList: () => {
|
||||
dispatch(clear_userlist())
|
||||
},
|
||||
getList: () => {
|
||||
dispatch(get_user_list());
|
||||
},
|
||||
addUser: data => {
|
||||
dispatch(add_user(data));
|
||||
},
|
||||
editUser: data => {
|
||||
dispatch(edit_user(data));
|
||||
},
|
||||
delUser: data=>{
|
||||
dispatch(del_user(data));
|
||||
}
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(UList);
|
33
src/containers/AdminPage/index.js
Normal file
33
src/containers/AdminPage/index.js
Normal file
@ -0,0 +1,33 @@
|
||||
import React from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import Datetime from 'react-datetime';
|
||||
import MainMenu from '../../containers/MenuControl';
|
||||
import Loading from '../../containers/LoadingControl';
|
||||
import Dialog from '../DialogControl';
|
||||
|
||||
class AdmPage extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
let {i18n, children} = this.props;
|
||||
if(!i18n || Object.keys(i18n).length == 0 || !i18n.t || !i18n.getResource) return null;
|
||||
return (
|
||||
<div style={{height: '100%'}}>
|
||||
<Loading />
|
||||
<Dialog />
|
||||
<MainMenu i18n={i18n} >
|
||||
{children}
|
||||
</MainMenu>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
i18n: state.i18n
|
||||
})
|
||||
|
||||
export default connect(mapStateToProps)(AdmPage);
|
17
src/containers/DialogControl.js
Normal file
17
src/containers/DialogControl.js
Normal file
@ -0,0 +1,17 @@
|
||||
import {connect} from 'react-redux';
|
||||
import Dialog from '../components/Dialog';
|
||||
import {remove_dialog_msg} from '../actions'
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
obj: state.dialog[0] || null
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
getNext : (act) => {
|
||||
//get next dialog message
|
||||
if(typeof act == 'function') act();
|
||||
dispatch(remove_dialog_msg());
|
||||
}
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Dialog);
|
8
src/containers/LoadingControl.js
Normal file
8
src/containers/LoadingControl.js
Normal file
@ -0,0 +1,8 @@
|
||||
import {connect} from 'react-redux';
|
||||
import Loading from '../components/Loading';
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
active: state.ui.showLoading
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(Loading);
|
26
src/containers/MenuControl.js
Normal file
26
src/containers/MenuControl.js
Normal file
@ -0,0 +1,26 @@
|
||||
import { connect } from 'react-redux';
|
||||
import MainMenu from '../components/MainMenu';
|
||||
import { toggle_menu } from '../actions'
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
show: state.ui.showMenu,
|
||||
permissions: (function() {
|
||||
let p = sessionStorage.getItem('permissions');
|
||||
if (!p) return {};
|
||||
let json = {};
|
||||
try {
|
||||
json = JSON.parse(p);
|
||||
} catch (e) {
|
||||
return {};
|
||||
}
|
||||
return json
|
||||
}())
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch, ownProps) => ({
|
||||
toggleMenu: (flag) => {
|
||||
dispatch(toggle_menu(flag));
|
||||
}
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(MainMenu);
|
25
src/index.js
Normal file
25
src/index.js
Normal file
@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
// import {Router, Route, browserHistory, IndexRoute} from 'react-router';
|
||||
import {Provider} from 'react-redux';
|
||||
import {createStore, applyMiddleware} from 'redux';
|
||||
import reducers from './reducers';
|
||||
// import routes from './routes';
|
||||
import Login from './components/Login';
|
||||
import thunk from 'redux-thunk';
|
||||
|
||||
const middleware = [thunk];
|
||||
|
||||
const store = createStore(reducers, applyMiddleware(...middleware));
|
||||
|
||||
store.subscribe(() => {
|
||||
console.log(store.getState());
|
||||
});
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<Login />
|
||||
{/*<Router history={browserHistory} routes={routes} />*/}
|
||||
</Provider>,
|
||||
document.getElementById('app')
|
||||
);
|
15
src/reducers/dialog.js
Normal file
15
src/reducers/dialog.js
Normal file
@ -0,0 +1,15 @@
|
||||
const dialogReducer = (state = [], action) => {
|
||||
switch(action.type) {
|
||||
case 'dialog_addmsg':
|
||||
return [...state, {
|
||||
msg: action.msg,
|
||||
act: action.act || null
|
||||
}];
|
||||
case 'dialog_remove_first':
|
||||
return state.slice(1);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export default dialogReducer;
|
10
src/reducers/i18n.js
Normal file
10
src/reducers/i18n.js
Normal file
@ -0,0 +1,10 @@
|
||||
const i18nReducer = (state = {}, action) => {
|
||||
switch(action.type) {
|
||||
case 'i18n_set_ctx':
|
||||
return action.i18n;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export default i18nReducer;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user