diff --git a/CHANGELOG.md b/CHANGELOG.md index e90499f8..4535a764 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,32 +7,36 @@ * [x] [test]: 完成遗留的单元测试问题 * [x] [feature]: API服务里,工单执行完成后,可以提供一个回调地址去通知调用API的服务 * [x] [fix]: 修复 sql 审核结果列表中的 执行语句未高亮的问题 +* [x] [fix]: 添加 renderOrderDesc 并修改创建工单的工单名称的正则校验 * [x] [feature]: 工单上线中止功能. 补充 useGenerateOrderStepInfo 单元测试 * [x] [fix]: 问题修复: 在点击工单概览中被禁用的按钮时,会切换到其他的tab选项卡 -* [ ] * [x] [chore]: 2.2305.0 界面优化 * [x] [fix]: react-monaco-editor 组件全部添加属性: automaticLayout: true, 解决生产环境下在弹窗里第一次打开时无法输入的问题. (dms 中已更换成 @monaco-editor/react) -* [ ] [chore]: 2.2306.0 界面优化 -* [ ] [feature]: 工单列表支持工单号展示以及筛选 -* [ ] [chore]: 项目成员界面优化(dms中已移除此页面) -* [ ] [feature]: 全局配置添加 操作记录的过期时间配置项 +* [x] [chore]: 2.2306.0 界面优化 +* [x] [feature]: 工单列表支持工单号展示以及筛选 +* [x] [chore]: 项目成员界面优化(dms中已移除此页面) (该页面在 dms 已移除) +* [x] [feature]: 全局配置添加 操作记录的过期时间配置项 (需要后端支持) * [x] [feature]: 优化系统配置中开关的交互流程 (已将 sqle 下的登录对接已经消息推送迁移至dms下, 并更新为最新版本代码) -* [ ] [feature]: 支持格式化 SQL 语句 -* [ ] [feature]: 添加公共组件 EnterpriseFeatureDisplay 统一处理 ce 模式与 ee 模式下的某些页面的不同表现 (公共组件已添加, 处理部分页面) -* [ ] [fix]: 修复: 对创建好的扫描任务中的数据源跟数据库进行移除,点击保存之后还存在 -* [ ] [fix]: 修复: 格式化 SQL 语句后审核时解析出错(后续格式化功能可能会移至后端处理) -* [ ] [chore]: 一些界面优化: -* [ ] [fix]:系统设置中 Webhook 配置文案错误 以及 测试微信推送永远显示成功 -* [ ] [feature]: 重构项目概览页面 -* [ ] [chore]: 界面优化长期任务【2.2307.0】 -* [ ] [feature]: 新增自定义规则页面 -* [ ] [fix]: 在不同时间段执行 Order/Detail/index.test.tsx 和 AuditResultCollection.test.tsx 时, 生成的快照文件不一致. 原因: 这两个页面中有些按钮的状态需要通过当前时间和工单概览接口返回的数据源运维时间做判断, 由于在 test case 中未 mock 当前时间, 导致不同时间段的按钮状态不一致. -* [ ] [fix]: 将 RuleList 中的 ALL Tab 固定在第一位. 优化自定义规则表单. 优化创建完自定义规则后的页面展示. 创建规则模板和修改规则模板新增参数: is_custom_rule. -* [ ] [feature]: 页面增加数据库Logo 遗留问题: 1. selectOptionByIndex 方法改造, 支持自定义的 option. 2. 图片资源缓存问题 -* [ ] [test]: 增加 selectCustomOptionByClassName 并修改部分单元测试 -* [ ] [fix]: 补充系统配置的单元测试, 测试企业微信配置时添加字段校验 -* [ ] [fix]: 规则列表分类进行排序, 优化编辑规则模板时的规则列表样式 -* [ ] [chore]: 项目概览界面中数据源最小单位改成1,数据源tips提示文案修改, 没有任何工单时总计显示 0. -* [ ] [fix]:修复在创建自定义规则时先修改了按钮状态然后才进行表单校验, 导致按钮状态未复原的问题 -* [ ] [feature]: 项目概览的工单状态报表添加 正在上线 状态 -* [ ] [chore]: 测试企业微信配置时接收着UserId 添加 tips +* [x] [feature]: 支持格式化 SQL 语句 +* [x] [feature]: 添加公共组件 EnterpriseFeatureDisplay 统一处理 ce 模式与 ee 模式下的某些页面的不同表现 +* [x] [fix]: 修复: 对创建好的扫描任务中的数据源跟数据库进行移除,点击保存之后还存在 +* [x] [fix]: 修复: 格式化 SQL 语句后审核时解析出错(后续格式化功能可能会移至后端处理) +* [x] [chore]: 一些界面优化: +* [x] [fix]:系统设置中 Webhook 配置文案错误 以及 测试微信推送永远显示成功 +* [x] [feature]: 重构项目概览页面 +* [x] [chore]: 界面优化长期任务【2.2307.0】 +* [x] [feature]: 新增自定义规则页面 +* [x] [fix]: 在不同时间段执行 Order/Detail/index.test.tsx 和 AuditResultCollection.test.tsx 时, 生成的快照文件不一致. 原因: 这两个页面中有些按钮的状态需要通过当前时间和工单概览接口返回的数据源运维时间做判断, 由于在 test case 中未 mock 当前时间, 导致不同时间段的按钮状态不一致. +* [x] [fix]: 将 RuleList 中的 ALL Tab 固定在第一位. 优化自定义规则表单. 优化创建完自定义规则后的页面展示. 创建规则模板和修改规则模板新增参数: is_custom_rule. +* [x] [feature]: 页面增加数据库Logo 遗留问题: 1. selectOptionByIndex 方法改造, 支持自定义的 option. 2. 图片资源缓存问题 +* [x] [test]: 增加 selectCustomOptionByClassName 并修改部分单元测试 +* [x] [fix]: 补充系统配置的单元测试, 测试企业微信配置时添加字段校验 +* [x] [fix]: 规则列表分类进行排序, 优化编辑规则模板时的规则列表样式 +* [x] [chore]: 项目概览界面中数据源最小单位改成1,数据源tips提示文案修改, 没有任何工单时总计显示 0. +* [x] [fix]:修复在创建自定义规则时先修改了按钮状态然后才进行表单校验, 导致按钮状态未复原的问题 +* [x] [feature]: 项目概览的工单状态报表添加 正在上线 状态 +* [x] [chore]: 测试企业微信配置时接收着UserId 添加 tips + +* [ ] [chore]: 扩宽部分表单 name 限制长度: +* [ ] [feature]: 工单列表添加筛选项, 导出历史工单同时添加该筛选条件 +* [ ] [feature]: 支持导出 智能扫描 审核报告 diff --git a/craco.config.js b/craco.config.js index abf52cc2..878d3c18 100644 --- a/craco.config.js +++ b/craco.config.js @@ -101,7 +101,7 @@ module.exports = { const res = {}; for (let i = 0; i < 10; i++) { res[`/v${i}`] = { - target: 'http://124.70.158.246:8889', + target: 'http://10.186.60.56:10001', secure: false, changeOrigin: true, ws: true, diff --git a/src/api/audit_plan/index.d.ts b/src/api/audit_plan/index.d.ts index 48b947ca..27ddd430 100644 --- a/src/api/audit_plan/index.d.ts +++ b/src/api/audit_plan/index.d.ts @@ -128,6 +128,14 @@ export interface IGetAuditPlanReportV1Params { export interface IGetAuditPlanReportV1Return extends IGetAuditPlanReportResV1 {} +export interface IExportAuditPlanReportV1Params { + project_name: string; + + audit_plan_name: string; + + audit_plan_report_id: string; +} + export interface IGetAuditPlanReportsSQLsV1Params { project_name: string; diff --git a/src/api/audit_plan/index.ts b/src/api/audit_plan/index.ts index 7e6cef56..82d0d446 100644 --- a/src/api/audit_plan/index.ts +++ b/src/api/audit_plan/index.ts @@ -30,6 +30,7 @@ import { IGetAuditPlanReportsV1Return, IGetAuditPlanReportV1Params, IGetAuditPlanReportV1Return, + IExportAuditPlanReportV1Params, IGetAuditPlanReportsSQLsV1Params, IGetAuditPlanReportsSQLsV1Return, IGetTaskAnalysisDataParams, @@ -248,6 +249,27 @@ class AuditPlanService extends ServiceBase { ); } + public exportAuditPlanReportV1( + params: IExportAuditPlanReportV1Params, + options?: AxiosRequestConfig + ) { + const paramsData = this.cloneDeep(params); + const project_name = paramsData.project_name; + delete paramsData.project_name; + + const audit_plan_name = paramsData.audit_plan_name; + delete paramsData.audit_plan_name; + + const audit_plan_report_id = paramsData.audit_plan_report_id; + delete paramsData.audit_plan_report_id; + + return this.get( + `/v1/projects/${project_name}/audit_plans/${audit_plan_name}/reports/${audit_plan_report_id}/export`, + paramsData, + options + ); + } + public getAuditPlanReportsSQLsV1( params: IGetAuditPlanReportsSQLsV1Params, options?: AxiosRequestConfig diff --git a/src/api/common.d.ts b/src/api/common.d.ts index 642ed868..b828ddc6 100644 --- a/src/api/common.d.ts +++ b/src/api/common.d.ts @@ -10,6 +10,7 @@ import { CreateAuditWhitelistReqV1MatchTypeEnum, CreateCustomRuleReqV1LevelEnum, CustomRuleResV1LevelEnum, + DirectAuditFileReqV1SqlTypeEnum, DirectAuditReqV1SqlTypeEnum, GetWorkflowTasksItemV1StatusEnum, InstanceTaskResV1LastSyncStatusEnum, @@ -37,7 +38,7 @@ import { WorkflowRecordResV2StatusEnum, WorkflowResV2ModeEnum, WorkflowStepResV2StateEnum, - WorkflowStepResV2TypeEnum, + WorkflowStepResV2TypeEnum } from './common.enum'; export interface IBaseRes { @@ -544,6 +545,20 @@ export interface IDingTalkConfigurationV1 { is_enable_ding_talk_notify?: boolean; } +export interface IDirectAuditFileReqV1 { + file_contents?: string[]; + + instance_name?: string; + + instance_type?: string; + + project_name?: string; + + schema_name?: string; + + sql_type?: DirectAuditFileReqV1SqlTypeEnum; +} + export interface IDirectAuditReqV1 { instance_name?: string; @@ -782,6 +797,14 @@ export interface IGetDriversResV1 { message?: string; } +export interface IGetFeishuAuditConfigurationResV1 { + code?: number; + + data?: IFeishuConfigurationV1; + + message?: string; +} + export interface IGetFeishuConfigurationResV1 { code?: number; diff --git a/src/api/common.enum.ts b/src/api/common.enum.ts index ac1de224..cf619b90 100644 --- a/src/api/common.enum.ts +++ b/src/api/common.enum.ts @@ -108,6 +108,14 @@ export enum CustomRuleResV1LevelEnum { 'error' = 'error' } +export enum DirectAuditFileReqV1SqlTypeEnum { + 'sql' = 'sql', + + 'mybatis' = 'mybatis', + + 'UNKNOWN' = '' +} + export enum DirectAuditReqV1SqlTypeEnum { 'sql' = 'sql', diff --git a/src/api/configuration/index.d.ts b/src/api/configuration/index.d.ts index b54ced00..206ed9dd 100644 --- a/src/api/configuration/index.d.ts +++ b/src/api/configuration/index.d.ts @@ -8,6 +8,7 @@ import { IUpdateFeishuConfigurationReqV1, ITestFeishuConfigurationReqV1, ITestFeishuConfigResV1, + IGetFeishuAuditConfigurationResV1, IGetLDAPConfigurationResV1, ILDAPConfigurationReqV1, IGetLicenseResV1, @@ -59,6 +60,17 @@ export interface ITestFeishuConfigV1Params export interface ITestFeishuConfigV1Return extends ITestFeishuConfigResV1 {} +export interface IGetFeishuAuditConfigurationV1Return + extends IGetFeishuAuditConfigurationResV1 {} + +export interface IUpdateFeishuAuditConfigurationV1Params + extends IUpdateFeishuConfigurationReqV1 {} + +export interface IUpdateFeishuAuditConfigurationV1Return extends IBaseRes {} + +export interface ITestFeishuAuditConfigV1Return + extends ITestFeishuConfigResV1 {} + export interface IGetLDAPConfigurationV1Return extends IGetLDAPConfigurationResV1 {} diff --git a/src/api/configuration/index.ts b/src/api/configuration/index.ts index 7f2899af..72850db7 100644 --- a/src/api/configuration/index.ts +++ b/src/api/configuration/index.ts @@ -17,6 +17,10 @@ import { IUpdateFeishuConfigurationV1Return, ITestFeishuConfigV1Params, ITestFeishuConfigV1Return, + IGetFeishuAuditConfigurationV1Return, + IUpdateFeishuAuditConfigurationV1Params, + IUpdateFeishuAuditConfigurationV1Return, + ITestFeishuAuditConfigV1Return, IGetLDAPConfigurationV1Return, IUpdateLDAPConfigurationV1Params, IUpdateLDAPConfigurationV1Return, @@ -124,6 +128,34 @@ class ConfigurationService extends ServiceBase { ); } + public getFeishuAuditConfigurationV1(options?: AxiosRequestConfig) { + return this.get( + '/v1/configurations/feishu_audit', + undefined, + options + ); + } + + public updateFeishuAuditConfigurationV1( + params: IUpdateFeishuAuditConfigurationV1Params, + options?: AxiosRequestConfig + ) { + const paramsData = this.cloneDeep(params); + return this.patch( + '/v1/configurations/feishu_audit', + paramsData, + options + ); + } + + public testFeishuAuditConfigV1(options?: AxiosRequestConfig) { + return this.post( + '/v1/configurations/feishu_audit/test', + undefined, + options + ); + } + public getLDAPConfigurationV1(options?: AxiosRequestConfig) { return this.get( '/v1/configurations/ldap', diff --git a/src/api/sql_audit/index.d.ts b/src/api/sql_audit/index.d.ts index a9390f8f..fccd6d96 100644 --- a/src/api/sql_audit/index.d.ts +++ b/src/api/sql_audit/index.d.ts @@ -1,10 +1,15 @@ import { - IDirectAuditReqV1, + IDirectAuditFileReqV1, IDirectAuditResV1, + IDirectAuditReqV1, IDirectAuditReqV2, IDirectAuditResV2 } from '../common.d'; +export interface IDirectAuditFilesV1Params extends IDirectAuditFileReqV1 {} + +export interface IDirectAuditFilesV1Return extends IDirectAuditResV1 {} + export interface IDirectAuditV1Params extends IDirectAuditReqV1 {} export interface IDirectAuditV1Return extends IDirectAuditResV1 {} diff --git a/src/api/sql_audit/index.ts b/src/api/sql_audit/index.ts index 344444b2..98e09576 100644 --- a/src/api/sql_audit/index.ts +++ b/src/api/sql_audit/index.ts @@ -7,6 +7,8 @@ import ServiceBase from '../Service.base'; import { AxiosRequestConfig } from 'axios'; import { + IDirectAuditFilesV1Params, + IDirectAuditFilesV1Return, IDirectAuditV1Params, IDirectAuditV1Return, IDirectAuditV2Params, @@ -14,6 +16,18 @@ import { } from './index.d'; class SqlAuditService extends ServiceBase { + public directAuditFilesV1( + params: IDirectAuditFilesV1Params, + options?: AxiosRequestConfig + ) { + const paramsData = this.cloneDeep(params); + return this.post( + '/v1/audit_files', + paramsData, + options + ); + } + public directAuditV1( params: IDirectAuditV1Params, options?: AxiosRequestConfig diff --git a/src/api/workflow/index.d.ts b/src/api/workflow/index.d.ts index f18527a1..da78280f 100644 --- a/src/api/workflow/index.d.ts +++ b/src/api/workflow/index.d.ts @@ -47,6 +47,8 @@ export interface IGetWorkflowsV1Params { filter_workflow_id?: string; + fuzzy_search_workflow_desc?: string; + filter_create_time_from?: string; filter_create_time_to?: string; @@ -95,6 +97,8 @@ export interface IBatchCompleteWorkflowsV1Return extends IBaseRes {} export interface IExportWorkflowV1Params { filter_subject?: string; + fuzzy_search_workflow_desc?: string; + filter_create_time_from?: string; filter_create_time_to?: string; diff --git a/src/locale/zh-CN/auditPlan.ts b/src/locale/zh-CN/auditPlan.ts index 8ac530da..b69ec1eb 100644 --- a/src/locale/zh-CN/auditPlan.ts +++ b/src/locale/zh-CN/auditPlan.ts @@ -106,6 +106,12 @@ export default { result: '审核结果', analyze: '分析', }, + + export: { + buttonText: '下载审核报告', + exporting: '正在下载审核报告', + exportSuccessTips: '审核报告下载成功', + }, }, subscribeNotice: { diff --git a/src/page/AuditPlan/PlanDetail/Detail/Report/__snapshots__/index.test.tsx.snap b/src/page/AuditPlan/PlanDetail/Detail/Report/__snapshots__/index.test.tsx.snap index e19c82a9..2d2ac288 100644 --- a/src/page/AuditPlan/PlanDetail/Detail/Report/__snapshots__/index.test.tsx.snap +++ b/src/page/AuditPlan/PlanDetail/Detail/Report/__snapshots__/index.test.tsx.snap @@ -24,6 +24,18 @@ exports[`AuditPlanReport should match snapshot 1`] = ` auditPlan.report.passRage +
+ +
+
+ +
{ return spy; }; + const mockExportReport = () => { + const spy = jest.spyOn(audit_plan, 'exportAuditPlanReportV1'); + spy.mockImplementation(() => resolveThreeSecond({})); + return spy; + }; + test('should match snapshot', async () => { const getReportSpy = mockGetReport(); const getReportInfoSpy = mockGetReportInfo(); @@ -90,4 +96,42 @@ describe('AuditPlanReport', () => { await act(async () => jest.advanceTimersByTime(3000)); expect(getAllRulesSpy).toBeCalledTimes(AuditReport.length); }); + + test('should download audit report when clicked export button', async () => { + mockGetReport(); + mockGetReportInfo(); + const exportSpy = mockExportReport(); + + render(); + await act(async () => jest.advanceTimersByTime(3000)); + + expect(exportSpy).toBeCalledTimes(0); + + fireEvent.click(screen.getByText('auditPlan.report.export.buttonText')); + + expect(exportSpy).toBeCalledTimes(1); + expect(exportSpy).toBeCalledWith( + { + project_name: projectName, + audit_plan_name: 'auditPlanName1', + audit_plan_report_id: '32', + }, + { responseType: 'blob' } + ); + + expect( + screen.getByText('auditPlan.report.export.buttonText').closest('button') + ).toBeDisabled(); + expect( + screen.getByText('auditPlan.report.export.exporting') + ).toBeInTheDocument(); + + await act(async () => jest.advanceTimersByTime(3000)); + expect( + screen.queryByText('auditPlan.report.export.exporting') + ).not.toBeInTheDocument(); + expect( + screen.getByText('auditPlan.report.export.buttonText').closest('button') + ).not.toBeDisabled(); + }); }); diff --git a/src/page/AuditPlan/PlanDetail/Detail/Report/index.tsx b/src/page/AuditPlan/PlanDetail/Detail/Report/index.tsx index d2071c72..0246b682 100644 --- a/src/page/AuditPlan/PlanDetail/Detail/Report/index.tsx +++ b/src/page/AuditPlan/PlanDetail/Detail/Report/index.tsx @@ -1,5 +1,5 @@ -import { useRequest } from 'ahooks'; -import { Card, Table, Typography } from 'antd'; +import { useBoolean, useRequest } from 'ahooks'; +import { Button, Card, Table, Typography, message } from 'antd'; import { useTranslation } from 'react-i18next'; import { useParams } from 'react-router-dom'; import audit_plan from '../../../../../api/audit_plan'; @@ -8,6 +8,7 @@ import { formatTime } from '../../../../../utils/Common'; import { useCurrentProjectName } from '../../../../ProjectManage/ProjectDetail'; import { AuditPlanReportUrlParams } from './index.type'; import { AuditPlanReportTableHeader } from './tableHeader'; +import { ResponseCode } from '../../../../../data/common'; const AuditPlanReport: React.FC = () => { const { t } = useTranslation(); @@ -53,6 +54,33 @@ const AuditPlanReport: React.FC = () => { ); }; + const [ + exportButtonDisabled, + { setFalse: finishExport, setTrue: startExport }, + ] = useBoolean(false); + const exportReport = () => { + startExport(); + const hideLoading = message.loading(t('auditPlan.report.export.exporting')); + audit_plan + .exportAuditPlanReportV1( + { + project_name: projectName, + audit_plan_name: urlParams.auditPlanName ?? '', + audit_plan_report_id: urlParams.reportId ?? '', + }, + { responseType: 'blob' } + ) + .then((res) => { + if (res.data.code === ResponseCode.SUCCESS) { + message.success(t('auditPlan.report.export.exportSuccessTips')); + } + }) + .finally(() => { + hideLoading(); + finishExport(); + }); + }; + return ( { } + extra={ + + } >