1- import { useMemo , type FC } from 'react' ;
1+ import { useMemo , useRef , type FC } from 'react' ;
22
33import { WizardTable } from '@/compoments' ;
44
@@ -9,17 +9,56 @@ import { UploadOutlined } from '@ant-design/icons';
99import { AssetsProtsFilterDrawer } from '@/pages/TaskDetail/compoments/TableOptionsFilterDrawer/AssetsProtsFilterDrawer' ;
1010import type { CreateTableProps } from '@/compoments/WizardTable/types' ;
1111import type { TGetAssetsProtsResponse } from '@/apis/taskDetail/types' ;
12- import { getBatchInvokingScriptTaskNode } from '@/apis/task' ;
12+ import { getAnalysisScript , getBatchInvokingScriptTaskNode } from '@/apis/task' ;
1313import { useRequest , useSafeState } from 'ahooks' ;
14+ import CopyOutlined from '@/pages/TaskDetail/compoments/utils/CopyOutlined' ;
15+ import { copyToClipboard } from '@/utils' ;
16+ import { Button , message } from 'antd' ;
17+ import type { TDeleteValues } from '@/pages/ReportManage/ReportManage' ;
18+ import { CreateTaskScriptModal } from '@/pages/TaskPageList/compoment/CreateTaskScriptModal' ;
19+ import type { UseModalRefType } from '@/compoments/WizardModal/useModal' ;
1420
1521const PortAssets : FC = ( ) => {
1622 const [ page ] = WizardTable . usePage ( ) ;
23+
1724 const [ tableFilter , setTableFilter ] = useSafeState <
1825 Record < string , any > | undefined
1926 > ( { } ) ;
27+ const [ checkedValue , setCheckedValue ] = useSafeState < TDeleteValues > ( ) ;
28+ const ipListRef = useRef < string [ ] > ( [ ] ) ;
29+ const openCreateTaskModalRef = useRef < UseModalRefType > ( null ) ;
2030
2131 const taskNameColumns : CreateTableProps < TGetAssetsProtsResponse > [ 'columns' ] =
2232 [
33+ {
34+ title : '网络地址' ,
35+ dataIndex : 'host' ,
36+ columnsHeaderFilterType : 'input' ,
37+ width : 180 ,
38+ rowSelection : 'checkbox' ,
39+ rowSelectKeys : checkedValue ,
40+ onSelectChange : setCheckedValue ,
41+ render : ( value ) =>
42+ value ? (
43+ < div className = "flex items-center justify-center gap-1" >
44+ < div className = "text-clip" > { value } </ div >
45+ < CopyOutlined
46+ style = { { minWidth : 16 } }
47+ onClick = { ( ) => {
48+ copyToClipboard ( value )
49+ . then ( ( ) => {
50+ message . success ( '复制成功' ) ;
51+ } )
52+ . catch ( ( ) => {
53+ message . info ( '复制失败,请重试' ) ;
54+ } ) ;
55+ } }
56+ />
57+ </ div >
58+ ) : (
59+ '-'
60+ ) ,
61+ } ,
2362 {
2463 title : '任务名' ,
2564 dataIndex : 'task_id' ,
@@ -28,6 +67,21 @@ const PortAssets: FC = () => {
2867 } ,
2968 ] ;
3069
70+ const { runAsync : hostListRunAsync , loading } = useRequest (
71+ async ( params ) => {
72+ const result = await postAssetsProts ( params ) ;
73+ const list = result ?. data ?. list ;
74+ const resultHostList = list ?. map ( ( it ) => it ?. host ) ;
75+ ipListRef . current = resultHostList ;
76+ } ,
77+ {
78+ manual : true ,
79+ onSuccess : ( ) => {
80+ run ( ) ;
81+ } ,
82+ } ,
83+ ) ;
84+
3185 // 获取执行节点 列表
3286 const { data : taskNodeData } = useRequest ( async ( ) => {
3387 const result = await getBatchInvokingScriptTaskNode ( ) ;
@@ -40,64 +94,126 @@ const PortAssets: FC = () => {
4094 return resultData ;
4195 } ) ;
4296
97+ const { run } = useRequest (
98+ async ( ) => {
99+ const result = await getAnalysisScript ( ) ;
100+ const {
101+ data : { list } ,
102+ } = result ;
103+ const targetData = list . map ( ( value ) => ( {
104+ ...value ,
105+ ip_list : ipListRef . current ,
106+ } ) ) ;
107+ return targetData ;
108+ } ,
109+ {
110+ manual : true ,
111+ onSuccess : ( values ) => {
112+ openCreateTaskModalRef . current ?. open ( values ) ;
113+ setCheckedValue ( { host : { ids : [ ] , isAll : false } } ) ;
114+ } ,
115+ } ,
116+ ) ;
117+
43118 const columns = useMemo ( ( ) => {
44119 const protColumnsList = ProtColumns ( {
45120 taskNodeData : taskNodeData ?? [ ] ,
46121 } ) ;
47- const result = [
48- ...protColumnsList . slice ( 0 , 1 ) ,
49- ...taskNameColumns ,
50- ...protColumnsList . slice ( 1 ) ,
51- ] ;
122+ const result = [ ...taskNameColumns , ...protColumnsList . slice ( 1 ) ] ;
52123 return result ;
53- } , [ taskNodeData ] ) ;
124+ } , [ taskNodeData , checkedValue ] ) ;
125+
126+ const triggerScanBtnDisable = useMemo ( ( ) => {
127+ const tableFilter = page . getParams ( ) ?. filter ;
128+ const isCidr = tableFilter ?. cidr ?. length > 0 ;
129+ const isService = tableFilter ?. service_type ?. length > 0 ;
130+
131+ const isAll = checkedValue ?. host ?. isAll ;
132+ const isIds = checkedValue ?. host && checkedValue ?. host ?. ids ?. length > 0 ;
133+ return isCidr || isService || isAll || isIds ;
134+ } , [ page . getParams ( ) ] ) ;
135+
136+ // 批量漏洞扫描
137+ const headVulnerabilityScanning = ( ) => {
138+ const isAll = checkedValue ?. [ 'host' ] . isAll ;
139+ const idsList = checkedValue ?. [ 'host' ] . ids ;
140+ const dataSource = page . getDataSource ( ) ;
141+ const ipList = dataSource
142+ . map ( ( item ) => ( idsList ?. includes ( item . id ) ? item . host : undefined ) )
143+ . filter ( ( list ) => list ) ;
144+ ipListRef . current = ipList ;
145+ if ( ! isAll ) {
146+ run ( ) ;
147+ } else {
148+ hostListRunAsync ( {
149+ ...tableFilter ,
150+ limit : - 1 ,
151+ } ) ;
152+ }
153+ } ;
54154
55155 return (
56- < WizardTable
57- page = { page }
58- rowKey = "id"
59- columns = { columns }
60- tableHeader = { {
61- title : '端口资产列表' ,
62- options : {
63- dowloadFile : {
64- fileName : '端口资产 (' + dayjs ( ) . unix ( ) + ').csv' ,
65- params : {
66- typ : 'port' ,
67- data : {
68- ...tableFilter ,
69- limit : - 1 ,
156+ < >
157+ < WizardTable
158+ page = { page }
159+ rowKey = "id"
160+ columns = { columns }
161+ tableHeader = { {
162+ title : '端口资产列表' ,
163+ options : {
164+ dowloadFile : {
165+ fileName : '端口资产 (' + dayjs ( ) . unix ( ) + ').csv' ,
166+ params : {
167+ typ : 'port' ,
168+ data : {
169+ ...tableFilter ,
170+ limit : - 1 ,
171+ } ,
70172 } ,
173+ url : '/assets/export/report' ,
174+ method : 'post' ,
175+ type : 'primary' ,
176+ title : (
177+ < div >
178+ < UploadOutlined />
179+ < span className = "ml-2" > 导出 Excel</ span >
180+ </ div >
181+ ) ,
71182 } ,
72- url : '/assets/export/report' ,
73- method : 'post' ,
74- type : 'primary' ,
75- title : (
76- < div >
77- < UploadOutlined />
78- < span className = "ml-2" > 导出 Excel</ span >
79- </ div >
183+ ProFilterSwitch : {
184+ trigger : < AssetsProtsFilterDrawer page = { page } /> ,
185+ layout : 'vertical' ,
186+ } ,
187+ trigger : (
188+ < Button
189+ type = "primary"
190+ loading = { loading }
191+ onClick = { ( ) => headVulnerabilityScanning ( ) }
192+ disabled = { ! triggerScanBtnDisable }
193+ >
194+ 漏洞扫描
195+ </ Button >
80196 ) ,
81197 } ,
82- ProFilterSwitch : {
83- trigger : < AssetsProtsFilterDrawer page = { page } /> ,
84- layout : 'vertical' ,
85- } ,
86- } ,
87- } }
88- request = { async ( params , filter ) => {
89- setTableFilter ( filter ) ;
90- const { data } = await postAssetsProts ( {
91- ...params ,
92- ...filter ,
93- } ) ;
198+ } }
199+ request = { async ( params , filter ) => {
200+ setTableFilter ( filter ) ;
201+ const { data } = await postAssetsProts ( {
202+ ...params ,
203+ ...filter ,
204+ } ) ;
94205
95- return {
96- list : data ?. list ?? [ ] ,
97- pagemeta : data ?. pagemeta ,
98- } ;
99- } }
100- />
206+ return {
207+ list : data ?. list ?? [ ] ,
208+ pagemeta : data ?. pagemeta ,
209+ } ;
210+ } }
211+ />
212+ < CreateTaskScriptModal
213+ ref = { openCreateTaskModalRef }
214+ pageLoad = { page . onLoad }
215+ />
216+ </ >
101217 ) ;
102218} ;
103219
0 commit comments