Commit ce6c3731 authored by 高东东's avatar 高东东

*)添加plc功能和iec104功能

parent ea9578bf
*.iml
node_modules
......@@ -8,21 +8,21 @@
// 普通http
httpURI: {
// 根url
baseURI: 'http://172.16.10.98:9008/',
baseURI: '/baseURI/',
// test
prifix: '',
// plugin uri 前缀
pluginURI: 'http://172.16.11.30:8201/',
// pluginURI: 'http://172.16.11.30:8201/',
// 安全模块api地址
securityBaseURI: 'http://172.16.10.98:8800/'
securityBaseURI: '/baseURI/',
},
// websocket 地址
wsURI: {
baseURI: 'ws://172.16.10.99:10600/',
pluginURI: 'ws://172.16.10.99:10600/',
securityBaseURI: 'ws://172.16.10.99:10600/',
realTimeMetricDataURL: 'ws://172.16.10.99:10600/',
onlineTestWsURL: 'ws://172.16.10.99s:10600/'
baseURI: 'ws:/172.16.11.20:10600/',
pluginURI: 'ws://172.16.11.20:10600/',
securityBaseURI: 'ws://172.16.11.20:10600/',
realTimeMetricDataURL: 'ws://172.16.11.20:10600/',
onlineTestWsURL: 'ws://172.16.11.20:10600/'
},
// 外部链接地址
outterURI: {
......
......@@ -2,7 +2,7 @@ import * as endConf from 'amos-processor/lib/config/endconf';
// import completeSecurityUrl, { completeSecurityWsUrl } from 'amos-security/lib/consts/securityUrl';
const completePrefix = endConf.completePrefix;
const baseURI = endConf.baseURI;
let baseURI = endConf.baseURI;
const securityBaseURI = endConf.securityBaseURI;
const mockURI = 'http://172.16.10.161:8087/';
......@@ -37,16 +37,38 @@ export const secExtUrl = {
// 新权限接口
currentUserUrl: completePrefix(securityBaseURI, `${secExVerson}/user/me`), // 获取当前登陆用户信息
systemMenusUrl: completePrefix(securityBaseURI, `${secExVerson}/permission/tree/menu?code={code}&userId={userId}`), // 获取当前系统所有菜单
// currentUserUrl: completePrefix(securityBaseURI, `${secExVerson}/user/me`), // 获取当前登陆用户信息
currentUserUrl: completePrefix(securityBaseURI, `privilege/${secExVerson}/agencyuser/me`), // 获取当前登陆用户信息
// systemMenusUrl: completePrefix(securityBaseURI, `${secExVerson}/permission/tree/menu?code={code}&userId={userId}`), // 获取当前系统所有菜单
systemMenusUrl: completePrefix(securityBaseURI, `privilege/${secExVerson}/permission/tree/me`), // 获取当前系统所有菜单
// permissionsCompanyUrl: completePrefix(securityBaseURI, `${secExVerson}/user/me`), // 登陆用户权限所有公司
permissionsCompanyUrl: completePrefix(securityBaseURI, `privilege/${secExVerson}/agencyuser/me`), // 登陆用户权限所有公司
// permissionsMenusUrl: completePrefix(securityUrlWithVersion, '/permission/tree/{roleSeq}'), // 登陆用户系统权限菜单---TODO新版待修改
permissionsMenusUrl: completePrefix(securityBaseURI, `privilege/${secExVerson}/permission/tree/role?roleSeq={roleSeq}`), // 登陆用户系统权限菜单
loginUrl: completePrefix(securityBaseURI, `${secExVerson}/system/login`), // 登陆获取accessToken
permissionsCompanyUrl: completePrefix(securityBaseURI, `${secExVerson}/user/me`), // 登陆用户权限所有公司
permissionsMenusUrl: completePrefix(securityUrlWithVersion, '/permission/tree/{roleSeq}'), // 登陆用户系统权限菜单---TODO新版待修改
loginOutUrl: completePrefix(securityBaseURI, `${secExVerson}/system/loginOutr`), // 登陆用户系统权限菜单
regionSelectUrl: completePrefix(baseURI, 'safe/save/curCompany') // 登陆用户系统权限菜单
regionSelectUrl: completePrefix(baseURI, 'iot/iot/safe/save/curCompany') // 登陆用户系统权限菜单
};
const iecBaseURI = completePrefix(baseURI, 'iec/');
export const IecUrl = {
channelUrl: completePrefix(iecBaseURI, 'channel'),
deleteChannelUrl: completePrefix(iecBaseURI, 'channel/serviceId/{id}'),
channelListUrl: completePrefix(iecBaseURI, 'channel/{type}'),
channelPointUrl: completePrefix(iecBaseURI, 'point/{channel}'),
iecChannelPointUrl: completePrefix(iecBaseURI, 'point/iec?channelNo={channelNo}&pointType={pointType}'),
pointUrl: completePrefix(iecBaseURI, 'point'),
deletePointUrl: completePrefix(iecBaseURI, 'point?ids={ids}'),
iecDownloadIecTmplUrl: completePrefix(iecBaseURI, 'point/export/model'),
iecImportUrl: completePrefix(iecBaseURI, 'point/import?serviceId={serviceId}&pointType={pointType}'),
}
baseURI = baseURI + 'iot/';
export const OltSerUrl = {
//脚本语言类型
scriptLangType: completePrefix(baseURI, 'dic/script-type'),
......@@ -72,6 +94,7 @@ export const OltSerUrl = {
capacityIntfUpdate: completePrefix(baseURI, 'device/capacity-intf-update'),//新增/编辑能力接口
deleteCapacityInterface: completePrefix(baseURI, 'device/capacity-interface-eliminate'),//删除能力接口
capacityPropertyUpdate: completePrefix(baseURI, 'device/capacity-property-update'),//新增/编辑能力属性
capacityPropertyUrl: completePrefix(baseURI, 'device/capacity-property'),//能力属性
deleteCapacityProperty: completePrefix(baseURI, 'device/capacity-property-eliminate'),//删除能力属性
deviceBasicInfoUpdate: completePrefix(baseURI, 'device/device-basic-info-update'),//设备基本信息编辑
deleteDeviceById: completePrefix(baseURI, 'device/device-eliminate'),//删除设备信息
......@@ -140,7 +163,7 @@ export const OltSerUrl = {
editSubviewImg: completePrefix(baseURI, 'topo/subgraph-img'),//编辑子图背景图片
// fetchCompanyById: completePrefix(securityBaseURI, 'company/unique-company'),//获取公司信息
fetchCompanyById: completePrefix(securityBaseURI, '/v1/company'),//获取公司信息
fetchCompanyById: completePrefix(securityBaseURI, `privilege/${secExVerson}/company`),//获取公司信息
fetchTopoDevice: completePrefix(baseURI, 'device/topo-device'),//查询拓扑中设备所有配置信息
addeEditEqpImg: completePrefix(baseURI, 'device/eqipment-img'),//新增编辑设备图片
//*************************************
......
......@@ -18,6 +18,8 @@ import * as endConf from 'amos-processor/lib/config/endconf';
import rootRoutes from './../routes';
import configureStore from './../store';
import { getSystemAllMenu } from '../services/securityService';
import SysConsts from 'amos-processor/lib/config/consts';
// import { loginAuth } from 'amos-security/lib/model/auth';
......@@ -48,9 +50,8 @@ class App extends Component {
componentWillMount() {
let code = LocationParam.getLocationParamByName('code');
let userId = LocationParam.getLocationParamByName('userId');
if (!(code || userId)) {
let token = LocationParam.getLocationParamByName('token');
if (!token) {
let systemMenu = JSON.parse(lsTool.read('systemMenu'));
if (!systemMenu) {
window.location.href = loginURI;
......@@ -58,10 +59,10 @@ class App extends Component {
}
this.setState({ rootRoutes: rootRoutes(systemMenu), visible: true });
return;
}else{
lsTool.write(SysConsts.token, token);
}
getSystemAllMenu(code, userId).then(
getSystemAllMenu(token).then(
menus => {
let systemMuens = this.filterSystemMenus(menus);
let routeMenus = [];
......@@ -70,6 +71,7 @@ class App extends Component {
routeMenus = [...routeMenus, ...item.children];
}
});
let a = rootRoutes(routeMenus);
this.setState({ rootRoutes: rootRoutes(routeMenus), visible: true });
lsTool.write('systemMenu', JSON.stringify(routeMenus));
},
......
......@@ -18,6 +18,7 @@ import * as endConf from 'amos-processor/lib/config/endconf';
import rootRoutes from './../routes/asyncRoutes';
import configureStore from './../store';
import { getSystemAllMenu } from '../services/securityService';
import SysConsts from 'amos-processor/lib/config/consts';
// import { loginAuth } from 'amos-security/lib/model/auth';
......@@ -48,9 +49,8 @@ class App extends Component {
componentWillMount() {
let code = LocationParam.getLocationParamByName('code');
let userId = LocationParam.getLocationParamByName('userId');
if (!(code || userId)) {
let token = LocationParam.getLocationParamByName('token');
if (!token) {
let systemMenu = JSON.parse(lsTool.read('systemMenu'));
if (!systemMenu) {
window.location.href = loginURI;
......@@ -58,9 +58,11 @@ class App extends Component {
}
this.setState({ rootRoutes: rootRoutes(systemMenu), visible: true });
return;
}else{
lsTool.write(SysConsts.token, token);
}
getSystemAllMenu(code, userId).then(
getSystemAllMenu(token).then(
menus => {
let systemMuens = this.filterSystemMenus(menus);
let routeMenus = [];
......@@ -69,6 +71,7 @@ class App extends Component {
routeMenus = [...routeMenus, ...item.children];
}
});
let a = rootRoutes(routeMenus);
this.setState({ rootRoutes: rootRoutes(routeMenus), visible: true });
lsTool.write('systemMenu', JSON.stringify(routeMenus));
},
......
......@@ -33,6 +33,7 @@ const AsyncKunShan = (props) => <AsyncLoader load={import('./../view/topoManage/
const AsyncHistoricalData = (props) => <AsyncLoader load={import('./../view/historicalData')} componentProps={props} />;
const AsyncCreateEquipment = (props) => <AsyncLoader load={import('./../view/createEquipment')} componentProps={props} />;
const AsyncSectionStoreRoom = (props) => <AsyncLoader load={import('./../view/sectionStoreRoom')} componentProps={props} />;
const AsyncPLCManager = (props) => <AsyncLoader load={import('../view/plcManager')} componentProps={props} />;
const Routes = {
// ...parsePlugin(),
......@@ -60,7 +61,8 @@ const Routes = {
ruledesign: AsyncRuleDesign,
overview: AsyncOverview,
createEquipment: AsyncCreateEquipment,
sectionStoreRoom: AsyncSectionStoreRoom
sectionStoreRoom: AsyncSectionStoreRoom,
plcManager: AsyncPLCManager
};
const pageCompontent = (key) => {
......
......@@ -33,6 +33,9 @@ import Overview from './../view/zonglan/home';
import EmptyPage from './../view/common/page/EmptyPage';
import CreateEquipment from './../view/createEquipment';
import SectionStoreRoom from './../view/sectionStoreRoom';
import PLCManager from './../view/plcManager';
import IECClient from './../view/iec/client';
import IECServer from './../view/iec/server';
const Routes = {
// ...parsePlugin(),
......@@ -61,7 +64,10 @@ const Routes = {
ruledesign: RuleDesign,
overview: Overview,
createEquipment: CreateEquipment,
sectionStoreRoom: SectionStoreRoom
sectionStoreRoom: SectionStoreRoom,
plcManager: PLCManager,
iec104client: IECClient,
iec104server: IECServer
};
const pageCompontent = (key) => {
......
import formatUrl from 'amos-processor/lib/utils/urlFormat';
import Url from 'CONSTS/urlConsts';
import { IecUrl } from 'CONSTS/urlConsts';
import { commonGet, commonPost, commonDelete, commonPut } from 'UTILS/request';
/**
......@@ -115,3 +116,54 @@ export const fetchTopoDeviceAction = (id) => {
const url = `${Url.fetchTopoDevice}/${id}`;
return commonGet(url);
};
export const getChannelByType = (type) => {
const url = formatUrl(IecUrl.channelListUrl, { type } );
return commonGet(url);
};
export const createChannel = (param) => {
return commonPost(IecUrl.channelUrl, param);
};
export const deleteChannel = (id) => {
const url = formatUrl(IecUrl.deleteChannelUrl, { id } );
return commonDelete(url);
};
export const getChannelPoint = (channel) => {
const url = formatUrl(IecUrl.channelPointUrl, { channel } );
return commonGet(url);
};
export const deleteChannelPoint = (channel) => {
const url = formatUrl(IecUrl.channelPointUrl, { channel } );
return commonDelete(url);
};
export const addPoint = (param) => {
return commonPost(IecUrl.pointUrl, param);
};
export const deletePoint = (ids) => {
const url = formatUrl(IecUrl.deletePointUrl, { ids } );
return commonDelete(url);
};
export const getIecChannelPoint = (channelNo, pointType) => {
const url = formatUrl(IecUrl.iecChannelPointUrl, { channelNo , pointType} );
return commonGet(url);
};
export const deleteIecChannelPoint = (channelNo, pointType) => {
const url = formatUrl(IecUrl.iecChannelPointUrl, { channelNo, pointType } );
return commonDelete(url);
};
export const downloadIecTmpl = () => {
let a = document.createElement('a')
a.href = IecUrl.iecDownloadIecTmplUrl;
a.click();
};
\ No newline at end of file
......@@ -48,3 +48,34 @@
}
}
}
.device-data-items {
.plc-title {
height: 40px;
}
.plc-divider {
margin: 1px 0 !important;
}
.ant-tabs-nav {
margin-left: 0px;
}
.con-eva-key {
float: left;
height: 36px;
padding: 10.5px 0;
font-size: 15px;
margin-left: 20px;
}
.con-eva-value {
height: 36px;
padding: 11.5px 0;
font-size: 13px;
padding-left: 7px;
}
}
.risk-model-button {
display: block;
margin-left: 0 !important;
}
\ No newline at end of file
export default function(data){
return new Promise((resolve, reject) => {
if (data && data.result === 'SUCCESS') {
if (data) {
if (data.dataList || data.dataList === null){
resolve(data.dataList);
} else {
} else if (data.result || data.result === null){
if(data.content){
resolve(data);
}else{
resolve(data.result);
}
} else {
if (data) {
reject(data.message);
} else {
}else if (data == 'TypeError: Failed to fetch'){
reject(data);
}else{
resolve(data);
}
} else {
reject(data);
}
});
}
import * as _fetch from 'amos-processor/lib/fetch';
// import * as _fetch from 'amos-processor/lib/fetch';
import { AmosFetch as oaf, XssAmosFetch as oxaf } from 'amos-processor';
import * as utils from 'amos-processor/lib/utils';
import AmosEnum from 'amos-processor/lib/enum/AmosEnum';
import * as permission from 'amos-processor/lib/config/permission';
import { utils as toolUtils, Store } from 'amos-tool';
import sysConsts from 'amos-processor/lib/config';
const lsTool = Store.lsTool;
const defaultHeaders = {
appKey: 'AMOS_IOT',
product: 'AMOS_IOT_WEB'
};
export default{
..._fetch,
// ..._fetch,
...utils,
AmosEnum,
...permission
};
export function getToken(){
return lsTool.read(sysConsts.token);
}
export const AmosFetch = {
_fetch(type) {
return (url, params, data) => {
if (!oaf[type]) {
throw new Error(`AmosFetch: ´íÎóµÄÇëÇó[${type}]`);
}
const newParams = toolUtils.merge(
{
headers: {
...defaultHeaders,
token: getToken()
},
// ÆôÓà cookie£¬ `include, same-origin, *omit`
// credentials: 'include'
},
params
);
return oaf[type](url, { params: newParams, data });
};
},
get(url, { params, data } = {}) {
return AmosFetch._fetch('get')(url, params, data);
},
put(url, { params, data } = {}) {
return AmosFetch._fetch('put')(url, params, data);
},
post(url, { params, data } = {}) {
return AmosFetch._fetch('post')(url, params, data);
},
del(url, { params, data } = {}) {
return AmosFetch._fetch('del')(url, params, data);
}
};
......@@ -6,13 +6,33 @@ import payload from './payload';
const lsTool = Store.lsTool;
const defaultHeaders = {
appKey: 'AMOS_IOT',
product: 'AMOS_IOT_WEB'
};
export const compleHeaders = () => {
return {
...defaultHeaders,
token: getToken()
};
};
export function commonGet(url) {
return amosRequest(url, { method: 'GET' }).then(data => payload(data));
return amosRequest(url, {
method: 'GET',
headers: compleHeaders(),
reject(error){
console.log('请求失败,服务器错误!');
message.danger(error.message || '请求失败,服务器错误!');
}
}).then(data => payload(data));
}
export function commonPost(url, data, params) {
return amosRequest(url, {
headers: compleHeaders(),
method: 'POST',
body: data,
reject(error){
......@@ -24,6 +44,7 @@ export function commonPost(url, data, params) {
export function commonPut(url, data, params) {
return amosRequest(url, {
headers: compleHeaders(),
method: 'PUT',
body: data,
reject(error){
......@@ -35,6 +56,7 @@ export function commonPut(url, data, params) {
export function commonDelete(url, data, params) {
return amosRequest(url, {
headers: compleHeaders(),
method: 'DELETE',
body: data,
reject(error){
......
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Form,Input,Button,Radio,Modal } from 'amos-antd';
import { AmosFetch,formatUrl } from 'UTILS/processor';
import { AmosFetch } from 'UTILS/processor';
import formatUrl from 'amos-processor/lib/utils/urlFormat';
import { dateToStr } from 'UTILS/DateUtil';
import OltSerUrl from 'CONSTS/urlConsts';
import { message } from 'amos-framework';
......
......@@ -159,7 +159,7 @@ class QueryPanel extends Component {
renderTreeNodes = (data) => {
return data.map((item) => {
return data && data.map((item) => {
if (item.children) {
return (
<TreeNode title={item.companyName} key={item.orgCode} value={item.sequenceNbr} dataRef={item}>
......
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Button, Upload, message, Icon } from 'amos-framework';
import { IecUrl } from 'CONSTS/urlConsts';
import { compleHeaders } from 'UTILS/request';
import formatUrl from 'amos-processor/lib/utils/urlFormat';
/**
* 工具栏
*
* @class ToolBar
* @extends {Component}
*/
class ToolBar extends Component {
constructor(props){
super(props);
this.state = {};
}
componentWillMount(){
}
onClick =(e,value)=>{
let { onButtonClick } = this.props;
onButtonClick(value);
}
render() {
const props = {
name: 'file',
action: formatUrl(IecUrl.iecImportUrl, { serviceId: this.props.serviceId, pointType: this.props.pointType }),
showUploadList: false,
headers: compleHeaders(),
onChange(info) {
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (info.file.status === 'done') {
message.success(`${info.file.name} 上传成功`);
this.props.reload();
} else if (info.file.status === 'error') {
message.danger(`${info.file.name} 上传失败`);
}
}
}
return (
<div className='risk-lever-toolbar'>
<div className='risk-lever-button' >
<Button title='添加' icon={<Icon icon="add-noborder" />} transparent onClick={e => this.onClick(e,'point-1')} />
<Button title='删除' icon={<Icon icon="delete" />} transparent onClick={e => this.onClick(e, 'point-2')} />
<Button title='编辑' icon={<Icon icon="edit" />} transparent onClick={e => this.onClick(e,'point-3')} />
<Upload {...props}><Button title='导入' icon={<Icon icon="upload" />} transparent /></Upload>
<Button title='清空' icon={<Icon icon="hdd" />} transparent onClick={e => this.onClick(e,'point-5')} />
<Button title='下载模板' icon={<Icon icon="download" />} transparent onClick={e => this.onClick(e,'point-6')} />
</div>
</div>
);
}
}
ToolBar.propTypes = {
onButtonClick: PropTypes.func,
pointType: PropTypes.string,
serviceId: PropTypes.string,
reload: PropTypes.func
};
export default ToolBar;
\ No newline at end of file
import React, { Component } from 'react';
import { Tabs, Table } from 'amos-antd';
import { Modal, AmosAlert, Form, Input, Button, Select, Tree, SplitPane, Icon, Divider, message } from 'amos-framework';
import ToolBar from './ToolBar';
import {
getChannelByType,
createChannel,
deleteChannel,
getIecChannelPoint,
addPoint,
deletePoint,
downloadIecTmpl,
deleteIecChannelPoint } from '../../../services/deviceService';
const FormItem = Form.Item;
const TabPane = Tabs.TabPane;
const TreeNode = Tree.TreeNode;
const { TabList, Tab, TabPanel } = Tabs;
const Option = Select.Option;
const tableColumns = [
{
title: '名称',
dataIndex: 'name',
key: 'name'
},
{
title: '编码',
dataIndex: 'pointCode',
key: 'pointCode'
},
{
title: '地址',
dataIndex: 'originatorAddress',
key: 'originatorAddress'
},
{
title: '值',
dataIndex: 'value',
key: 'value'
}
];
class IEC104ClientManager extends Component {
constructor(props){
super(props);
this.pageConfig = {
pageNumber: 0,
pageSize: 10
};
this.state = {
yxDataSource: [],
yCDataSource: [],
selectedKeys: [],
channels: [],
form: {},
modal: false,
rules: {
name: [
{ required: true, message: '请输入通道名称' },
],
commonAddress: [
{ required: true, message: '请输入公共地址' },
],
ip: [
{ required: true, message: '请输入IP地址' },
],
port: [
{ required: true, message: '请输入端口' },
]
}
};
}
componentDidMount(){
document.addEventListener('click', this._handleClick);//页面增加鼠标单击监听
window.addEventListener('resize', this._resize);
this.setOncontextmenu();//移除浏览器自带右键菜单
this.queryPLCChannelList();
}
setOncontextmenu =()=>{
document.oncontextmenu = (e) =>{
return false;
};
}
componentWillReceiveProps(nextProps) {
}
ccomponentWillUnmount() {
let channelDiv = document.getElementsByClassName('channel')[0];
let riskModelTabDiv = document.getElementsByClassName('device-data-items')[0];
channelDiv && channelDiv.removeEventListener('click', this._handleClick);//页面移除鼠标单击监听
riskModelTabDiv && riskModelTabDiv.removeEventListener('click', this._handleClick);//页面移除鼠标单击监听
window.addEventListener('resize', this._resize);
}
_resize =()=>{
this.onscroll();
}
onscroll =(e)=>{
const { rightClickNodeTreeItem } = this.state;
rightClickNodeTreeItem ? this.setState({ rightClickNodeTreeItem: null }) : '';
}
queryRiskSourceTree =(riskSourceId)=>{
}
onSelect =(selectedKeys,e)=>{
}
queryPLCChannelList = () => {
getChannelByType("IEC_CLIENT").then(
data => {
this.setState({ channels: data });
}
);
}
refeshPLCDetail = (id) =>{
}
questItemsData = (channelNo, pointType) => {
console.log(channelNo);
if (!channelNo) {
this.setState({ yxDataSource: [] });
this.setState({ ycDataSource: [] });
return;
}
getIecChannelPoint(channelNo, pointType).then(
data => {
if (pointType === 'yx') {
this.setState({ yxDataSource: data });
} else if (pointType === 'yc') {
this.setState({ ycDataSource: data });
}
}
);
};
queryPLCListData = (searchParam, pageNumber, pageSize) => {
}
onClick = (e,key)=>{
}
onToolBarClick = (toolBarFlag) => {
if (toolBarFlag === 'point-1'){
const selectedNode = this.state.selectedNode;
if (!selectedNode) {
message.danger("请选择通道");
return;
}
this.setState({modal: true, toolBarFlag });
} else if (toolBarFlag === 'point-3'){
const { selectedRows } = this.state
if (selectedRows.length > 1) {
message.danger("行数大于1,请重新选择");
return;
}
if (selectedRows.length < 1) {
message.danger("请重新选择数据项");
return;
}
this.setState({modal: true, toolBarFlag, form: selectedRows[0] });
} else if (toolBarFlag === 'point-2'){
const { selectedRowKeys } = this.state
this.deletePoints(selectedRowKeys);
} else if (toolBarFlag === 'point-5') {
const {selectedNode, pointType} = this.state;
deleteIecChannelPoint(selectedNode, pointType).then(
data => {
message.success('操作成功');
this.questItemsData(selectedNode, pointType);
}
);
} else if (toolBarFlag === 'point-6') {
downloadIecTmpl();
}
}
deletePoints = (selectedRowKeys) => {
const {selectedNode, pointType} = this.state;
deletePoint(selectedRowKeys).then(
data => {
message.success('操作成功');
this.questItemsData(selectedNode, pointType);
}
);
}
onSelectTreeNode = (selectedKeys, { selectedNodes }) =>{
console.log(selectedNodes);
this.setState({selectedNode: selectedNodes[0].props.channelNo, selectedKeys, pointType: 'yx'});
this.questItemsData(selectedNodes[0].props.channelNo, 'yx');
}
reload = () => {
const { selectedNode , pointType } = this.state;
this.questItemsData(selectedNode, pointType);
}
getToolBar = (pointType) => {
const { selectedNode } = this.state;
return <ToolBar reload={this.reload} onButtonClick={this.onToolBarClick} pointType={pointType} serviceId={selectedNode} />;
}
readerTreeNode = () => {
const { channels } = this.state;
return (
<TreeNode icon={<Icon icon="folder" />} title="客户端通道" key="0-0">
{channels.map( item=> <TreeNode icon={<Icon icon="file-leaf" />} channel={item} channelNo={item.channelNo} title={item.name} key={item.id} />)}
</TreeNode>
);
}
onRightClick = ({event, node}) => {
this.setState({
rightClickNodeTreeItem: {
pageX: event.pageX,
pageY: event.pageY
}, selectedNode: node.props.channelNo, channel: node.props.channel });
}
_handleClick = (event) => {
this.setState({ rightClickNodeTreeItem: null });
}
//树按钮点击事件
onButtonClick = (value) => {
let channelNo = this.state.selectedNode;
const channel = this.state.channel;
if (value === '1') {
this.setState({ modal: true,toolBarFlag: value , form: {} });
} else if (value === '2') {
this.setState({ modal: true,toolBarFlag: value, form: channel });
} else if (value === '3'){
this.channelDelete(channelNo);
}
this.setState({ rightClickNodeTreeItem: null });
}
channelDelete = (channelNo) => {
deleteChannel(channelNo).then(
data => {
message.success('删除成功');
this.queryPLCChannelList();
}
);
}
getModalHeader =(toolBarFlag)=>{
let header = '';
if (toolBarFlag === '2') {
header = '编辑通道';
} else if (toolBarFlag === '2'){
header = '添加通道';
} else if (toolBarFlag === 'point-1'){
header = '新增数据项';
} else if (toolBarFlag === 'point-3'){
header = '编辑数据项';
}
return header;
}
getNodeTreeRightClickMenu = () => {
let { pageX, pageY } = { ...this.state.rightClickNodeTreeItem };
let channelNo = this.state.selectedNode;
const height = document.body.offsetHeight;
let overHeight = height - (pageY + 120);
overHeight > 0 ? '' : pageY = height - 120;
const tmpStyle = {
position: 'absolute',
left: `${pageX}px`,
top: `${pageY - 45}px`,
backgroundColor: '#ffffff',
border: 'solid',
height: '70px',
borderWidth: '1px',
borderColor: '#c9c9c9'
};
const menu = (
<div style={tmpStyle}>
{!channelNo ? <Button onClick={()=>this.onButtonClick('1')} className='risk-model-button' transparent>添加</Button>:
<Button onClick={()=>this.onButtonClick('2')} className='risk-model-button' transparent>编辑</Button>}
{channelNo ? <Button onClick={()=>this.onButtonClick('3')} className='risk-model-button' transparent>删除</Button>:''}
</div>
);
return this.state.rightClickNodeTreeItem ? menu : '';
};
onOk = () =>{
let form = this.state.form;
const { toolBarFlag } = this.state;
if (toolBarFlag === '1' || toolBarFlag === '2') {
form.serviceType = "IEC_CLIENT";
createChannel(form).then(
data => {
if (data) {
message.danger(data);
return;
}
message.success('操作成功');
this.setState({modal: false});
this.queryPLCChannelList();
}
);
} else if (toolBarFlag === 'point-1' || toolBarFlag === 'point-3') {
const selectedNode = this.state.selectedNode;
const { pointType } = this.state;
form.channelNo = selectedNode;
form.pointType = pointType;
addPoint(form).then(
data => {
message.success('操作成功');
this.setState({modal: false});
this.questItemsData(selectedNode, pointType);
}
);
}
}
cancel = () => {
this.setState({ modal: false });
};
getModalFooter = () => {
return [<Button className='amos-btn-minor' key='cancel' onClick={this.cancel}>取消</Button>, <Button key='ok' onClick={() => this.onOk()}>确定</Button>];
}
onChange = (key, e) => {
const value = e.target.value;
const newForm = Object.assign({}, this.state.form, { [key]: value });
this.setState({
form: newForm
});
}
getContext = (toolBarFlag) => {
let form = this.state.form;
const rules = this.state.rules;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 8 },
className: 'colspanlab'
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
className: 'colspan'
}
};
if (toolBarFlag === '1' || toolBarFlag === '2') {
return (
<Form style={{ width: 300, padding: '30px 0 0 0' }} className="basic-demo" ref={component => this.form = component} model={form} rules={rules}>
<FormItem label={<span>通道名称</span>} field="name" {...formItemLayout} >
<Input
value={form.name}
placeholder="请输入通道名称"
onChange={(e) => this.onChange('name', e)}
/>
</FormItem>
<FormItem label={<span>对端地址</span>} field="ip" {...formItemLayout} >
<Input
value={form.ip}
placeholder="请输入对端地址"
onChange={(e) => this.onChange('ip', e)}
/>
</FormItem>
<FormItem label={<span>本地端口</span>} field="port" {...formItemLayout} >
<Input
value={form.port}
placeholder="请输入端口号"
onChange={(e) => this.onChange('port', e)}
/>
</FormItem>
<FormItem label="公共地址" field="commonAddress" {...formItemLayout} >
<Input
value={form.commonAddress}
placeholder="请输入公共地址"
onChange={(e) => this.onChange('commonAddress', e)}
/>
</FormItem>
</Form>
);
} else if (toolBarFlag === 'point-1' || toolBarFlag === 'point-3') {
return (
<Form style={{ width: 300, padding: '30px 0 0 0' }} className="basic-demo" ref={component => this.form = component} model={form} rules={rules}>
<FormItem label={<span>数据项名称</span>} field="name" {...formItemLayout} >
<Input
value={form.name}
placeholder="请输入通道名称"
onChange={(e) => this.onChange('name', e)}
/>
</FormItem>
<FormItem label={<span>数据项编码</span>} field="pointCode" {...formItemLayout} >
<Input
value={form.pointCode}
placeholder="请输入数据项编码"
onChange={(e) => this.onChange('pointCode', e)}
/>
</FormItem>
<FormItem label={<span>信息地址</span>} field="originatorAddress" {...formItemLayout} >
<Input
value={form.originatorAddress}
placeholder="请输入信息地址"
onChange={(e) => this.onChange('originatorAddress', e)}
/>
</FormItem>
{/* <FormItem label="点位类型" field="pointType" {...formItemLayout} >
<Select value={form.pointType} onChange={this.onPointTypeChange}>
<Option value="yx">遥信</Option>
<Option value="yc">遥测</Option>
</Select>
</FormItem> */}
</Form>
);
}
return "";
}
onPointTypeChange = (value, item) => {
const newForm = Object.assign({}, this.state.form, { pointType: value });
this.setState({
form: newForm
});
}
onSelectChange = (selectedRowKeys,selectedRows) => {
this.setState({selectedRowKeys,selectedRows});
}
handleChange = (key) => {
this.setState({pointType: key});
const {selectedNode} = this.state;
this.questItemsData(selectedNode, key);
}
render() {
let {
selectedKeys,
selectedNode,
toolBarFlag,
selectedRowKeys,
pointType,
modal
} = this.state;
let rowSelection = {
selectedRowKeys: selectedRowKeys,
onChange: this.onSelectChange
};
return (
<div>
<SplitPane percentage={true} mainPaneMinSize={15} secondaryMinSize={85}>
<div className="channel" >
<Tree
showIcon
defaultExpandAll
selectedKeys={selectedKeys}
onSelect={this.onSelectTreeNode}
onRightClick={this.onRightClick}
defaultSelectedKeys={['0-0-0']}>
{this.readerTreeNode()}
</Tree>
</div>
<div className="device-data-items" >
<div className="plc-title">
<div className="con-eva-key">编号: </div>
<div className="con-eva-value">{selectedNode}</div>
</div>
<Divider className="plc-divider" />
<div className="plc-body">
<Tabs
className="quyu-info-tab"
// type="card"
activeKey={pointType}
defaultActiveKey={pointType}
onChange={this.handleChange}
tabBarExtraContent={this.getToolBar(pointType)}
>
<TabPane tab={<span>遥信转发表</span>} key="yx">
<Table
columns={tableColumns}
rowKey={record => record.id}
rowSelection={rowSelection}
bordered
dataSource={this.state.yxDataSource} >
</Table>
</TabPane>
<TabPane tab={<span>遥测转发表</span>} key="yc">
<Table
columns={tableColumns}
rowKey={record => record.id}
rowSelection={rowSelection}
bordered
dataSource={this.state.ycDataSource} >
</Table>
</TabPane>
</Tabs>
</div>
</div>
</SplitPane>
<Modal
header={this.getModalHeader(toolBarFlag)}
visible={modal}
className="risk-model-model"
destroyContent
width={'30%'}
content={this.getContext(toolBarFlag)}
onCancel={() => this.cancel()}
onOk={() => this.onOk()}
footer={this.getModalFooter()}
outterClosable={false}
/>
{this.getNodeTreeRightClickMenu()}
</div>
);
}
}
IEC104ClientManager.propTypes = {
};
export default IEC104ClientManager;
\ No newline at end of file
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Button, Upload, message, Icon } from 'amos-framework';
import { IecUrl } from 'CONSTS/urlConsts';
import { compleHeaders } from 'UTILS/request';
import formatUrl from 'amos-processor/lib/utils/urlFormat';
/**
* 工具栏
*
* @class ToolBar
* @extends {Component}
*/
class ToolBar extends Component {
constructor(props){
super(props);
this.state = {};
}
componentWillMount(){
}
onClick =(e,value)=>{
let { onButtonClick } = this.props;
onButtonClick(value);
}
render() {
const props = {
name: 'file',
action: formatUrl(IecUrl.iecImportUrl, { serviceId: this.props.serviceId, pointType: this.props.pointType }),
showUploadList: false,
headers: compleHeaders(),
onChange(info) {
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (info.file.status === 'done') {
message.success(`${info.file.name} 上传成功`);
this.props.reload();
} else if (info.file.status === 'error') {
message.danger(`${info.file.name} 上传失败`);
}
}
}
return (
<div className='risk-lever-toolbar'>
<div className='risk-lever-button' >
<Button title='添加' icon={<Icon icon="add-noborder" />} transparent onClick={e => this.onClick(e,'point-1')} />
<Button title='删除' icon={<Icon icon="delete" />} transparent onClick={e => this.onClick(e, 'point-2')} />
<Button title='编辑' icon={<Icon icon="edit" />} transparent onClick={e => this.onClick(e,'point-3')} />
<Upload {...props}><Button title='导入' icon={<Icon icon="upload" />} transparent /></Upload>
<Button title='清空' icon={<Icon icon="hdd" />} transparent onClick={e => this.onClick(e,'point-5')} />
<Button title='下载模板' icon={<Icon icon="download" />} transparent onClick={e => this.onClick(e,'point-6')} />
</div>
</div>
);
}
}
ToolBar.propTypes = {
onButtonClick: PropTypes.func,
pointType: PropTypes.string,
serviceId: PropTypes.string,
reload: PropTypes.func
};
export default ToolBar;
\ No newline at end of file
import React, { Component } from 'react';
import { Tabs, Table } from 'amos-antd';
import { Modal, AmosAlert, Form, Input, Button, Select, Tree, SplitPane, Icon, Divider, message } from 'amos-framework';
import ToolBar from './ToolBar';
import {
getChannelByType,
createChannel,
deleteChannel,
getIecChannelPoint,
addPoint,
deletePoint,
downloadIecTmpl,
deleteIecChannelPoint } from '../../../services/deviceService';
const FormItem = Form.Item;
const TabPane = Tabs.TabPane;
const TreeNode = Tree.TreeNode;
const { TabList, Tab, TabPanel } = Tabs;
const Option = Select.Option;
const tableColumns = [
{
title: '名称',
dataIndex: 'name',
key: 'name'
},
{
title: '编码',
dataIndex: 'pointCode',
key: 'pointCode'
},
{
title: '地址',
dataIndex: 'originatorAddress',
key: 'originatorAddress'
},
{
title: '值',
dataIndex: 'value',
key: 'value'
}
];
class IEC104ClientManager extends Component {
constructor(props){
super(props);
this.pageConfig = {
pageNumber: 0,
pageSize: 10
};
this.state = {
yxDataSource: [],
yCDataSource: [],
selectedKeys: [],
channels: [],
form: {},
modal: false,
rules: {
name: [
{ required: true, message: '请输入通道名称' },
],
commonAddress: [
{ required: true, message: '请输入公共地址' },
],
ip: [
{ required: true, message: '请输入IP地址' },
],
port: [
{ required: true, message: '请输入端口' },
]
}
};
}
componentDidMount(){
document.addEventListener('click', this._handleClick);//页面增加鼠标单击监听
window.addEventListener('resize', this._resize);
this.setOncontextmenu();//移除浏览器自带右键菜单
this.queryPLCChannelList();
}
setOncontextmenu =()=>{
document.oncontextmenu = (e) =>{
return false;
};
}
componentWillReceiveProps(nextProps) {
}
ccomponentWillUnmount() {
let channelDiv = document.getElementsByClassName('channel')[0];
let riskModelTabDiv = document.getElementsByClassName('device-data-items')[0];
channelDiv && channelDiv.removeEventListener('click', this._handleClick);//页面移除鼠标单击监听
riskModelTabDiv && riskModelTabDiv.removeEventListener('click', this._handleClick);//页面移除鼠标单击监听
window.addEventListener('resize', this._resize);
}
_resize =()=>{
this.onscroll();
}
onscroll =(e)=>{
const { rightClickNodeTreeItem } = this.state;
rightClickNodeTreeItem ? this.setState({ rightClickNodeTreeItem: null }) : '';
}
queryRiskSourceTree =(riskSourceId)=>{
}
onSelect =(selectedKeys,e)=>{
}
queryPLCChannelList = () => {
getChannelByType("IEC_SERVER").then(
data => {
this.setState({ channels: data });
}
);
}
refeshPLCDetail = (id) =>{
}
questItemsData = (channelNo, pointType) => {
console.log(channelNo);
if (!channelNo) {
this.setState({ yxDataSource: [] });
this.setState({ ycDataSource: [] });
return;
}
getIecChannelPoint(channelNo, pointType).then(
data => {
if (pointType === 'yx') {
this.setState({ yxDataSource: data });
} else if (pointType === 'yc') {
this.setState({ ycDataSource: data });
}
}
);
};
queryPLCListData = (searchParam, pageNumber, pageSize) => {
}
onClick = (e,key)=>{
}
onToolBarClick = (toolBarFlag) => {
if (toolBarFlag === 'point-1'){
const selectedNode = this.state.selectedNode;
if (!selectedNode) {
message.danger("请选择通道");
return;
}
this.setState({modal: true, toolBarFlag });
} else if (toolBarFlag === 'point-3'){
const { selectedRows } = this.state
if (selectedRows.length > 1) {
message.danger("行数大于1,请重新选择");
return;
}
if (selectedRows.length < 1) {
message.danger("请重新选择数据项");
return;
}
this.setState({modal: true, toolBarFlag, form: selectedRows[0] });
} else if (toolBarFlag === 'point-2'){
const { selectedRowKeys } = this.state
this.deletePoints(selectedRowKeys);
} else if (toolBarFlag === 'point-5') {
const {selectedNode, pointType} = this.state;
deleteIecChannelPoint(selectedNode, pointType).then(
data => {
message.success('操作成功');
this.questItemsData(selectedNode, pointType);
}
);
} else if (toolBarFlag === 'point-6') {
downloadIecTmpl();
}
}
deletePoints = (selectedRowKeys) => {
const {selectedNode, pointType} = this.state;
deletePoint(selectedRowKeys).then(
data => {
message.success('操作成功');
this.questItemsData(selectedNode, pointType);
}
);
}
onSelectTreeNode = (selectedKeys, { selectedNodes }) =>{
console.log(selectedNodes);
this.setState({selectedNode: selectedNodes[0].props.channelNo, selectedKeys, pointType: 'yx'});
this.questItemsData(selectedNodes[0].props.channelNo, 'yx');
}
reload = () => {
const { selectedNode , pointType } = this.state;
this.questItemsData(selectedNode, pointType);
}
getToolBar = (pointType) => {
const { selectedNode } = this.state;
return <ToolBar reload={this.reload} onButtonClick={this.onToolBarClick} pointType={pointType} serviceId={selectedNode} />;
}
readerTreeNode = () => {
const { channels } = this.state;
return (
<TreeNode icon={<Icon icon="folder" />} title="客户端通道" key="0-0">
{channels.map( item=> <TreeNode icon={<Icon icon="file-leaf" />} channel={item} channelNo={item.channelNo} title={item.name} key={item.id} />)}
</TreeNode>
);
}
onRightClick = ({event, node}) => {
this.setState({
rightClickNodeTreeItem: {
pageX: event.pageX,
pageY: event.pageY
}, selectedNode: node.props.channelNo, channel: node.props.channel });
}
_handleClick = (event) => {
this.setState({ rightClickNodeTreeItem: null });
}
//树按钮点击事件
onButtonClick = (value) => {
let channelNo = this.state.selectedNode;
const channel = this.state.channel;
if (value === '1') {
this.setState({ modal: true,toolBarFlag: value , form: {} });
} else if (value === '2') {
this.setState({ modal: true,toolBarFlag: value, form: channel });
} else if (value === '3'){
this.channelDelete(channelNo);
}
this.setState({ rightClickNodeTreeItem: null });
}
channelDelete = (channelNo) => {
deleteChannel(channelNo).then(
data => {
message.success('删除成功');
this.queryPLCChannelList();
}
);
}
getModalHeader =(toolBarFlag)=>{
let header = '';
if (toolBarFlag === '2') {
header = '编辑通道';
} else if (toolBarFlag === '2'){
header = '添加通道';
} else if (toolBarFlag === 'point-1'){
header = '新增数据项';
} else if (toolBarFlag === 'point-3'){
header = '编辑数据项';
}
return header;
}
getNodeTreeRightClickMenu = () => {
let { pageX, pageY } = { ...this.state.rightClickNodeTreeItem };
let channelNo = this.state.selectedNode;
const height = document.body.offsetHeight;
let overHeight = height - (pageY + 120);
overHeight > 0 ? '' : pageY = height - 120;
const tmpStyle = {
position: 'absolute',
left: `${pageX}px`,
top: `${pageY - 45}px`,
backgroundColor: '#ffffff',
border: 'solid',
height: '70px',
borderWidth: '1px',
borderColor: '#c9c9c9'
};
const menu = (
<div style={tmpStyle}>
{!channelNo ? <Button onClick={()=>this.onButtonClick('1')} className='risk-model-button' transparent>添加</Button>:
<Button onClick={()=>this.onButtonClick('2')} className='risk-model-button' transparent>编辑</Button>}
{channelNo ? <Button onClick={()=>this.onButtonClick('3')} className='risk-model-button' transparent>删除</Button>:''}
</div>
);
return this.state.rightClickNodeTreeItem ? menu : '';
};
onOk = () =>{
let form = this.state.form;
const { toolBarFlag } = this.state;
if (toolBarFlag === '1' || toolBarFlag === '2') {
form.serviceType = "IEC_SERVER";
createChannel(form).then(
data => {
if (data) {
message.danger(data);
return;
}
message.success('操作成功');
this.setState({modal: false});
this.queryPLCChannelList();
}
);
} else if (toolBarFlag === 'point-1' || toolBarFlag === 'point-3') {
const selectedNode = this.state.selectedNode;
const { pointType } = this.state;
form.channelNo = selectedNode;
form.pointType = pointType;
addPoint(form).then(
data => {
message.success('操作成功');
this.setState({modal: false});
this.questItemsData(selectedNode, pointType);
}
);
}
}
cancel = () => {
this.setState({ modal: false });
};
getModalFooter = () => {
return [<Button className='amos-btn-minor' key='cancel' onClick={this.cancel}>取消</Button>, <Button key='ok' onClick={() => this.onOk()}>确定</Button>];
}
onChange = (key, e) => {
const value = e.target.value;
const newForm = Object.assign({}, this.state.form, { [key]: value });
this.setState({
form: newForm
});
}
getContext = (toolBarFlag) => {
let form = this.state.form;
const rules = this.state.rules;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 8 },
className: 'colspanlab'
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
className: 'colspan'
}
};
if (toolBarFlag === '1' || toolBarFlag === '2') {
return (
<Form style={{ width: 300, padding: '30px 0 0 0' }} className="basic-demo" ref={component => this.form = component} model={form} rules={rules}>
<FormItem label={<span>通道名称</span>} field="name" {...formItemLayout} >
<Input
value={form.name}
placeholder="请输入通道名称"
onChange={(e) => this.onChange('name', e)}
/>
</FormItem>
<FormItem label={<span>对端地址</span>} field="ip" {...formItemLayout} >
<Input
value={form.ip}
placeholder="请输入对端地址"
onChange={(e) => this.onChange('ip', e)}
/>
</FormItem>
<FormItem label={<span>本地端口</span>} field="port" {...formItemLayout} >
<Input
value={form.port}
placeholder="请输入端口号"
onChange={(e) => this.onChange('port', e)}
/>
</FormItem>
<FormItem label="公共地址" field="commonAddress" {...formItemLayout} >
<Input
value={form.commonAddress}
placeholder="请输入公共地址"
onChange={(e) => this.onChange('commonAddress', e)}
/>
</FormItem>
</Form>
);
} else if (toolBarFlag === 'point-1' || toolBarFlag === 'point-3') {
return (
<Form style={{ width: 300, padding: '30px 0 0 0' }} className="basic-demo" ref={component => this.form = component} model={form} rules={rules}>
<FormItem label={<span>数据项名称</span>} field="name" {...formItemLayout} >
<Input
value={form.name}
placeholder="请输入通道名称"
onChange={(e) => this.onChange('name', e)}
/>
</FormItem>
<FormItem label={<span>数据项编码</span>} field="pointCode" {...formItemLayout} >
<Input
value={form.pointCode}
placeholder="请输入数据项编码"
onChange={(e) => this.onChange('pointCode', e)}
/>
</FormItem>
<FormItem label={<span>信息地址</span>} field="originatorAddress" {...formItemLayout} >
<Input
value={form.originatorAddress}
placeholder="请输入信息地址"
onChange={(e) => this.onChange('originatorAddress', e)}
/>
</FormItem>
{/* <FormItem label="点位类型" field="pointType" {...formItemLayout} >
<Select value={form.pointType} onChange={this.onPointTypeChange}>
<Option value="yx">遥信</Option>
<Option value="yc">遥测</Option>
</Select>
</FormItem> */}
</Form>
);
}
return "";
}
onPointTypeChange = (value, item) => {
const newForm = Object.assign({}, this.state.form, { pointType: value });
this.setState({
form: newForm
});
}
onSelectChange = (selectedRowKeys,selectedRows) => {
this.setState({selectedRowKeys,selectedRows});
}
handleChange = (key) => {
this.setState({pointType: key});
const {selectedNode} = this.state;
this.questItemsData(selectedNode, key);
}
render() {
let {
selectedKeys,
selectedNode,
toolBarFlag,
selectedRowKeys,
pointType,
modal
} = this.state;
let rowSelection = {
selectedRowKeys: selectedRowKeys,
onChange: this.onSelectChange
};
return (
<div>
<SplitPane percentage={true} mainPaneMinSize={15} secondaryMinSize={85}>
<div className="channel" >
<Tree
showIcon
defaultExpandAll
selectedKeys={selectedKeys}
onSelect={this.onSelectTreeNode}
onRightClick={this.onRightClick}
defaultSelectedKeys={['0-0-0']}>
{this.readerTreeNode()}
</Tree>
</div>
<div className="device-data-items" >
<div className="plc-title">
<div className="con-eva-key">编号: </div>
<div className="con-eva-value">{selectedNode}</div>
</div>
<Divider className="plc-divider" />
<div className="plc-body">
<Tabs
className="quyu-info-tab"
// type="card"
activeKey={pointType}
defaultActiveKey={pointType}
onChange={this.handleChange}
tabBarExtraContent={this.getToolBar(pointType)}
>
<TabPane tab={<span>遥信转发表</span>} key="yx">
<Table
columns={tableColumns}
rowKey={record => record.id}
rowSelection={rowSelection}
bordered
dataSource={this.state.yxDataSource} >
</Table>
</TabPane>
<TabPane tab={<span>遥测转发表</span>} key="yc">
<Table
columns={tableColumns}
rowKey={record => record.id}
rowSelection={rowSelection}
bordered
dataSource={this.state.ycDataSource} >
</Table>
</TabPane>
</Tabs>
</div>
</div>
</SplitPane>
<Modal
header={this.getModalHeader(toolBarFlag)}
visible={modal}
className="risk-model-model"
destroyContent
width={'30%'}
content={this.getContext(toolBarFlag)}
onCancel={() => this.cancel()}
onOk={() => this.onOk()}
footer={this.getModalFooter()}
outterClosable={false}
/>
{this.getNodeTreeRightClickMenu()}
</div>
);
}
}
IEC104ClientManager.propTypes = {
};
export default IEC104ClientManager;
\ No newline at end of file
......@@ -17,27 +17,9 @@ const lsTool = Store.lsTool;
class AutoLogin extends Component {
componentWillMount() {
let code = LocationParam.getLocationParamByName('code');
let userId = LocationParam.getLocationParamByName('userId');
if (code && userId) {
login(code, userId).then(
data => {
const { companys = [], companyDepartments = {}, orgRoles = {} } = data.user;
lsTool.write(SysConsts.token, data.accessToken);
lsTool.write(SysConsts.userId, data.userId);
lsTool.write(SysConsts.company, JSON.stringify(data.user.companys));
lsTool.write(SysConsts.userName, data.user.userName);
lsTool.write(SysConsts.nickName, data.user.realName);
if (companys.length > 0) {
let token = LocationParam.getLocationParamByName('token');
if (token) {
browserHistory.push('/region');
return;
}
},
err => {
AmosAlert.error('警告', err || '系统初始化失败,请重新尝试!');
}
);
} else {
AmosAlert.error('警告', '无法打开该系统,请重新尝试!');
}
......
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Button, Icon} from 'amos-framework';
/**
* 工具栏
*
* @class ToolBar
* @extends {Component}
*/
class ToolBar extends Component {
constructor(props){
super(props);
this.state = {};
}
componentWillMount(){
}
onClick =(e,value)=>{
let { onButtonClick } = this.props;
onButtonClick(value);
}
render() {
return (
<div className='risk-lever-toolbar'>
<div className='risk-lever-button' >
<Button title='添加' icon={<Icon icon="add" />} transparent onClick={e => this.onClick(e,'point-1')} />
<Button title='删除' icon={<Icon icon="delete" />} transparent onClick={e => this.onClick(e, 'point-2')} />
<Button title='编辑' icon={<Icon icon="edit" />} transparent onClick={e => this.onClick(e,'point-3')} />
</div>
</div>
);
}
}
ToolBar.propTypes = {
onButtonClick: PropTypes.func,
parent: PropTypes.any
};
export default ToolBar;
\ No newline at end of file
import React, { Component } from 'react';
import { Tabs, Table } from 'amos-antd';
import { Modal, AmosAlert, Form, Input, Button, Select, Tree, SplitPane, Icon, Divider, message } from 'amos-framework';
import ToolBar from './ToolBar';
import {
getChannelByType,
createChannel,
deleteChannel,
getChannelPoint,
addPoint,
deletePoint,
deleteChannelPoint } from '../../services/deviceService';
const FormItem = Form.Item;
const TabPane = Tabs.TabPane;
const TreeNode = Tree.TreeNode;
const { TabList, Tab, TabPanel } = Tabs;
const tableColumns = [
{
title: '名称',
dataIndex: 'name',
key: 'name'
},
{
title: '编码',
dataIndex: 'pointCode',
key: 'pointCode'
},
{
title: '地址',
dataIndex: 'originatorAddress',
key: 'originatorAddress'
},
{
title: '值',
dataIndex: 'value',
key: 'value'
}
];
class PLCManager extends Component {
constructor(props){
super(props);
this.pageConfig = {
pageNumber: 0,
pageSize: 10
};
this.state = {
dataSource: [],
selectedKeys: [],
channels: [],
form: {},
modal: false,
rules: {
name: [
{ required: true, message: '请输入通道名称' },
],
userName: [
{ required: true, message: '请输入用户名' },
],
ip: [
{ required: true, message: '请输入IP地址' },
],
password: [
{ required: true, message: '请输入密码' },
]
}
};
}
componentDidMount(){
document.addEventListener('click', this._handleClick);//页面增加鼠标单击监听
window.addEventListener('resize', this._resize);
this.setOncontextmenu();//移除浏览器自带右键菜单
this.queryPLCChannelList();
}
setOncontextmenu =()=>{
document.oncontextmenu = (e) =>{
return false;
};
}
componentWillReceiveProps(nextProps) {
}
ccomponentWillUnmount() {
let channelDiv = document.getElementsByClassName('channel')[0];
let riskModelTabDiv = document.getElementsByClassName('device-data-items')[0];
channelDiv && channelDiv.removeEventListener('click', this._handleClick);//页面移除鼠标单击监听
riskModelTabDiv && riskModelTabDiv.removeEventListener('click', this._handleClick);//页面移除鼠标单击监听
window.addEventListener('resize', this._resize);
}
_resize =()=>{
this.onscroll();
}
onscroll =(e)=>{
const { rightClickNodeTreeItem } = this.state;
rightClickNodeTreeItem ? this.setState({ rightClickNodeTreeItem: null }) : '';
}
queryRiskSourceTree =(riskSourceId)=>{
}
onSelect =(selectedKeys,e)=>{
}
queryPLCChannelList = () => {
getChannelByType("OPC_CLIENT").then(
data => {
this.setState({ channels: data });
}
);
}
refeshPLCDetail = (id) =>{
}
questItemsData = (channelNo) => {
console.log(channelNo);
getChannelPoint(channelNo).then(
data => {
this.setState({ dataSource: data });
}
);
};
queryPLCListData = (searchParam, pageNumber, pageSize) => {
}
onClick = (e,key)=>{
}
onToolBarClick = (toolBarFlag) => {
if (toolBarFlag === 'point-1'){
const selectedNode = this.state.selectedNode;
if (!selectedNode) {
message.danger("请选择通道");
return;
}
this.setState({modal: true, toolBarFlag });
} else if (toolBarFlag === 'point-3'){
const { selectedRows } = this.state
if (selectedRows.length > 1) {
message.danger("行数大于1,请重新选择");
return;
}
if (selectedRows.length < 1) {
message.danger("请重新选择数据项");
return;
}
this.setState({modal: true, toolBarFlag, form: selectedRows[0] });
} else if (toolBarFlag === 'point-2'){
const { selectedRowKeys } = this.state
this.deletePoints(selectedRowKeys);
}
}
deletePoints = (selectedRowKeys) => {
const {selectedNode} = this.state;
deletePoint(selectedRowKeys).then(
data => {
message.success('操作成功');
this.questItemsData(selectedNode);
}
);
}
onSelectTreeNode = (selectedKeys, { selectedNodes }) =>{
console.log(selectedNodes);
this.setState({selectedNode: selectedNodes[0].props.channelNo, selectedKeys});
this.questItemsData(selectedNodes[0].props.channelNo);
}
getToolBar = (parent) => {
return <ToolBar onButtonClick={this.onToolBarClick} parent={parent} />;
}
readerTreeNode = () => {
const { channels } = this.state;
return (
<TreeNode icon={<Icon icon="folder" />} title="通道" key="0-0">
{channels.map( item=> <TreeNode icon={<Icon icon="file-leaf" />} channel={item} channelNo={item.channelNo} title={item.name} key={item.id} />)}
</TreeNode>
);
}
onRightClick = ({event, node}) => {
this.setState({
rightClickNodeTreeItem: {
pageX: event.pageX,
pageY: event.pageY
}, selectedNode: node.props.channelNo, channel: node.props.channel });
}
_handleClick = (event) => {
this.setState({ rightClickNodeTreeItem: null });
}
//树按钮点击事件
onButtonClick = (value) => {
let channelNo = this.state.selectedNode;
const channel = this.state.channel;
if (value === '1') {
this.setState({ modal: true,toolBarFlag: value , form: {} });
} else if (value === '2') {
this.setState({ modal: true,toolBarFlag: value, form: channel });
} else if (value === '3'){
this.channelDelete(channelNo);
}
this.setState({ rightClickNodeTreeItem: null });
}
channelDelete = (channelNo) => {
deleteChannel(channelNo).then(
data => {
message.success('删除成功');
this.queryPLCChannelList();
}
);
}
getModalHeader =(toolBarFlag)=>{
let header = '';
if (toolBarFlag === '2') {
header = '编辑通道';
} else if (toolBarFlag === '2'){
header = '添加通道';
} else if (toolBarFlag === 'point-1'){
header = '新增数据项';
} else if (toolBarFlag === 'point-3'){
header = '编辑数据项';
}
return header;
}
getNodeTreeRightClickMenu = () => {
let { pageX, pageY } = { ...this.state.rightClickNodeTreeItem };
let channelNo = this.state.selectedNode;
const height = document.body.offsetHeight;
let overHeight = height - (pageY + 120);
overHeight > 0 ? '' : pageY = height - 120;
const tmpStyle = {
position: 'absolute',
left: `${pageX}px`,
top: `${pageY - 45}px`,
backgroundColor: '#ffffff',
border: 'solid',
height: '70px',
borderWidth: '1px',
borderColor: '#c9c9c9'
};
const menu = (
<div style={tmpStyle}>
{!channelNo ? <Button onClick={()=>this.onButtonClick('1')} className='risk-model-button' transparent>添加</Button>:
<Button onClick={()=>this.onButtonClick('2')} className='risk-model-button' transparent>编辑</Button>}
{channelNo ? <Button onClick={()=>this.onButtonClick('3')} className='risk-model-button' transparent>删除</Button>:''}
</div>
);
return this.state.rightClickNodeTreeItem ? menu : '';
};
onOk = () =>{
let form = this.state.form;
const { toolBarFlag } = this.state;
if (toolBarFlag === '1' || toolBarFlag === '2') {
form.serviceType = "OPC_CLIENT";
createChannel(form).then(
data => {
message.success('操作成功');
this.setState({modal: false});
this.queryPLCChannelList();
}
);
} else if (toolBarFlag === 'point-1' || toolBarFlag === 'point-3') {
const selectedNode = this.state.selectedNode;
form.channelNo = selectedNode;
addPoint(form).then(
data => {
message.success('操作成功');
this.setState({modal: false});
this.questItemsData(selectedNode);
}
);
}
}
cancel = () => {
this.setState({ modal: false });
};
getModalFooter = () => {
return [<Button className='amos-btn-minor' key='cancel' onClick={this.cancel}>取消</Button>, <Button key='ok' onClick={() => this.onOk()}>确定</Button>];
}
onChange = (key, e) => {
const value = e.target.value;
const newForm = Object.assign({}, this.state.form, { [key]: value });
this.setState({
form: newForm
});
}
getContext = (toolBarFlag) => {
let form = this.state.form;
const rules = this.state.rules;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 8 },
className: 'colspanlab'
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
className: 'colspan'
}
};
if (toolBarFlag === '1' || toolBarFlag === '2') {
return (
<Form style={{ width: 300, padding: '30px 0 0 0' }} className="basic-demo" ref={component => this.form = component} model={form} rules={rules}>
<FormItem label={<span>通道名称</span>} field="name" {...formItemLayout} >
<Input
value={form.name}
placeholder="请输入通道名称"
onChange={(e) => this.onChange('name', e)}
/>
</FormItem>
<FormItem label={<span>服务器地址</span>} field="ip" {...formItemLayout} >
<Input
value={form.ip}
placeholder="请输入服务器地址"
onChange={(e) => this.onChange('ip', e)}
/>
</FormItem>
<FormItem label={<span>用户名</span>} field="userName" {...formItemLayout} >
<Input
value={form.userName}
placeholder="请输入用户名"
onChange={(e) => this.onChange('userName', e)}
/>
</FormItem>
<FormItem label="密码" field="password" {...formItemLayout} >
<Input
value={form.password}
type="password"
placeholder="请输入密码"
onChange={(e) => this.onChange('password', e)}
/>
</FormItem>
</Form>
);
} else if (toolBarFlag === 'point-1' || toolBarFlag === 'point-3') {
return (
<Form style={{ width: 300, padding: '30px 0 0 0' }} className="basic-demo" ref={component => this.form = component} model={form} rules={rules}>
<FormItem label={<span>数据项名称</span>} field="name" {...formItemLayout} >
<Input
value={form.name}
placeholder="请输入通道名称"
onChange={(e) => this.onChange('name', e)}
/>
</FormItem>
<FormItem label={<span>itemId</span>} field="originatorAddress" {...formItemLayout} >
<Input
value={form.originatorAddress}
placeholder="请输入itemId"
onChange={(e) => this.onChange('originatorAddress', e)}
/>
</FormItem>
<FormItem label={<span>数据项编码</span>} field="pointCode" {...formItemLayout} >
<Input
value={form.pointCode}
placeholder="请输入数据项编码"
onChange={(e) => this.onChange('pointCode', e)}
/>
</FormItem>
</Form>
);
}
return "";
}
onSelectChange = (selectedRowKeys,selectedRows) => {
this.setState({selectedRowKeys,selectedRows});
}
render() {
let {
selectedKeys,
selectedNode,
toolBarFlag,
selectedRowKeys,
modal
} = this.state;
let rowSelection = {
selectedRowKeys: selectedRowKeys,
onChange: this.onSelectChange
};
return (
<div>
<SplitPane percentage={true} mainPaneMinSize={15} secondaryMinSize={85}>
<div className="channel" >
<Tree
showIcon
defaultExpandAll
selectedKeys={selectedKeys}
onSelect={this.onSelectTreeNode}
onRightClick={this.onRightClick}
defaultSelectedKeys={['0-0-0']}>
{this.readerTreeNode()}
</Tree>
</div>
<div className="device-data-items" >
<div className="plc-title">
<div className="con-eva-key">编号: </div>
<div className="con-eva-value">{selectedNode}</div>
</div>
<Divider className="plc-divider" />
<div className="plc-body">
<Tabs
className="quyu-info-tab"
type="card"
tabBarExtraContent={this.getToolBar(this)}
>
<TabPane tab={<span>数据项</span>}>
<Table
columns={tableColumns}
rowKey={record => record.id}
rowSelection={rowSelection}
bordered
dataSource={this.state.dataSource} >
</Table>
</TabPane>
</Tabs>
</div>
</div>
</SplitPane>
<Modal
header={this.getModalHeader(toolBarFlag)}
visible={modal}
className="risk-model-model"
destroyContent
width={'30%'}
content={this.getContext(toolBarFlag)}
onCancel={() => this.cancel()}
onOk={() => this.onOk()}
footer={this.getModalFooter()}
outterClosable={false}
/>
{this.getNodeTreeRightClickMenu()}
</div>
);
}
}
PLCManager.propTypes = {
};
export default PLCManager;
\ No newline at end of file
......@@ -8,6 +8,7 @@ import { regionSelectAction } from './../../services/navApi';
import { getCurrentUser } from './../../services/securityService';
import { CONSTS } from '../../consts/storageConsts';
import { Store, utils } from 'amos-tool';
import SysConsts from 'amos-processor/lib/config/consts';
const lsTool = Store.lsTool;
const AmosConfig = endConf.AmosConfig;
......@@ -78,6 +79,12 @@ class RegionSelect extends Component {
getCurrentUser().then(data => {
const { reginParams } = this.state;
const { companys = [], companyDepartments = {}, orgRoles = {} } = data;
lsTool.write(SysConsts.userId, data.userId);
lsTool.write(SysConsts.company, JSON.stringify(companys));
lsTool.write(SysConsts.userName, data.userName);
lsTool.write(SysConsts.nickName, data.realName);
if (companys.length === 1) {
let company = companys[0];
let departments = companyDepartments[company.sequenceNbr] || [];
......
......@@ -55,4 +55,17 @@ const defaultConfig = simpleConfig(config);
defaultConfig.name = 'amos-tpl';
if (__ENV__ === 'development'){
// 开发模式下,配置 proxy,跳过跨域问题
defaultConfig.devServer.proxy = {
'/baseURI': {
// target: 'http://172.16.10.70:10005/',
target: 'http://172.16.3.3:10005/',
pathRewrite: { '^/baseURI': '' }
}
};
}
module.exports = defaultConfig;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment