Align auth and statistics APIs with frontend

This commit is contained in:
黄仁欢 2026-03-16 13:38:02 +08:00
parent d0eb41dbf4
commit 5a78c8c01f
4 changed files with 106 additions and 0 deletions

21
interface-checklist.md Normal file
View File

@ -0,0 +1,21 @@
# 接口清单(前端需求)
来源:`refer/认监-扫描件识别/frontend/report-detect-web/src/api/*.js` 及页面直接拼接的接口。
| # | Method | Path | 用途(前端) | 前端引用 | 状态 | 备注 |
|---|---|---|---|---|
| 1 | POST | `/api/login` | 登录 | `src/api/user.js` | ✅ 已修正 | 后端改为 `data=token`(字符串),并保留 `tokenName` 字段 |
| 2 | POST | `/api/logout` | 退出登录 | `src/api/user.js` | ✅ 已核对 | 后端存在:`src/main/java/com/chinaweal/youfool/reportdetect/modules/task/controller/TaskController.java`,返回 `code=0` |
| 3 | GET | `/api/user/info` | 用户信息 | `src/api/user.js` | ✅ 已修正 | 现返回 `name/avatar/roles`,并将角色转为小写 |
| 4 | GET | `/api/sys/institutions` | 机构列表 | `src/api/user.js` | ✅ 已核对 | 返回 `id/name/cmaNumber` 列表,前端可直接使用 |
| 5 | POST | `/api/auditor/switch-institution` | 切换机构 | `src/api/user.js` | ✅ 已核对 | 后端存在并接收 `{ institutionId }` |
| 6 | GET | `/api/statistics` | 报告统计 | `src/api/report.js` | ✅ 已修正 | 新增接口并返回 `{待审核报告, 已通过报告, 驳回报告, 本月审核量}` |
| 7 | GET | `/api/reports` | 报告列表 | `src/api/report.js` | | |
| 8 | GET | `/api/reports/{id}` | 报告详情 | `src/api/report.js` | | |
| 9 | GET | `/api/reports/{id}/preview` | 报告预览(图片/历史) | `src/api/report.js` | | |
| 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` | | |
| 13 | DELETE | `/api/reports/{id}` | 删除报告 | `src/api/report.js` | | |
| 14 | POST | `/api/validate-cma` | CMA 校验 | `src/api/report.js` | | |
| 15 | GET | `/api/reports/{id}/pdf` | PDF 预览 | `src/views/shibieneirong/shenhe/index.vue` | | |

View File

@ -140,4 +140,14 @@ public class TaskController {
resp.put("msg", "Success"); resp.put("msg", "Success");
return ResponseEntity.ok(resp); return ResponseEntity.ok(resp);
} }
@GetMapping("/statistics")
@SaCheckRole(value = { "ADMIN", "AUDITOR", "USER" }, mode = SaMode.OR)
public ResponseEntity<?> getStatistics() {
Map<String, Object> resp = new HashMap<>();
resp.put("code", 0);
resp.put("data", taskService.getStatistics());
resp.put("msg", "Success");
return ResponseEntity.ok(resp);
}
} }

View File

@ -26,4 +26,20 @@ public interface TaskRepository extends JpaRepository<Task, String> {
long countByStatus(String status); long countByStatus(String status);
long countBySubmitTimeAfter(java.util.Date date); long countBySubmitTimeAfter(java.util.Date date);
long countByStatusIn(List<String> statuses);
long countByStatusAndInstitutionId(String status, Long institutionId);
long countByStatusAndCreatorId(String status, Long creatorId);
long countByStatusInAndInstitutionId(List<String> statuses, Long institutionId);
long countByStatusInAndCreatorId(List<String> statuses, Long creatorId);
long countByStatusInAndSubmitTimeAfter(List<String> statuses, java.util.Date date);
long countByStatusInAndSubmitTimeAfterAndInstitutionId(List<String> statuses, java.util.Date date, Long institutionId);
long countByStatusInAndSubmitTimeAfterAndCreatorId(List<String> statuses, java.util.Date date, Long creatorId);
} }

View File

@ -29,6 +29,8 @@ import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
@ -341,6 +343,63 @@ public class TaskService {
} }
} }
public Map<String, Object> getStatistics() {
List<String> pendingStatuses = List.of("pending", "ocr_completed");
List<String> auditedStatuses = List.of("compliant", "non-compliant");
LocalDate monthStart = LocalDate.now().withDayOfMonth(1);
Date monthStartDate = Date.from(monthStart.atStartOfDay(ZoneId.systemDefault()).toInstant());
long pendingCount;
long compliantCount;
long nonCompliantCount;
long monthAuditedCount;
if (StpUtil.hasRole("ADMIN")) {
pendingCount = taskRepository.countByStatusIn(pendingStatuses);
compliantCount = taskRepository.countByStatus("compliant");
nonCompliantCount = taskRepository.countByStatus("non-compliant");
monthAuditedCount = taskRepository.countByStatusInAndSubmitTimeAfter(auditedStatuses, monthStartDate);
} else if (StpUtil.hasRole("AUDITOR")) {
Long institutionId = getEffectiveInstitutionId();
if (institutionId == null) {
pendingCount = 0;
compliantCount = 0;
nonCompliantCount = 0;
monthAuditedCount = 0;
} else {
pendingCount = taskRepository.countByStatusInAndInstitutionId(pendingStatuses, institutionId);
compliantCount = taskRepository.countByStatusAndInstitutionId("compliant", institutionId);
nonCompliantCount = taskRepository.countByStatusAndInstitutionId("non-compliant", institutionId);
monthAuditedCount = taskRepository.countByStatusInAndSubmitTimeAfterAndInstitutionId(auditedStatuses, monthStartDate, institutionId);
}
} else {
Long userId = Long.valueOf(StpUtil.getLoginId().toString());
pendingCount = taskRepository.countByStatusInAndCreatorId(pendingStatuses, userId);
compliantCount = taskRepository.countByStatusAndCreatorId("compliant", userId);
nonCompliantCount = taskRepository.countByStatusAndCreatorId("non-compliant", userId);
monthAuditedCount = taskRepository.countByStatusInAndSubmitTimeAfterAndCreatorId(auditedStatuses, monthStartDate, userId);
}
Map<String, Object> stats = new HashMap<>();
stats.put("待审核报告", pendingCount);
stats.put("已通过报告", compliantCount);
stats.put("驳回报告", nonCompliantCount);
stats.put("本月审核量", monthAuditedCount);
return stats;
}
private Long getEffectiveInstitutionId() {
Object overrideInstId = StpUtil.getSession().get("OVERRIDE_INSTITUTION_ID");
if (overrideInstId != null) {
return Long.valueOf(overrideInstId.toString());
}
Long userId = Long.valueOf(StpUtil.getLoginId().toString());
com.chinaweal.youfool.reportdetect.modules.sys.entity.SysUser user = sysUserRepository.findById(userId)
.orElse(null);
return user != null ? user.getInstitutionId() : null;
}
/** /**
* Reference result for similarity calculation * Reference result for similarity calculation
*/ */