实现了服务的增删改查、设备增加

This commit is contained in:
Yu Sun
2022-08-12 13:55:31 +08:00
parent d4385e6471
commit 59f5a646c6
10 changed files with 547 additions and 11 deletions

View File

@@ -7,6 +7,7 @@ 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::', ['no_dup_code', 'server_name:', 'port::', 'user:', 'password:', 'help::']); $options = getopt('h::', ['no_dup_code', 'server_name:', 'port::', 'user:', 'password:', 'help::']);
@@ -109,6 +110,47 @@ $worker -> onMessage = function(TcpConnection $connection, Request $request) {
))); )));
} }
} }
} 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, no_dup_code: $options['no_dup_code'] ?? true, 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') {
@@ -176,7 +218,7 @@ $worker -> onMessage = function(TcpConnection $connection, Request $request) {
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(
@@ -227,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,
@@ -273,6 +328,26 @@ $consumer -> onMessage = function(TcpConnection $connection, $task_data) {
'msg' => '服务器内部逻辑错误,请联系开发者!' '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) {
$connection -> send(json_encode(array(
'code' => 1,
'msg' => '服务器内部逻辑错误,请联系开发者!'
)));
}
} }
}; };

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

@@ -25,12 +25,25 @@ function init_db($server_name, $port, $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

@@ -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,