第一步 安装 react-resizable 并封装
import React, { useState, useEffect } from ‘react’;
import { Table } from ‘antd’;
import { Resizable } from ‘react-resizable’;
import ‘./resizable.less’;
const components = {
header: {
cell: (props) => {
let index = props.className.indexOf(‘ant-table-cell-fix’)
const { onResize, width, …restProps } = props;
if (!width || index !== -1) {
return <th {…restProps} />;
}
return (
<th {…restProps} />
);
},
},
};
function modifyDeepTreeNodeValueFn ({ colList, modifyObj, indexes }) {
let colList_ = colList;
let tempArr = […colList_];
function modifyDeepTreeNodeValue (indexes) {
const indexLen = indexes.length;
for (let i = 0; i < indexLen; i++) {
const index_ = indexes[i];
if (i < indexLen - 1) {
const targetArr = tempArr[index_];
if (!targetArr) {
break;
}
tempArr = (tempArr[index_] && tempArr[index_].children) || [];
} else {
const target = tempArr[index_];
if (!target) {
break;
}
tempArr[index_] = {
…target,
…modifyObj,
};
}
}
}
if (indexes.length === 1) {
const index_ = indexes[0];
colList_[index_] = {
…colList_[index_],
…modifyObj,
};
return colList_;
}
modifyDeepTreeNodeValue(indexes);
return colList_;
}
export default function ResizeTable (props) {
const [selfColumns, setSelfColumns] = useState([]);
const { columns } = props;
useEffect(() => {
setSelfColumns([…columns]);
}, [columns]);
const handleResize = (indexes) => {
return (e, d) => {
const { width } = d.size;
const nextColumns = modifyDeepTreeNodeValueFn({
colList: selfColumns,
modifyObj: { width },
indexes,
});
setSelfColumns([…nextColumns]);
};
};
const setColumnsResizeable = (cols, indexes = []) => {
return […cols].map((colItem, index) => {
const { children, width } = colItem;
const currentIndexes = […indexes, index];
const children_ = Array.isArray(children)
? setColumnsResizeable(children, currentIndexes)
: null;
return {
…colItem,
onHeaderCell: () => ({
width,
onResize: handleResize(currentIndexes),
}),
children: children_,
indexes: currentIndexes,
};
});
};
const columns_ = setColumnsResizeable(selfColumns);
return <Table {…props} columns={columns_} components={components} />;
}
第二部载入样式
.react-resizable {
position: relative;
background-clip: padding-box;
}
.react-resizable-handle {
position: absolute;
right: 0;
bottom: 0;
z-index: 100;
width: 1px;
height: 100%; // border-right: 1px dashed #40a9ff;
cursor: col-resize;
}
.react-resizable-handle:hover {
border-right: 2px solid #40a9ff;
}
第三步在组件中引入 ResizeTable
import React, { useState, useEffect } from “react”;
import ‘./columnTable.less’;
import { Table, Checkbox, Tooltip, Tag } from ‘antd’;
import moment from ‘moment’;
import { getNsEnum } from ‘./…/…/pages/security/service’
import ResizeTable from “./…/resizable/resizable”;
const CheckboxGroup = Checkbox.Group;
function ColumnComponent (props) {
const [severityData, setSeverityData] = useState([])
const [classtypeData, setClasstypeData] = useState([])
const [threatTagData, setThreatTagData] = useState([])
// 获取威胁等级枚举值
const getSeveritNsEnum = async () => {
let res = await getNsEnum({ key: ‘severity’ })
if (res && res.res && res.data.length > 0) {
let obj = {}
let array = []
res.data.map((item) => {
obj = {
text: item.name,
value: item.id
}
array.push(obj)
})
setSeverityData(array)
columns[2].filters = array
}
}
// 获取威胁类型枚举值
const getClasstypeNsEnum = async () => {
let res = await getNsEnum({ key: ‘classtype’ })
if (res && res.res && res.data.length > 0) {
let array = []
let obj = {}
let newObj = {}
let newArray = []
let arr = []
res.data.map((item) => {
if (item.name !== ‘扫描爆破’) {
obj = {
text: item.name,
value: item.id
}
}
array.push(obj)
newArray = […new Set(array)]
})
newArray.length > 0 && newArray.map((item) => {
if (item.text !== ‘挖矿行为’) {
newObj = {
text: item.text,
value: item.value
}
}
arr.push(newObj)
newArray = […new Set(arr)]
})
setClasstypeData(newArray)
columns[5].filters = newArray
}
}
// 获取威胁标签枚举值
const getThreatTagNsEnum = async () => {
let res = await getNsEnum({ key: ‘threat_tag’ })
if (res && res.res && res.data.length > 0) {
let array = []
let obj = {}
res.data.map((item) => {
obj = {
text: item.name,
value: item.id
}
array.push(obj)
})
if (array && array.length > 0) {
columns[6].filters = array
setThreatTagData(array)
}
}
}
useEffect(() => {
getSeveritNsEnum()
getClasstypeNsEnum()
getThreatTagNsEnum()
}, [])
// 暴露出table的方法和属性
const { dataSource, scroll, onChange, pagination, loading, onClick } = props;
const dataclumns = [
{
title: '受害者',
key: 'victims_list',
checked: true,
dataIndex: 'victims_list',
width: 150,
ellipsis: true,
render: (text, record) => (
<div className="allList">
<Tooltip title={record.victims_list && record.victims_list.toString()} placement="topLeft">{record.victims_list && record.victims_list.toString()}
</Tooltip>
</div>
)
},
{
title: '威胁类型',
key: 'threat_class',
checked: true,
dataIndex: 'threat_class',
width: 130,
ellipsis: true,
filters: [classtypeData] ? [...classtypeData] : [],
},
{
title: '威胁标签',
dataIndex: 'threat_tag',
key: 'threat_tag',
checked: true,
width: 200,
ellipsis: true,
filters: [threatTagData] ? [...threatTagData] : [],
render: (text, record) => {
return <div style={{ display: 'flex', }} className="hidden">
{record.threat_tag.length > 0 && record.threat_tag.map((item, index) => (
<div key={index}>
{index < 2 ? <Tooltip title={item} placement="topLeft" key={index}>
<Tag color="#108ee9" key={Math.random()}>{item}</Tag>
</Tooltip> : null}
</div>
))}
<div>
{record.threat_tag.length > 0 && record.threat_tag.map((item, i) => {
return (
<div key={i}>
{i === 2 ? <Tooltip title={record && record.threat_tag.toString()} placement="topLeft">
<span style={{ fontSize: '30px', marginTop: "-20px", display: "inline-block", }}>...</span>
</Tooltip> : null}
</div>
)
})}
</div>
</div>
}
},
{
title: '攻击结果',
key: 'attack_res',
width: 120,
dataIndex: 'attack_res',
checked: true,
ellipsis: true,
filters: [
{
text: '侦察',
value: 0
},
{
text: '失败',
value: 1,
},
{
text: '成功',
value: 2
},
{
text: '攻陷',
value: 3
},
],
render: (text, record) => (
<div style={{ display: 'flex' }}>
<div>{record.attack_res === "侦察" ? <div className="zhengcha">{record.attack_res}</div> : ''}</div>
<div>{record.attack_res === "成功" ? <div className="fail">{record.attack_res}</div> : ''}</div>
<div>{record.attack_res === "失败" ? <div className="success">{record.attack_res}</div> : ''}</div>
<div>{record.attack_res === "攻陷" ? <div className="gongxian">{record.attack_res}</div> : ''}</div>
</div>
)
},
{
title: '操作',
key: 'enabled',
fixed: 'right',
checked: true,
width: 132,
render: (text, record) => (
<span>
<span onClick={() => onClick(record)} className="detail">详情</span>
{/* <span className="verticalLine"></span> */}
{/* <span onClick={() => routeMenu(record)} className="detail">原始告警</span> */}
</span>
)
},
{
fixed: 'right',
key: 'more',
className: 'menuDown',
width: 50,
filterIcon: <span className="inco"><i className="iconfont"></i></span>,
// filterIcon: <PauseOutlined />,
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (
<div className="custom-filter-dropdown">
<CheckboxGroup options={dataclumns.filter(item => item.key !== 'more').map(item => {
return {
label: item['title'],
value: item['key'],
}
})} defaultValue={dataclumns.filter(item => item.key !== 'more' && item.checked).map(item => item.key)} onChange={onChangeColumn()} />
</div>
),
},
];
const [columns, setColumns] = useState(dataclumns.filter(item => item.checked || item.key === “more”))
const onChangeColumn = (checkedValues) => (checkedValues) => {
let data = []
dataclumns && dataclumns.forEach((item, index) => {
checkedValues && checkedValues.forEach(rs => {
if (item.key === rs) {
data.push(item)
}
})
})
data.push(dataclumns.filter(item => item.key === ‘more’)[0])
setColumns(data)
}
return (
<ResizeTable
className=“netList”
columns={columns}
dataSource={dataSource}
rowKey={(record) =>
complete${record.event_time}${Math.random()}
}
scroll={scroll}
loading={loading}
onChange={onChange}
pagination={pagination}
>
)
}
export default ColumnComponent;