Initial commit

This commit is contained in:
dushixiang
2020-12-20 21:19:11 +08:00
commit e7f2773c77
77 changed files with 27866 additions and 0 deletions

View File

@ -0,0 +1,512 @@
import React, {Component} from 'react';
import "video-react/dist/video-react.css";
import {
Badge,
Button,
Col,
Divider,
Input,
Layout,
Modal,
PageHeader,
Row,
Select,
Space,
Table,
Tag,
Tooltip,
Typography
} from "antd";
import qs from "qs";
import AssetModal from "./AssetModal";
import request from "../../common/request";
import {message} from "antd/es";
import {
CodeTwoTone,
CopyTwoTone,
DeleteOutlined,
DeleteTwoTone,
EditTwoTone,
ExclamationCircleOutlined,
PlusOutlined,
SyncOutlined,
UndoOutlined
} from '@ant-design/icons';
import {itemRender} from "../../utils/utils";
import {PROTOCOL_COLORS} from "../../common/constants";
const confirm = Modal.confirm;
const {Search} = Input;
const {Content} = Layout;
const {Title, Text} = Typography;
const routes = [
{
path: '',
breadcrumbName: '首页',
},
{
path: 'assets',
breadcrumbName: '资产管理',
}
];
class Asset extends Component {
inputRefOfName = React.createRef();
state = {
items: [],
total: 0,
queryParams: {
pageIndex: 1,
pageSize: 10,
protocol: ''
},
loading: false,
modalVisible: false,
modalTitle: '',
modalConfirmLoading: false,
credentials: [],
model: {},
selectedRowKeys: [],
delBtnLoading: false,
};
async componentDidMount() {
await this.loadTableData();
}
async delete(id) {
const result = await request.delete('/assets/' + id);
if (result['code'] === 1) {
message.success('删除成功');
await this.loadTableData(this.state.queryParams);
} else {
message.error('删除失败 :( ' + result.message, 10);
}
}
async loadTableData(queryParams) {
this.setState({
loading: true
});
queryParams = queryParams || this.state.queryParams;
// queryParams
let paramsStr = qs.stringify(queryParams);
let data = {
items: [],
total: 0
};
try {
let result = await request.get('/assets/paging?' + paramsStr);
if (result['code'] === 1) {
data = result['data'];
} else {
message.error(result['message']);
}
} catch (e) {
} finally {
const items = data.items.map(item => {
return {'key': item['id'], ...item}
})
this.setState({
items: items,
total: data.total,
queryParams: queryParams,
loading: false
});
}
}
handleChangPage = async (pageIndex, pageSize) => {
let queryParams = this.state.queryParams;
queryParams.pageIndex = pageIndex;
queryParams.pageSize = pageSize;
this.setState({
queryParams: queryParams
});
await this.loadTableData(queryParams)
};
handleSearchByName = name => {
let query = {
...this.state.queryParams,
'pageIndex': 1,
'pageSize': this.state.queryParams.pageSize,
'name': name,
}
this.loadTableData(query);
};
handleSearchByProtocol = protocol => {
let query = {
...this.state.queryParams,
'pageIndex': 1,
'pageSize': this.state.queryParams.pageSize,
'protocol': protocol,
}
this.loadTableData(query);
}
showDeleteConfirm(id, content) {
let self = this;
confirm({
title: '您确定要删除此资产吗?',
content: content,
okText: '确定',
okType: 'danger',
cancelText: '取消',
onOk() {
self.delete(id);
}
});
};
async update(id) {
let result = await request.get(`/assets/${id}`);
if (result.code !== 1) {
message.error(result.message, 10);
return;
}
await this.showModal('更新资产', result.data);
}
async copy(id) {
let result = await request.get(`/assets/${id}`);
if (result.code !== 1) {
message.error(result.message, 10);
return;
}
result.data['id'] = undefined;
await this.showModal('复制资产', result.data);
}
async showModal(title, assets = {}) {
let result = await request.get('/credentials');
let credentials = [];
if (result.code === 1) {
credentials = result.data;
}
this.setState({
modalTitle: title,
modalVisible: true,
credentials: credentials,
model: assets
});
};
handleCancelModal = e => {
this.setState({
modalTitle: '',
modalVisible: false
});
};
handleOk = async (formData) => {
// 弹窗 form 传来的数据
this.setState({
modalConfirmLoading: true
});
if (formData.id) {
// 向后台提交数据
const result = await request.put('/assets/' + formData.id, formData);
if (result.code === 1) {
message.success('操作成功', 3);
this.setState({
modalVisible: false
});
await this.loadTableData(this.state.queryParams);
} else {
message.error('操作失败 :( ' + result.message, 10);
}
} else {
// 向后台提交数据
const result = await request.post('/assets', formData);
if (result.code === 1) {
message.success('操作成功', 3);
this.setState({
modalVisible: false
});
await this.loadTableData(this.state.queryParams);
} else {
message.error('操作失败 :( ' + result.message, 10);
}
}
this.setState({
modalConfirmLoading: false
});
};
access = async (id, protocol) => {
message.loading({content: '正在检测资产是否在线...', key: id});
let result = await request.post(`/assets/${id}/tcping`);
if (result.code === 1) {
if (result.data === true) {
message.success({content: '检测完成,您访问的资产在线,即将打开窗口进行访问。', key: id, duration: 3});
window.open(`#/access?assetsId=${id}&protocol=${protocol}`);
} else {
message.warn('您访问的资产未在线,请确认网络状态。', 10);
}
} else {
message.error('操作失败 :( ' + result.message, 10);
}
}
batchDelete = async () => {
this.setState({
delBtnLoading: true
})
try {
let result = await request.delete('/assets/' + this.state.selectedRowKeys.join(','));
if (result.code === 1) {
message.success('操作成功', 3);
this.setState({
selectedRowKeys: []
})
await this.loadTableData(this.state.queryParams);
} else {
message.error('删除失败 :( ' + result.message, 10);
}
} finally {
this.setState({
delBtnLoading: false
})
}
}
render() {
const columns = [{
title: '序号',
dataIndex: 'id',
key: 'id',
render: (id, record, index) => {
return index + 1;
}
}, {
title: '资产名称',
dataIndex: 'name',
key: 'name',
render: (name, record) => {
if (name && name.length > 20) {
name = name.substring(0, 20) + "...";
}
return (
<Tooltip placement="topLeft" title={name}>
{name}
</Tooltip>
);
}
}, {
title: 'IP',
dataIndex: 'ip',
key: 'ip',
}, {
title: '端口',
dataIndex: 'port',
key: 'port',
}, {
title: '连接协议',
dataIndex: 'protocol',
key: 'protocol',
render: (text, record) => {
return (<Tag color={PROTOCOL_COLORS[text]}>{text}</Tag>);
}
}, {
title: '状态',
dataIndex: 'active',
key: 'active',
render: text => {
if (text) {
return (<Badge status="processing" text="运行中"/>);
} else {
return (<Badge status="error" text="不可用"/>);
}
}
}, {
title: '创建日期',
dataIndex: 'created',
key: 'created'
},
{
title: '操作',
key: 'action',
render: (text, record) => {
return (
<div>
<Button type="link" size='small' icon={<CodeTwoTone/>}
onClick={() => this.access(record.id, record.protocol)}>接入</Button>
<Button type="link" size='small' icon={<EditTwoTone/>}
onClick={() => this.update(record.id)}>编辑</Button>
<Button type="link" size='small' icon={<CopyTwoTone/>}
onClick={() => this.copy(record.id)}>复制</Button>
<Button type="link" size='small' icon={<DeleteTwoTone/>}
onClick={() => this.showDeleteConfirm(record.id, record.name)}>删除</Button>
</div>
)
},
}
];
const selectedRowKeys = this.state.selectedRowKeys;
const rowSelection = {
selectedRowKeys: this.state.selectedRowKeys,
onChange: (selectedRowKeys, selectedRows) => {
this.setState({selectedRowKeys});
},
};
const hasSelected = selectedRowKeys.length > 0;
return (
<>
<PageHeader
className="site-page-header-ghost-wrapper page-herder"
title="资产管理"
breadcrumb={{
routes: routes,
itemRender: itemRender
}}
subTitle="资产"
>
</PageHeader>
<Content key='page-content' className="site-layout-background page-content">
<div style={{marginBottom: 20}}>
<Row justify="space-around" align="middle" gutter={24}>
<Col span={12} key={1}>
<Title level={3}>资产列表</Title>
</Col>
<Col span={12} key={2} style={{textAlign: 'right'}}>
<Space>
<Search
ref={this.inputRefOfName}
placeholder="资产名称"
allowClear
onSearch={this.handleSearchByName}
/>
<Select onChange={this.handleSearchByProtocol}
value={this.state.queryParams.protocol ? this.state.queryParams.protocol : ''}
style={{width: 100}}>
<Select.Option value="">全部协议</Select.Option>
<Select.Option value="rdp">rdp</Select.Option>
<Select.Option value="ssh">ssh</Select.Option>
<Select.Option value="vnc">vnc</Select.Option>
<Select.Option value="telnet">telnet</Select.Option>
</Select>
<Tooltip title='重置查询'>
<Button icon={<UndoOutlined/>} onClick={() => {
this.inputRefOfName.current.setValue('');
this.loadTableData({pageIndex: 1, pageSize: 10, protocol: ''})
}}>
</Button>
</Tooltip>
<Divider type="vertical"/>
<Tooltip title="新增">
<Button type="dashed" icon={<PlusOutlined/>}
onClick={() => this.showModal('新增资产', {})}>
</Button>
</Tooltip>
<Tooltip title="刷新列表">
<Button icon={<SyncOutlined/>} onClick={() => {
this.loadTableData(this.state.queryParams)
}}>
</Button>
</Tooltip>
<Tooltip title="批量删除">
<Button type="primary" danger disabled={!hasSelected} icon={<DeleteOutlined/>}
loading={this.state.delBtnLoading}
onClick={() => {
const content = <div>
您确定要删除选中的<Text style={{color: '#1890FF'}}
strong>{this.state.selectedRowKeys.length}</Text>
</div>;
confirm({
icon: <ExclamationCircleOutlined/>,
content: content,
onOk: () => {
this.batchDelete()
},
onCancel() {
},
});
}}>
</Button>
</Tooltip>
</Space>
</Col>
</Row>
</div>
<Table key='assets-table'
rowSelection={rowSelection}
dataSource={this.state.items}
columns={columns}
position={'both'}
pagination={{
showSizeChanger: true,
current: this.state.queryParams.pageIndex,
pageSize: this.state.queryParams.pageSize,
onChange: this.handleChangPage,
onShowSizeChange: this.handleChangPage,
total: this.state.total,
showTotal: total => `总计 ${total}`
}}
loading={this.state.loading}
/>
{
this.state.modalVisible ?
<AssetModal
modalFormRef={this.modalFormRef}
visible={this.state.modalVisible}
title={this.state.modalTitle}
handleOk={this.handleOk}
handleCancel={this.handleCancelModal}
confirmLoading={this.state.modalConfirmLoading}
credentials={this.state.credentials}
model={this.state.model}
/>
: null
}
</Content>
</>
);
}
}
export default Asset;