diff --git a/backend/framework/domain/src/main/resources/migration/3.3.0/dml/V3.3.0_2_1__data.sql b/backend/framework/domain/src/main/resources/migration/3.3.0/dml/V3.3.0_2_1__data.sql index bb64ad756c..18cb42ca88 100644 --- a/backend/framework/domain/src/main/resources/migration/3.3.0/dml/V3.3.0_2_1__data.sql +++ b/backend/framework/domain/src/main/resources/migration/3.3.0/dml/V3.3.0_2_1__data.sql @@ -4,6 +4,9 @@ SET SESSION innodb_lock_wait_timeout = 7200; -- 组织管理员增加权限 INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'org_admin', 'ORGANIZATION_PROJECT_MEMBER_UPDATE'); +-- 项目管理员增加导出权限 +INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_API_REPORT:READ+EXPORT'); +INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN_REPORT:READ+EXPORT'); -- 初始化默认参数文件上传大小 INSERT INTO system_parameter (param_key, param_value, type) VALUES ('upload.file.size', '50', 'text'); diff --git a/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/PermissionConstants.java b/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/PermissionConstants.java index ff8534c025..f5313b8a9d 100644 --- a/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/PermissionConstants.java +++ b/backend/framework/sdk/src/main/java/io/metersphere/sdk/constants/PermissionConstants.java @@ -293,6 +293,7 @@ public class PermissionConstants { public static final String PROJECT_API_REPORT_UPDATE = "PROJECT_API_REPORT:READ+UPDATE"; public static final String PROJECT_API_REPORT_DELETE = "PROJECT_API_REPORT:READ+DELETE"; public static final String PROJECT_API_REPORT_SHARE = "PROJECT_API_REPORT:READ+SHARE"; + public static final String PROJECT_API_REPORT_EXPORT = "PROJECT_API_REPORT:READ+EXPORT"; /*------ end: API_REPORT ------*/ //个人中心 @@ -317,6 +318,7 @@ public class PermissionConstants { public static final String TEST_PLAN_REPORT_READ_UPDATE = "PROJECT_TEST_PLAN_REPORT:READ+UPDATE"; public static final String TEST_PLAN_REPORT_READ_SHARE = "PROJECT_TEST_PLAN_REPORT:READ+SHARE"; public static final String TEST_PLAN_REPORT_READ_DELETE = "PROJECT_TEST_PLAN_REPORT:READ+DELETE"; + public static final String TEST_PLAN_REPORT_READ_EXPORT = "PROJECT_TEST_PLAN_REPORT:READ+EXPORT"; /*------ end: TEST_PLAN ------*/ /*------ start: SYSTEM_TASK_CENTER ------*/ diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiReportController.java b/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiReportController.java index 8e584653c8..5192638433 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiReportController.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/controller/definition/ApiReportController.java @@ -112,4 +112,10 @@ public class ApiReportController { return apiReportService.getDetail(reportId, stepId); } + @GetMapping("/export/{reportId}") + @Operation(summary = "接口测试-用例报告-导出日志") + @RequiresPermissions(PermissionConstants.PROJECT_API_REPORT_EXPORT) + public void exportLog(@PathVariable String reportId) { + apiReportService.exportLog(reportId, SessionUtils.getUserId()); + } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/controller/scenario/ApiScenarioReportController.java b/backend/services/api-test/src/main/java/io/metersphere/api/controller/scenario/ApiScenarioReportController.java index e4280efe0b..772883f70a 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/controller/scenario/ApiScenarioReportController.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/controller/scenario/ApiScenarioReportController.java @@ -112,4 +112,10 @@ public class ApiScenarioReportController { return apiScenarioReportService.getDetail(reportId, stepId); } + @GetMapping("/export/{reportId}") + @Operation(summary = "接口测试-场景报告-导出日志") + @RequiresPermissions(PermissionConstants.PROJECT_API_REPORT_EXPORT) + public void exportLog(@PathVariable String reportId) { + apiScenarioReportService.exportLog(reportId, SessionUtils.getUserId()); + } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiReportLogService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiReportLogService.java index e22ddcaa6f..b671e746db 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiReportLogService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiReportLogService.java @@ -87,4 +87,19 @@ public class ApiReportLogService { }); operationLogService.batchAdd(logs); } + + public void exportLog(ApiReport report, String userId) { + Project project = projectMapper.selectByPrimaryKey(report.getProjectId()); + LogDTO dto = new LogDTO( + report.getProjectId(), + project.getOrganizationId(), + report.getId(), + userId, + OperationLogType.EXPORT.name(), + OperationLogModule.API_REPORT, + report.getName()); + dto.setPath("/api/report/case/export/" + report.getId()); + dto.setMethod(HttpMethodConstants.GET.name()); + operationLogService.add(dto); + } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiReportService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiReportService.java index 9c210704af..0dba815e07 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiReportService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/definition/ApiReportService.java @@ -258,4 +258,9 @@ public class ApiReportService { apiReport.setUpdateTime(System.currentTimeMillis()); apiReportMapper.updateByPrimaryKeySelective(apiReport); } + + public void exportLog(String reportId, String userId) { + ApiReport apiReport = apiReportMapper.selectByPrimaryKey(reportId); + Optional.ofNullable(apiReport).ifPresent(report -> apiReportLogService.exportLog(report, userId)); + } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioReportLogService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioReportLogService.java index ee72b7a1b1..acc81f20ca 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioReportLogService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioReportLogService.java @@ -87,4 +87,19 @@ public class ApiScenarioReportLogService { }); operationLogService.batchAdd(logs); } + + public void exportLog(ApiScenarioReport report, String userId) { + Project project = projectMapper.selectByPrimaryKey(report.getProjectId()); + LogDTO dto = new LogDTO( + report.getProjectId(), + project.getOrganizationId(), + report.getId(), + userId, + OperationLogType.EXPORT.name(), + OperationLogModule.API_TEST_REPORT_SCENARIO, + report.getName()); + dto.setPath("/api/report/scenario/export/" + report.getId()); + dto.setMethod(HttpMethodConstants.GET.name()); + operationLogService.add(dto); + } } diff --git a/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioReportService.java b/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioReportService.java index 3818e0c48d..8cc4737e89 100644 --- a/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioReportService.java +++ b/backend/services/api-test/src/main/java/io/metersphere/api/service/scenario/ApiScenarioReportService.java @@ -392,4 +392,9 @@ public class ApiScenarioReportService { reportExample.createCriteria().andIdIn(reportIds); return apiScenarioReportMapper.selectByExample(reportExample); } + + public void exportLog(String reportId, String userId) { + ApiScenarioReport apiScenarioReport = apiScenarioReportMapper.selectByPrimaryKey(reportId); + Optional.ofNullable(apiScenarioReport).ifPresent(report -> apiScenarioReportLogService.exportLog(report, userId)); + } } diff --git a/backend/services/api-test/src/main/resources/permission.json b/backend/services/api-test/src/main/resources/permission.json index acdd88a17b..e855525494 100644 --- a/backend/services/api-test/src/main/resources/permission.json +++ b/backend/services/api-test/src/main/resources/permission.json @@ -153,6 +153,9 @@ { "id": "PROJECT_API_REPORT:READ+SHARE", "name": "permission.api_doc.share" + }, + { + "id": "PROJECT_API_REPORT:READ+EXPORT" } ] } diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiReportControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiReportControllerTests.java index 2f226018fc..97e6bf6eee 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiReportControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiReportControllerTests.java @@ -80,6 +80,7 @@ public class ApiReportControllerTests extends BaseTest { private static final String GET = BASIC + "/get/"; private static final String BATCH_DELETE = BASIC + "/batch/delete"; private static final String DETAIL = BASIC + "/get/detail/"; + private static final String EXPORT_REPORT = BASIC + "/export/"; @Test @@ -487,4 +488,9 @@ public class ApiReportControllerTests extends BaseTest { .andExpect(status().is5xxServerError()); } + @Test + @Order(5) + public void testExportReport() throws Exception { + this.requestGet(EXPORT_REPORT + "api-report-id1"); + } } diff --git a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioReportControllerTests.java b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioReportControllerTests.java index 8517a7fdbe..47bdef9a78 100644 --- a/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioReportControllerTests.java +++ b/backend/services/api-test/src/test/java/io/metersphere/api/controller/ApiScenarioReportControllerTests.java @@ -87,6 +87,7 @@ public class ApiScenarioReportControllerTests extends BaseTest { private static final String GET = BASIC + "/get/"; private static final String BATCH_DELETE = BASIC + "/batch/delete"; private static final String DETAIL = BASIC + "/get/detail/"; + private static final String EXPORT_REPORT = BASIC + "/export/"; @Test @Order(1) @@ -532,5 +533,9 @@ public class ApiScenarioReportControllerTests extends BaseTest { .andExpect(status().is5xxServerError()); } - + @Test + @Order(9) + public void testExportReport() throws Exception { + this.requestGet(EXPORT_REPORT + "scenario-report-id1"); + } } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanReportController.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanReportController.java index b72f2b7760..8dc605bccf 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanReportController.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/controller/TestPlanReportController.java @@ -220,4 +220,12 @@ public class TestPlanReportController { public ResponseEntity previewMd(@PathVariable String projectId, @PathVariable String fileId, @PathVariable("compressed") boolean compressed) { return testPlanReportService.previewMd(projectId, fileId, compressed); } + + + @GetMapping("/export/{reportId}") + @Operation(summary = "测试计划-报告-导出日志") + @RequiresPermissions(PermissionConstants.TEST_PLAN_REPORT_READ_EXPORT) + public void exportLog(@PathVariable String reportId) { + testPlanReportService.exportLog(reportId, SessionUtils.getUserId()); + } } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportLogService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportLogService.java index b6c71319d3..20cad9d361 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportLogService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportLogService.java @@ -136,4 +136,19 @@ public class TestPlanReportLogService { log.setOriginalValue(JSON.toJSONBytes(report)); operationLogService.add(log); } + + public void exportLog(TestPlanReport report, String userId) { + Project project = projectMapper.selectByPrimaryKey(report.getProjectId()); + LogDTO log = new LogDTO( + report.getProjectId(), + project.getOrganizationId(), + report.getId(), + userId, + OperationLogType.EXPORT.name(), + report.getIntegrated() ? OperationLogModule.TEST_PLAN_GROUP_REPORT : OperationLogModule.TEST_PLAN_REPORT, + report.getName()); + log.setMethod(HttpMethodConstants.GET.name()); + log.setPath("/test-plan/report/export/" + report.getId()); + operationLogService.add(log); + } } diff --git a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportService.java b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportService.java index 8a119984db..95cbc0aba4 100644 --- a/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportService.java +++ b/backend/services/test-plan/src/main/java/io/metersphere/plan/service/TestPlanReportService.java @@ -1263,4 +1263,9 @@ public class TestPlanReportService { } return modules.stream().collect(Collectors.toMap(TestPlanBaseModule::getId, TestPlanBaseModule::getName)); } + + public void exportLog(String reportId, String userId) { + TestPlanReport testPlanReport = testPlanReportMapper.selectByPrimaryKey(reportId); + Optional.ofNullable(testPlanReport).ifPresent(report -> testPlanReportLogService.exportLog(report, userId)); + } } diff --git a/backend/services/test-plan/src/main/resources/permission.json b/backend/services/test-plan/src/main/resources/permission.json index 30c91fa8ce..f40036a5e1 100644 --- a/backend/services/test-plan/src/main/resources/permission.json +++ b/backend/services/test-plan/src/main/resources/permission.json @@ -45,6 +45,9 @@ }, { "id": "PROJECT_TEST_PLAN_REPORT:READ+DELETE" + }, + { + "id": "PROJECT_TEST_PLAN_REPORT:READ+EXPORT" } ] } diff --git a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanReportControllerTests.java b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanReportControllerTests.java index bfce2b95ab..c0b8cfbfa3 100644 --- a/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanReportControllerTests.java +++ b/backend/services/test-plan/src/test/java/io/metersphere/plan/controller/TestPlanReportControllerTests.java @@ -70,6 +70,7 @@ public class TestPlanReportControllerTests extends BaseTest { private static final String GET_SHARE_REPORT_API_REPORT_LIST = "/test-plan/report/share/detail/api-report"; private static final String GET_SHARE_REPORT_SCENARIO_REPORT_LIST = "/test-plan/report/share/detail/scenario-report"; private static final String GET_SHARE_REPORT_DETAIL_FUNCTIONAL_RESULT = "/test-plan/report/share/detail/functional/case/step"; + private static final String GET_EXPORT_REPORT = "/test-plan/report/export/"; @Autowired private TestPlanReportMapper testPlanReportMapper; @@ -473,4 +474,11 @@ public class TestPlanReportControllerTests extends BaseTest { example.createCriteria().andTestPlanIdEqualTo("plan_id_for_gen_report").andDefaultLayoutEqualTo(false); return testPlanReportMapper.selectByExample(example).getFirst().getId(); } + + @Test + @Order(25) + void testExportReport() throws Exception { + this.requestGet(GET_EXPORT_REPORT + "test-plan-report-id-1"); + this.requestGet(GET_EXPORT_REPORT + "test-plan-report-id-3"); + } }