From 573b5f22cd242e67ea420342f750115c6c386155 Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Fri, 19 Jun 2026 02:18:32 +0800 Subject: [PATCH] feat: add SQL remediation tracking delivery Fixes #2988 --- packages/base/src/locale/en-US/dmsMenu.ts | 1 + packages/base/src/locale/zh-CN/dmsMenu.ts | 1 + .../lib/api/sqle/service/SqlManage/index.d.ts | 26 +++- .../api/sqle/service/SqlManage/index.enum.ts | 20 ++++ .../lib/api/sqle/service/SqlManage/index.ts | 51 ++++++++ .../shared/lib/api/sqle/service/common.d.ts | 74 ++++++++++++ packages/sqle/src/data/EmitterKey.ts | 1 + .../sqle/src/locale/en-US/managementConf.ts | 13 ++ .../sqle/src/locale/en-US/sqlManagement.ts | 21 ++++ .../sqle/src/locale/zh-CN/managementConf.ts | 12 ++ .../sqle/src/locale/zh-CN/sqlManagement.ts | 33 +++++ .../page/SqlAnalyze/SqlAnalyze/SqlAnalyze.tsx | 30 +++-- .../src/page/SqlAnalyze/SqlAnalyze/index.tsx | 2 + .../SqlManage/RemediationCompare.tsx | 113 ++++++++++++++++++ .../src/page/SqlAnalyze/SqlManage/index.tsx | 17 ++- .../SQLEEIndex/RemediationStatusTag.tsx | 36 ++++++ .../Detail/ScanTypeSqlCollection/style.ts | 55 +++++++++ .../SqlManagementRemediationReport/index.tsx | 70 +++++++++++ packages/sqle/src/router/config.tsx | 4 + 19 files changed, 564 insertions(+), 16 deletions(-) create mode 100644 packages/sqle/src/page/SqlAnalyze/SqlManage/RemediationCompare.tsx create mode 100644 packages/sqle/src/page/SqlManagement/component/SQLEEIndex/RemediationStatusTag.tsx create mode 100644 packages/sqle/src/page/SqlManagementRemediationReport/index.tsx diff --git a/packages/base/src/locale/en-US/dmsMenu.ts b/packages/base/src/locale/en-US/dmsMenu.ts index 75c3595578..40443b36a2 100644 --- a/packages/base/src/locale/en-US/dmsMenu.ts +++ b/packages/base/src/locale/en-US/dmsMenu.ts @@ -63,6 +63,7 @@ export default { title: 'Global settings', userCenter: 'User center', reportStatistics: 'Report statistics', + sqlManagementRemediationReport: 'SQL management remediation report', viewRule: 'View rule', ruleManage: 'Rule management', system: 'System settings', diff --git a/packages/base/src/locale/zh-CN/dmsMenu.ts b/packages/base/src/locale/zh-CN/dmsMenu.ts index 232d307dd4..f5a4f89abf 100644 --- a/packages/base/src/locale/zh-CN/dmsMenu.ts +++ b/packages/base/src/locale/zh-CN/dmsMenu.ts @@ -65,6 +65,7 @@ export default { title: '全局设置', userCenter: '用户中心', reportStatistics: '报表统计', + sqlManagementRemediationReport: 'SQL 管控整改报表', viewRule: '查看规则', ruleManage: '规则管理', system: '系统设置', diff --git a/packages/shared/lib/api/sqle/service/SqlManage/index.d.ts b/packages/shared/lib/api/sqle/service/SqlManage/index.d.ts index 47e4da1ef4..c369d280f1 100644 --- a/packages/shared/lib/api/sqle/service/SqlManage/index.d.ts +++ b/packages/shared/lib/api/sqle/service/SqlManage/index.d.ts @@ -44,7 +44,9 @@ import { ISqlManageCodingReq, IPostSqlManageCodingResp, IGetSqlManageSqlAnalysisResp, - ISqlManageAnalysisChartResp + ISqlManageAnalysisChartResp, + IGetSqlManageRemediationResp, + IGetSqlManageRemediationOverviewResp } from '../common.d'; export interface IGetGlobalSqlManageListParams { @@ -162,6 +164,8 @@ export interface IExportSqlManageV1Params { sort_order?: exportSqlManageV1SortOrderEnum; } +export interface IExportGlobalSqlManageRemediationV1Params {} + export interface IGetSqlManageRuleTipsParams { project_name: string; } @@ -247,6 +251,26 @@ export interface IGetSqlManageListV2Params { export interface IGetSqlManageListV2Return extends IGetSqlManageListResp {} +export interface IGetSqlManageRemediationV1Params { + project_name: string; + + sql_manage_id: string; +} + +export interface IGetSqlManageRemediationV1Return + extends IGetSqlManageRemediationResp {} + +export interface IGetSqlManageRemediationOverviewV1Params { + project_name: string; + + instance_audit_plan_id?: number; + + audit_plan_type?: string; +} + +export interface IGetSqlManageRemediationOverviewV1Return + extends IGetSqlManageRemediationOverviewResp {} + export interface IExportSqlManageV2Params { project_name: string; diff --git a/packages/shared/lib/api/sqle/service/SqlManage/index.enum.ts b/packages/shared/lib/api/sqle/service/SqlManage/index.enum.ts index 0d04710fc9..331d8041db 100644 --- a/packages/shared/lib/api/sqle/service/SqlManage/index.enum.ts +++ b/packages/shared/lib/api/sqle/service/SqlManage/index.enum.ts @@ -102,6 +102,14 @@ export enum exportSqlManageV1SortOrderEnum { 'desc' = 'desc' } +export enum exportSqlManageRemediationV1ExportScopeEnum { + 'project' = 'project', + + 'data_source' = 'data_source', + + 'scan_task' = 'scan_task' +} + export enum GetSqlManageListV2FilterSourceEnum { 'audit_plan' = 'audit_plan', @@ -136,6 +144,18 @@ export enum GetSqlManageListV2FilterPriorityEnum { 'low' = 'low' } +export enum GetSqlManageListV2FilterRemediationStatusEnum { + 'resolved' = 'resolved', + + 'partially_fixed' = 'partially_fixed', + + 'unchanged' = 'unchanged', + + 'deteriorated' = 'deteriorated', + + 'newly_discovered' = 'newly_discovered' +} + export enum GetSqlManageListV2SortFieldEnum { 'first_appear_timestamp' = 'first_appear_timestamp', diff --git a/packages/shared/lib/api/sqle/service/SqlManage/index.ts b/packages/shared/lib/api/sqle/service/SqlManage/index.ts index 535cf514a6..f70533e1b5 100644 --- a/packages/shared/lib/api/sqle/service/SqlManage/index.ts +++ b/packages/shared/lib/api/sqle/service/SqlManage/index.ts @@ -18,6 +18,7 @@ import { IBatchUpdateSqlManageParams, IBatchUpdateSqlManageReturn, IExportSqlManageV1Params, + IExportGlobalSqlManageRemediationV1Params, IGetSqlManageRuleTipsParams, IGetSqlManageRuleTipsReturn, ISendSqlManageParams, @@ -28,6 +29,10 @@ import { IGetSqlManageSqlAnalysisChartV1Return, IGetSqlManageListV2Params, IGetSqlManageListV2Return, + IGetSqlManageRemediationV1Params, + IGetSqlManageRemediationV1Return, + IGetSqlManageRemediationOverviewV1Params, + IGetSqlManageRemediationOverviewV1Return, IExportSqlManageV2Params, IGetSqlManageListV3Params, IGetSqlManageListV3Return @@ -118,6 +123,19 @@ class SqlManageService extends ServiceBase { ); } + public exportGlobalSqlManageRemediationV1( + params: IExportGlobalSqlManageRemediationV1Params = {}, + options?: AxiosRequestConfig + ) { + const paramsData = this.cloneDeep(params); + + return this.get( + `/v1/sql_manages/remediation_exports`, + paramsData, + options + ); + } + public GetSqlManageRuleTips( params: IGetSqlManageRuleTipsParams, options?: AxiosRequestConfig @@ -199,6 +217,39 @@ class SqlManageService extends ServiceBase { ); } + public GetSqlManageRemediationV1( + params: IGetSqlManageRemediationV1Params, + options?: AxiosRequestConfig + ) { + const paramsData = this.cloneDeep(params); + const project_name = paramsData.project_name; + delete paramsData.project_name; + + const sql_manage_id = paramsData.sql_manage_id; + delete paramsData.sql_manage_id; + + return this.get( + `/v1/projects/${project_name}/sql_manages/${sql_manage_id}/remediation`, + paramsData, + options + ); + } + + public getSqlManageRemediationOverviewV1( + params: IGetSqlManageRemediationOverviewV1Params, + options?: AxiosRequestConfig + ) { + const paramsData = this.cloneDeep(params); + const project_name = paramsData.project_name; + delete paramsData.project_name; + + return this.get( + `/v1/projects/${project_name}/sql_manages/remediation_overview`, + paramsData, + options + ); + } + public exportSqlManageV2( params: IExportSqlManageV2Params, options?: AxiosRequestConfig diff --git a/packages/shared/lib/api/sqle/service/common.d.ts b/packages/shared/lib/api/sqle/service/common.d.ts index 57804bfc7f..c4ce25b8c6 100644 --- a/packages/shared/lib/api/sqle/service/common.d.ts +++ b/packages/shared/lib/api/sqle/service/common.d.ts @@ -5103,3 +5103,77 @@ export interface ICompleteWorkflowReq { workflow_id?: string; } + +export interface IRuleDiff { + new?: IAuditResult[]; + + resolved?: IAuditResult[]; + + unchanged?: IAuditResult[]; +} + +export interface ISqlManageRemediation { + first_audit_missing?: boolean; + + first_audit_result?: IAuditResult[]; + + first_audit_time?: string; + + id?: number; + + latest_audit_result?: IAuditResult[]; + + latest_audit_time?: string; + + remediation_status?: string; + + rule_diff?: IRuleDiff; + + sql?: string; + + sql_fingerprint?: string; +} + +export interface IGetSqlManageRemediationResp { + code?: number; + + data?: ISqlManageRemediation; + + message?: string; +} + +export interface ISqlManageRemediationOverviewStatusCount { + deteriorated?: number; + + newly_discovered?: number; + + partially_fixed?: number; + + resolved?: number; + + unchanged?: number; +} + +export interface ISqlManageRemediationOverview { + first_audit_missing_num?: number; + + first_score?: number; + + latest_score?: number; + + remediation_rate?: number; + + score_change?: number; + + sql_total_num?: number; + + remediation_status_count?: ISqlManageRemediationOverviewStatusCount; +} + +export interface IGetSqlManageRemediationOverviewResp { + code?: number; + + data?: ISqlManageRemediationOverview; + + message?: string; +} diff --git a/packages/sqle/src/data/EmitterKey.ts b/packages/sqle/src/data/EmitterKey.ts index 1650a2d028..58f4ec1475 100644 --- a/packages/sqle/src/data/EmitterKey.ts +++ b/packages/sqle/src/data/EmitterKey.ts @@ -27,6 +27,7 @@ enum EmitterKey { Refresh_Sql_Management_Conf_Overview_List = 'Refresh_Sql_Management_Conf_Overview_List', Refresh_Sql_Management_Conf_Detail_Sql_List = 'Refresh_Sql_Management_Conf_Detail_Sql_List', Export_Sql_Management_Conf_Detail_Sql_List = 'Export_Sql_Management_Conf_Detail_Sql_List', + Export_Sql_Management_Conf_Detail_Remediation = 'Export_Sql_Management_Conf_Detail_Remediation', Refresh_Sql_management_Exception_List = 'Refresh_Sql_management_Exception_List', diff --git a/packages/sqle/src/locale/en-US/managementConf.ts b/packages/sqle/src/locale/en-US/managementConf.ts index ba29a61570..a515518e1a 100644 --- a/packages/sqle/src/locale/en-US/managementConf.ts +++ b/packages/sqle/src/locale/en-US/managementConf.ts @@ -111,6 +111,19 @@ export default { auditImmediately: 'Audit immediately', auditImmediatelySuccessTips: 'Audit successfully', exportTips: 'Exporting scan task details', + remediationExport: 'SQL remediation', + remediationExportTips: 'Exporting SQL management remediation report', + remediationExportSuccessTips: + 'Export SQL management remediation report successfully', + remediationOverview: { + title: 'Remediation overview', + sqlTotal: 'SQL total', + firstScore: 'First score', + latestScore: 'Latest score', + scoreChange: 'Score change', + remediationRate: 'Remediation rate', + loadFailed: 'Failed to load remediation overview: {{message}}' + }, overview: { title: 'Overview', column: { diff --git a/packages/sqle/src/locale/en-US/sqlManagement.ts b/packages/sqle/src/locale/en-US/sqlManagement.ts index a52c99dd8c..0e97c50c07 100644 --- a/packages/sqle/src/locale/en-US/sqlManagement.ts +++ b/packages/sqle/src/locale/en-US/sqlManagement.ts @@ -11,6 +11,19 @@ export default { } } }, + remediationReport: { + pageTitle: 'SQL management remediation report', + description: + 'Export SQL management remediation tracking data in global scope. The Excel file contains Overview, Rule summary and Details.', + exportButton: 'Export SQL management remediation report', + exporting: 'Exporting SQL management remediation report', + exportSuccessTips: 'Export SQL management remediation report successfully', + scopeTitle: 'Export scope', + scopeContent: + 'Global scope: includes SQL management remediation data across all projects available to platform administrators.', + permissionTips: + 'Only platform administrators / global operators can see and export this report.' + }, statistics: { SQLTotalNum: 'SQL total', problemSQlNum: 'Problem SQL', @@ -67,9 +80,17 @@ export default { occurrenceCount: 'Occurrence count', personInCharge: 'Person in charge', status: 'Status', + remediationStatus: 'Remediation status', comment: 'Comment', endpoints: 'Endpoint info' }, + remediationStatus: { + resolved: 'Resolved', + partially_fixed: 'Partially fixed', + unchanged: 'Unchanged', + deteriorated: 'Deteriorated', + newly_discovered: 'Newly discovered' + }, filter: { time: 'Time range', status: { diff --git a/packages/sqle/src/locale/zh-CN/managementConf.ts b/packages/sqle/src/locale/zh-CN/managementConf.ts index d49f3a62d6..1252395e15 100644 --- a/packages/sqle/src/locale/zh-CN/managementConf.ts +++ b/packages/sqle/src/locale/zh-CN/managementConf.ts @@ -116,6 +116,18 @@ export default { auditImmediately: '立即审核', auditImmediatelySuccessTips: '审核成功', exportTips: '正在导出扫描任务详情', + remediationExport: 'SQL 管控整改', + remediationExportTips: '正在导出 SQL 管控整改报表', + remediationExportSuccessTips: 'SQL 管控整改报表导出成功', + remediationOverview: { + title: '整改概览', + sqlTotal: 'SQL 总数', + firstScore: '首次评分', + latestScore: '最末次评分', + scoreChange: '评分变化', + remediationRate: '整改率', + loadFailed: '整改概览加载失败:{{message}}' + }, overview: { title: '概览', column: { diff --git a/packages/sqle/src/locale/zh-CN/sqlManagement.ts b/packages/sqle/src/locale/zh-CN/sqlManagement.ts index 9d1f95c2e4..8591d7e73f 100644 --- a/packages/sqle/src/locale/zh-CN/sqlManagement.ts +++ b/packages/sqle/src/locale/zh-CN/sqlManagement.ts @@ -11,6 +11,18 @@ export default { } } }, + remediationReport: { + pageTitle: 'SQL 管控整改报表', + description: + '导出全局范围内 SQL 管控整改追踪数据,Excel 包含概览、规则维度汇总和明细。', + exportButton: '导出 SQL 管控整改报表', + exporting: '正在导出 SQL 管控整改报表', + exportSuccessTips: 'SQL 管控整改报表导出成功', + scopeTitle: '导出范围', + scopeContent: + '全局范围:覆盖当前用户有平台管理权限的全部项目 SQL 管控整改数据', + permissionTips: '仅平台超管 / 全局运维可见并可导出。' + }, statistics: { SQLTotalNum: 'SQL总数', problemSQlNum: '问题SQL数', @@ -92,9 +104,17 @@ export default { occurrenceCount: '出现数量', personInCharge: '负责人', status: '状态', + remediationStatus: '整改状态', comment: '备注', endpoints: '端点信息' }, + remediationStatus: { + resolved: '已整改', + partially_fixed: '部分整改', + unchanged: '未变化', + deteriorated: '恶化', + newly_discovered: '新发现' + }, filter: { time: '时间范围', status: { @@ -127,5 +147,18 @@ export default { statusReport: { title: 'SQL审核结果' } + }, + remediationCompare: { + tab: '整改对比', + title: '整改对比', + description: '对比首次审核与最末次审核结果,展示规则整改变化', + firstAuditMissing: '无首次审核快照,当前按最末次结果展示新发现问题。', + firstAuditResult: '首次审核结果', + latestAuditResult: '最末次审核结果', + ruleDiffTitle: '规则差异', + resolved: '已解决规则', + new: '新增规则', + unchanged: '维持规则', + emptyRules: '无命中规则' } }; diff --git a/packages/sqle/src/page/SqlAnalyze/SqlAnalyze/SqlAnalyze.tsx b/packages/sqle/src/page/SqlAnalyze/SqlAnalyze/SqlAnalyze.tsx index e33b5b516a..ed3a2d9bf3 100644 --- a/packages/sqle/src/page/SqlAnalyze/SqlAnalyze/SqlAnalyze.tsx +++ b/packages/sqle/src/page/SqlAnalyze/SqlAnalyze/SqlAnalyze.tsx @@ -12,6 +12,7 @@ import { SqlAnalyzeContStyleWrapper, SqlContStyleWrapper } from './style'; import useTableSchema from './useTableSchema'; import useSQLExecPlan from './useSQLExecPlan'; import { SqlAnalyzeProps } from '.'; +import RemediationCompare from '../SqlManage/RemediationCompare'; const SqlAnalyze: React.FC = (props) => { const { t } = useTranslation(); const { @@ -20,6 +21,7 @@ const SqlAnalyze: React.FC = (props) => { errorMessage, loading = false, performanceStatistics, + remediationCompare, errorType = 'error', sqlExecPlanCostDataSource, getSqlExecPlanCostDataSource, @@ -69,25 +71,27 @@ const SqlAnalyze: React.FC = (props) => { return ; }; const getSegmentedOption = useMemo(() => { + const options = [ + { + label: t('sqlAnalyze.sqlExplain'), + value: 'sql' + } + ]; + if (remediationCompare) { + options.push({ + label: t('sqlAnalyze.remediationCompare'), + value: 'remediation' + }); + } if ( !( Array.isArray(tableMetas?.table_meta_items) && tableMetas?.table_meta_items.length ) ) { - return [ - { - label: t('sqlAnalyze.sqlExplain'), - value: 'sql' - } - ]; + return options; } - return [ - { - label: t('sqlAnalyze.sqlExplain'), - value: 'sql' - } - ].concat( + return options.concat( (tableMetas?.table_meta_items ?? []).map((table) => { return { label: t('sqlAnalyze.tableTitle', { @@ -97,7 +101,7 @@ const SqlAnalyze: React.FC = (props) => { }; }) ); - }, [tableMetas?.table_meta_items, t]); + }, [remediationCompare, tableMetas?.table_meta_items, t]); return ( diff --git a/packages/sqle/src/page/SqlAnalyze/SqlAnalyze/index.tsx b/packages/sqle/src/page/SqlAnalyze/SqlAnalyze/index.tsx index 417d3dcd60..b0aa92c9d5 100644 --- a/packages/sqle/src/page/SqlAnalyze/SqlAnalyze/index.tsx +++ b/packages/sqle/src/page/SqlAnalyze/SqlAnalyze/index.tsx @@ -2,6 +2,7 @@ import { ResultStatusType } from 'antd/es/result'; import SqlAnalyze from './SqlAnalyze'; import { IPerformanceStatistics, + ISqlManageRemediation, ISQLExplain, ITableMeta, ITableMetas, @@ -17,6 +18,7 @@ export type SqlAnalyzeProps = { tableMetas?: ITableMetas; sqlExplain?: ISQLExplain; performanceStatistics?: IPerformanceStatistics; + remediationCompare?: ISqlManageRemediation; loading?: boolean; sqlExecPlanCostDataSource?: IChartPoint[]; getSqlExecPlanCostDataSourceLoading?: boolean; diff --git a/packages/sqle/src/page/SqlAnalyze/SqlManage/RemediationCompare.tsx b/packages/sqle/src/page/SqlAnalyze/SqlManage/RemediationCompare.tsx new file mode 100644 index 0000000000..9960cbb8cb --- /dev/null +++ b/packages/sqle/src/page/SqlAnalyze/SqlManage/RemediationCompare.tsx @@ -0,0 +1,113 @@ +import { Empty, Alert, Card, Space, Typography } from 'antd'; +import { useTranslation } from 'react-i18next'; +import AuditResultMessage from '../../../components/AuditResultMessage'; +import { ISqlManageRemediation } from '@actiontech/shared/lib/api/sqle/service/common'; +import RemediationStatusTag from '../../SqlManagement/component/SQLEEIndex/RemediationStatusTag'; + +type RemediationCompareProps = { + data?: ISqlManageRemediation; +}; + +const filterRuleNames = (names?: Array) => + names?.filter((name): name is string => !!name); + +const ruleNames = (rules?: ISqlManageRemediation['rule_diff']) => ({ + resolved: filterRuleNames(rules?.resolved?.map((rule) => rule.rule_name)), + newRules: filterRuleNames(rules?.new?.map((rule) => rule.rule_name)), + unchanged: filterRuleNames(rules?.unchanged?.map((rule) => rule.rule_name)) +}); + +const RuleList: React.FC<{ title: string; rules?: string[] }> = ({ + title, + rules +}) => { + const { t } = useTranslation(); + + return ( + + {title} + {rules?.length ? ( + rules.map((rule) => ( + {rule} + )) + ) : ( + + {t('sqlManagement.remediationCompare.emptyRules')} + + )} + + ); +}; + +const AuditResultList: React.FC<{ + results?: NonNullable; +}> = ({ results }) => { + if (!results?.length) { + return ; + } + + return ( + + {results.map((result, index) => ( + + ))} + + ); +}; + +const RemediationCompare: React.FC = ({ data }) => { + const { t } = useTranslation(); + + if (!data) { + return ; + } + + const rules = ruleNames(data.rule_diff); + + return ( + + + + + {t('sqlManagement.remediationCompare.description')} + + {data.first_audit_missing && ( + + )} + + + + + + + + + + + + + + + + + + ); +}; + +export default RemediationCompare; diff --git a/packages/sqle/src/page/SqlAnalyze/SqlManage/index.tsx b/packages/sqle/src/page/SqlAnalyze/SqlManage/index.tsx index bdf209f9a5..00f3b9a748 100644 --- a/packages/sqle/src/page/SqlAnalyze/SqlManage/index.tsx +++ b/packages/sqle/src/page/SqlAnalyze/SqlManage/index.tsx @@ -5,6 +5,7 @@ import { ResponseCode } from '../../../data/common'; import SqlManage from '@actiontech/shared/lib/api/sqle/service/SqlManage'; import { IPerformanceStatistics, + ISqlManageRemediation, ISQLExplain, ITableMetas } from '@actiontech/shared/lib/api/sqle/service/common'; @@ -30,6 +31,8 @@ const SQLManageAnalyze = () => { const [tableMetas, setTableMetas] = useState(); const [performanceStatistics, setPerformancesStatistics] = useState(); + const [remediationCompare, setRemediationCompare] = + useState(); const [ loading, @@ -53,11 +56,17 @@ const SQLManageAnalyze = () => { async (affectRowsEnabled = false) => { startGetSqlAnalyze(); try { - const res = await SqlManage.GetSqlManageSqlAnalysisV1({ + const [res, remediationRes] = await Promise.all([ + SqlManage.GetSqlManageSqlAnalysisV1({ sql_manage_id: urlParams.sqlManageId ?? '', project_name: projectName, affectRowsEnabled - }); + }), + SqlManage.GetSqlManageRemediationV1({ + sql_manage_id: urlParams.sqlManageId ?? '', + project_name: projectName + }) + ]); if (res.data.code === ResponseCode.SUCCESS) { if (affectRowsEnabled) { setPerformanceInfoLoaded(); @@ -70,6 +79,9 @@ const SQLManageAnalyze = () => { setSqlExplain(data?.sql_explain); setTableMetas(data?.table_metas); setPerformancesStatistics(data?.performance_statistics); + if (remediationRes.data.code === ResponseCode.SUCCESS) { + setRemediationCompare(remediationRes.data.data); + } setOptimizationCreationParams({ instance_name: queryParams?.instance_name, schema_name: queryParams?.schema, @@ -132,6 +144,7 @@ const SQLManageAnalyze = () => { sqlExplain={sqlExplain} errorMessage={errorMessage} performanceStatistics={performanceStatistics} + remediationCompare={remediationCompare} loading={loading} sqlExecPlanCostDataSource={data} getSqlExecPlanCostDataSourceLoading={ diff --git a/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/RemediationStatusTag.tsx b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/RemediationStatusTag.tsx new file mode 100644 index 0000000000..52c8e25b84 --- /dev/null +++ b/packages/sqle/src/page/SqlManagement/component/SQLEEIndex/RemediationStatusTag.tsx @@ -0,0 +1,36 @@ +import { BasicTag } from '@actiontech/dms-kit'; +import { t } from '../../../../locale'; + +export const remediationStatusOptions = [ + 'resolved', + 'partially_fixed', + 'unchanged', + 'deteriorated', + 'newly_discovered' +]; + +type RemediationStatusTagProps = { + status?: string; +}; + +const remediationStatusColor: Record = { + resolved: 'green', + partially_fixed: 'blue', + unchanged: 'gray', + deteriorated: 'red', + newly_discovered: 'orange' +}; + +const RemediationStatusTag: React.FC = ({ + status +}) => { + const currentStatus = status || 'unchanged'; + + return ( + + {t(`sqlManagement.table.remediationStatus.${currentStatus}` as any)} + + ); +}; + +export default RemediationStatusTag; diff --git a/packages/sqle/src/page/SqlManagementConf/Detail/ScanTypeSqlCollection/style.ts b/packages/sqle/src/page/SqlManagementConf/Detail/ScanTypeSqlCollection/style.ts index 52aabf0add..81fb7b9b9c 100644 --- a/packages/sqle/src/page/SqlManagementConf/Detail/ScanTypeSqlCollection/style.ts +++ b/packages/sqle/src/page/SqlManagementConf/Detail/ScanTypeSqlCollection/style.ts @@ -2,6 +2,61 @@ import { styled } from '@mui/material'; import { ActiontechTable } from '@actiontech/dms-kit/es/components/ActiontechTable'; export const ScanTypeSqlCollectionStyleWrapper = styled('section')` + .remediation-overview-card { + margin-bottom: 16px; + } + + .remediation-overview-metrics { + display: flex; + flex-wrap: wrap; + margin: -8px; + } + + .remediation-overview-metric { + min-width: 160px; + margin: 8px; + padding-right: 24px; + + strong { + display: block; + color: ${({ theme }) => theme.sharedTheme.uiToken.colorTextBase}; + font-size: 24px; + font-weight: 600; + line-height: 32px; + } + + span { + color: ${({ theme }) => theme.sharedTheme.uiToken.colorTextTertiary}; + font-size: 13px; + } + } + + .remediation-overview-status-list { + display: flex; + flex-wrap: wrap; + margin: 8px -8px -8px; + padding-top: 12px; + border-top: 1px solid + ${({ theme }) => theme.sharedTheme.uiToken.colorBorderSecondary}; + } + + .remediation-overview-status { + display: flex; + align-items: center; + margin: 8px; + + strong { + margin-left: 8px; + color: ${({ theme }) => theme.sharedTheme.uiToken.colorTextBase}; + font-size: 16px; + font-weight: 600; + } + } + + .remediation-overview-error { + color: ${({ theme }) => theme.sharedTheme.uiToken.colorError}; + } + .table-describe-column { max-width: 600px; } diff --git a/packages/sqle/src/page/SqlManagementRemediationReport/index.tsx b/packages/sqle/src/page/SqlManagementRemediationReport/index.tsx new file mode 100644 index 0000000000..da6cff3388 --- /dev/null +++ b/packages/sqle/src/page/SqlManagementRemediationReport/index.tsx @@ -0,0 +1,70 @@ +import { BasicButton, PageHeader } from '@actiontech/dms-kit'; +import SqlManage from '@actiontech/shared/lib/api/sqle/service/SqlManage'; +import { DownArrowLineOutlined } from '@actiontech/icons'; +import { Card, Space, Typography, message } from 'antd'; +import { useBoolean } from 'ahooks'; +import { useTranslation } from 'react-i18next'; + +const SqlManagementRemediationReport = () => { + const { t } = useTranslation(); + const [messageApi, messageContextHolder] = message.useMessage(); + const [exporting, { setTrue: startExport, setFalse: finishExport }] = + useBoolean(false); + + const handleExport = () => { + startExport(); + const hideLoading = messageApi.loading( + t('sqlManagement.remediationReport.exporting') + ); + + SqlManage.exportGlobalSqlManageRemediationV1({}, { responseType: 'blob' }) + .then((res) => { + if (res.status === 200) { + messageApi.success( + t('sqlManagement.remediationReport.exportSuccessTips') + ); + } + }) + .finally(() => { + hideLoading(); + finishExport(); + }); + }; + + return ( +
+ {messageContextHolder} + } + onClick={handleExport} + disabled={exporting} + > + {t('sqlManagement.remediationReport.exportButton')} + + } + /> + + + + {t('sqlManagement.remediationReport.scopeTitle')} + + + {t('sqlManagement.remediationReport.description')} + + + {t('sqlManagement.remediationReport.scopeContent')} + + + {t('sqlManagement.remediationReport.permissionTips')} + + + +
+ ); +}; + +export default SqlManagementRemediationReport; diff --git a/packages/sqle/src/router/config.tsx b/packages/sqle/src/router/config.tsx index 37b30cc5b8..eb8acb5c46 100644 --- a/packages/sqle/src/router/config.tsx +++ b/packages/sqle/src/router/config.tsx @@ -196,6 +196,10 @@ const UpdateCustomRule = React.lazy( ); const ReportStatistics = React.lazy(() => import('../page/ReportStatistics')); +const SqlManagementRemediationReport = React.lazy( + () => import('../page/SqlManagementRemediationReport') +); + const PushRuleConfiguration = React.lazy( () => import('../page/PushRuleConfiguration') );