diff --git a/.env.production b/.env.production index 817cf7a..80754fc 100644 --- a/.env.production +++ b/.env.production @@ -1,8 +1,8 @@ # 高鹏 本地 -# VITE_BASE_URL = "http://192.168.3.3:8082/" +VITE_BASE_URL = "http://192.168.3.3:8082/" # 秦晨凯 本地 -VITE_BASE_URL = "http://192.168.3.179:8082/" +# VITE_BASE_URL = "http://192.168.3.179:8082/" # 线上 地址 # VITE_BASE_URL = "http://legion-4g.yaklang.com:8080/pre/" \ No newline at end of file diff --git a/src/App/routers/routers.tsx b/src/App/routers/routers.tsx index f2a6a5a..be39ecf 100644 --- a/src/App/routers/routers.tsx +++ b/src/App/routers/routers.tsx @@ -22,6 +22,7 @@ import SystemManagement from '@/pages/SystemManagement'; import { PortAssets } from '@/pages/DataService/PortAssets'; import { AssetsVulns } from '@/pages/DataService/AssetsVulns'; import { SensitiveMessage } from '@/pages/DataService/SensitiveMessage'; +import { CveLoophole } from '@/pages/DataService/CveLoophole'; // 继承路由接口,增加name字段 type RouteObjectRootMy = RouteObject & { @@ -106,6 +107,12 @@ const routers: RouteObjectRootMy[] = [ key: 'sensitive-message', element: , }, + { + path: 'cve-loophole', + name: 'CVE漏洞库', + key: 'cve-loophole', + element: , + }, ], }, { diff --git a/src/apis/CveLoopholeApi/index.ts b/src/apis/CveLoopholeApi/index.ts new file mode 100644 index 0000000..dbbca44 --- /dev/null +++ b/src/apis/CveLoopholeApi/index.ts @@ -0,0 +1,14 @@ +import axios from '@/utils/axios'; +import { ResponseData, TableResponseData } from '@/utils/commonTypes'; +import { TCveQueryRequest, TCveQueryResponse } from './type'; + +// 节点是否安装成功 +const postCveQuery = ( + data: TCveQueryRequest, +): Promise>> => + axios.post>>( + `/cve/query`, + data, + ); + +export { postCveQuery }; diff --git a/src/apis/CveLoopholeApi/type.ts b/src/apis/CveLoopholeApi/type.ts new file mode 100644 index 0000000..46fe9a7 --- /dev/null +++ b/src/apis/CveLoopholeApi/type.ts @@ -0,0 +1,115 @@ +interface TCveQueryRequest { + cpe?: string[]; + CPEVersion?: { [key: string]: any }; + cve?: string; + CVEExploitabilityScore?: { [key: string]: any }; + CVEImpactScore?: { [key: string]: any }; + CVELastModifiedTime?: { [key: string]: any }; + CVEPublishedTime?: { [key: string]: any }; + CVESeverity?: { [key: string]: any }; + cvssV2Scope?: { [key: string]: any }; + cwe?: string; + keyword?: string[]; + Order?: { [key: string]: any }; + limit: number; + page: number; + total: number; + total_page: number; + order?: string; + order_by?: string; +} + +/** + * CVEList,CVE 列表 + * + * CVE,CVE 的具体内容 + */ +interface TCveQueryResponse { + /** + * 攻击复杂度 + */ + access_complexity: string; + /** + * 攻击路径 + */ + access_vector: string; + /** + * 需要的认证情况 + */ + authentication: string; + /** + * 可用性影响 + */ + availability_impact: string; + /** + * CVSS 评分 + */ + base_cvss_v2_score: number; + /** + * 泄密影响 + */ + confidentiality_impact: string; + /** + * CVE 编号 + */ + cve: string; + /** + * 漏洞类型/CWE类型 + */ + cwe: string; + /** + * 漏洞详细描述信息 + */ + description: string; + /** + * 精确搜索,如果为 True,表明搜索结果应该是准确的,如果为 False 说明可能不准确 + */ + exact_search: boolean; + /** + * 利用评分 + */ + exploitability_score: number; + /** + * CVE 的搜索来源 + */ + from: string; + /** + * 影响评分 + */ + impact_score: number; + /** + * 完整性影响 + */ + integrity_impact: string; + /** + * 最近修改日期 + */ + last_modified_date: string; + /** + * 是否可以获取所有权限 + */ + obtain_all_privilege: boolean; + /** + * 是否可以获取其他权限 + */ + obtain_other_privilege: boolean; + /** + * 是否可以获取用户权限 + */ + obtain_user_privilege: boolean; + /** + * 发布日期 + */ + published_date: string; + /** + * 严重程度 + */ + severity: string; + /** + * 是否需要用户交互利用 + */ + user_interaction_required: boolean; + vulnerable_product: string; +} + +export type { TCveQueryRequest, TCveQueryResponse }; diff --git a/src/apis/SystemManagementApi/index.ts b/src/apis/SystemManagementApi/index.ts index 50a24fc..092e1d6 100644 --- a/src/apis/SystemManagementApi/index.ts +++ b/src/apis/SystemManagementApi/index.ts @@ -21,4 +21,16 @@ const postAddUser = ( ): Promise> => axios.post>('/user', data); -export { getUserList, postAddUser }; +// 重置密码 +const postUserReset = (data: { + username: string; +}): Promise> => + axios.post>( + `/user/reset?username=${data.username}`, + ); + +// 添加用户 +const deleteUser = (username: string): Promise> => + axios.delete>(`/user?username=${username}`); + +export { getUserList, postAddUser, postUserReset, deleteUser }; diff --git a/src/compoments/WizardTable/index.tsx b/src/compoments/WizardTable/index.tsx index 4a69a09..81d471b 100644 --- a/src/compoments/WizardTable/index.tsx +++ b/src/compoments/WizardTable/index.tsx @@ -1,5 +1,5 @@ import { useCallback, useEffect, useMemo, useReducer, useRef } from 'react'; -import { message, Spin, Table } from 'antd'; +import { Button, message, Spin, Table } from 'antd'; import { AnyObject } from 'antd/es/_util/type'; import { useRequest, useSafeState } from 'ahooks'; @@ -37,7 +37,7 @@ const WizardTable = ( const preFilter = useRef(undefined); // 跟踪上次的 filter, 触发请求 const manualReq = useRef(false); // 表格容器的 ref,用来控制滚动 - const tableRef = useRef(null); + const tableContainerRef = useRef(null); const [state, dispatch] = useReducer(reducer, initialValue); const { dataSource, params, filter } = state; @@ -78,6 +78,7 @@ const WizardTable = ( } dispatch({ loading: false, noResetFields: true }); + setIsBottom(false); } }, { @@ -106,7 +107,8 @@ const WizardTable = ( [params, filter], ); - const [wizardScrollHeight, wizardScrollWidth] = useListenWidth(tableRef); + const [wizardScrollHeight, wizardScrollWidth] = + useListenWidth(tableContainerRef); const [isBottom, setIsBottom] = useSafeState(false); // 表格容器的 state, 用来保存计算得到的可滚动高度和表格高度 @@ -115,10 +117,11 @@ const WizardTable = ( // 动态计算表格高度 useEffect(() => { const tableFilterDomHeight = - tableRef.current?.children[0].getBoundingClientRect().height ?? 0; + tableContainerRef.current?.children[0].getBoundingClientRect() + .height ?? 0; const antTableHeader = - tableRef?.current && - tableRef.current.querySelector('.ant-table-header'); + tableContainerRef?.current && + tableContainerRef.current.querySelector('.ant-table-header'); const antTableHeaderHeight = antTableHeader?.getBoundingClientRect().height ?? 0; @@ -136,14 +139,15 @@ const WizardTable = ( const pagemetaStatus = (pagemeta?.page ?? 0) * (pagemeta?.limit ?? 0) >= (pagemeta?.total ?? 1); + if ( dataSource && dataSource.length > 0 && - tableRef.current && + tableContainerRef.current && !pagemetaStatus ) { // 获取表格 DOM 节点 - const tableElement = tableRef.current.querySelector( + const tableElement = tableContainerRef.current.querySelector( '#table-container > .ant-table-wrapper', ); if (tableElement && !state.loading) { @@ -198,29 +202,17 @@ const WizardTable = ( requestTable(request); }, [requestTable]); - // 回到顶部,并清空数据方法 - const handClearFilter = () => { - if (tableRef.current) { - // 滚动条回到顶部 - tableRef.current.scrollTop = 0; - - dispatch({ - dataSource: [], // 清空数据源 - }); - } - }; - // 对外提供方法 // 刷新 page.refresh = async () => { - handClearFilter(); + handleScrollToFirstRow(); runAsync(request, true); }; // 手动触发 - page.onLoad = (arg) => { - handClearFilter(); - runAsync(request, true, arg); + page.onLoad = async (arg) => { + handleScrollToFirstRow(); + await runAsync(request, false, arg); }; // 获取表格参数 @@ -230,7 +222,7 @@ const WizardTable = ( // 清除页面选中项 page.clear = () => { - handClearFilter(); + handleScrollToFirstRow(); dispatch({ params: { page: 1, @@ -247,6 +239,7 @@ const WizardTable = ( // 更改高级筛选项 page.editFilter = (args) => { + handleScrollToFirstRow(); dispatch({ filter: { ...state.filter, @@ -312,6 +305,27 @@ const WizardTable = ( .exhaustive(); }; + const tableRef = useRef(null); + + // 回到顶部,并清空数据方法 + const handleScrollToFirstRow = () => { + if (tableRef.current) { + // 调用 scrollTo 方法,传递 (0, 0) 来滚动到顶部 + tableRef.current.scrollTo(0, 0); + dispatch({ + params: { + page: 1, + limit: state.params!.limit, + total: state.pagemeta!.total, + total_page: state.pagemeta!.total_page, + }, + dataSource: [], // 清空数据源 + }); + + runAsync(request, true); + } + }; + // 底部loading状态 const bottomLoading = useMemo(() => { const pagemeta = state.pagemeta; @@ -321,16 +335,15 @@ const WizardTable = ( (pagemeta?.total ?? 1); const width = - (tableRef.current?.getBoundingClientRect().width ?? 0) - 108; + (tableContainerRef.current?.getBoundingClientRect().width ?? 0) - + 108; return (
{pagemetaStatus && @@ -367,7 +380,7 @@ const WizardTable = (
( /> ( pagination={false} scroll={{ x: wizardScrollHeight, - y: height - 1, + y: isBottom || state.loading ? height - 48 : height, + scrollToFirstRowOnChange: true, }} onScroll={throttledTableOnScrollFn} loading={state.loading && dataSource!.length === 0} + virtual /> - {bottomLoading} + {(isBottom || state.loading) && dataSource?.length + ? bottomLoading + : null} {/* 右侧抽屉 */} diff --git a/src/compoments/WizardTableFilter/index.tsx b/src/compoments/WizardTableFilter/index.tsx index 4ec996a..3458f0f 100644 --- a/src/compoments/WizardTableFilter/index.tsx +++ b/src/compoments/WizardTableFilter/index.tsx @@ -81,7 +81,8 @@ const WizardTableFilter: FC<{ {props?.options?.trigger} {proFilterSwitch?.trigger && !filterState?.proSwitchStatus && ( -
+
+
高级筛选
)} diff --git a/src/index.scss b/src/index.scss index 1ffcf02..f26f524 100644 --- a/src/index.scss +++ b/src/index.scss @@ -128,24 +128,7 @@ li { } /* 强制让横向滚动条始终出现 */ -.ant-table-body{ +.ant-table-tbody-virtual{ padding-bottom: 48px; - scrollbar-width: auto !important; - scrollbar-color: auto !important; - overflow-x: scroll !important; /* 强制显示横向滚动条 */ - &::-webkit-scrollbar { - width: 8px; - height: 8px; - -webkit-appearance: none; - } - - &::-webkit-scrollbar-thumb { - background-color: rgba(167, 164, 164, 0.8); - border-radius: 10px; - } - - &::-webkit-scrollbar-track-piece { - background-color: rgba(0, 0, 0, 0); - border-radius: 0; - } + border-right: 1px solid #f0f0f0; } diff --git a/src/pages/DataService/AssetsVulns/index.tsx b/src/pages/DataService/AssetsVulns/index.tsx index 157b696..7e5a50d 100644 --- a/src/pages/DataService/AssetsVulns/index.tsx +++ b/src/pages/DataService/AssetsVulns/index.tsx @@ -3,10 +3,7 @@ import { FC, useMemo } from 'react'; import { WizardTable } from '@/compoments'; import { getAssetsValueFilter, postAssetsVulns } from '@/apis/taskDetail'; -import { - AssetsVulnsColumns, - ProtColumns, -} from '@/pages/TaskDetail/compoments/Columns'; +import { AssetsVulnsColumns } from '@/pages/TaskDetail/compoments/Columns'; import dayjs from 'dayjs'; import { UploadOutlined } from '@ant-design/icons'; import { useRequest } from 'ahooks'; @@ -62,7 +59,7 @@ const AssetsVulns: FC = () => { const result = [ ...columns.slice(0, 1), ...taskNameColumns, - ...ProtColumns.slice(1), + ...columns.slice(1), ]; return result; }, [data]); diff --git a/src/pages/DataService/CveLoophole/CVETable.module.scss b/src/pages/DataService/CveLoophole/CVETable.module.scss new file mode 100644 index 0000000..e2cf0b7 --- /dev/null +++ b/src/pages/DataService/CveLoophole/CVETable.module.scss @@ -0,0 +1,71 @@ +.cve-list-product-success { + border: 1px solid #ffe5c6; + color: #ffb660; + display: flex; + flex-direction: row; + align-items: center; + border-radius: 4px; + width: fit-content; + height: 22px; + + .cve-list-severity { + padding: 2px 6px; + border-right: 1px solid #ffe5c6; + background-color: rgba(255, 213, 131, 0.1); + border-radius: 4px 0 0 4px; + height: 20px; + line-height: 20px; + display: flex; + align-items: center; + } + + .cve-list-baseCVSSv2Score { + padding: 2px 6px; + color: #85899e; + height: 20px; + line-height: 20px; + display: flex; + align-items: center; + } +} + +.cve-list-product-warning { + border: 1px solid #ffe5c6; + color: #ffb660; + + .cve-list-severity { + border-right: 1px solid #ffe5c6; + background-color: rgba(255, 213, 131, 0.1); + } +} + +.cve-list-product-info { + border: 1px solid #fbc6a1; + color: #f28b44; + + .cve-list-severity { + border-right: 1px solid #fbc6a1; + background-color: #fbe7d9; + } +} + + +.cve-list-product-danger { + border: 1px solid #f3c2bf; + color: #f7544a; + + .cve-list-severity { + border-right: 1px solid #f3c2bf; + background-color: rgba(246, 84, 74, 0.2); + } +} + +.cve-list-product-serious { + border: 1px solid #e99a95; + color: #cb2318; + + .cve-list-severity { + border-right: 1px solid #e99a95; + background-color: rgba(203, 35, 24, 0.2); + } +} \ No newline at end of file diff --git a/src/pages/DataService/CveLoophole/compoments/CveLoopholeFilterDrawer.tsx b/src/pages/DataService/CveLoophole/compoments/CveLoopholeFilterDrawer.tsx new file mode 100644 index 0000000..7720049 --- /dev/null +++ b/src/pages/DataService/CveLoophole/compoments/CveLoopholeFilterDrawer.tsx @@ -0,0 +1,75 @@ +import { FC } from 'react'; +import { Button, Form, Radio } from 'antd'; + +import { UsePageRef } from '@/hooks/usePage'; +import { difficultyList, levelList, orderList, routeList } from '../data'; +import { FilterTag } from './FilterTag'; + +const CveLoopholeFilterDrawer: FC<{ page: UsePageRef }> = ({ page }) => { + const { Item } = Form; + + const headReset = () => { + page.editFilter({ + AccessVector: [], + AccessComplexity: [], + Severity: [], + }); + }; + return ( +
+
+
CVE 查询条件
+ +
+
+
披露时间
+ + + +
+ +
+
更新时间
+ + + +
+ +
+
利用路径
+ + + +
+
+
利用难度
+ + + +
+
+
漏洞级别
+ + + +
+
+ ); +}; + +export { CveLoopholeFilterDrawer }; diff --git a/src/pages/DataService/CveLoophole/compoments/FilterTag.tsx b/src/pages/DataService/CveLoophole/compoments/FilterTag.tsx new file mode 100644 index 0000000..20185c1 --- /dev/null +++ b/src/pages/DataService/CveLoophole/compoments/FilterTag.tsx @@ -0,0 +1,49 @@ +import { FC, memo } from 'react'; + +import { randomString } from '@/utils'; + +interface TIpTagProps { + value?: string[]; + onChange?: (value: TIpTagProps['value']) => TIpTagProps['value']; + data: Array; +} + +const FilterTag: FC = memo(({ value, onChange, data }) => { + return ( +
+ {data.map((it) => + value?.includes(it.value) ? ( +
+ onChange?.( + value?.includes(it.value) + ? value?.filter((key) => key !== it.value) + : value?.concat(it.value), + ) + } + > + {it.label} +
+ ) : ( +
+ onChange?.( + value?.includes(it.value) + ? value?.filter((key) => key !== it.value) + : value?.concat(it.value), + ) + } + > + {it.label} +
+ ), + )} +
+ ); +}); + +export { FilterTag }; diff --git a/src/pages/DataService/CveLoophole/data.ts b/src/pages/DataService/CveLoophole/data.ts new file mode 100644 index 0000000..819ae60 --- /dev/null +++ b/src/pages/DataService/CveLoophole/data.ts @@ -0,0 +1,32 @@ +const difficultyList = [ + { value: 'HIGH', label: '困难' }, + { value: 'MEDIUM', label: '一般' }, + { value: 'LOW', label: '容易' }, +]; + +const routeList = [ + { value: 'NETWORK', label: '网络' }, + { value: 'ADJACENT_NETWORK', label: '局域网' }, + { value: 'LOCAL', label: '本地' }, + { value: 'PHYSICAL', label: '物理' }, +]; + +const levelList = [ + { value: 'CRITICAL', label: '严重' }, + { value: 'HIGH', label: '高危' }, + { value: 'MEDIUM', label: '中危' }, + { value: 'LOW', label: '低危' }, +]; + +const orderList = [ + { + value: 'desc', + label: '顺序', + }, + { + value: 'asc', + label: '正序', + }, +]; + +export { difficultyList, routeList, levelList, orderList }; diff --git a/src/pages/DataService/CveLoophole/index.tsx b/src/pages/DataService/CveLoophole/index.tsx new file mode 100644 index 0000000..12b1187 --- /dev/null +++ b/src/pages/DataService/CveLoophole/index.tsx @@ -0,0 +1,222 @@ +import { FC } from 'react'; + +import dayjs from 'dayjs'; +import classNames from 'classnames'; + +import { postCveQuery } from '@/apis/CveLoopholeApi'; +import { TCveQueryResponse } from '@/apis/CveLoopholeApi/type'; +import { WizardTable } from '@/compoments'; +import { CreateTableProps } from '@/compoments/WizardTable/types'; +import { YakitTag } from '@/compoments/YakitTag/YakitTag'; +import styles from './CVETable.module.scss'; +import { SeverityMapTag } from '@/pages/TaskDetail/compoments/utils'; +import { CveLoopholeFilterDrawer } from './compoments/CveLoopholeFilterDrawer'; +import { Button, Input, Popover, Select, Space } from 'antd'; +import { useSafeState } from 'ahooks'; +import { SyncOutlined } from '@ant-design/icons'; + +const options = [ + { + value: 'cve', + label: 'CVE', + text: 'CVE编号或关键字搜索', + }, + { + value: 'cwe', + label: 'CWE', + text: 'CWE编号搜索', + }, +]; + +const CveLoophole: FC = () => { + const [page] = WizardTable.usePage(); + const [search, setSearch] = useSafeState({ + key: 'cve', + value: '', + }); + + const columns: CreateTableProps['columns'] = [ + { + dataIndex: 'cve', + title: 'CVE编号', + width: 120, + }, + { + dataIndex: 'description', + title: '概述', + width: 180, + }, + { + dataIndex: 'cwe', + title: 'CWE编号', + width: 120, + render: (text: string) => + text ? ( + <> + {text.split('|').map((ele) => ( + + {ele} + + ))} + + ) : ( + '' + ), + }, + { + dataIndex: 'vulnerable_product', + title: '影响产品', + width: 120, + }, + { + dataIndex: 'severity', + title: '漏洞级别', + width: 120, + render: (value, record) => { + if (value) { + const toLowerCaseValue = value.toLowerCase(); + const targetItem = SeverityMapTag.find((item) => + item.key.includes(toLowerCaseValue), + ); + return ( +
+
+ {targetItem?.name} +
+ + {record.exploitability_score ?? 0} + +
+ ); + } else { + return '-'; + } + }, + }, + { + dataIndex: 'published_date', + title: '披露时间', + width: 180, + render: (value) => + value ? dayjs(value).format('YYYY-MM-DD MM:hh') : '-', + }, + { + dataIndex: 'last_modified_date', + title: '更新时间', + width: 180, + render: (value) => + value ? dayjs(value).format('YYYY-MM-DD MM:hh') : '-', + }, + ]; + + return ( + + + - - - + + {title === '重置密码' ? ( + + + + ) : ( + + + + )}
diff --git a/src/pages/SystemManagement/Outline.tsx b/src/pages/SystemManagement/Outline.tsx new file mode 100644 index 0000000..25ad67c --- /dev/null +++ b/src/pages/SystemManagement/Outline.tsx @@ -0,0 +1,24 @@ +import { FC } from 'react'; + +import { TIcon } from '@/types'; + +const Outline: FC = (props) => ( + + + +); + +export default Outline; diff --git a/src/pages/SystemManagement/SystemManagement.tsx b/src/pages/SystemManagement/SystemManagement.tsx index 9112c45..d4d6eb7 100644 --- a/src/pages/SystemManagement/SystemManagement.tsx +++ b/src/pages/SystemManagement/SystemManagement.tsx @@ -1,17 +1,29 @@ import { FC, useRef } from 'react'; -import { Button, Tag } from 'antd'; +import { Button, message, Popover } from 'antd'; -import { getUserList } from '@/apis/SystemManagementApi'; +import { + deleteUser, + getUserList, + postUserReset, +} from '@/apis/SystemManagementApi'; import { User, UserRequest } from '@/apis/SystemManagementApi/types'; import { WizardTable } from '@/compoments'; import { UseModalRefType } from '@/compoments/WizardModal/useModal'; import { CreateTableProps } from '@/compoments/WizardTable/types'; -import { PlusOutlined } from '@ant-design/icons'; +import { InfoCircleOutlined, PlusOutlined } from '@ant-design/icons'; import { CreateUserModal } from './CreateUserModal'; +import TableDeleteOutlined from '@/assets/task/TableDeleteOutlined'; +import TableFormOutlined from '@/assets/task/TableFormOutlined'; +import Outline from './Outline'; +import { useRequest, useSafeState } from 'ahooks'; +import { UsePageRef } from '@/hooks/usePage'; const SystemManagement: FC = () => { const [page] = WizardTable.usePage(); const CreateUserModalRef = useRef(null); + const [modalTitle, setModalTitle] = useSafeState< + '创建用户' | '编辑用户' | '重置密码' + >('创建用户'); const UserColumns: CreateTableProps['columns'] = [ { @@ -21,35 +33,73 @@ const SystemManagement: FC = () => { { title: '邮箱', dataIndex: 'email', - width: 320, - }, - { - title: 'Roles', - dataIndex: 'role', - width: 160, - render: (val) => - val && Array.isArray(val) ? ( -
- {val.map((it) => ( - - {it} - - ))} -
- ) : ( - '-' - ), }, { title: '操作', dataIndex: 'report_id', fixed: 'right', - width: 160, - render: (_, record) =>
这是操作项 {record?.email}
, + width: 120, + render: (_, record) => { + return ( +
+
+ { + setModalTitle('重置密码'); + if (record.username) { + if (record.username === 'root') { + message.info( + '无法重置超级管理员root的帐户密码', + ); + } else { + postUserReset({ + username: record.username, + }).then((res) => { + const { data } = res; + CreateUserModalRef.current?.open( + { + ...record, + ...data, + type: 'reset', + }, + ); + }); + } + } else { + message.info( + '获取用户名失败,请刷新页面重试', + ); + } + }} + /> +
+ { + setModalTitle('编辑用户'); + CreateUserModalRef.current?.open({ + ...record, + type: 'edit', + }); + }} + /> + +
+ ); + }, }, ]; const handCreateUser = async () => { + setModalTitle('创建用户'); CreateUserModalRef.current?.open(); }; @@ -97,11 +147,70 @@ const SystemManagement: FC = () => { /> ); }; export { SystemManagement }; + +const DeletePopover: FC<{ + username: string; + localRefrech: UsePageRef['localRefrech']; +}> = ({ username, localRefrech }) => { + const [open, setOpen] = useSafeState(false); + + const { loading, runAsync } = useRequest(deleteUser, { manual: true }); + + return ( + setOpen(newOpen)} + content={ +
+ + +
+ } + title={ +
+ + 删除确定 +
+ } + placement="left" + trigger="click" + > + +
+ ); +}; diff --git a/src/pages/TaskDetail/compoments/Columns.tsx b/src/pages/TaskDetail/compoments/Columns.tsx index 35ba2cc..7861072 100644 --- a/src/pages/TaskDetail/compoments/Columns.tsx +++ b/src/pages/TaskDetail/compoments/Columns.tsx @@ -84,11 +84,6 @@ const AssetsVulnsColumns = (filterData: { transformList: any[]; }): CreateTableProps['columns'] => { return [ - // { - // title: '序号', - // dataIndex: 'id', - // width: 80, - // }, { title: '标题', dataIndex: 'title', diff --git a/src/pages/TaskPageList/compoment/CreateTaskScriptCard.tsx b/src/pages/TaskPageList/compoment/CreateTaskScriptCard.tsx index 2a55095..ccf3621 100644 --- a/src/pages/TaskPageList/compoment/CreateTaskScriptCard.tsx +++ b/src/pages/TaskPageList/compoment/CreateTaskScriptCard.tsx @@ -32,7 +32,7 @@ const CreateTaskScriptCard: FC = ({ const target_script_type = scriptTypeOption.find( (it) => it.value === items.script_type, - )?.label; + )?.value; const resuteItems = { ...items, diff --git a/src/pages/TaskPageList/compoment/CreateTaskScriptModal.tsx b/src/pages/TaskPageList/compoment/CreateTaskScriptModal.tsx index 790aa80..5c6d914 100644 --- a/src/pages/TaskPageList/compoment/CreateTaskScriptModal.tsx +++ b/src/pages/TaskPageList/compoment/CreateTaskScriptModal.tsx @@ -35,7 +35,7 @@ const CreateTaskScriptModal = forwardRef< modal={model1} title="选择脚本" > -
+
{scriptData?.map((items) => ( = ({ await getTaskStartEditDispaly(record.id).then(({ data }) => { const transformModalFormdata = { ...data, - script_type: scriptTypeOption.find( - (it) => it.label === data?.script_type, - )?.value, id: record.id, headerGroupValue, execution_date: data?.params?.execution_date @@ -182,11 +179,11 @@ const PublicAndExecutionOperateRender: FC = ({ : undefined, params: { ...data.params, - 'preset-protes': data?.params?.['preset-protes'] - ? (data?.params['preset-protes']) - .split(', ') - .map((item) => item.trim()) - : [], + // 'preset-protes': data?.params?.['preset-protes'] + // ? (data?.params['preset-protes']) + // .split(', ') + // .map((item) => item.trim()) + // : [], }, }; itemsRef.current = transformModalFormdata; @@ -591,9 +588,6 @@ const ExecutionOperateRender: FC = ({ await getTaskStartEditDispaly(record.id).then(({ data }) => { const transformModalFormdata = { ...data, - script_type: scriptTypeOption.find( - (it) => it.label === data?.script_type, - )?.value, headerGroupValue, sched_type: 3, timestamp: @@ -608,11 +602,11 @@ const ExecutionOperateRender: FC = ({ : undefined, params: { ...data.params, - 'preset-protes': data?.params?.['preset-protes'] - ? (data?.params['preset-protes']) - .split(', ') - .map((item) => item.trim()) - : [], + // 'preset-protes': data?.params?.['preset-protes'] + // ? (data?.params['preset-protes']) + // .split(', ') + // .map((item) => item.trim()) + // : [], }, }; itemsRef.current = transformModalFormdata; diff --git a/src/pages/TaskScript/compoment/CreateTaskItems.tsx b/src/pages/TaskScript/compoment/CreateTaskItems.tsx index 3d16cf5..8c58265 100644 --- a/src/pages/TaskScript/compoment/CreateTaskItems.tsx +++ b/src/pages/TaskScript/compoment/CreateTaskItems.tsx @@ -37,7 +37,7 @@ type TScriptGrounpList = Array<{ value: string; label: string }>; type TCreateTaskItemsProps = ( title: string, - scriptTypeValue: '端口与漏洞扫描' | '敏感信息', + scriptTypeValue: 'portAndVulScan' | 'weakinfo', scriptGroupList: TScriptGrounpList, scannerDataList?: TScannerDataList, ) => ItemType[] | any; @@ -351,18 +351,18 @@ const CreateTaskItems: TCreateTaskItemsProps = ( {({ setFieldValue }) => { return ( {scriptTypeValue === - '端口与漏洞扫描' + 'portAndVulScan' ? '扫描目标' : '关键词'}
} name={[ 'params', - scriptTypeValue === '端口与漏洞扫描' + scriptTypeValue === 'portAndVulScan' ? 'target' : 'keyword', ]} @@ -385,7 +385,7 @@ const CreateTaskItems: TCreateTaskItemsProps = ( [ 'params', scriptTypeValue === - '端口与漏洞扫描' + 'portAndVulScan' ? 'target' : 'keyword', ], @@ -418,7 +418,7 @@ const CreateTaskItems: TCreateTaskItemsProps = ( [ 'params', scriptTypeValue === - '端口与漏洞扫描' + 'portAndVulScan' ? 'target' : 'keyword', ], @@ -430,7 +430,7 @@ const CreateTaskItems: TCreateTaskItemsProps = ( ); }} - {scriptTypeValue === '端口与漏洞扫描' && ( + {scriptTypeValue === 'portAndVulScan' && ( {({ setFieldValue }) => { return ( @@ -465,7 +465,7 @@ const CreateTaskItems: TCreateTaskItemsProps = ( }} )} - {scriptTypeValue === '端口与漏洞扫描' && ( + {scriptTypeValue === 'portAndVulScan' && ( {({ setFieldValue }) => ( )} - {scriptTypeValue === '端口与漏洞扫描' && ( + {scriptTypeValue === 'portAndVulScan' && ( @@ -537,7 +537,7 @@ const CreateTaskItems: TCreateTaskItemsProps = ( )} - {scriptTypeValue === '端口与漏洞扫描' && ( + {scriptTypeValue === 'portAndVulScan' && ( @@ -656,7 +656,7 @@ const CreateTaskItems: TCreateTaskItemsProps = ( ); }} - {scriptTypeValue === '端口与漏洞扫描' && ( + {scriptTypeValue === 'portAndVulScan' && ( { const preScannerStr = Array.isArray( diff --git a/src/pages/TaskScript/compoment/StartUpScriptModal.tsx b/src/pages/TaskScript/compoment/StartUpScriptModal.tsx index 7634af3..4be1433 100644 --- a/src/pages/TaskScript/compoment/StartUpScriptModal.tsx +++ b/src/pages/TaskScript/compoment/StartUpScriptModal.tsx @@ -142,9 +142,10 @@ const StartUpScriptModal = forwardRef< async open(items, scriptGroupList) { await runAsync() .then(() => { + console.log(items, 'items'); const targetSetFormData = { task_id: `[${items?.script_name}]-[${dayjs().format('M月DD日')}]-[${randomString(6)}]-`, - script_type: items?.script_type, + // script_type: items?.script_type, ...items, execution_date: diff --git a/src/pages/TaskScript/compoment/TaskScriptDrawer.tsx b/src/pages/TaskScript/compoment/TaskScriptDrawer.tsx index 23e1273..38a6278 100644 --- a/src/pages/TaskScript/compoment/TaskScriptDrawer.tsx +++ b/src/pages/TaskScript/compoment/TaskScriptDrawer.tsx @@ -78,7 +78,7 @@ const TaskScriptDrawer = forwardRef< loading={loading} drawer={drawer} title={title} - width={'60%'} + width={'75%'} onClose={() => { form.resetFields(); }} diff --git a/src/pages/TaskScript/data.ts b/src/pages/TaskScript/data.ts index a5d4144..f5652f8 100644 --- a/src/pages/TaskScript/data.ts +++ b/src/pages/TaskScript/data.ts @@ -46,11 +46,14 @@ const transformFormData = (values: any): TPostTaskStartRequest => { params: { ...values.params, plugins: values.params?.plugins?.ScriptName?.ids?.join(','), - 'enable-brute': `${values?.params?.['enable-brute']}`, - 'enbale-cve-baseline': `${values?.params?.['enbale-cve-baseline']}`, - 'preset-protes': values?.params?.['preset-protes'] - ? `${values?.params?.['preset-protes']?.join()}` - : undefined, + 'enable-brute': + typeof values?.params?.['enable-brute'] === 'boolean' + ? `${values?.params?.['enable-brute']}` + : undefined, + 'enbale-cve-baseline': + typeof values?.params?.['enbale-cve-baseline'] === 'boolean' + ? `${values?.params?.['enbale-cve-baseline']}` + : undefined, }, param_files: values?.param_files ? { @@ -70,9 +73,6 @@ const transformFormData = (values: any): TPostTaskStartRequest => { task_type: 'batch-invoking-script', enable_sched: values?.['sched_type'] !== 1 ? true : false, timestamp: undefined, - script_type: scriptTypeOption.find( - (it) => it.label === values?.script_type, - )?.value, }; };