diff --git a/spug_web/src/menus.js b/spug_web/src/menus.js
index 9b44f6c..8057e22 100644
--- a/spug_web/src/menus.js
+++ b/spug_web/src/menus.js
@@ -9,6 +9,13 @@ export default [
},
{icon: 'schedule', title: '任务计划', path: '/schedule'},
{icon: 'monitor', title: '监控中心', path: '/monitor'},
+ {
+ icon: 'alert', title: '报警中心', child: [
+ {title: '报警历史', path: '/alarm/alarm'},
+ {title: '报警联系人', path: '/alarm/contact'},
+ {title: '报警联系组', path: '/alarm/group'},
+ ]
+ },
{
icon: 'setting', title: '系统管理', child: [
{title: '账户管理', path: '/system/account'},
diff --git a/spug_web/src/pages/alarm/alarm/Table.js b/spug_web/src/pages/alarm/alarm/Table.js
new file mode 100644
index 0000000..9c75b46
--- /dev/null
+++ b/spug_web/src/pages/alarm/alarm/Table.js
@@ -0,0 +1,72 @@
+import React from 'react';
+import { observer } from 'mobx-react';
+import { Table, Divider, Modal, message } from 'antd';
+import http from 'libs/http';
+import store from './store';
+import { LinkButton } from "components";
+
+@observer
+class ComTable extends React.Component {
+ componentDidMount() {
+ store.fetchRecords()
+ }
+
+ columns = [{
+ title: '序号',
+ key: 'series',
+ render: (_, __, index) => index + 1,
+ width: 80,
+ }, {
+ title: '任务名称',
+ dataIndex: 'name',
+ }, {
+ title: '监控类型',
+ dataIndex: 'type',
+ }, {
+ title: '持续时间',
+ render: text => text.body,
+ ellipsis: true
+ }, {
+ title: '描述信息',
+ dataIndex: 'desc',
+ ellipsis: true
+ }, {
+ title: '操作',
+ render: info => (
+
+ store.showForm(info)}>编辑
+
+ this.handleDelete(info)}>删除
+
+ )
+ }];
+
+ handleDelete = (text) => {
+ Modal.confirm({
+ title: '删除确认',
+ content: `确定要删除【${text['name']}】?`,
+ onOk: () => {
+ return http.delete('/api/exec/template/', {params: {id: text.id}})
+ .then(() => {
+ message.success('删除成功');
+ store.fetchRecords()
+ })
+ }
+ })
+ };
+
+ render() {
+ let data = store.records;
+ if (store.f_name) {
+ data = data.filter(item => item['name'].toLowerCase().includes(store.f_name.toLowerCase()))
+ }
+ if (store.f_type) {
+ data = data.filter(item => item['type'].toLowerCase().includes(store.f_type.toLowerCase()))
+ }
+ return (
+
+ )
+ }
+}
+
+export default ComTable
\ No newline at end of file
diff --git a/spug_web/src/pages/alarm/alarm/index.js b/spug_web/src/pages/alarm/alarm/index.js
new file mode 100644
index 0000000..4bf62df
--- /dev/null
+++ b/spug_web/src/pages/alarm/alarm/index.js
@@ -0,0 +1,22 @@
+import React from 'react';
+import { observer } from 'mobx-react';
+import { Card, Input, Button } from 'antd';
+import { SearchForm } from 'components';
+import ComTable from './Table';
+import store from './store';
+
+export default observer(function () {
+ return (
+
+
+
+ store.f_name = e.target.value} placeholder="请输入"/>
+
+
+
+
+
+
+
+ )
+})
\ No newline at end of file
diff --git a/spug_web/src/pages/alarm/alarm/store.js b/spug_web/src/pages/alarm/alarm/store.js
new file mode 100644
index 0000000..caca221
--- /dev/null
+++ b/spug_web/src/pages/alarm/alarm/store.js
@@ -0,0 +1,18 @@
+import { observable } from "mobx";
+import http from 'libs/http';
+
+class Store {
+ @observable records = [];
+ @observable isFetching = false;
+
+ @observable f_name;
+
+ fetchRecords = () => {
+ this.isFetching = true;
+ http.get('/api/alarm/alarm/')
+ .then(res => this.records = res)
+ .finally(() => this.isFetching = false)
+ };
+}
+
+export default new Store()
\ No newline at end of file
diff --git a/spug_web/src/pages/alarm/contact/Form.js b/spug_web/src/pages/alarm/contact/Form.js
new file mode 100644
index 0000000..254818c
--- /dev/null
+++ b/spug_web/src/pages/alarm/contact/Form.js
@@ -0,0 +1,76 @@
+import React from 'react';
+import { observer } from 'mobx-react';
+import { Modal, Form, Input, message } from 'antd';
+import http from 'libs/http';
+import store from './store';
+
+@observer
+class ComForm extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ loading: false,
+ }
+ }
+
+ handleSubmit = () => {
+ this.setState({loading: true});
+ const formData = this.props.form.getFieldsValue();
+ formData['id'] = store.record.id;
+ http.post('/api/alarm/contact/', formData)
+ .then(res => {
+ message.success('操作成功');
+ store.formVisible = false;
+ store.fetchRecords()
+ }, () => this.setState({loading: false}))
+ };
+
+ render() {
+ const info = store.record;
+ const {getFieldDecorator} = this.props.form;
+ const itemLayout = {
+ labelCol: {span: 6},
+ wrapperCol: {span: 14}
+ };
+ return (
+ store.formVisible = false}
+ confirmLoading={this.state.loading}
+ onOk={this.handleSubmit}>
+
+ {getFieldDecorator('name', {initialValue: info['name']})(
+
+ )}
+
+
+ {getFieldDecorator('phone', {initialValue: info['phone']})(
+
+ )}
+
+
+ {getFieldDecorator('email', {initialValue: info['email']})(
+
+ )}
+
+
+ {getFieldDecorator('wx_token', {initialValue: info['wx_token']})(
+
+ )}
+
+
+ {getFieldDecorator('ding', {initialValue: info['ding']})(
+
+ )}
+
+
+
+ )
+ }
+}
+
+export default Form.create()(ComForm)
\ No newline at end of file
diff --git a/spug_web/src/pages/alarm/contact/Table.js b/spug_web/src/pages/alarm/contact/Table.js
new file mode 100644
index 0000000..91195ab
--- /dev/null
+++ b/spug_web/src/pages/alarm/contact/Table.js
@@ -0,0 +1,73 @@
+import React from 'react';
+import { observer } from 'mobx-react';
+import { Table, Divider, Modal, message } from 'antd';
+import ComForm from './Form';
+import http from 'libs/http';
+import store from './store';
+import { LinkButton } from "components";
+
+@observer
+class ComTable extends React.Component {
+ componentDidMount() {
+ store.fetchRecords()
+ }
+
+ columns = [{
+ title: '序号',
+ key: 'series',
+ render: (_, __, index) => index + 1,
+ width: 80,
+ }, {
+ title: '姓名',
+ dataIndex: 'name',
+ }, {
+ title: '手机号',
+ dataIndex: 'phone',
+ }, {
+ title: '邮箱',
+ dataIndex: 'email',
+ ellipsis: true
+ }, {
+ title: '钉钉',
+ dataIndex: 'ding',
+ ellipsis: true
+ }, {
+ title: '操作',
+ render: info => (
+
+ store.showForm(info)}>编辑
+
+ this.handleDelete(info)}>删除
+
+ )
+ }];
+
+ handleDelete = (text) => {
+ Modal.confirm({
+ title: '删除确认',
+ content: `确定要删除【${text['name']}】?`,
+ onOk: () => {
+ return http.delete('/api/alarm/contact/', {params: {id: text.id}})
+ .then(() => {
+ message.success('删除成功');
+ store.fetchRecords()
+ })
+ }
+ })
+ };
+
+ render() {
+ let data = store.records;
+ if (store.f_name) {
+ data = data.filter(item => item['name'].toLowerCase().includes(store.f_name.toLowerCase()))
+ }
+ return (
+
+
+ {store.formVisible && }
+
+ )
+ }
+}
+
+export default ComTable
\ No newline at end of file
diff --git a/spug_web/src/pages/alarm/contact/index.js b/spug_web/src/pages/alarm/contact/index.js
new file mode 100644
index 0000000..d3da9ab
--- /dev/null
+++ b/spug_web/src/pages/alarm/contact/index.js
@@ -0,0 +1,25 @@
+import React from 'react';
+import { observer } from 'mobx-react';
+import { Card, Input, Button } from 'antd';
+import { SearchForm } from 'components';
+import ComTable from './Table';
+import store from './store';
+
+export default observer(function () {
+ return (
+
+
+
+ store.f_name = e.target.value} placeholder="请输入"/>
+
+
+
+
+
+
+
+
+
+
+ )
+})
\ No newline at end of file
diff --git a/spug_web/src/pages/alarm/contact/store.js b/spug_web/src/pages/alarm/contact/store.js
new file mode 100644
index 0000000..9ecbc88
--- /dev/null
+++ b/spug_web/src/pages/alarm/contact/store.js
@@ -0,0 +1,25 @@
+import { observable } from "mobx";
+import http from 'libs/http';
+
+class Store {
+ @observable records = [];
+ @observable record = {};
+ @observable isFetching = false;
+ @observable formVisible = false;
+
+ @observable f_name;
+
+ fetchRecords = () => {
+ this.isFetching = true;
+ return http.get('/api/alarm/contact/')
+ .then(res => this.records = res)
+ .finally(() => this.isFetching = false)
+ };
+
+ showForm = (info = {}) => {
+ this.formVisible = true;
+ this.record = info
+ }
+}
+
+export default new Store()
\ No newline at end of file
diff --git a/spug_web/src/pages/alarm/group/Form.js b/spug_web/src/pages/alarm/group/Form.js
new file mode 100644
index 0000000..01c2fe0
--- /dev/null
+++ b/spug_web/src/pages/alarm/group/Form.js
@@ -0,0 +1,75 @@
+import React from 'react';
+import { observer } from 'mobx-react';
+import { Modal, Form, Input, Transfer, message } from 'antd';
+import http from 'libs/http';
+import store from './store';
+import contactStore from '../contact/store';
+
+@observer
+class ComForm extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ loading: false,
+ targetKeys: [],
+ dataSource: contactStore.records.map(x => ({key: x.id, title: x.name}))
+ }
+ }
+
+ handleSubmit = () => {
+ this.setState({loading: true});
+ const formData = this.props.form.getFieldsValue();
+ formData['id'] = store.record.id;
+ http.post('/api/alarm/group/', formData)
+ .then(res => {
+ message.success('操作成功');
+ store.formVisible = false;
+ store.fetchRecords()
+ }, () => this.setState({loading: false}))
+ };
+
+ render() {
+ const info = store.record;
+ const {getFieldDecorator} = this.props.form;
+ const itemLayout = {
+ labelCol: {span: 6},
+ wrapperCol: {span: 14}
+ };
+ return (
+ store.formVisible = false}
+ confirmLoading={this.state.loading}
+ onOk={this.handleSubmit}>
+
+ {getFieldDecorator('name', {initialValue: info['name']})(
+
+ )}
+
+
+ {getFieldDecorator('desc', {initialValue: info['desc']})(
+
+ )}
+
+
+ {getFieldDecorator('contacts', {valuePropName: 'targetKeys', initialValue: info['contacts']})(
+ this.setState({targetKeys: v})}
+ render={item => item.title}/>
+ )}
+
+
+
+ )
+ }
+}
+
+export default Form.create()(ComForm)
\ No newline at end of file
diff --git a/spug_web/src/pages/alarm/group/Table.js b/spug_web/src/pages/alarm/group/Table.js
new file mode 100644
index 0000000..09b1838
--- /dev/null
+++ b/spug_web/src/pages/alarm/group/Table.js
@@ -0,0 +1,91 @@
+import React from 'react';
+import { observer } from 'mobx-react';
+import { Table, Divider, Modal, message } from 'antd';
+import ComForm from './Form';
+import http from 'libs/http';
+import store from './store';
+import contactStore from '../contact/store';
+import { LinkButton } from "components";
+import lds from 'lodash';
+
+@observer
+class ComTable extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ contactMap: {}
+ }
+ }
+ componentDidMount() {
+ store.fetchRecords();
+ if (contactStore.records.length === 0) {
+ contactStore.fetchRecords().then(() => {
+ const tmp = {};
+ for (let item of contactStore.records) {
+ tmp[item.id] = item
+ }
+ this.setState({contactMap: tmp})
+ })
+ }
+ }
+
+ columns = [{
+ title: '序号',
+ key: 'series',
+ render: (_, __, index) => index + 1,
+ width: 80,
+ }, {
+ title: '组名称',
+ dataIndex: 'name',
+ }, {
+ title: '成员',
+ dataIndex: 'contacts',
+ render: value => value.map(x => lds.get(this.state.contactMap, `${x}.name`)).join(','),
+ ellipsis: true
+ }, {
+ title: '描述信息',
+ dataIndex: 'desc',
+ ellipsis: true
+ }, {
+ title: '操作',
+ render: info => (
+
+ store.showForm(info)}>编辑
+
+ this.handleDelete(info)}>删除
+
+ )
+ }];
+
+ handleDelete = (text) => {
+ Modal.confirm({
+ title: '删除确认',
+ content: `确定要删除【${text['name']}】?`,
+ onOk: () => {
+ return http.delete('/api/exec/template/', {params: {id: text.id}})
+ .then(() => {
+ message.success('删除成功');
+ store.fetchRecords()
+ })
+ }
+ })
+ };
+
+ render() {
+ let data = store.records;
+ if (store.f_name) {
+ data = data.filter(item => item['name'].toLowerCase().includes(store.f_name.toLowerCase()))
+ }
+ if (store.f_type) {
+ data = data.filter(item => item['type'].toLowerCase().includes(store.f_type.toLowerCase()))
+ }
+ return (
+
+
+ {store.formVisible && }
+
+ )
+ }
+}
+
+export default ComTable
\ No newline at end of file
diff --git a/spug_web/src/pages/alarm/group/index.js b/spug_web/src/pages/alarm/group/index.js
new file mode 100644
index 0000000..341b145
--- /dev/null
+++ b/spug_web/src/pages/alarm/group/index.js
@@ -0,0 +1,25 @@
+import React from 'react';
+import { observer } from 'mobx-react';
+import { Card, Input, Button } from 'antd';
+import { SearchForm } from 'components';
+import ComTable from './Table';
+import store from './store';
+
+export default observer(function () {
+ return (
+
+
+
+ store.f_name = e.target.value} placeholder="请输入"/>
+
+
+
+
+
+
+
+
+
+
+ )
+})
\ No newline at end of file
diff --git a/spug_web/src/pages/alarm/group/store.js b/spug_web/src/pages/alarm/group/store.js
new file mode 100644
index 0000000..06245a4
--- /dev/null
+++ b/spug_web/src/pages/alarm/group/store.js
@@ -0,0 +1,25 @@
+import { observable } from "mobx";
+import http from 'libs/http';
+
+class Store {
+ @observable records = [];
+ @observable record = {};
+ @observable isFetching = false;
+ @observable formVisible = false;
+
+ @observable f_name;
+
+ fetchRecords = () => {
+ this.isFetching = true;
+ http.get('/api/alarm/group/')
+ .then(res => this.records = res)
+ .finally(() => this.isFetching = false)
+ };
+
+ showForm = (info = {}) => {
+ this.formVisible = true;
+ this.record = info
+ }
+}
+
+export default new Store()
\ No newline at end of file
diff --git a/spug_web/src/pages/alarm/routes.js b/spug_web/src/pages/alarm/routes.js
new file mode 100644
index 0000000..47650af
--- /dev/null
+++ b/spug_web/src/pages/alarm/routes.js
@@ -0,0 +1,11 @@
+import { makeRoute } from 'libs/router';
+import Alarm from './alarm';
+import Contact from './contact';
+import Group from './group';
+
+
+export default [
+ makeRoute('/alarm', Alarm),
+ makeRoute('/contact', Contact),
+ makeRoute('/group', Group),
+]
\ No newline at end of file
diff --git a/spug_web/src/routes.js b/spug_web/src/routes.js
index 8406ac7..47a5bc3 100644
--- a/spug_web/src/routes.js
+++ b/spug_web/src/routes.js
@@ -6,6 +6,7 @@ import systemRoutes from './pages/system/routes';
import execRoutes from './pages/exec/routes';
import scheduleRoutes from './pages/schedule/routes';
import monitorRoutes from './pages/monitor/routes';
+import alarmRoutes from './pages/alarm/routes';
export default [
@@ -15,4 +16,5 @@ export default [
makeModuleRoute('/exec', execRoutes),
makeModuleRoute('/schedule', scheduleRoutes),
makeModuleRoute('/monitor', monitorRoutes),
+ makeModuleRoute('/alarm', alarmRoutes),
]
\ No newline at end of file