From e4f9b6f511113827fd28c5f26586e69a1ae7c8c9 Mon Sep 17 00:00:00 2001 From: huangrh Date: Mon, 16 Mar 2026 16:34:24 +0800 Subject: [PATCH] Add report preview API --- interface-checklist.md | 2 +- .../task/controller/TaskController.java | 17 +++++ .../modules/task/service/TaskService.java | 72 +++++++++++++++++++ 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/interface-checklist.md b/interface-checklist.md index 593bbe6..c120430 100644 --- a/interface-checklist.md +++ b/interface-checklist.md @@ -12,7 +12,7 @@ | 6 | GET | `/api/statistics` | 报告统计 | `src/api/report.js` | ✅ 已修正 | 新增接口并返回 `{待审核报告, 已通过报告, 驳回报告, 本月审核量}` | | 7 | GET | `/api/reports` | 报告列表 | `src/api/report.js` | ✅ 已修正 | 支持 `status` 过滤并返回前端表格字段(含 `approval_id`、`报告编号`、`检测机构`、`提交时间`、`状态`) | | 8 | GET | `/api/reports/{id}` | 报告详情 | `src/api/report.js` | ✅ 已修正 | 返回 `status(0/1/2/3)`、`report_id`、`report_type`、`institution`、`submit_time`、`testing_date`、`audit_opinion`、`ocr_result`、`attachments`、`history` | -| 9 | GET | `/api/reports/{id}/preview` | 报告预览(图片/历史) | `src/api/report.js` | | | +| 9 | GET | `/api/reports/{id}/preview` | 报告预览(图片/历史) | `src/api/report.js` | ✅ 已修正 | 返回 `ocr_result.API核验/org_exists/cma_exists`,并附带 `pages/history` 与 `status` | | 10 | POST | `/api/tasks` | 创建识别任务 | `src/api/report.js` | | | | 11 | POST | `/api/reports/{id}/submit` | 用户确认提交 | `src/api/report.js` | | | | 12 | POST | `/api/reports/{id}/audit` | 审核提交 | `src/api/report.js` | | | diff --git a/src/main/java/com/chinaweal/youfool/reportdetect/modules/task/controller/TaskController.java b/src/main/java/com/chinaweal/youfool/reportdetect/modules/task/controller/TaskController.java index c72d8a4..46ee087 100644 --- a/src/main/java/com/chinaweal/youfool/reportdetect/modules/task/controller/TaskController.java +++ b/src/main/java/com/chinaweal/youfool/reportdetect/modules/task/controller/TaskController.java @@ -159,6 +159,23 @@ public class TaskController { return ResponseEntity.ok(resp); } + @GetMapping("/reports/{id}/preview") + @SaCheckRole(value = { "ADMIN", "AUDITOR", "USER" }, mode = SaMode.OR) + public ResponseEntity getReportPreview(@PathVariable("id") String id) { + Map preview = taskService.getReportPreview(id); + if (preview == null) { + Map resp = new HashMap<>(); + resp.put("code", 1); + resp.put("msg", "Report not found"); + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(resp); + } + Map resp = new HashMap<>(); + resp.put("code", 0); + resp.put("data", preview); + resp.put("msg", "Success"); + return ResponseEntity.ok(resp); + } + @GetMapping("/statistics") @SaCheckRole(value = { "ADMIN", "AUDITOR", "USER" }, mode = SaMode.OR) public ResponseEntity getStatistics() { diff --git a/src/main/java/com/chinaweal/youfool/reportdetect/modules/task/service/TaskService.java b/src/main/java/com/chinaweal/youfool/reportdetect/modules/task/service/TaskService.java index 19dc980..cf292d4 100644 --- a/src/main/java/com/chinaweal/youfool/reportdetect/modules/task/service/TaskService.java +++ b/src/main/java/com/chinaweal/youfool/reportdetect/modules/task/service/TaskService.java @@ -459,6 +459,78 @@ public class TaskService { }; } + private String mapStatusForPreview(String internalStatus) { + if (internalStatus == null) { + return ""; + } + return switch (internalStatus) { + case "ocr_pending" -> "0"; + case "ocr_completed" -> "4"; + case "pending" -> "1"; + case "compliant" -> "2"; + case "non-compliant" -> "3"; + default -> internalStatus; + }; + } + + @Transactional(readOnly = true) + public Map getReportPreview(String approvalId) { + if (approvalId == null || approvalId.isBlank()) { + return null; + } + Task task = taskRepository.findByApprovalId(approvalId); + if (task == null) { + return null; + } + + Map preview = new HashMap<>(); + preview.put("approval_id", task.getApprovalId()); + preview.put("status", mapStatusForPreview(task.getStatus())); + + OCRResult ocr = task.getOcrResult(); + Map ocrMap = new HashMap<>(); + if (ocr == null || "ocr_pending".equals(task.getStatus())) { + ocrMap.put("API核验", "识别中..."); + ocrMap.put("org_exists", false); + ocrMap.put("cma_exists", false); + ocrMap.put("api_status", null); + } else { + String apiStatus = ocr.getApiStatus(); + ocrMap.put("API核验", apiStatus != null ? apiStatus : "识别中..."); + ocrMap.put("org_exists", Boolean.TRUE.equals(ocr.getOrgExists())); + ocrMap.put("cma_exists", Boolean.TRUE.equals(ocr.getCmaExists())); + ocrMap.put("api_status", apiStatus); + } + preview.put("ocr_result", ocrMap); + + if (task.getPages() != null) { + List> pages = task.getPages().stream().map(p -> { + Map m = new HashMap<>(); + m.put("page_number", p.getPageNumber()); + m.put("image_path", p.getImagePath()); + return m; + }).collect(Collectors.toList()); + preview.put("pages", pages); + } else { + preview.put("pages", List.of()); + } + + if (task.getHistories() != null) { + List> history = task.getHistories().stream().map(h -> { + Map m = new HashMap<>(); + m.put("action", h.getAction()); + m.put("timestamp", h.getTimestamp()); + m.put("opinion", h.getOpinion()); + return m; + }).collect(Collectors.toList()); + preview.put("history", history); + } else { + preview.put("history", List.of()); + } + + return preview; + } + public Map getStatistics() { List pendingStatuses = List.of("pending", "ocr_completed"); List auditedStatuses = List.of("compliant", "non-compliant");