浏览代码

Merge branch 'fix/修正报告Blob文件名路径' of jyx/dcjxb.microservice into master

金逸霄 6 天之前
父节点
当前提交
cd24c02449

+ 1 - 7
abilities/exam-sprint/infrastructure/src/main/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/storage/AzureBlobExamSprintReportStorage.java

@@ -75,7 +75,7 @@ public class AzureBlobExamSprintReportStorage implements ExamSprintReportStorage
             byte[] pdfBytes,
             Instant expiresAt) {
         long uploadStartedNanos = System.nanoTime();
-        String blobName = blobName(reportId, fileName);
+        String blobName = normalizeSegment(fileName, "fileName");
         BlobClient blobClient = containerClient.getBlobClient(blobName);
         log.info(
                 "exam_sprint_report_azure_storage_upload_stage_completed reportId={} reportType={} stage=client_resolved storageObjectKey={} blobName={} fileName={} pdfByteLength={} durationMs={}",
@@ -163,12 +163,6 @@ public class AzureBlobExamSprintReportStorage implements ExamSprintReportStorage
         return storageObjectKey.substring(storageObjectKey.lastIndexOf('/') + 1);
     }
 
-    private String blobName(String reportId, String fileName) {
-        return normalizeSegment(reportId, "reportId")
-                + "/"
-                + normalizeSegment(fileName, "fileName");
-    }
-
     private static String normalizeDownloadUrlPrefix(String value) {
         if (!hasText(value)) {
             throw new IllegalStateException("Azure storage download-url-prefix is incomplete");

+ 18 - 19
abilities/exam-sprint/infrastructure/src/test/java/cn/yunzhixue/ability/center/examsprint/infrastructure/report/storage/AzureBlobExamSprintReportStorageTest.java

@@ -79,7 +79,7 @@ class AzureBlobExamSprintReportStorageTest {
                 Duration.ofMinutes(15));
 
         assertThat(downloadUrl).isEqualTo(URI.create(
-                "https://dcjxbtest.blob.core.chinacloudapi.cn/report/report-123/exam-sprint-outlook-report-report-123.pdf"));
+                "https://dcjxbtest.blob.core.chinacloudapi.cn/report/exam-sprint-outlook-report-report-123.pdf"));
         verifyNoInteractions(containerClient);
     }
 
@@ -97,11 +97,11 @@ class AzureBlobExamSprintReportStorageTest {
                 Duration.ofMinutes(15));
 
         assertThat(downloadUrl).isEqualTo(URI.create(
-                "https://dcjxbtest.blob.core.chinacloudapi.cn/report/report-123/file.pdf"));
+                "https://dcjxbtest.blob.core.chinacloudapi.cn/report/file.pdf"));
     }
 
     @Test
-    void generateDownloadUrlEncodesReportScopedFileNameWithoutReportTypePath() {
+    void generateDownloadUrlEncodesFileNameWithoutReportScopedPath() {
         BlobContainerClient containerClient = mock(BlobContainerClient.class);
         AzureBlobExamSprintReportStorage storage = new AzureBlobExamSprintReportStorage(
                 containerClient,
@@ -110,13 +110,13 @@ class AzureBlobExamSprintReportStorageTest {
                 FIXED_CLOCK);
 
         URI downloadUrl = storage.generateDownloadUrl(
-                "report-123/John Doe-报告 #1?.pdf",
+                "John Doe-报告 #1?.pdf",
                 Duration.ofMinutes(15));
 
         assertThat(downloadUrl.toString()).isEqualTo(
-                "https://dcjxbtest.blob.core.chinacloudapi.cn/report/report-123/John%20Doe-报告%20%231%3F.pdf");
+                "https://dcjxbtest.blob.core.chinacloudapi.cn/report/John%20Doe-报告%20%231%3F.pdf");
         assertThat(downloadUrl.getRawPath()).isEqualTo(
-                "/report/report-123/John%20Doe-报告%20%231%3F.pdf");
+                "/report/John%20Doe-报告%20%231%3F.pdf");
         assertThat(downloadUrl.getRawQuery()).isNull();
         assertThat(downloadUrl.getRawFragment()).isNull();
     }
@@ -176,7 +176,7 @@ class AzureBlobExamSprintReportStorageTest {
     }
 
     @Test
-    void uploadUsesReportIdAndFileNameAsBlobNameAndSendsHeadersAndMetadataInUploadRequest() {
+    void uploadUsesFileNameAsBlobNameAndSendsHeadersAndMetadataInUploadRequest() {
         BlobContainerClient containerClient = mock(BlobContainerClient.class);
         BlobClient blobClient = mock(BlobClient.class);
         when(containerClient.getBlobClient(anyString())).thenReturn(blobClient);
@@ -193,9 +193,9 @@ class AzureBlobExamSprintReportStorageTest {
                 new byte[]{1, 2, 3},
                 Instant.parse("2026-01-10T00:00:00Z"));
 
-        assertThat(storedFile.storageObjectKey()).isEqualTo("report-123/file.pdf");
+        assertThat(storedFile.storageObjectKey()).isEqualTo("file.pdf");
         assertThat(storedFile.fileName()).isEqualTo("file.pdf");
-        verify(containerClient).getBlobClient("report-123/file.pdf");
+        verify(containerClient).getBlobClient("file.pdf");
         verify(blobClient).uploadWithResponse(argThat(options ->
                         options.getLength() == 3
                                 && options.getHeaders() != null
@@ -234,8 +234,8 @@ class AzureBlobExamSprintReportStorageTest {
                 .contains("exam_sprint_report_azure_storage_upload_completed")
                 .contains("reportId=report-123")
                 .contains("reportType=OUTLOOK")
-                .contains("storageObjectKey=report-123/file.pdf")
-                .contains("blobName=report-123/file.pdf")
+                .contains("storageObjectKey=file.pdf")
+                .contains("blobName=file.pdf")
                 .contains("fileName=file.pdf")
                 .contains("pdfByteLength=3")
                 .contains("durationMs=")
@@ -274,8 +274,8 @@ class AzureBlobExamSprintReportStorageTest {
                 .contains("exam_sprint_report_azure_storage_upload_failed")
                 .contains("reportId=report-123")
                 .contains("reportType=OUTLOOK")
-                .contains("storageObjectKey=report-123/file.pdf")
-                .contains("blobName=report-123/file.pdf")
+                .contains("storageObjectKey=file.pdf")
+                .contains("blobName=file.pdf")
                 .contains("fileName=file.pdf")
                 .contains("pdfByteLength=3")
                 .contains("durationMs=")
@@ -290,7 +290,7 @@ class AzureBlobExamSprintReportStorageTest {
     }
 
     @Test
-    void uploadUsesReportIdAndDisplayFileNameAsTheStorageObjectKey() {
+    void uploadUsesDisplayFileNameAsTheStorageObjectKey() {
         BlobContainerClient containerClient = mock(BlobContainerClient.class);
         BlobClient blobClient = mock(BlobClient.class);
         when(containerClient.getBlobClient(anyString())).thenReturn(blobClient);
@@ -313,9 +313,8 @@ class AzureBlobExamSprintReportStorageTest {
                 new byte[]{2},
                 Instant.parse("2026-01-10T00:00:00Z"));
 
-        assertThat(firstStoredFile.storageObjectKey()).isEqualTo("report-123/same-display-name.pdf");
-        assertThat(secondStoredFile.storageObjectKey()).isEqualTo("report-456/same-display-name.pdf");
-        assertThat(firstStoredFile.storageObjectKey()).isNotEqualTo(secondStoredFile.storageObjectKey());
+        assertThat(firstStoredFile.storageObjectKey()).isEqualTo("same-display-name.pdf");
+        assertThat(secondStoredFile.storageObjectKey()).isEqualTo("same-display-name.pdf");
         assertThat(firstStoredFile.fileName()).isEqualTo("same-display-name.pdf");
         assertThat(secondStoredFile.fileName()).isEqualTo("same-display-name.pdf");
     }
@@ -331,7 +330,7 @@ class AzureBlobExamSprintReportStorageTest {
                 true,
                 null);
         return new SimpleResponse<>(
-                new HttpRequest(HttpMethod.PUT, "https://example.test/report/report-123/file.pdf"),
+                new HttpRequest(HttpMethod.PUT, "https://example.test/report/file.pdf"),
                 201,
                 headers,
                 blockBlobItem);
@@ -346,7 +345,7 @@ class AzureBlobExamSprintReportStorageTest {
                 .set("x-ms-error-code", "ServerBusy"));
         when(response.getHeaderValue(HttpHeaderName.X_MS_REQUEST_ID)).thenReturn("azure-request-failed");
         when(response.getHeaderValue(HttpHeaderName.X_MS_CLIENT_REQUEST_ID)).thenReturn("client-request-failed");
-        when(response.getRequest()).thenReturn(new HttpRequest(HttpMethod.PUT, new URL("https://example.test/report/report-123/file.pdf")));
+        when(response.getRequest()).thenReturn(new HttpRequest(HttpMethod.PUT, new URL("https://example.test/report/file.pdf")));
         return new BlobStorageException("ServerBusy", response, null);
     }
 }

+ 6 - 6
ability-center-runtime/src/test/java/cn/yunzhixue/ability/center/examsprint/adapter/http/ExamSprintReportControllerWebMvcTest.java

@@ -124,7 +124,7 @@ class ExamSprintReportControllerWebMvcTest {
                 Instant.parse("2026-01-01T00:00:00Z"),
                 Instant.parse("2026-01-01T00:01:00Z"),
                 Instant.parse("2026-01-02T00:00:00Z"),
-                "https://dcjxbtest.blob.core.chinacloudapi.cn/report/report-sync-001/exam-sprint-outlook-report-report-sync-001.pdf"));
+                "https://dcjxbtest.blob.core.chinacloudapi.cn/report/exam-sprint-outlook-report-report-sync-001.pdf"));
 
         String requestJson = requestJson("requests/exam-sprint-outlook-report-request.json");
 
@@ -134,7 +134,7 @@ class ExamSprintReportControllerWebMvcTest {
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$.data.reportType").value("OUTLOOK"))
                 .andExpect(jsonPath("$.data.generationStatus").value("SUCCESS"))
-                .andExpect(jsonPath("$.data.downloadUrl").value("https://dcjxbtest.blob.core.chinacloudapi.cn/report/report-sync-001/exam-sprint-outlook-report-report-sync-001.pdf"));
+                .andExpect(jsonPath("$.data.downloadUrl").value("https://dcjxbtest.blob.core.chinacloudapi.cn/report/exam-sprint-outlook-report-report-sync-001.pdf"));
 
         verify(applicationService).createOutlookReportSync(any());
     }
@@ -149,7 +149,7 @@ class ExamSprintReportControllerWebMvcTest {
                 Instant.parse("2026-01-01T00:00:00Z"),
                 Instant.parse("2026-01-01T00:01:00Z"),
                 Instant.parse("2026-01-02T00:00:00Z"),
-                "https://dcjxbtest.blob.core.chinacloudapi.cn/report/report-sync-002/exam-sprint-achievement-report-report-sync-002.pdf"));
+                "https://dcjxbtest.blob.core.chinacloudapi.cn/report/exam-sprint-achievement-report-report-sync-002.pdf"));
 
         String requestJson = requestJson("requests/exam-sprint-achievement-report-request.json");
 
@@ -159,7 +159,7 @@ class ExamSprintReportControllerWebMvcTest {
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$.data.reportType").value("ACHIEVEMENT"))
                 .andExpect(jsonPath("$.data.generationStatus").value("SUCCESS"))
-                .andExpect(jsonPath("$.data.downloadUrl").value("https://dcjxbtest.blob.core.chinacloudapi.cn/report/report-sync-002/exam-sprint-achievement-report-report-sync-002.pdf"));
+                .andExpect(jsonPath("$.data.downloadUrl").value("https://dcjxbtest.blob.core.chinacloudapi.cn/report/exam-sprint-achievement-report-report-sync-002.pdf"));
 
         verify(applicationService).createAchievementReportSync(any());
     }
@@ -214,7 +214,7 @@ class ExamSprintReportControllerWebMvcTest {
                 Instant.parse("2026-01-01T00:00:00Z"),
                 Instant.parse("2026-01-01T00:05:00Z"),
                 Instant.parse("2026-01-02T00:00:00Z"),
-                "https://dcjxbtest.blob.core.chinacloudapi.cn/report/report-001/exam-sprint-outlook-report-report-001.pdf",
+                "https://dcjxbtest.blob.core.chinacloudapi.cn/report/exam-sprint-outlook-report-report-001.pdf",
                 null));
         given(applicationService.downloadReport("report-001")).willReturn(new ReportDownloadContent(
                 "exam-sprint-outlook-report-report-001.pdf",
@@ -224,7 +224,7 @@ class ExamSprintReportControllerWebMvcTest {
         mockMvc.perform(get("/api/exam-sprint/reports/{reportId}", "report-001"))
                 .andExpect(status().isOk())
                 .andExpect(jsonPath("$.data.reportId").value("report-001"))
-                .andExpect(jsonPath("$.data.downloadUrl").value("https://dcjxbtest.blob.core.chinacloudapi.cn/report/report-001/exam-sprint-outlook-report-report-001.pdf"));
+                .andExpect(jsonPath("$.data.downloadUrl").value("https://dcjxbtest.blob.core.chinacloudapi.cn/report/exam-sprint-outlook-report-report-001.pdf"));
 
         mockMvc.perform(get("/api/exam-sprint/reports/{reportId}/download", "report-001"))
                 .andExpect(status().isOk())