12 Commits

15 changed files with 659 additions and 51 deletions

1
.dockerignore Normal file
View File

@@ -0,0 +1 @@
*

View File

@@ -7,10 +7,26 @@ use Workerman\Protocols\Http\Response;
require_once __DIR__ . '/vendor/autoload.php'; require_once __DIR__ . '/vendor/autoload.php';
use EdgeManager\EDataCapture\{ EDataCapture, ENodeConfigure }; use EdgeManager\EDataCapture\{ EDataCapture, ENodeConfigure };
use EdgeManager\EController\EConfigure;
$options = getopt('h::', ['server_name:', 'user:', 'password:', 'help::']); $options = getopt('h::', ['no_dup_code', 'server_name:', 'port::', 'user:', 'password:', 'help::']);
init_db($options['server_name'], $options['user'], $options['password']); if (array_key_exists('h', $options) or array_key_exists('help', $options)) {
print_r(
"EdgeManager使用说明
--no_dup_code 禁止code在不同的working subclass间复用
--server_name pg实例的FQDN
--user pg实例的用户名
--port pg实例的端口号
--password pg实例的密码
-h, --help 显示此帮助信息
"
);
exit;
}
init_db($options['server_name'], $options['port'] ?? 5432, $options['user'], $options['password']);
$worker = new Worker('http://0.0.0.0:8888'); $worker = new Worker('http://0.0.0.0:8888');
$worker -> name = 'EntryPoint'; $worker -> name = 'EntryPoint';
@@ -20,8 +36,8 @@ $worker -> onWorkerStart = function(Worker $worker) {
global $options, $dbconn; global $options, $dbconn;
$dbconn = pg_connect(sprintf( $dbconn = pg_connect(sprintf(
"host=%s dbname=scada user=%s password=%s", "host=%s port=%s dbname=scada user=%s password=%s",
$options['server_name'], $options['user'], $options['password'] $options['server_name'], $options['port'] ?? 5432, $options['user'], $options['password']
)); ));
}; };
@@ -79,7 +95,7 @@ $worker -> onMessage = function(TcpConnection $connection, Request $request) {
// 执行异步连接 // 执行异步连接
$task_connection->connect(); $task_connection->connect();
} else { } else {
$enode_configure = new ENodeConfigure($dbconn, post: $post); $enode_configure = new ENodeConfigure($dbconn, no_dup_code: $options['no_dup_code'] ?? true, post: $post);
$res = $enode_configure -> $action(); $res = $enode_configure -> $action();
if ($res === true) if ($res === true)
@@ -93,16 +109,57 @@ $worker -> onMessage = function(TcpConnection $connection, Request $request) {
'msg' => '服务器内部逻辑错误,请联系开发者!' 'msg' => '服务器内部逻辑错误,请联系开发者!'
))); )));
} }
} }
} else if (
str_ends_with($post -> action, 'server')
or str_ends_with($post -> action, 'device')
) {
$action = $post -> action;
unset($post -> action);
if ($action === 'add_server') {
$task_connection = new AsyncTcpConnection('Text://127.0.0.1:1888');
$task_data = array(
'action' => 'add_server',
'data' => $post,
);
$task_connection -> send(json_encode($task_data));
$task_connection -> onMessage = function(AsyncTcpConnection $task_connection, $task_result) use ($connection) {
$task_connection -> close();
$connection -> send($task_result);
};
// 执行异步连接
$task_connection->connect();
} else {
$e_configure = new EConfigure($dbconn, post: $post);
$res = $e_configure -> $action();
if ($res === true)
$connection -> send(json_encode(array(
'code' => 0,
'msg' => 'Success'
)));
else if ($res === "REMAINING") {
$connection -> send(json_encode(array(
'code' => 1,
'msg' => '该服务中仍有关联的设备,不允许删除!'
)));
} else if ($res === false) {
$connection -> send(json_encode(array(
'code' => 1,
'msg' => '服务器内部逻辑错误,请联系开发者!'
)));
}
}
} else if ($post -> action === 'set_node_data') { } else if ($post -> action === 'set_node_data') {
$data_capture = new EDataCapture($dbconn, post: $post); $data_capture = new EDataCapture($dbconn, no_dup_code: $options['no_dup_code'] ?? true, post: $post);
if ($data_capture -> check_res === 'WRONG_WORKING_SUBCLASS') { if ($data_capture -> check_res === 'WRONG_WORKING_SUBCLASS') {
$response = new Response(200, [ $response = new Response(200, [
'Content-Type' => 'application/json;charset=utf-8', 'Content-Type' => 'application/json;charset=utf-8',
], json_encode(array( ], json_encode(array(
'action' => 'result_set_node_data', 'action' => 'result_set_node_data',
'errcode' => 4002, 'errcode' => 4002,
'errmsg' => '未登记过的工序单元!' 'errmsg' => '工序单元有误,请检查是否未指定或未登记'
))); )));
$connection -> send($response); $connection -> send($response);
} else if ($data_capture -> check_res === 'MISMATCH_TYPE') { } else if ($data_capture -> check_res === 'MISMATCH_TYPE') {
@@ -156,12 +213,12 @@ $worker -> onMessage = function(TcpConnection $connection, Request $request) {
$get = $request -> get(); $get = $request -> get();
if (isset($get['query'])) { if (isset($get['query'])) {
if ($get['query'] == 'nodes') { if ($get['query'] == 'nodes') {
$enode_configure = new ENodeConfigure($dbconn, get: $get); $enode_configure = new ENodeConfigure($dbconn, no_dup_code: $options['no_dup_code'] ?? true, get: $get);
$nodes = $enode_configure -> get_nodes(); $nodes = $enode_configure -> get_nodes();
if (is_null($nodes)) if (is_null($nodes))
$connection -> send(json_encode(array( $connection -> send(json_encode(array(
'code' => 1, 'code' => 1,
'msg' => 'no node data yet' 'msg' => '未添加过节点!'
))); )));
else else
$connection -> send(json_encode(array( $connection -> send(json_encode(array(
@@ -169,7 +226,7 @@ $worker -> onMessage = function(TcpConnection $connection, Request $request) {
'data' => $nodes 'data' => $nodes
))); )));
} else if ($get['query'] == 'working_subclasses') { } else if ($get['query'] == 'working_subclasses') {
$enode_configure = new ENodeConfigure($dbconn, get: $get); $enode_configure = new ENodeConfigure($dbconn, no_dup_code: $options['no_dup_code'] ?? true, get: $get);
$working_subclasses = $enode_configure -> get_working_subclasses($dbconn); $working_subclasses = $enode_configure -> get_working_subclasses($dbconn);
if (is_null($working_subclasses)) if (is_null($working_subclasses))
$connection -> send(json_encode(array( $connection -> send(json_encode(array(
@@ -182,7 +239,7 @@ $worker -> onMessage = function(TcpConnection $connection, Request $request) {
'data' => $working_subclasses 'data' => $working_subclasses
))); )));
} else if ($get['query'] == 'codes') { } else if ($get['query'] == 'codes') {
$enode_configure = new ENodeConfigure($dbconn, get: $get); $enode_configure = new ENodeConfigure($dbconn, no_dup_code: $options['no_dup_code'] ?? true, get: $get);
$codes = $enode_configure -> get_codes_by_working_subclasses(); $codes = $enode_configure -> get_codes_by_working_subclasses();
if (is_null($codes)) if (is_null($codes))
$connection -> send(json_encode(array( $connection -> send(json_encode(array(
@@ -195,7 +252,7 @@ $worker -> onMessage = function(TcpConnection $connection, Request $request) {
'data' => $codes 'data' => $codes
))); )));
} else if ($get['query'] == 'node_data') { } else if ($get['query'] == 'node_data') {
$data_capture = new EDataCapture($dbconn, get: $get); $data_capture = new EDataCapture($dbconn, no_dup_code: $options['no_dup_code'] ?? true, get: $get);
$data = $data_capture -> get_node_data(); $data = $data_capture -> get_node_data();
if (is_null($data)) if (is_null($data))
$connection -> send(json_encode(array( $connection -> send(json_encode(array(
@@ -212,6 +269,19 @@ $worker -> onMessage = function(TcpConnection $connection, Request $request) {
'code' => 0, 'code' => 0,
'data' => $data 'data' => $data
))); )));
} else if ($get['query'] == 'servers') {
$e_configure = new EConfigure($dbconn, get: $get);
$nodes = $e_configure -> get_servers();
if (is_null($nodes))
$connection -> send(json_encode(array(
'code' => 1,
'msg' => '未添加过服务!'
)));
else
$connection -> send(json_encode(array(
'code' => 0,
'data' => $nodes
)));
} else { } else {
$connection -> send(json_encode(array( $connection -> send(json_encode(array(
'code' => 1, 'code' => 1,
@@ -228,8 +298,8 @@ $consumer -> onWorkerStart = function(Worker $consumer) {
global $options, $consumer_dbconn; global $options, $consumer_dbconn;
$consumer_dbconn = pg_connect(sprintf( $consumer_dbconn = pg_connect(sprintf(
"host=%s dbname=scada user=%s password=%s", "host=%s port=%s dbname=scada user=%s password=%s",
$options['server_name'], $options['user'], $options['password'] $options['server_name'], $options['port'] ?? 5432, $options['user'], $options['password']
)); ));
}; };
@@ -239,7 +309,7 @@ $consumer -> onMessage = function(TcpConnection $connection, $task_data) {
$task_data = json_decode($task_data); $task_data = json_decode($task_data);
if ($task_data -> action === 'add_node') { if ($task_data -> action === 'add_node') {
$enode_configure = new ENodeConfigure($consumer_dbconn, post: $task_data -> data); $enode_configure = new ENodeConfigure($consumer_dbconn, no_dup_code: $options['no_dup_code'] ?? true, post: $task_data -> data);
$res = $enode_configure -> add_node(); $res = $enode_configure -> add_node();
if ($res === true) if ($res === true)
@@ -250,7 +320,27 @@ $consumer -> onMessage = function(TcpConnection $connection, $task_data) {
else if ($res === "REPLICATED") else if ($res === "REPLICATED")
$connection -> send(json_encode(array( $connection -> send(json_encode(array(
'code' => 1, 'code' => 1,
'msg' => '同一工序单元内的节点编码不可重复!' 'msg' => isset($options['no_dup_code']) ? '节点编码不可重复!' : '同一工序单元内的节点编码不可重复!'
)));
else if ($res === false) {
$connection -> send(json_encode(array(
'code' => 1,
'msg' => '服务器内部逻辑错误,请联系开发者!'
)));
}
} else if ($task_data -> action === 'add_server') {
$e_configure = new EConfigure($consumer_dbconn, post: $task_data -> data);
$res = $e_configure -> add_server();
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) { else if ($res === false) {
$connection -> send(json_encode(array( $connection -> send(json_encode(array(

View File

@@ -0,0 +1,100 @@
<?php
namespace EdgeManager\EController;
class EConfigure {
function __construct(
protected $dbconn,
protected $post = NULL,
protected $get = NULL,
) {}
function add_server() {
pg_query($this -> dbconn, "BEGIN");
$addr_exists = pg_query($this -> dbconn, sprintf(
"SELECT EXISTS (
SELECT 1 FROM hf_mes_scada_edgeserver_controller_server
WHERE url = '%s'
AND port = '%s'
)",
$this -> post -> url,
$this -> post -> port
));
$name_exists = pg_query($this -> dbconn, sprintf(
"SELECT EXISTS (
SELECT 1 FROM hf_mes_scada_edgeserver_controller_server
WHERE name = '%s'
)",
$this -> post -> name
));
if (
pg_fetch_assoc($addr_exists)['exists'] === 't'
or pg_fetch_assoc($name_exists)['exists'] === 't'
) {
pg_query($this -> dbconn, "ROLLBACK");
return "REPLICATED";
} else {
$res = pg_insert(
$this -> dbconn,
'hf_mes_scada_edgeserver_controller_server',
(array) $this -> post
);
if ($res) {
pg_query($this -> dbconn, "COMMIT");
return true;
} else {
pg_query($this -> dbconn, "ROLLBACK");
return false;
}
}
}
function remove_server() {
pg_query($this -> dbconn, "BEGIN");
$exists = pg_query($this -> dbconn, sprintf(
"SELECT EXISTS(
SELECT 1 FROM hf_mes_scada_edgeserver_controller_device
WHERE server_id = '%s'
)", $this -> post -> id
));
if (pg_fetch_assoc($exists)['exists'] === 't') {
pg_query($this -> dbconn, "ROLLBACK");
return "REMAINING";
} else {
$res = pg_delete(
$this -> dbconn,
'hf_mes_scada_edgeserver_controller_server',
(array) $this -> post,
);
if ($res) {
pg_query($this -> dbconn, "COMMIT");
return true;
} else {
pg_query($this -> dbconn, "ROLLBACK");
return false;
}
}
}
function update_server() {
return pg_update(
$this -> dbconn,
'hf_mes_scada_edgeserver_controller_server',
(array) $this -> post,
['id' => $this -> post -> id]
);
}
function get_servers() {
$res = pg_query($this -> dbconn, "SELECT * FROM hf_mes_scada_edgeserver_controller_server");
return pg_fetch_all($res);
}
function add_device() {
return pg_insert(
$this -> dbconn,
'hf_mes_scada_edgeserver_controller_server',
(array) $this -> post
);
}
}

View File

@@ -4,31 +4,41 @@ namespace EdgeManager\EDataCapture;
class EDataCapture { class EDataCapture {
function __construct( function __construct(
protected $dbconn, protected $dbconn,
protected $no_dup_code,
protected $post = NULL, protected $post = NULL,
protected $get = NULL, protected $get = NULL,
public $check_res = NULL, public $check_res = NULL,
protected $working_subclass = NULL, protected $working_subclass = NULL,
protected $code_type = [], protected $code_type = [],
protected $data = [] protected $data = [],
) { ) {
if (!is_null($this -> post)) { if (!is_null($this -> post)) {
if (!in_array( if(isset($this -> post -> param -> working_subclass)){
$this -> post -> param -> working_subclass, if (!in_array(
ENodeConfigure::get_working_subclasses($this -> dbconn) $this -> post -> param -> working_subclass,
)) { ENodeConfigure::get_working_subclasses($this -> dbconn)
$this -> check_res = 'WRONG_WORKING_SUBCLASS'; )) {
return; $this -> check_res = 'WRONG_WORKING_SUBCLASS';
} else { return;
$this -> working_subclass = $this -> post -> param -> working_subclass; } else {
$this -> working_subclass = $this -> post -> param -> working_subclass;
}
}else{
if ($this -> no_dup_code) {
$this -> check_res = 'WRONG_WORKING_SUBCLASS';
return;
}
$working_subclass = ENodeConfigure::get_working_subclasses_by_codes($this -> dbconn, $this -> post -> param -> data[0] -> code);
$this -> working_subclass = $working_subclass['working_subclass'];
} }
$res = pg_fetch_all(pg_query($this -> dbconn, sprintf( $res = pg_fetch_all(pg_query($this -> dbconn, sprintf(
"SELECT code, type "SELECT code, type
FROM hf_mes_scada_data_capture_node_configure FROM hf_mes_scada_data_capture_node_configure
WHERE working_subclass = '%s'", WHERE working_subclass = '%s'",
$this -> post -> param -> working_subclass $this -> working_subclass
))); )));
$code_type = &$this -> code_type; $code_type = &$this -> code_type;
array_walk($res, function(&$v, $k) use (&$code_type) { array_walk($res, function(&$v, $k) use (&$code_type) {
$code_type[$v['code']] = $v['type']; $code_type[$v['code']] = $v['type'];

View File

@@ -4,19 +4,30 @@ namespace EdgeManager\EDataCapture;
class ENodeConfigure { class ENodeConfigure {
function __construct( function __construct(
protected $dbconn, protected $dbconn,
protected $no_dup_code,
protected $post = NULL, protected $post = NULL,
protected $get = NULL protected $get = NULL,
) {} ) {}
function add_node() { function add_node() {
pg_query($this -> dbconn, "BEGIN"); pg_query($this -> dbconn, "BEGIN");
$exists = pg_query($this -> dbconn, sprintf( if ($this -> no_dup_code) {
"SELECT EXISTS( $exists = pg_query($this -> dbconn, sprintf(
SELECT 1 FROM hf_mes_scada_data_capture_node_configure "SELECT EXISTS(
WHERE code = '%s' SELECT 1 FROM hf_mes_scada_data_capture_node_configure
AND working_subclass = '%s' WHERE code = '%s'
)", $this -> post -> code, $this -> post -> working_subclass AND working_subclass = '%s'
)); )", $this -> post -> code, $this -> post -> working_subclass
));
} else {
$exists = pg_query($this -> dbconn, 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') { if (pg_fetch_assoc($exists)['exists'] === 't') {
pg_query($this -> dbconn, "ROLLBACK"); pg_query($this -> dbconn, "ROLLBACK");
return "REPLICATED"; return "REPLICATED";
@@ -100,7 +111,7 @@ class ENodeConfigure {
$this -> dbconn, $this -> dbconn,
'hf_mes_scada_data_capture_node_configure', 'hf_mes_scada_data_capture_node_configure',
(array) $this -> post, (array) $this -> post,
['code' => $this -> post -> code] ['id' => $this -> post -> id]
); );
} }
@@ -114,6 +125,16 @@ class ENodeConfigure {
return pg_fetch_all_columns($res, 0); return pg_fetch_all_columns($res, 0);
} }
static function get_working_subclasses_by_codes($dbconn, $code) {
$res = pg_query($dbconn, sprintf(
"SELECT working_subclass
FROM hf_mes_scada_data_capture_node_configure
WHERE code = '%s'",
$code
));
return pg_fetch_assoc($res);
}
function get_codes_by_working_subclasses() { function get_codes_by_working_subclasses() {
$res = pg_query($this -> dbconn, sprintf( $res = pg_query($this -> dbconn, sprintf(
"SELECT code "SELECT code

View File

@@ -1,13 +1,13 @@
<?php <?php
function init_db($server_name, $user, $password) { function init_db($server_name, $port, $user, $password) {
$dbconn = pg_connect(sprintf("host=%s user=%s password=%s", $server_name, $user, $password)); $dbconn = pg_connect(sprintf("host=%s port=%s user=%s password=%s", $server_name, $port, $user, $password));
$res = pg_query($dbconn, "select datname from pg_database"); $res = pg_query($dbconn, "select datname from pg_database");
if (!in_array('scada', pg_fetch_all_columns($res, 0))) if (!in_array('scada', pg_fetch_all_columns($res, 0)))
pg_query($dbconn, "CREATE DATABASE scada"); pg_query($dbconn, "CREATE DATABASE scada");
pg_close($dbconn); pg_close($dbconn);
$dbconn = pg_connect(sprintf("host=%s dbname=scada user=%s password=%s", $server_name, $user, $password)); $dbconn = pg_connect(sprintf("host=%s port=%s dbname=scada user=%s password=%s", $server_name, $port, $user, $password));
// 全局未启用TSDB的时候在这里对scada数据库启用就好 // 全局未启用TSDB的时候在这里对scada数据库启用就好
pg_query($dbconn, "CREATE EXTENSION IF NOT EXISTS timescaledb"); pg_query($dbconn, "CREATE EXTENSION IF NOT EXISTS timescaledb");
pg_query($dbconn, "CREATE TABLE IF NOT EXISTS hf_mes_scada_data_capture_node_configure ( pg_query($dbconn, "CREATE TABLE IF NOT EXISTS hf_mes_scada_data_capture_node_configure (
@@ -25,12 +25,25 @@ function init_db($server_name, $user, $password) {
id serial2 primary key, id serial2 primary key,
code text, code text,
name text NOT NULL, name text NOT NULL,
ip text NOT NULL, url text NOT NULL,
port int2 NOT NULL, port int2 NOT NULL,
sync_addr text NOT NULL, address text NOT NULL,
create_date timestamp NOT NULL DEFAULT NOW(), create_date timestamp NOT NULL DEFAULT NOW(),
note text note text
)"); )");
pg_query($dbconn, "CREATE TABLE IF NOT EXISTS hf_mes_scada_edgeserver_controller_device (
id serial2 primary key,
code text,
name text NOT NULL,
server_id serial2 references hf_mes_scada_edgeserver_controller_server(id),
conf json,
create_date timestamp NOT NULL DEFAULT NOW(),
note text,
status bool,
success_count int8,
failed_count int8,
duration int8
)");
pg_query($dbconn, "CREATE TABLE IF NOT EXISTS hf_mes_scada_edgeserver_controller_command ( pg_query($dbconn, "CREATE TABLE IF NOT EXISTS hf_mes_scada_edgeserver_controller_command (
id serial8 primary key, id serial8 primary key,
server_id serial2 references hf_mes_scada_edgeserver_controller_server(id), server_id serial2 references hf_mes_scada_edgeserver_controller_server(id),

View File

@@ -8,6 +8,7 @@
- [后端](#后端) - [后端](#后端)
- [前端](#前端) - [前端](#前端)
- [开发环境](#开发环境) - [开发环境](#开发环境)
- [调试环境](#调试环境)
- [技术细节](#技术细节) - [技术细节](#技术细节)
- [0. `EdgeManager\EDataCapture\EDataCapture -> set_data()`为什么是以`6710885`为大小chunked的](#0-edgemanageredatacaptureedatacapture---set_data为什么是以6710885为大小chunked的) - [0. `EdgeManager\EDataCapture\EDataCapture -> set_data()`为什么是以`6710885`为大小chunked的](#0-edgemanageredatacaptureedatacapture---set_data为什么是以6710885为大小chunked的)
@@ -257,6 +258,7 @@ cd EdgeManager
一键部署PHP workerman和TimescaleDB环境 一键部署PHP workerman和TimescaleDB环境
```bash ```bash
# docker build --network host -t edge_manager .
docker compose up -d docker compose up -d
``` ```
@@ -270,7 +272,7 @@ docker exec -it edge_manager bash
```bash ```bash
# In container # In container
php EdgeManager.php --server_name=GPU-server-01 --user=postgres --password=big_dick start php EdgeManager.php --no_dup_code --server_name=GPU-server-01 --user=postgres --password=big_dick start
``` ```
前端调试: 前端调试:
@@ -292,6 +294,29 @@ psql -h localhost -U postgres
\l \l
``` ```
## 调试环境
不使用`docker compose`创建两个container分别运行EdgeManager和pg
```bash
# cd EdgeManager # 先定位到项目目录方便创建image和挂载
# 创建EdgeManager的image
docker build --network host -t edge_manager .
# 创建container运行EdgeManager
docker run -d --name edge_manager_test -v $PWD:/EdgeManager --network host -it edge_manager
# 创建container运行pg将端口映射到host的55432
docker run -d --name pg_test -v $PWD/config/postgresql.conf:/etc/postgresql/postgresql.conf -p 55432:5432 -e POSTGRES_PASSWORD=big_dick -it timescale/timescaledb-ha:pg14-latest postgres -c 'config_file=/etc/postgresql/postgresql.conf'
# 进入交互式Prompt
docker exec -it edge_manager_test bash
# 启动EdgeManagerworkerman命令省略...
# 常用命令
# 查看全部container
docker ps -a
# 启动已停止的container
docker start [container]
```
## 技术细节 ## 技术细节
### 0. `EdgeManager\EDataCapture\EDataCapture -> set_data()`为什么是以`6710885`为大小chunked的 ### 0. `EdgeManager\EDataCapture\EDataCapture -> set_data()`为什么是以`6710885`为大小chunked的

View File

@@ -1,5 +1,5 @@
services: services:
scada: edge_manager:
build: build:
context: . context: .
container_name: edge_manager container_name: edge_manager

View File

@@ -0,0 +1,38 @@
import { handlePost } from '../tools'
export default ({ service, request, serviceForMock, requestForMock, mock, faker, tools }) => ({
/**
* @description 方法名称
* @param {Object} data 请求携带的信息
*/
VERIFY_SERVER (url, username, password) {
return request({
auth: {
username: username,
password: password
},
method: 'post',
url: url + '/Admin/ServerSettingsRequest'
})
},
MODIFY_SERVER (url, username, password, data) {
return request({
auth: {
username: username,
password: password
},
data: data,
method: 'post',
url: url + '/Admin/ServerSettingsModify'
})
},
ADD_SERVER: (data) => handlePost(request, data),
UPDATE_SERVER: (data) => handlePost(request, data),
REMOVE_SERVER: (data) => handlePost(request, data),
QUERY_SERVERS () {
return request({ url: '?query=servers' })
}
})

View File

@@ -1,8 +1,4 @@
const handlePost = (request, data) => (request({ import { handlePost } from '../tools'
url: '',
method: 'post',
data
}))
export default ({ service, request, serviceForMock, requestForMock, mock, faker, tools }) => ({ export default ({ service, request, serviceForMock, requestForMock, mock, faker, tools }) => ({
/** /**
@@ -14,7 +10,7 @@ export default ({ service, request, serviceForMock, requestForMock, mock, faker,
UPDATE_NODE: (data) => handlePost(request, data), UPDATE_NODE: (data) => handlePost(request, data),
REMOVE_NODE: (data) => handlePost(request, data), REMOVE_NODE: (data) => handlePost(request, data),
QUERY_NODE () { QUERY_NODES () {
return request({ url: '?query=nodes' }) return request({ url: '?query=nodes' })
}, },

View File

@@ -84,3 +84,9 @@ export function errorCreate (msg) {
errorLog(error) errorLog(error)
throw error throw error
} }
export const handlePost = (request, data) => (request({
url: '',
method: 'post',
data
}))

View File

@@ -23,5 +23,12 @@ export const menuAside = supplementPath([
{ path: '/scada_configure', title: 'SCADA节点配置' }, { path: '/scada_configure', title: 'SCADA节点配置' },
{ path: '/scada_query', title: 'SCADA数据查询' } { path: '/scada_query', title: 'SCADA数据查询' }
] ]
},
{
title: '采集服务管理',
children: [
{ path: '/edge_server_configure', title: '服务配置' },
{ path: '/edge_server_monitor', title: '服务监控' }
]
} }
]) ])

View File

@@ -39,6 +39,24 @@ const frameIn = [
}, },
component: _import('scada/scadaQuery') component: _import('scada/scadaQuery')
}, },
{
path: 'edge_server_configure',
name: 'edge_server_configure',
meta: {
title: '服务配置',
auth: true
},
component: _import('edgeServer/edgeServerConfigure')
},
{
path: 'edge_server_monitor',
name: 'edge_server_monitor',
meta: {
title: '服务监控',
auth: true
},
component: _import('edgeServer/edgeServerMonitor')
},
// 系统 前端日志 // 系统 前端日志
{ {
path: 'log', path: 'log',

View File

@@ -0,0 +1,283 @@
<template>
<d2-container>
<d2-crud
ref="d2Crud"
:columns="columns"
:data="data"
:rowHandle="rowHandle"
add-title="新增服务"
edit-title="修改服务配置"
:add-template="addTemplate"
:edit-template="editTemplate"
:form-options="formOptions"
:add-rules="addRules"
@row-add="handleRowAdd"
@row-edit="handleRowEdit"
@row-remove="handleRowRemove"
@dialog-cancel="handleDialogCancel">
<el-button slot="header" style="margin-bottom: 5px" @click="addRow">新增</el-button>
</d2-crud>
</d2-container>
</template>
<script>
import { assign, each } from 'lodash'
const genRanHex = size => [...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16).toUpperCase()).join('')
export default {
data () {
return {
columns: [
{
title: '序号',
key: 'id'
},
{
title: '名称',
key: 'name'
},
{
title: 'URL',
key: 'url'
},
{
title: '端口',
key: 'port'
},
{
title: '绑定地址',
key: 'address'
},
{
title: '创建时间',
key: 'create_date'
},
{
title: '备注',
key: 'note'
}
],
data: [],
serverSettings: {},
rowHandle: {
minWidth: '200',
edit: {
icon: 'el-icon-edit',
text: '编辑',
size: 'small',
show (index, row) {
if (row.showEditButton) {
return true
}
return false
}
},
remove: {
icon: 'el-icon-delete',
size: 'small',
fixed: 'right',
confirm: true,
show (index, row) {
if (row.showRemoveButton) {
return true
}
return false
}
}
},
addTemplate: {
deviceName: {
title: '服务名称',
value: 'Edge:' + genRanHex(12)
},
uniqueID: {
title: '唯一标识',
value: '',
component: {
disabled: true,
placeholder: '采集服务唯一标识,测试成功后返回'
}
},
url: {
title: 'URL',
value: '',
component: {
span: 12
}
},
port: {
title: '端口',
value: 522,
component: {
span: 12
}
},
userName: {
title: '用户名',
value: 'admin',
component: {
span: 12
}
},
password: {
title: '密码',
value: '123456',
component: {
span: 12,
'show-password': true
}
},
address: {
title: '绑定地址',
value: '',
component: {
placeholder: '请填入绑定EdgeManager实例的地址比如http://xxx.xxx:xxxx'
}
}
},
editTemplate: {
address: {
title: '绑定地址',
component: {
placeholder: '仅可以修改已绑定EdgeManager实例的地址'
}
}
},
formOptions: {
labelWidth: '80px',
labelPosition: 'left',
saveLoading: false,
saveButtonText: '测试',
saveButtonType: 'text'
},
addRules: {
deviceName: [{ required: true, type: 'string', message: '服务名称不可为空', trigger: 'blur' }],
url: [{ required: true, type: 'string', message: '服务地址不可为空', trigger: 'blur' }],
port: [{ required: true, type: 'integer', transform: v => +v, message: '端口号必须指定,且需为(0, 65535]内的正整数', trigger: 'blur' }],
userName: [{ required: true, message: '用户名不可为空', trigger: 'blur' }],
password: [{ required: true, type: 'string', message: '密码不可为空', trigger: 'blur' }],
address: [{ type: 'url', message: '绑定地址必须为合法URL', trigger: 'blur' }]
}
}
},
methods: {
async getServers () {
try {
const res = await this.$api.QUERY_SERVERS()
this.data = each(res, (o) => (
assign(o, {
showEditButton: true,
showRemoveButton: true
})
))
} catch (e) {
console.log(e)
}
},
// 普通的新增
addRow () {
this.$refs.d2Crud.showDialog({
mode: 'add'
})
},
async handleRowAdd (row, done) {
this.formOptions.saveLoading = true
try {
// 定义测试动作
if (this.formOptions.saveButtonText === '测试') {
this.serverSettings = await this.$api.VERIFY_SERVER('http://' + row.url + ':' + row.port, row.userName, row.password)
if (this.serverSettings) {
this.$message({
message: '测试通过!',
type: 'success'
})
}
this.formOptions.saveLoading = false
each(Object.keys(row), (p) => {
this.addTemplate[p].value = row[p]
})
this.addTemplate.uniqueID.value = this.serverSettings.Content.ServerInfoConfig.UniqueId
this.$refs.d2Crud.showDialog({
mode: 'add'
})
this.formOptions.saveButtonText = '添加'
this.formOptions.saveButtonType = 'success'
// 定义添加动作
} else {
this.serverSettings.Content.ServerInfoConfig.DeviceName = row.deviceName
this.serverSettings.Content.ServerInfoConfig.CaptureURL = row.address
console.log(this.serverSettings.Content.ServerInfoConfig)
await this.$api.MODIFY_SERVER(
'http://' + row.url + ':' + row.port,
row.userName,
row.password,
{ data: this.serverSettings.Content }
)
await this.$api.ADD_SERVER({
action: 'add_server',
name: row.deviceName,
url: row.url,
port: row.port,
address: row.address
})
this.$message({
message: '添加成功',
type: 'success'
})
this.getServers()
done()
}
} catch (e) {
this.$message({
message: '测试/添加失败!',
type: 'error'
})
console.log(e)
}
},
async handleRowEdit ({ index, row }, done) {
this.formOptions.saveLoading = true
this.serverSettings.Content.ServerInfoConfig.CaptureURL = row.address
await this.$api.MODIFY_SERVER(
'http://' + row.url + ':' + row.port,
row.userName,
row.password,
{ data: this.serverSettings.Content }
)
await this.$api.UPDATE_SERVER({
action: 'update_server',
id: row.id,
address: row.address
})
this.$message({
message: '编辑成功',
type: 'success'
})
done()
this.formOptions.saveLoading = false
},
async handleRowRemove ({ index, row }, done) {
await this.$api.REMOVE_SERVER({
action: 'remove_server',
id: row.id
})
this.$message({
message: '删除成功',
type: 'success'
})
done()
},
handleDialogCancel (done) {
this.$message({
message: '用户放弃改动',
type: 'warning'
})
done()
}
},
mounted () {
this.getServers()
}
}
</script>

View File

@@ -193,7 +193,7 @@ export default {
methods: { methods: {
async getNodes () { async getNodes () {
try { try {
const res = await this.$api.QUERY_NODE() const res = await this.$api.QUERY_NODES()
this.data = each(res, (o) => ( this.data = each(res, (o) => (
assign(o, { assign(o, {
showEditButton: true, showEditButton: true,