diff --git a/EdgeManager.php b/EdgeManager.php index cc1c2a5..0a92e8a 100644 --- a/EdgeManager.php +++ b/EdgeManager.php @@ -11,7 +11,7 @@ $options = getopt('h::', ['server_name:', 'user:', 'password:', 'help::']); init_db($options['server_name'], $options['user'], $options['password']); -$worker = new Worker('http://0.0.0.0:1818'); +$worker = new Worker('http://0.0.0.0:8888'); $worker -> name = 'CaptureWorker'; $worker -> onWorkerStart = function(Worker $worker) { @@ -30,9 +30,40 @@ $worker -> onMessage = function(TcpConnection $connection, Request $request) { unset($post['action']); $enode_configure = new ENodeConfigure($dbconn, $post = $post); $res = $enode_configure -> $action(); - if ($res) - $connection -> send(json_encode(array ('code' => 0, - 'msg' => 'Set threshold success'))); + if ($res === true) + $connection -> send(json_encode(array( + 'code' => 0, + 'msg' => 'Success' + ))); + else if ($res === "REPLICATED") + $connection -> send(json_encode(array( + 'code' => 1, + 'msg' => '节点编码不可重复!' + ))); + else if ($res === false) { + $connection -> send(json_encode(array( + 'code' => 1, + 'msg' => '服务器内部逻辑错误,请联系开发者!' + ))); + } + } else if (isset($post['action']) and str_contains($post['action'], 'data')) { + $action = $post['action']; + unset($post['action']); + $data_capture = new EDataCapture($dbconn, $post = $post); + $res = $data_capture -> $action(); + if ($res === true) { + $connection -> send(json_encode(array( + 'action' => 'result_set_data', + 'errcode' => 0, + 'errmsg' => '' + ))); + } else { + $connection -> send(json_encode(array( + 'action' => 'result_set_data', + 'errcode' => 4002, + 'errmsg' => 'ROLLBACKed: Bad data received (structure and/or values)' + ))); + } } $get = $request -> get(); @@ -40,9 +71,15 @@ $worker -> onMessage = function(TcpConnection $connection, Request $request) { $enode_configure = new ENodeConfigure($dbconn, $get = $get); $nodes = $enode_configure -> get_nodes(); if (is_null($nodes)) - $connection -> send(json_encode(array('code' => 1, 'msg' => 'no node data'))); + $connection -> send(json_encode(array( + 'code' => 1, + 'msg' => 'no node data' + ))); else - $connection -> send(json_encode(array('code' => 0, 'data' => $nodes))); + $connection -> send(json_encode(array( + 'code' => 0, + 'data' => $nodes + ))); } }; diff --git a/app/EDataCapture/EDataCapture.php b/app/EDataCapture/EDataCapture.php index 472bc88..e16f52b 100644 --- a/app/EDataCapture/EDataCapture.php +++ b/app/EDataCapture/EDataCapture.php @@ -2,7 +2,31 @@ namespace EdgeManager\EDataCapture; class EDataCapture { + // 我不主张在构造函数内实现类型检查,因为在请求过于密集、记录较多时会严重影响性能 + // 请使用SCADA系统的开发人员自觉遵守文档内规范 + function __construct( + protected $dbconn, + protected $post = NULL, + protected $get = NULL + ) {} + private function set_data() { - + foreach (array_chunk($this -> post -> param, 6507524, true) as $chunk) { + $sql_cmd[] = [sprintf( + "INSERT INTO hf_mes_scada_data_capture_node_data_%s", + $chunk[0] -> working_subclass + )]; + foreach ($chunk as $row) { + $sql_cmd[] = sprintf( + "(code, v_%s, device_code, batch) VALUES('%s', %s, %s, %s)", + $row -> type, + $row -> code, + $row -> value, + $row -> device_code ?? NULL, + $row -> batch ?? NULL + ); + } + return pg_query($this -> dbconn, implode(' ', $sql_cmd)); + } } -} \ No newline at end of file +} diff --git a/app/EDataCapture/ENodeConfigure.php b/app/EDataCapture/ENodeConfigure.php index e52890a..7bf157d 100644 --- a/app/EDataCapture/ENodeConfigure.php +++ b/app/EDataCapture/ENodeConfigure.php @@ -9,11 +9,20 @@ class ENodeConfigure { ) {} function add_node() { - $table_name = "hf_mes_scada_data_capture_node_data_" . $this -> post['process_code']; + $exists = pg_query(sprintf( + "SELECT EXISTS( + SELECT 1 FROM hf_mes_scada_data_capture_node_configure WHERE code='%s' + )", $this -> post['code'] + )); + if (pg_fetch_assoc($exists)['exists'] == 't') { + return "REPLICATED"; + } + + $table_name = "hf_mes_scada_data_capture_node_data_" . $this -> post['working_subclass']; pg_query($this -> dbconn, "BEGIN"); - $res1 = pg_query($this -> dbconn, sprintf( - "CREATE TABLE IF NOT EXISTS %s( + $res[] = pg_query($this -> dbconn, sprintf( + "CREATE TABLE IF NOT EXISTS %s ( id serial8, code text references hf_mes_scada_data_capture_node_configure(code), v_string text, @@ -22,35 +31,70 @@ class ENodeConfigure { v_bool bool, device_code text, batch text, - create_date timestamp + capture_time timestamp NOT NULL DEFAULT NOW() )", $table_name )); - $res2 = pg_insert( + $res[] = pg_insert( $this -> dbconn, 'hf_mes_scada_data_capture_node_configure', $this -> post ); - - if ($res1 and $res2) - pg_query($this -> dbconn, "COMMIT"); - else - pg_query($this -> dbconn, "ROLLBACK"); - - pg_query($this -> dbconn, sprintf("SELECT create_hypertable('%s','create_date')", $table_name)); - pg_query($this -> dbconn, sprintf( - "CREATE INDEX ON %s (v_string, v_int, v_float, v_bool, create_date DESC) - WHERE COALESCE(v_string, v_int::text, v_float::text, v_bool::text) IS NOT NULL + // 检查一下,如果超表已经有了就不要尝试重复创建了 + $table_exists = pg_query(sprintf( + "SELECT * + FROM timescaledb_information.hypertables + WHERE hypertable_name = '%s' ", $table_name )); + if (!in_array($table_name, pg_fetch_all_columns($table_exists, 1))) { + $res[] = pg_query($this -> dbconn, sprintf("SELECT create_hypertable('%s', 'capture_time')", $table_name)); + $res[] = pg_query($this -> dbconn, sprintf( + "CREATE INDEX ON %s (v_string, v_int, v_float, v_bool, capture_time DESC) + WHERE COALESCE(v_string, v_int::text, v_float::text, v_bool::text) IS NOT NULL + ", $table_name + )); + } + + if (in_array(false, $res)) { + pg_query($this -> dbconn, "ROLLBACK"); + return false; + } else { + pg_query($this -> dbconn, "COMMIT"); + return true; + } } function remove_node() { + pg_query($this -> dbconn, "BEGIN"); + $res[] = pg_delete( + $this -> dbconn, + 'hf_mes_scada_data_capture_node_configure', + $this -> post, + ); + $exists = pg_query(sprintf( + "SELECT EXISTS( + SELECT 1 FROM hf_mes_scada_data_capture_node_configure WHERE code='%s' + )", $this -> post['working_subclass'] + )); + if (pg_fetch_assoc($exists)['exists'] == 'f') { + $res[] = pg_query(sprintf( + "DROP TABLE hf_mes_scada_data_capture_node_data_%s", + $this -> post['working_subclass'] + )); + } + if (in_array(false, $res)) { + pg_query($this -> dbconn, "ROLLBACK"); + return false; + } else { + pg_query($this -> dbconn, "COMMIT"); + return true; + } } function update_node() { return pg_update( - $this -> dbconn, + $this -> dbconn, 'hf_mes_scada_data_capture_node_configure', $this -> post, ['code' => $this -> post['code']] @@ -61,4 +105,4 @@ class ENodeConfigure { $res = pg_query($this -> dbconn, "SELECT * FROM hf_mes_scada_data_capture_node_configure"); return pg_fetch_all($res); } -} \ No newline at end of file +} diff --git a/app/Init.php b/app/Init.php index c079602..ea4c2dd 100644 --- a/app/Init.php +++ b/app/Init.php @@ -2,20 +2,21 @@ function init_db($server_name, $user, $password) { $dbconn = pg_connect(sprintf("host=%s user=%s password=%s", $server_name, $user, $password)); $res = pg_query("select datname from pg_database"); - if (find_key_value(pg_fetch_assoc($res), 'datname', 'scada')) + + if (!in_array('scada', pg_fetch_all_columns($res, 0))) pg_query("CREATE DATABASE scada"); pg_close($dbconn); $dbconn = pg_connect(sprintf("host=%s dbname=scada user=%s password=%s", $server_name, $user, $password)); pg_query("CREATE TABLE IF NOT EXISTS hf_mes_scada_data_capture_node_configure ( id serial2, - code text primary key, - name text, - type text, + code text primary key NOT NULL, + name text NOT NULL, + type text NOT NULL, flow_code text, - process_code text, + working_subclass text NOT NULL, workstation text, - create_date timestamp, + create_date timestamp NOT NULL DEFAULT NOW(), note text )"); pg_close($dbconn); diff --git a/src/api/modules/scada.configure.api.js b/src/api/modules/scada.configure.api.js index 7238836..d73bf78 100644 --- a/src/api/modules/scada.configure.api.js +++ b/src/api/modules/scada.configure.api.js @@ -1,23 +1,18 @@ +const handlePost = (request, data) => (request({ + url: '', + method: 'post', + data +})) + export default ({ service, request, serviceForMock, requestForMock, mock, faker, tools }) => ({ /** * @description 方法名称 * @param {Object} data 请求携带的信息 */ - ADD_NODE (data) { - return request({ - url: '', - method: 'post', - data - }) - }, - UPDATE_NODE (data) { - return request({ - url: '', - method: 'post', - data - }) - }, + ADD_NODE: (data) => handlePost(request, data), + UPDATE_NODE: (data) => handlePost(request, data), + REMOVE_NODE: (data) => handlePost(request, data), QUERY_NODE () { return request({ url: '?query=nodes' }) diff --git a/src/views/scada/scadaConfigure/index.vue b/src/views/scada/scadaConfigure/index.vue index e586ca6..644289a 100644 --- a/src/views/scada/scadaConfigure/index.vue +++ b/src/views/scada/scadaConfigure/index.vue @@ -21,7 +21,7 @@