From 7925e4ce0b805c6469f10037f6f0d7e15ea14068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E4=BA=8C=E7=8C=9B?= Date: Mon, 18 Nov 2019 21:05:34 +0800 Subject: [PATCH] U web add host module --- spug_web/src/components/LinkButton.js | 7 ++ spug_web/src/components/index.js | 2 + spug_web/src/index.css | 3 +- spug_web/src/menus.js | 1 + spug_web/src/pages/host/Form.js | 122 +++++++++++++++++++++ spug_web/src/pages/host/Table.js | 73 ++++++++++++ spug_web/src/pages/host/index.js | 24 ++++ spug_web/src/pages/host/routes.js | 7 ++ spug_web/src/pages/host/store.js | 26 +++++ spug_web/src/pages/system/account/Table.js | 2 +- spug_web/src/routes.js | 2 + 11 files changed, 266 insertions(+), 3 deletions(-) create mode 100644 spug_web/src/components/LinkButton.js create mode 100644 spug_web/src/pages/host/Form.js create mode 100644 spug_web/src/pages/host/Table.js create mode 100644 spug_web/src/pages/host/index.js create mode 100644 spug_web/src/pages/host/routes.js create mode 100644 spug_web/src/pages/host/store.js diff --git a/spug_web/src/components/LinkButton.js b/spug_web/src/components/LinkButton.js new file mode 100644 index 0000000..4eb153e --- /dev/null +++ b/spug_web/src/components/LinkButton.js @@ -0,0 +1,7 @@ +import React from 'react'; +import { Button } from 'antd'; + + +export default function LinkButton(props) { + return +} \ No newline at end of file diff --git a/spug_web/src/components/index.js b/spug_web/src/components/index.js index ae41a1f..dcc34c1 100644 --- a/spug_web/src/components/index.js +++ b/spug_web/src/components/index.js @@ -1,7 +1,9 @@ import StatisticsCard from './StatisticsCard'; import SearchForm from './SearchForm'; +import LinkButton from './LinkButton'; export { StatisticsCard, SearchForm, + LinkButton, } \ No newline at end of file diff --git a/spug_web/src/index.css b/spug_web/src/index.css index 07afb21..4e61174 100644 --- a/spug_web/src/index.css +++ b/spug_web/src/index.css @@ -16,6 +16,5 @@ code { /* Common CSS style */ .span-button { - cursor: pointer; - color: #1890ff; + padding: 0; } \ No newline at end of file diff --git a/spug_web/src/menus.js b/spug_web/src/menus.js index cab947d..3fd57dc 100644 --- a/spug_web/src/menus.js +++ b/spug_web/src/menus.js @@ -1,5 +1,6 @@ export default [ {icon: 'desktop', title: '工作台', path: '/home'}, + {icon: 'cloud-server', title: '主机管理', path: '/host'}, { icon: 'setting', title: '系统管理', child: [ {title: '账户管理', path: '/system/account'}, diff --git a/spug_web/src/pages/host/Form.js b/spug_web/src/pages/host/Form.js new file mode 100644 index 0000000..9252775 --- /dev/null +++ b/spug_web/src/pages/host/Form.js @@ -0,0 +1,122 @@ +import React from 'react'; +import { Modal, Form, Input, message } from 'antd'; +import http from 'libs/http'; +import store from './store'; + +class ComForm extends React.Component { + constructor(props) { + super(props); + this.state = { + loading: false, + password: null, + } + } + + handleSubmit = () => { + this.setState({loading: true}); + const formData = this.props.form.getFieldsValue(); + formData['id'] = store.record.id; + http.post('/api/host/', formData) + .then(res => { + if (res === 'auth fail') { + this.setState({loading: false}); + Modal.confirm({ + icon: 'exclamation-circle', + title: '首次验证请输入密码', + content: this.confirmForm(formData.username), + onOk: () => this.handleConfirm(formData), + }) + } else { + message.success('操作成功'); + store.formVisible = false; + store.fetchRecords() + } + }, () => this.setState({loading: false})) + }; + + handleConfirm = (formData) => { + if (this.state.password) { + formData['password'] = this.state.password; + return http.post('/api/host/', formData).then(res => { + message.success('验证成功'); + store.formVisible = false; + store.fetchRecords() + }) + } + message.error('请输入授权密码') + }; + + confirmForm = (username) => { + return ( +
+ + this.setState({password: val.target.value})}/> + +
+ ) + }; + + render() { + const info = store.record; + const {getFieldDecorator} = this.props.form; + const itemLayout = { + labelCol: {span: 6}, + wrapperCol: {span: 14} + }; + const itemTailLayout = { + labelCol: {span: 6}, + wrapperCol: {span: 14, offset: 6} + }; + return ( + store.formVisible = false} + confirmLoading={this.state.loading} + onOk={this.handleSubmit}> +
+ + {getFieldDecorator('zone', {initialValue: info['zone']})( + + )} + + + {getFieldDecorator('name', {initialValue: info['name']})( + + )} + + + + {getFieldDecorator('username', {initialValue: info['username']})( + + )} + + + {getFieldDecorator('hostname', {initialValue: info['hostname']})( + + )} + + + {getFieldDecorator('port', {initialValue: info['port']})( + + )} + + + + {getFieldDecorator('desc', {initialValue: info['desc']})( + + )} + + + ⚠️ 首次验证时需要输入登录用户名对应的密码,但不会存储该密码。 + +
+
+ ) + } +} + +export default Form.create()(ComForm) \ No newline at end of file diff --git a/spug_web/src/pages/host/Table.js b/spug_web/src/pages/host/Table.js new file mode 100644 index 0000000..3596f1d --- /dev/null +++ b/spug_web/src/pages/host/Table.js @@ -0,0 +1,73 @@ +import React from 'react'; +import { observer } from 'mobx-react'; +import { Table, Divider, Modal, message } from 'antd'; +import { LinkButton } from 'components'; +import ComForm from './Form'; +import http from 'libs/http'; +import store from './store'; + +@observer +class ComTable extends React.Component { + componentDidMount() { + store.fetchRecords() + } + + columns = [{ + title: '序号', + key: 'series', + render: (_, __, index) => index + 1 + }, { + title: '类别', + dataIndex: 'zone', + }, { + title: '名称', + dataIndex: 'name', + }, { + title: '主机', + dataIndex: 'hostname', + }, { + title: '端口', + dataIndex: 'port' + }, { + title: '备注', + dataIndex: 'desc' + }, { + title: '操作', + render: info => ( + + store.showForm(info)}>编辑 + + this.handleDelete(info)}>删除 + + ) + }]; + + handleDelete = (text) => { + Modal.confirm({ + title: '删除确认', + content: `确定要删除【${text['name']}】?`, + onOk: () => { + return http.delete('/api/host/', {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/host/index.js b/spug_web/src/pages/host/index.js new file mode 100644 index 0000000..f458f8e --- /dev/null +++ b/spug_web/src/pages/host/index.js @@ -0,0 +1,24 @@ +import React from 'react'; +import { Card, Input, Button } from 'antd'; +import { SearchForm } from 'components'; +import ComTable from './Table'; +import store from './store'; + +export default function () { + return ( + + + + store.f_name = e.target.value} placeholder="请输入"/> + + + + + +
+ +
+ +
+ ) +} \ No newline at end of file diff --git a/spug_web/src/pages/host/routes.js b/spug_web/src/pages/host/routes.js new file mode 100644 index 0000000..6e03f0b --- /dev/null +++ b/spug_web/src/pages/host/routes.js @@ -0,0 +1,7 @@ +import { makeRoute } from "../../libs/router"; +import Index from './index'; + + +export default [ + makeRoute('', Index), +] \ No newline at end of file diff --git a/spug_web/src/pages/host/store.js b/spug_web/src/pages/host/store.js new file mode 100644 index 0000000..83299a3 --- /dev/null +++ b/spug_web/src/pages/host/store.js @@ -0,0 +1,26 @@ +import { observable } from "mobx"; +import http from 'libs/http'; + +class Store { + @observable records = []; + @observable record = {}; + @observable isFetching = false; + @observable formVisible = false; + + @observable f_name; + @observable f_status; + + fetchRecords = () => { + this.isFetching = true; + http.get('/api/host/') + .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/system/account/Table.js b/spug_web/src/pages/system/account/Table.js index ea801e1..92a3581 100644 --- a/spug_web/src/pages/system/account/Table.js +++ b/spug_web/src/pages/system/account/Table.js @@ -1,6 +1,6 @@ import React from 'react'; import { observer } from 'mobx-react'; -import { Table, Divider, Modal, Badge, message, Button } from 'antd'; +import { Table, Divider, Modal, Badge, message } from 'antd'; import ComForm from './Form'; import http from 'libs/http'; import store from './store'; diff --git a/spug_web/src/routes.js b/spug_web/src/routes.js index 3089dea..66f9ebc 100644 --- a/spug_web/src/routes.js +++ b/spug_web/src/routes.js @@ -1,10 +1,12 @@ import { makeModuleRoute } from "./libs/router"; import homeRoutes from './pages/home/routes'; +import hostRoutes from './pages/host/routes'; import systemRoutes from './pages/system/routes'; export default [ makeModuleRoute('/home', homeRoutes), + makeModuleRoute('/host', hostRoutes), makeModuleRoute('/system', systemRoutes), ] \ No newline at end of file