From 1ca34bde7620de4f359cc64244a01f9d711a6489 Mon Sep 17 00:00:00 2001 From: zyh Date: Sat, 30 Aug 2025 23:21:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E8=B4=A6=E6=88=B7=E7=9A=84=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=8C=E5=8C=85=E5=90=AB=E6=9D=83=E9=99=90=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E5=92=8C=E8=87=AA=E6=88=91=E5=88=A0=E9=99=A4=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/admin/AccountController.java | 25 +++++++++++++++++ .../service/account/AccountService.java | 28 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/main/java/com/gameplatform/server/controller/admin/AccountController.java b/src/main/java/com/gameplatform/server/controller/admin/AccountController.java index 38c9971..b9bddb3 100644 --- a/src/main/java/com/gameplatform/server/controller/admin/AccountController.java +++ b/src/main/java/com/gameplatform/server/controller/admin/AccountController.java @@ -76,6 +76,31 @@ public class AccountController { return accountService.resetPassword(id, req.getNewPassword(), Boolean.TRUE.equals(req.getForceLogout())); } + @DeleteMapping("/{id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @Operation(summary = "删除用户", description = "删除指定的用户账户,管理员不能删除自己或最后一个管理员") + public Mono delete( + @Parameter(description = "账户ID") @PathVariable Long id, + @Parameter(hidden = true) @RequestHeader("Authorization") String authHeader) { + return Mono.fromCallable(() -> { + if (authHeader == null || !authHeader.startsWith("Bearer ")) { + throw new IllegalArgumentException("Authorization header is required"); + } + + String token = authHeader.substring(7); + io.jsonwebtoken.Claims claims = jwtService.parse(token); + Long currentUserId = claims.get("userId", Long.class); + + if (currentUserId == null) { + throw new IllegalArgumentException("Invalid token: userId not found"); + } + + return currentUserId; + }) + .flatMap(currentUserId -> accountService.delete(id, currentUserId)) + .then(); + } + @GetMapping("/me/points-balance") @Operation(summary = "获取当前用户积分余额", description = "根据token解析用户ID并获取当前用户的积分余额") public Mono getCurrentUserPointsBalance( diff --git a/src/main/java/com/gameplatform/server/service/account/AccountService.java b/src/main/java/com/gameplatform/server/service/account/AccountService.java index 5f8a4ab..38d7abc 100644 --- a/src/main/java/com/gameplatform/server/service/account/AccountService.java +++ b/src/main/java/com/gameplatform/server/service/account/AccountService.java @@ -163,6 +163,34 @@ public class AccountService { .subscribeOn(Schedulers.boundedElastic()); } + @Transactional + public Mono delete(Long id, Long currentUserId) { + return Mono.fromCallable(() -> { + // 检查用户是否存在 + UserAccount user = mapper.selectById(id); + if (user == null) { + throw new IllegalArgumentException("用户不存在"); + } + + // 不能删除自己 + if (id.equals(currentUserId)) { + throw new IllegalArgumentException("不能删除当前登录的用户"); + } + + // 如果要删除的是管理员,检查是否是最后一个管理员 + if ("ADMIN".equals(user.getUserType())) { + long adminCount = mapper.countByFilter("ADMIN", "ENABLED", null); + if (adminCount <= 1) { + throw new IllegalArgumentException("不能删除最后一个管理员账户"); + } + } + + // 执行删除 + return mapper.deleteById(id) > 0; + }) + .subscribeOn(Schedulers.boundedElastic()); + } + private AccountResponse toResp(UserAccount a) { if (a == null) return null; AccountResponse r = new AccountResponse();