From 60c1d626a27d92d67be1c5bd1c40132c8099fdec Mon Sep 17 00:00:00 2001 From: "weicw1996@qq.com" Date: Fri, 2 Oct 2026 17:05:42 +0800 Subject: [PATCH] =?UTF-8?q?:bug:=20=E8=AE=A4=E8=AF=81=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=94=B9=E7=94=A8=E8=8F=9C=E5=8D=95=E6=9D=83?= =?UTF-8?q?=E9=99=90=E7=A0=81=EF=BC=8C=E5=B9=B6=E8=A1=A5=E5=9B=9E=E8=A2=AB?= =?UTF-8?q?=E6=BC=8F=E6=8E=89=E7=9A=84=E5=AE=A1=E6=A0=B8=E5=B2=97=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原写法 @PreAuth("hasAnyRole('administrator','admin')") 有两个实际缺陷: 1. 库中**并不存在 admin 角色**(实查 blade_role:超级管理员 administrator、 运管 yunguan、财务 caiwu、录单员 ludan…),该分支永远不成立; 2. 真正承担认证审核的「运管」岗位**被排除在外**——即审核功能上线后没人能审。 改为按本项目的权限模型走菜单码(票 01 已建好这四个码): cert_certification_audit_driver / _vehicle(列表与详情) cert_certification_audit_driver_audit / _vehicle_audit(审核动作) 用 SpEL 而非 @PreAuth(menu = "..."),是因为同一组接口由 bizType 区分同时服务 司机与车辆两侧,单值 menu 表达不了「二者之一」。 已核对框架实现:AuthAspect 把 value 交给 SpEL 求值,root object 即 AuthFun, 而 hasMenu 是它的公开方法,故该表达式可用;menu() 非空时才会先行校验。 73 个测试通过。 --- .../CertificationAuditController.java | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/CertificationAuditController.java b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/CertificationAuditController.java index e0399779..efcdae5d 100644 --- a/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/CertificationAuditController.java +++ b/blade-service/blade-transport/src/main/java/org/springblade/transport/controller/CertificationAuditController.java @@ -56,12 +56,31 @@ import org.springframework.web.bind.annotation.RestController; @Tag(name = "认证审核", description = "管理端司机认证与车辆认证审核") public class CertificationAuditController extends BladeController { + /** + * 待审列表与详情的权限:司机或车辆任一审核菜单即可。 + *

+ * 用菜单码而不是角色名——本项目的权限走「角色-菜单」授权, + * 写死角色名会漏掉实际承担审核的岗位(例如「运管」), + * 也会在角色改名后静默失效。 + *

+ * 用 SpEL 而非 {@code @PreAuth(menu = "...")},是因为同一组接口同时服务 + * 司机与车辆两侧(由 {@code bizType} 区分),单值 menu 表达不了「二者之一」。 + */ + private static final String AUDIT_MENU_EXPRESSION = + "hasMenu('cert_certification_audit_driver') or hasMenu('cert_certification_audit_vehicle')"; + + /** + * 审核动作的权限:司机或车辆任一「审核」按钮权限即可 + */ + private static final String AUDIT_ACTION_MENU_EXPRESSION = + "hasMenu('cert_certification_audit_driver_audit') or hasMenu('cert_certification_audit_vehicle_audit')"; + private final ICertAuditService certAuditService; @GetMapping("/pending-page") @ApiOperationSupport(order = 1) @Operation(summary = "待审列表", description = "按认证对象类型分页查询审核中的记录,按提交时间倒序") - @PreAuth("hasAnyRole('administrator','admin')") + @PreAuth(AUDIT_MENU_EXPRESSION) public R> pendingPage( @Parameter(description = "认证对象类型:driver-司机,vehicle-车辆", required = true) @RequestParam String bizType, @@ -75,7 +94,7 @@ public class CertificationAuditController extends BladeController { @GetMapping("/detail") @ApiOperationSupport(order = 2) @Operation(summary = "审核详情", description = "同时返回待审快照与当前生效值,供前端做字段级对比") - @PreAuth("hasAnyRole('administrator','admin')") + @PreAuth(AUDIT_MENU_EXPRESSION) public R detail( @Parameter(description = "认证记录主键", required = true) @RequestParam Long id) { return R.data(certAuditService.detail(id)); @@ -84,7 +103,7 @@ public class CertificationAuditController extends BladeController { @PostMapping("/audit") @ApiOperationSupport(order = 3) @Operation(summary = "审核认证记录", description = "通过使该记录成为生效快照;驳回只终结该记录,生效快照不变") - @PreAuth("hasAnyRole('administrator','admin')") + @PreAuth(AUDIT_ACTION_MENU_EXPRESSION) public R audit( @Parameter(description = "认证记录主键", required = true) @RequestParam Long id, @Parameter(description = "是否通过", required = true) @RequestParam Boolean pass,