reghao 8 mesi fa
parent
commit
6f9c1b2c9a
86 ha cambiato i file con 292 aggiunte e 314 eliminazioni
  1. 6 2
      account/account-api/src/main/java/cn/reghao/tnb/account/api/constant/AccountRole.java
  2. 0 22
      account/account-api/src/main/java/cn/reghao/tnb/account/api/dto/ExamAccount.java
  3. 0 1
      account/account-api/src/main/java/cn/reghao/tnb/account/api/iface/AccountQuery.java
  4. 13 8
      account/account-service/src/main/java/cn/reghao/tnb/account/app/db/repository/AccountRepository.java
  5. 0 4
      account/account-service/src/main/java/cn/reghao/tnb/account/app/model/po/UserAccount.java
  6. 1 1
      account/account-service/src/main/java/cn/reghao/tnb/account/app/model/po/UserAuthority.java
  7. 0 26
      account/account-service/src/main/java/cn/reghao/tnb/account/app/rpc/AccountQueryImpl.java
  8. 9 5
      account/account-service/src/main/java/cn/reghao/tnb/account/app/service/impl/AccountLoginServiceImpl.java
  9. 39 27
      account/account-service/src/main/java/cn/reghao/tnb/account/app/service/impl/AccountTokenServiceImpl.java
  10. 3 3
      account/account-service/src/main/resources/mapper/LoginAttemptsMapper.xml
  11. 8 0
      common/src/main/java/cn/reghao/tnb/common/auth/LoginUser.java
  12. 11 3
      common/src/main/java/cn/reghao/tnb/common/auth/UserContext.java
  13. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/chat/model/po/Hongbao.java
  14. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/chat/model/po/HongbaoReceiver.java
  15. 6 6
      content/content-service/src/main/java/cn/reghao/tnb/content/app/chat/service/ChatDialogService.java
  16. 4 4
      content/content-service/src/main/java/cn/reghao/tnb/content/app/chat/service/ChatMessageService.java
  17. 2 2
      content/content-service/src/main/java/cn/reghao/tnb/content/app/chat/service/ChatRecordService.java
  18. 16 2
      content/content-service/src/main/java/cn/reghao/tnb/content/app/config/web/TokenFilter.java
  19. 5 5
      content/content-service/src/main/java/cn/reghao/tnb/content/app/config/web/WebConfig.java
  20. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/data/controller/ArticleController.java
  21. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/data/controller/ArticlePostController.java
  22. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/data/controller/ImagePostController.java
  23. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/data/model/po/AudioPost.java
  24. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/data/model/po/ImagePost.java
  25. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/data/service/ArticlePostService.java
  26. 2 2
      content/content-service/src/main/java/cn/reghao/tnb/content/app/data/service/AudioPostService.java
  27. 3 3
      content/content-service/src/main/java/cn/reghao/tnb/content/app/data/service/AudioService.java
  28. 2 2
      content/content-service/src/main/java/cn/reghao/tnb/content/app/data/service/ChartService.java
  29. 3 3
      content/content-service/src/main/java/cn/reghao/tnb/content/app/data/service/ImagePostService.java
  30. 9 8
      content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/controller/ExamController.java
  31. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/controller/ExamResultController.java
  32. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/controller/MarkController.java
  33. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/model/po/Paper.java
  34. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/model/po/PaperResult.java
  35. 0 25
      content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/service/ExamAccountService.java
  36. 2 2
      content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/service/ExamService.java
  37. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/service/MarkService.java
  38. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/service/PaperService.java
  39. 14 7
      content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/service/PaperViewService.java
  40. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/service/QuestionService.java
  41. 5 22
      content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/web/ExamRoleInterceptor.java
  42. 2 2
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/GeoPoint.java
  43. 2 2
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/service/MapService.java
  44. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/service/PhotoMapService.java
  45. 3 3
      content/content-service/src/main/java/cn/reghao/tnb/content/app/mall/controller/CartController.java
  46. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/mall/controller/DeliveryController.java
  47. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/mall/controller/LogisticsController.java
  48. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/mall/model/po/Product.java
  49. 2 2
      content/content-service/src/main/java/cn/reghao/tnb/content/app/mall/service/BuyService.java
  50. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/controller/CategoryController.java
  51. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/controller/RecommendController.java
  52. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/controller/VideoPlayController.java
  53. 3 2
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/controller/VideoQueryController.java
  54. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/model/po/Favlist.java
  55. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/model/po/PostAlbum.java
  56. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/model/po/SearchRecord.java
  57. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/model/po/UserComment.java
  58. 2 2
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/model/po/VideoPost.java
  59. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/model/query/AlbumQuery.java
  60. 5 5
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/AlbumService.java
  61. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/CommentService.java
  62. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/ContentPermission.java
  63. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/ContentService.java
  64. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/VideoEditService.java
  65. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/VideoService.java
  66. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/impl/SearchServiceImpl.java
  67. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/impl/VideoPlayServiceImpl.java
  68. 5 5
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/impl/VideoPostQueryImpl.java
  69. 1 1
      content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/impl/VideoPostServiceImpl.java
  70. 1 1
      file/file-service/src/main/java/cn/reghao/tnb/file/app/service/AvatarService.java
  71. 2 2
      file/file-service/src/main/java/cn/reghao/tnb/file/app/service/OrderService.java
  72. 15 1
      file/file-service/src/test/java/FileTest.java
  73. 2 2
      gateway/src/main/java/cn/reghao/tnb/gateway/config/RedisKeys.java
  74. 14 21
      gateway/src/main/java/cn/reghao/tnb/gateway/token/GlobalTokenFilter.java
  75. 4 2
      gateway/src/main/java/cn/reghao/tnb/gateway/token/model/UserLogin.java
  76. 1 1
      user/user-service/src/main/java/cn/reghao/tnb/user/app/controller/UserContactController.java
  77. 2 2
      user/user-service/src/main/java/cn/reghao/tnb/user/app/controller/UserMessageController.java
  78. 3 3
      user/user-service/src/main/java/cn/reghao/tnb/user/app/controller/UserRelationController.java
  79. 3 3
      user/user-service/src/main/java/cn/reghao/tnb/user/app/controller/UserWalletController.java
  80. 1 1
      user/user-service/src/main/java/cn/reghao/tnb/user/app/model/po/WalletCharge.java
  81. 7 7
      user/user-service/src/main/java/cn/reghao/tnb/user/app/service/ContactService.java
  82. 3 3
      user/user-service/src/main/java/cn/reghao/tnb/user/app/service/GroupInfoService.java
  83. 6 6
      user/user-service/src/main/java/cn/reghao/tnb/user/app/service/GroupMemberService.java
  84. 2 2
      user/user-service/src/main/java/cn/reghao/tnb/user/app/service/GroupNoticeService.java
  85. 2 2
      user/user-service/src/main/java/cn/reghao/tnb/user/app/service/UserProfileService.java
  86. 2 2
      user/user-service/src/main/java/cn/reghao/tnb/user/app/service/UserVipService.java

+ 6 - 2
account/account-service/src/main/java/cn/reghao/tnb/account/app/model/constant/AccountRole.java → account/account-api/src/main/java/cn/reghao/tnb/account/api/constant/AccountRole.java

@@ -1,11 +1,15 @@
-package cn.reghao.tnb.account.app.model.constant;
+package cn.reghao.tnb.account.api.constant;
 
 /**
  * @author reghao
  * @date 2024-02-14 19:13:18
  */
 public enum AccountRole {
-    user("ROLE_USER");
+    examUser("ROLE_EXAM_USER"),
+    examAdmin("ROLE_EXAM_ADMIN"),
+    disk("ROLE_DISK"),
+    user("ROLE_USER"),
+    admin("ROLE_ADMIN");
 
     private final String value;
     AccountRole(String value) {

+ 0 - 22
account/account-api/src/main/java/cn/reghao/tnb/account/api/dto/ExamAccount.java

@@ -1,22 +0,0 @@
-package cn.reghao.tnb.account.api.dto;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-
-import java.io.Serializable;
-
-/**
- * 可访问 exam 系统的帐号
- * @author reghao
- * @date 2025-08-13 16:29:09
- */
-@NoArgsConstructor
-@AllArgsConstructor
-@Getter
-public class ExamAccount implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    private boolean exist;
-    private boolean examAdmin;
-}

+ 0 - 1
account/account-api/src/main/java/cn/reghao/tnb/account/api/iface/AccountQuery.java

@@ -20,5 +20,4 @@ public interface AccountQuery {
     void updateAvatar(long userId, String avatarUrl);
     String getUserIdStr(long userIdLong);
     long getUserIdLong(String userIdStr);
-    ExamAccount getExamAccount(long userId);
 }

+ 13 - 8
account/account-service/src/main/java/cn/reghao/tnb/account/app/db/repository/AccountRepository.java

@@ -109,19 +109,24 @@ public class AccountRepository {
 
     public UserAccount getUserAccountByUsername(String username) {
         UserAccount userAccount = userAccountMapper.findByUsername(username);
-        Set<UserAuthority> set = userAccountRoleMapper.findByUserId(userAccount.getUserId()).stream()
-                .map(userAccountRole -> new UserAuthority(userAccountRole.getName()))
-                .collect(Collectors.toSet());
-        userAccount.setAuthorities(set);
-
-        return userAccount;
+        return userAccount != null ? setAuthorities(userAccount) : null;
     }
 
     public UserAccount getUserAccountByEmail(String email) {
-        return userAccountMapper.findByEmail(email);
+        UserAccount userAccount = userAccountMapper.findByEmail(email);
+        return userAccount != null ? setAuthorities(userAccount) : null;
     }
 
     public UserAccount getUserAccountByMobile(String mobile) {
-        return userAccountMapper.findByMobile(mobile);
+        UserAccount userAccount = userAccountMapper.findByMobile(mobile);
+        return userAccount != null ? setAuthorities(userAccount) : null;
+    }
+
+    private UserAccount setAuthorities(UserAccount userAccount) {
+        Set<UserAuthority> set = userAccountRoleMapper.findByUserId(userAccount.getUserId()).stream()
+                .map(userAccountRole -> new UserAuthority(userAccountRole.getName()))
+                .collect(Collectors.toSet());
+        userAccount.setAuthorities(set);
+        return userAccount;
     }
 }

+ 0 - 4
account/account-service/src/main/java/cn/reghao/tnb/account/app/model/po/UserAccount.java

@@ -1,8 +1,6 @@
 package cn.reghao.tnb.account.app.model.po;
 
 import cn.reghao.jutil.jdk.db.BaseObject;
-import cn.reghao.tnb.account.app.model.constant.AccountRole;
-import cn.reghao.tnb.account.app.model.constant.AccountType;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
@@ -14,9 +12,7 @@ import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
 import java.time.LocalDateTime;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.Set;
-import java.util.stream.Collectors;
 
 /**
  * 用户账号

+ 1 - 1
account/account-service/src/main/java/cn/reghao/tnb/account/app/model/po/UserAuthority.java

@@ -1,6 +1,6 @@
 package cn.reghao.tnb.account.app.model.po;
 
-import cn.reghao.tnb.account.app.model.constant.AccountRole;
+import cn.reghao.tnb.account.api.constant.AccountRole;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.SpringSecurityCoreVersion;
 import org.springframework.util.Assert;

+ 0 - 26
account/account-service/src/main/java/cn/reghao/tnb/account/app/rpc/AccountQueryImpl.java

@@ -123,30 +123,4 @@ public class AccountQueryImpl implements AccountQuery {
     public long getUserIdLong(String userIdStr) {
         return userIdObfuscation.restore(userIdStr);
     }
-
-    /**
-     * 判断帐号是否可访问 exam 系统
-     *
-     * @param
-     * @return
-     * @date 2025-08-13 16:46:05
-     */
-    @Override
-    public ExamAccount getExamAccount(long userId) {
-        /*UserAccount userAccount = accountRepository.getUserAccountByUserId(userId);
-        List<Integer> roleIds = Arrays.stream(userAccount.getRoles().split(","))
-                .map(Integer::parseInt)
-                .collect(Collectors.toList());
-        Set<String> roles = new HashSet<>(accountRepository.getRoles(roleIds));
-
-        String examAdmin = "ROLE_EXAM_ADMIN";
-        String examUser = "ROLE_EXAM_USER";
-        if (roles.contains(examAdmin)) {
-            return new ExamAccount(true, true);
-        } else if (roles.contains(examUser)) {
-            return new ExamAccount(true, false);
-        }*/
-
-        return new ExamAccount(false, false);
-    }
 }

+ 9 - 5
account/account-service/src/main/java/cn/reghao/tnb/account/app/service/impl/AccountLoginServiceImpl.java

@@ -70,9 +70,7 @@ public class AccountLoginServiceImpl implements AccountLoginService {
         }
 
         String loginId = UUID.randomUUID().toString().replace("-", "");
-        AccountAuthToken accountAuthToken = new AccountAuthToken(plat, loginId, loginType, rememberMe, principal, decryptCredential);
-        loginAttemptService.saveLoginAttempts(accountAuthToken);
-        return accountAuthToken;
+        return new AccountAuthToken(plat, loginId, loginType, rememberMe, principal, decryptCredential);
     }
 
     @Override
@@ -109,7 +107,7 @@ public class AccountLoginServiceImpl implements AccountLoginService {
         }
 
         userDetail.setLoginType(LoginType.usernamePassword.getValue());
-        return new AccountAuthToken(authToken, userDetail);
+        return getAccountAuthToken(authToken, userDetail);
     }
 
     /**
@@ -149,6 +147,12 @@ public class AccountLoginServiceImpl implements AccountLoginService {
         }
 
         userDetail.setLoginType(LoginType.mobileCode.getValue());
-        return new AccountAuthToken(authToken, userDetail);
+        return getAccountAuthToken(authToken, userDetail);
+    }
+
+    private AccountAuthToken getAccountAuthToken(AccountAuthToken authToken, UserAccount userDetail) {
+        AccountAuthToken accountAuthToken = new AccountAuthToken(authToken, userDetail);
+        loginAttemptService.saveLoginAttempts(accountAuthToken);
+        return accountAuthToken;
     }
 }

+ 39 - 27
account/account-service/src/main/java/cn/reghao/tnb/account/app/service/impl/AccountTokenServiceImpl.java

@@ -28,6 +28,7 @@ import org.springframework.stereotype.Service;
 
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
+import java.security.NoSuchAlgorithmException;
 import java.security.interfaces.RSAPrivateKey;
 import java.security.interfaces.RSAPublicKey;
 import java.util.List;
@@ -63,39 +64,42 @@ public class AccountTokenServiceImpl implements AccountTokenService {
 
     @Override
     public AccountToken grantUserToken(AccountAuthToken authToken) {
+        String signKeyRandom = RandomString.getSalt(64);
+        RSAPrivateKey signKeyPrivate = null;
+        try {
+            signKeyPrivate = pubkeyService.getPrivateKey();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+
         long userId = authToken.getUserId();
         long accessExpireIn = 1000L*3600*24*7;
         long accessExpireAt = System.currentTimeMillis() + accessExpireIn;
         String accessToken = "";
-        try {
-            RSAPrivateKey privateKey = pubkeyService.getPrivateKey();
-            accessToken = JwtUtil.createAccessToken(authToken, userId, accessExpireAt, privateKey);
-        } catch (Exception e) {
-            log.error("error -> {}", e.getMessage());
-        }
-
-        String accessSignKey = RandomString.getSalt(64);
-        if (accessToken.isBlank()) {
-            accessToken = JwtUtil.createAccessToken(authToken, userId, accessExpireAt, accessSignKey);
+        if (signKeyPrivate != null) {
+            accessToken = JwtUtil.createAccessToken(authToken, userId, accessExpireAt, signKeyPrivate);
+        } else {
+            accessToken = JwtUtil.createAccessToken(authToken, userId, accessExpireAt, signKeyRandom);
         }
 
         long refreshExpireIn = accessExpireIn*4;
         long refreshExpireAt = System.currentTimeMillis() + refreshExpireIn;
-        String refreshSignKey = RandomString.getSalt(64);
-        String refreshToken = JwtUtil.createRefreshToken(authToken, refreshExpireAt, refreshSignKey);
+        String refreshToken = JwtUtil.createRefreshToken(authToken, refreshExpireAt, signKeyRandom);
 
-        redisStringObject.setWithTimeout(RedisKeys.getAccessSignKeyKey(accessToken), accessSignKey, accessExpireIn);
-        redisStringObject.setWithTimeout(RedisKeys.getRefreshSignKeyKey(refreshToken), refreshSignKey, refreshExpireIn);
+        if (signKeyPrivate == null) {
+            redisString.setWithTimeout(RedisKeys.getAccessSignKeyKey(accessToken), signKeyRandom, accessExpireIn);
+        }
+        redisString.setWithTimeout(RedisKeys.getRefreshSignKeyKey(refreshToken), signKeyRandom, refreshExpireIn);
 
         String loginId = authToken.getLoginId();
         redisStringObject.setWithTimeout(RedisKeys.getAuthTokenKey(userId, loginId), authToken, accessExpireIn);
-        redisStringObject.setWithTimeout(RedisKeys.getAccessTokenKey(userId, loginId), accessToken, accessExpireIn);
-        redisStringObject.setWithTimeout(RedisKeys.getRefreshTokenKey(userId, loginId), refreshToken, refreshExpireIn);
+        redisString.setWithTimeout(RedisKeys.getAccessTokenKey(userId, loginId), accessToken, accessExpireIn);
+        redisString.setWithTimeout(RedisKeys.getRefreshTokenKey(userId, loginId), refreshToken, refreshExpireIn);
         return new AccountToken(accessToken, accessExpireAt, refreshToken, refreshExpireAt);
     }
 
     public void refreshToken(long userId, String loginId) {
-
+        log.info("令牌刷新尚未实现");
     }
 
     @Override
@@ -142,12 +146,16 @@ public class AccountTokenServiceImpl implements AccountTokenService {
                 deleteSession(loginId);
             }
 
-            SecurityContext context = SecurityContextHolder.getContext();
-            context.setAuthentication(null);
-            SecurityContextHolder.clearContext();
+            clearSecurityContext();
         }
     }
 
+    private void clearSecurityContext() {
+        SecurityContext context = SecurityContextHolder.getContext();
+        context.setAuthentication(null);
+        SecurityContextHolder.clearContext();
+    }
+
     @Override
     public void clearCookie() {
         String path = "/";
@@ -161,6 +169,7 @@ public class AccountTokenServiceImpl implements AccountTokenService {
 
     @Override
     public void logout(String loginId) {
+        String currentLoginId = getAuthToken().getLoginId();
         List<LoginAttempts> loginAttemptsList = loginAttemptsMapper.findByLoginIds(List.of(loginId));
         if (!loginAttemptsList.isEmpty() && !loginAttemptsList.get(0).getRememberMe()) {
             LoginAttempts loginAttempts = loginAttemptsList.get(0);
@@ -172,12 +181,16 @@ public class AccountTokenServiceImpl implements AccountTokenService {
                 String userdata = String.format("%s:%s:%s", userId, plat, loginId);
                 deleteSession(loginId);
             }
+
+            if (loginId.equals(currentLoginId)) {
+                clearSecurityContext();
+            }
         }
     }
 
     private void revokeUserToken(long userId, String loginId) {
-        String refreshToken = redisString.get(RedisKeys.getRefreshTokenKey(userId, loginId));
         String accessToken = redisString.get(RedisKeys.getAccessTokenKey(userId, loginId));
+        String refreshToken = redisString.get(RedisKeys.getRefreshTokenKey(userId, loginId));
         String[] keys = List.of(
                         RedisKeys.getAuthTokenKey(userId, loginId),
                         RedisKeys.getAccessTokenKey(userId, loginId),
@@ -218,16 +231,15 @@ public class AccountTokenServiceImpl implements AccountTokenService {
         if (!loginIds.isEmpty()) {
             loginIds.forEach(this::logout);
         }
+
+        long loginUser = getAuthToken().getUserId();
+        if (loginUser == userId) {
+            clearSecurityContext();
+        }
     }
 
     @Override
     public void deleteOnSessionExpired(String loginId) {
-        /*LoginAttempts loginAttempts = loginAttemptsMapper.findByLoginId(loginId);
-        if (loginAttempts != null && !loginAttempts.getRememberMe()) {
-            long userId = loginAttempts.getUserId();
-            int plat = loginAttempts.getPlat();
-            deleteSession(userId, plat, loginId, false);
-        }*/
     }
 
     @Override

+ 3 - 3
account/account-service/src/main/resources/mapper/LoginAttemptsMapper.xml

@@ -4,14 +4,14 @@
 <mapper namespace="cn.reghao.tnb.account.app.db.mapper.LoginAttemptsMapper">
     <insert id="save">
         insert into msg_login_attempts
-        (`id`,`deleted`,`create_time`,`update_time`,`login_id`,`user_id`,`login_type`,`user_agent`,`login_ip`,`login_at`,`plat`,`remember_me`)
+        (`login_id`,`user_id`,`login_type`,`user_agent`,`login_ip`,`login_at`,`plat`,`remember_me`,`success`)
         values
-        (#{id},#{deleted},#{createTime},#{updateTime},#{loginId},#{userId},#{loginType},#{userAgent},#{loginIp},#{loginAt},#{plat},#{rememberMe})
+        (#{loginId},#{userId},#{loginType},#{userAgent},#{loginIp},#{loginAt},#{plat},#{rememberMe},`success`)
     </insert>
 
     <update id="updateSetFailed">
         update msg_login_attempts
-        set update_time=now(),`status`=0
+        set update_time=now(),`success`=0
         where login_id=#{loginId}
     </update>
 

+ 8 - 0
common/src/main/java/cn/reghao/tnb/common/auth/LoginUser.java

@@ -3,6 +3,8 @@ package cn.reghao.tnb.common.auth;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 
+import java.util.Set;
+
 /**
  * @author reghao
  * @date 2024-02-14 15:26:42
@@ -11,4 +13,10 @@ import lombok.Getter;
 @Getter
 public class LoginUser {
     private long userId;
+    private String loginId;
+    private Set<String> roles;
+
+    public LoginUser(long userId) {
+        this.userId = userId;
+    }
 }

+ 11 - 3
common/src/main/java/cn/reghao/tnb/common/auth/UserContext.java

@@ -1,5 +1,8 @@
 package cn.reghao.tnb.common.auth;
 
+import java.util.HashSet;
+import java.util.Set;
+
 /**
  * @author reghao
  * @date 2023-06-02 10:48:59
@@ -15,14 +18,19 @@ public class UserContext implements AutoCloseable {
         return CURRENT.get();
     }
 
-    public static long getUser() {
+    public static long getUserId() {
         LoginUser loginUser = CURRENT.get();
         return loginUser != null ? loginUser.getUserId() : -1;
     }
 
-    public static int getUserId() {
+    public static String getLoginId() {
+        LoginUser loginUser = CURRENT.get();
+        return loginUser != null ? loginUser.getLoginId() : "-1";
+    }
+
+    public static Set<String> getUserRoles() {
         LoginUser loginUser = CURRENT.get();
-        return loginUser != null ? (int) loginUser.getUserId() : -1;
+        return loginUser != null ? loginUser.getRoles() : new HashSet<>();
     }
 
     @Override

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/chat/model/po/Hongbao.java

@@ -37,7 +37,7 @@ public class Hongbao extends BaseObject<Integer> {
         this.num = hongbaoDto.getNum();
         this.remain = hongbaoDto.getNum();
         this.remark = hongbaoDto.getRemark();
-        this.createBy = UserContext.getUser();
+        this.createBy = UserContext.getUserId();
         this.createAt = LocalDateTime.now();
     }
 }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/chat/model/po/HongbaoReceiver.java

@@ -24,7 +24,7 @@ public class HongbaoReceiver extends BaseObject<Integer> {
 
     public HongbaoReceiver(long hongbaoId, double amount) {
         this.hongbaoId = hongbaoId;
-        this.receiverId = UserContext.getUser();
+        this.receiverId = UserContext.getUserId();
         this.amount = amount;
         this.remark = "";
         this.createAt = LocalDateTime.now();

+ 6 - 6
content/content-service/src/main/java/cn/reghao/tnb/content/app/chat/service/ChatDialogService.java

@@ -33,7 +33,7 @@ public class ChatDialogService {
     }
 
     public ChatInitialRet createChatDialog(ChatInitial chatInitial) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         long receiverId = chatInitial.getReceiverId();
         int chatType = chatInitial.getTalkType();
         ChatDialog chatDialog;
@@ -92,7 +92,7 @@ public class ChatDialogService {
     }
 
     public List<ChatInitialRet> getChatDialogs() {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         List<ChatDialog> chatDialogs = chatDialogMapper.findChatDialogsByUserId(loginUser);
         return chatDialogs.stream()
                 .map(chatDialog -> {
@@ -109,12 +109,12 @@ public class ChatDialogService {
     }
 
     public void deleteChatDialog(long dialogId) {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         chatDialogMapper.updateSetDisplay(dialogId, loginUser, false);
     }
 
     public void setChatDialogTop(ChatTop chatTop) {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         long dialogId = chatTop.getListId();
         int type = chatTop.getType();
         boolean top = type == 1;
@@ -122,7 +122,7 @@ public class ChatDialogService {
     }
 
     public void setChatDialogDisturb(ChatDisturb chatDisturb) {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         boolean disturb = chatDisturb.getIsDisturb() == 1;
         long receiverId = chatDisturb.getReceiverId();
         ChatDialog chatDialog = chatDialogMapper.findByReceiverAndUserId(receiverId, loginUser);
@@ -132,6 +132,6 @@ public class ChatDialogService {
     }
 
     public void clearUnread(long receiverId) {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
     }
 }

+ 4 - 4
content/content-service/src/main/java/cn/reghao/tnb/content/app/chat/service/ChatMessageService.java

@@ -57,7 +57,7 @@ public class ChatMessageService {
     }
 
     public void sendTextMessage(TextMsg textMsg) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         long receiverId = textMsg.getReceiverId();
         int chatType = textMsg.getTalkType();
 
@@ -82,7 +82,7 @@ public class ChatMessageService {
     }
 
     public void sendImageMessage(ImageMsg imageMsg) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         long receiverId = imageMsg.getReceiverId();
         int chatType = imageMsg.getTalkType();
         String uploadId = imageMsg.getUploadId();
@@ -131,7 +131,7 @@ public class ChatMessageService {
     }
 
     public void sendFileMessage(FileMsg fileMsg) throws IOException {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         long receiverId = fileMsg.getReceiverId();
         int chatType = fileMsg.getTalkType();
         String uploadId = fileMsg.getUploadId();
@@ -170,7 +170,7 @@ public class ChatMessageService {
     }
 
     public void sendCodeBlockMessage(CodeBlockMsg codeBlockMsg) throws IOException {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         long receiverId = codeBlockMsg.getReceiverId();
         int chatType = codeBlockMsg.getTalkType();
 

+ 2 - 2
content/content-service/src/main/java/cn/reghao/tnb/content/app/chat/service/ChatRecordService.java

@@ -48,7 +48,7 @@ public class ChatRecordService {
 
 
     public ChatRecordGetRetList getChatRecords(long receiverId, long recordId, int limit) {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         List<ChatRecordGetRet> list = chatRecordMapper.findChatRecordGetRet(receiverId, loginUser, recordId, limit);
         list.forEach(chatRecordGetRet -> {
             try {
@@ -113,7 +113,7 @@ public class ChatRecordService {
     }
 
     public ChatRecordGetRetList getChatRecords(int msgType, long receiverId, long recordId, int limit) {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         List<ChatRecordGetRet> list =
                 chatRecordMapper.findChatRecordGetRetByMsgType(msgType, receiverId, loginUser, recordId, limit);
         list.forEach(chatRecordGetRet -> {

+ 16 - 2
content/content-service/src/main/java/cn/reghao/tnb/content/app/config/web/TokenFilter.java

@@ -8,6 +8,9 @@ import org.springframework.stereotype.Component;
 
 import javax.servlet.*;
 import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * HTTP 请求过滤器
@@ -33,8 +36,19 @@ public class TokenFilter implements Filter {
             userId = Long.parseLong(userIdStr);
         }
 
-        String loginId = ServletUtil.getHeader("x-login-id");
-        LoginUser loginUser = new LoginUser(userId);
+        String loginId = "-1";
+        String loginIdStr = ServletUtil.getHeader("x-login-id");
+        if (loginIdStr != null) {
+            loginId = loginIdStr;
+        }
+
+        Set<String> roles = new HashSet<>();
+        String rolesStr = ServletUtil.getHeader("x-user-roles");
+        if (rolesStr != null) {
+            roles.addAll(Arrays.asList(rolesStr.split(",")));
+        }
+
+        LoginUser loginUser = new LoginUser(userId, loginId, roles);
         try (UserContext context = new UserContext(loginUser)) {
             chain.doFilter(request, response);
         } finally {

+ 5 - 5
content/content-service/src/main/java/cn/reghao/tnb/content/app/config/web/WebConfig.java

@@ -1,6 +1,6 @@
 package cn.reghao.tnb.content.app.config.web;
 
-import cn.reghao.tnb.content.app.exam.web.ExamAccountInterceptor;
+import cn.reghao.tnb.content.app.exam.web.ExamRoleInterceptor;
 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -15,15 +15,15 @@ import javax.servlet.Filter;
  */
 @Configuration
 public class WebConfig implements WebMvcConfigurer {
-    private final ExamAccountInterceptor examAccountInterceptor;
+    private final ExamRoleInterceptor examRoleInterceptor;
 
-    public WebConfig(ExamAccountInterceptor examAccountInterceptor) {
-        this.examAccountInterceptor = examAccountInterceptor;
+    public WebConfig(ExamRoleInterceptor examRoleInterceptor) {
+        this.examRoleInterceptor = examRoleInterceptor;
     }
 
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
-        registry.addInterceptor(examAccountInterceptor);
+        registry.addInterceptor(examRoleInterceptor);
     }
 
     @Bean

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/data/controller/ArticleController.java

@@ -31,7 +31,7 @@ public class ArticleController {
     @Operation(summary = "获取文章列表")
     @GetMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getArticles(@RequestParam("page") int page) {
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
         PageList<ArticleHeader> pageList = articleService.getArticleHeaders(userId, page);
         return WebResult.success(pageList);
     }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/data/controller/ArticlePostController.java

@@ -64,7 +64,7 @@ public class ArticlePostController {
     @Operation(summary = "获取文章贴列表")
     @GetMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getArticlePosts(@RequestParam("page") int page) {
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
         PageList<ArticlePost> pageList = articleService.getPageByUserId(userId, page);
         return WebResult.success(pageList);
     }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/data/controller/ImagePostController.java

@@ -50,7 +50,7 @@ public class ImagePostController {
     @Operation(summary = "获取用户发布的图片稿件列表", description = "N")
     @GetMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getUserImageAlbum(@RequestParam("page") int page) {
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
         PageList<AlbumCard> pageList = imagePostService.getUserAlbums(userId, page);
         return WebResult.success(pageList);
     }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/data/model/po/AudioPost.java

@@ -38,6 +38,6 @@ public class AudioPost extends BaseObject<Integer> {
         this.codec = codec;
         this.scope = PostScope.PUBLIC.getCode();
         this.publishAt = audioPublishSbt.getScheduledPubDate() != null ? audioPublishSbt.getScheduledPubDate() : LocalDateTime.now();
-        this.publishBy = UserContext.getUser();
+        this.publishBy = UserContext.getUserId();
     }
 }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/data/model/po/ImagePost.java

@@ -33,6 +33,6 @@ public class ImagePost extends BaseObject<Integer> {
         this.total = 0;
         this.createdAt = LocalDateTime.now();
         this.scope = scope;
-        this.userId = UserContext.getUser();
+        this.userId = UserContext.getUserId();
     }
 }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/data/service/ArticlePostService.java

@@ -40,7 +40,7 @@ public class ArticlePostService {
     }
 
     public void submitArticle(ArticlePublishSbt articlePublishSbt) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         String title = articlePublishSbt.getTitle();
         String content = articlePublishSbt.getContent();
 

+ 2 - 2
content/content-service/src/main/java/cn/reghao/tnb/content/app/data/service/AudioPostService.java

@@ -68,7 +68,7 @@ public class AudioPostService {
             return;
         }
 
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         long publishBy = audioPost.getPublishBy();
         if (loginUser == publishBy) {
             audioPostMapper.updateAudioScope(audioScopeUpdate);
@@ -88,7 +88,7 @@ public class AudioPostService {
     }
 
     public PageList<UserAudioCard> getPageByUserId(int page) {
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
         int total = audioPostMapper.countByUserId(userId);
         Page page1 = new Page(page, pageSize);
         List<UserAudioCard> list = audioPostMapper.findAudioCardByUserIdAndByPage(page1, userId);

+ 3 - 3
content/content-service/src/main/java/cn/reghao/tnb/content/app/data/service/AudioService.java

@@ -25,7 +25,7 @@ public class AudioService {
     }
 
     public PageList<UserAudioCard> getAudios(int page) {
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
         int total = audioPostMapper.countByUserId(userId);
         Page page1 = new Page(page, pageSize);
         List<UserAudioCard> list = audioPostMapper.findAudioCardByUserIdAndByPage(page1, userId);
@@ -45,7 +45,7 @@ public class AudioService {
             return null;
         }
 
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         String audioFileId = audioPost.getAudioFileId();
         try {
             int reqUser = 1;
@@ -55,7 +55,7 @@ public class AudioService {
             }
             String audioUrl = list.get(0).getUrl();
 
-            long userId = UserContext.getUser();
+            long userId = UserContext.getUserId();
             double currentTime = 0.0;
             if (userId != -1) {
                 Double currentTime1 = videoRecordService.getCurrentTime(userId, audioId);

+ 2 - 2
content/content-service/src/main/java/cn/reghao/tnb/content/app/data/service/ChartService.java

@@ -89,7 +89,7 @@ public class ChartService {
     }
 
     public List<String> getWatchLineChart() {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
 
         List<String> xAxis = new ArrayList<>();
         LocalDateTime current = LocalDateTime.now();
@@ -114,7 +114,7 @@ public class ChartService {
     }
 
     public List<String> getRegionPieChart() {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
 
         CategoryQuery categoryQuery = new CategoryQuery.Builder().pid(1).build();
         List<VideoCategory> videoCategories = categoryService.getVideoCategories(categoryQuery);

+ 3 - 3
content/content-service/src/main/java/cn/reghao/tnb/content/app/data/service/ImagePostService.java

@@ -115,13 +115,13 @@ public class ImagePostService {
     }
 
     private boolean isCollected(String imageFileId) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         return albumRepository.getByImagePost(imageFileId, loginUser) != null;
     }
 
     public PageList<AlbumCard> getUserAlbums(long userId, int page) {
         List<Integer> scopes = contentPermission.getUserScopes();
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         if (loginUser == userId) {
             scopes.add(PostScope.PRIVATE.getCode());
         }
@@ -166,7 +166,7 @@ public class ImagePostService {
 
         long owner = imagePost.getUserId();
         int scope = imagePost.getScope();
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         if (scope == PostScope.PRIVATE.getCode() && owner != loginUser) {
             return WebResult.notFound();
         }

+ 9 - 8
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/controller/ExamController.java

@@ -2,13 +2,13 @@ package cn.reghao.tnb.content.app.exam.controller;
 
 import cn.reghao.jutil.jdk.db.PageList;
 import cn.reghao.jutil.web.WebResult;
+import cn.reghao.tnb.account.api.constant.AccountRole;
 import cn.reghao.tnb.common.auth.UserContext;
 import cn.reghao.tnb.content.app.exam.model.constant.PaperViewType;
 import cn.reghao.tnb.content.app.exam.model.dto.UserResult;
 import cn.reghao.tnb.content.app.exam.model.query.PaperQuery;
 import cn.reghao.tnb.content.app.exam.model.vo.*;
 import cn.reghao.tnb.content.app.exam.service.ExamService;
-import cn.reghao.tnb.content.app.exam.service.ExamAccountService;
 import cn.reghao.tnb.content.app.exam.service.PaperService;
 import cn.reghao.tnb.content.app.exam.service.PaperViewService;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -27,14 +27,11 @@ import java.util.List;
 @RestController
 @RequestMapping("/api/content/exam/eval")
 public class ExamController {
-    private final ExamAccountService examAccountService;
     private final ExamService examService;
     private final PaperService paperService;
     private final PaperViewService paperViewService;
 
-    public ExamController(ExamAccountService examAccountService, ExamService examService,
-                          PaperService paperService, PaperViewService paperViewService) {
-        this.examAccountService = examAccountService;
+    public ExamController(ExamService examService, PaperService paperService, PaperViewService paperViewService) {
         this.examService = examService;
         this.paperService = paperService;
         this.paperViewService = paperViewService;
@@ -43,8 +40,12 @@ public class ExamController {
     @Operation(summary = "获取测评试卷列表", description = "N")
     @GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getExams(PaperQuery paperQuery) {
-        long loginUser = UserContext.getUser();
-        int role = examAccountService.getExamRole(loginUser);
+        int role = -1;
+        if (UserContext.getUserRoles().contains(AccountRole.examAdmin.getValue())) {
+            role = 1;
+        } else if (UserContext.getUserRoles().contains(AccountRole.examUser.getValue())) {
+            role = 2;
+        }
 
         paperQuery.setScope(role);
         PageList<EvalPaper> pageList1 = paperService.getEvalPapers(paperQuery);
@@ -55,7 +56,7 @@ public class ExamController {
     @GetMapping(value = "/start/{paperId}", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getExamPaperView(@PathVariable("paperId") int paperId) {
         int viewType = PaperViewType.PaperExam.getCode();
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
 
         int resultId = 0;
         PaperDetail paperDetail = paperViewService.getPaperDetail(paperId, viewType, resultId);

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/controller/ExamResultController.java

@@ -32,7 +32,7 @@ public class ExamResultController {
     @GetMapping(value = "/view/{paperId}", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getExamMark(@PathVariable("paperId") Integer paperId) {
         int viewType = PaperViewType.PaperResult.getCode();
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
 
         PaperResult paperResult = paperService.getPaperResult(paperId, loginUser);
         if (paperResult == null) {

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/controller/MarkController.java

@@ -48,7 +48,7 @@ public class MarkController {
     public String getMarkPaperView(@RequestParam("paperId") int paperId,
                                    @RequestParam("userId") long userId) {
         int viewType = PaperViewType.PaperMark.getCode();
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         if (userId == 0) {
             userId = loginUser;
         }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/model/po/Paper.java

@@ -43,6 +43,6 @@ public class Paper extends BaseObject<Integer> {
         this.passcode = paperAddDto.getExamPassword();
         this.hasSubjective = false;
         this.createAt = LocalDateTime.now();
-        this.createBy = UserContext.getUser();
+        this.createBy = UserContext.getUserId();
     }
 }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/model/po/PaperResult.java

@@ -30,7 +30,7 @@ public class PaperResult extends BaseObject<Integer> {
         this.userScore = this.objectiveScore + this.subjectiveScore;
         this.examTime = LocalDateTime.now();
         this.consumedTime = 0;
-        this.createBy = UserContext.getUser();
+        this.createBy = UserContext.getUserId();
         this.marked = marked;
     }
 }

+ 0 - 25
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/service/ExamAccountService.java

@@ -1,25 +0,0 @@
-package cn.reghao.tnb.content.app.exam.service;
-
-import cn.reghao.tnb.account.api.dto.ExamAccount;
-import cn.reghao.tnb.account.api.iface.AccountQuery;
-import org.apache.dubbo.config.annotation.DubboReference;
-import org.springframework.stereotype.Service;
-
-/**
- * @author reghao
- * @date 2025-08-11 15:14:56
- */
-@Service
-public class ExamAccountService {
-    @DubboReference(check = false, retries = 0, timeout = 10_000)
-    private AccountQuery accountQuery;
-
-    public ExamAccount getExamAccount(long userId) {
-        return accountQuery.getExamAccount(userId);
-    }
-
-    public int getExamRole(long userId) {
-        ExamAccount examAccount = accountQuery.getExamAccount(userId);
-        return examAccount.isExamAdmin() ? 1 : 2;
-    }
-}

+ 2 - 2
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/service/ExamService.java

@@ -42,7 +42,7 @@ public class ExamService {
     }
 
     public void cacheUserAnswers(UserResult userResult) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         int paperId = userResult.getPaperId();
         String key = String.format("%s:%s:%s", keyPrefix, paperId, loginUser);
 
@@ -95,7 +95,7 @@ public class ExamService {
         PaperResult paperResult = new PaperResult(paperId, objectiveScore, marked);
         int resultId = savePaperResult(paperResult, paperAnswers);
 
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         String key = String.format("%s:%s:%s", keyPrefix, paperId, loginUser);
         redisOps.del(key);
         return resultId;

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/service/MarkService.java

@@ -56,7 +56,7 @@ public class MarkService {
     @Transactional(rollbackFor = Exception.class)
     public void markExamResult(UserResult userResult) {
         int paperId = userResult.getPaperId();
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         PaperResult paperResult = getPaperResult(paperId, loginUser);
         if (paperResult == null) {
             return;

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/service/PaperService.java

@@ -87,7 +87,7 @@ public class PaperService {
     }
 
     public PageList<EvalPaper> getEvalPapers(PaperQuery paperQuery) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         int total = paperMapper.countByCriteria(paperQuery);
         Page page = paperQuery.getPage();
         List<Paper> list = paperMapper.findPaperByPage(page, paperQuery);

+ 14 - 7
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/service/PaperViewService.java

@@ -1,5 +1,6 @@
 package cn.reghao.tnb.content.app.exam.service;
 
+import cn.reghao.tnb.account.api.constant.AccountRole;
 import cn.reghao.tnb.common.auth.UserContext;
 import cn.reghao.tnb.content.app.exam.db.mapper.*;
 import cn.reghao.tnb.content.app.exam.model.constant.PaperViewType;
@@ -28,25 +29,31 @@ public class PaperViewService {
     private final QuestionOptionMapper questionOptionMapper;
     private final RedisHash redisHash;
     private PaperAnswerMapper paperAnswerMapper;
-    private ExamAccountService examAccountService;
 
     public PaperViewService(PaperMapper paperMapper, PaperQuestionMapper paperQuestionMapper,
                             QuestionMapper questionMapper, QuestionOptionMapper questionOptionMapper,
-                            RedisHash redisHash, PaperAnswerMapper paperAnswerMapper,
-                            ExamAccountService examAccountService) {
+                            RedisHash redisHash, PaperAnswerMapper paperAnswerMapper) {
         this.paperMapper = paperMapper;
         this.paperQuestionMapper = paperQuestionMapper;
         this.questionMapper = questionMapper;
         this.questionOptionMapper = questionOptionMapper;
         this.redisHash = redisHash;
         this.paperAnswerMapper = paperAnswerMapper;
-        this.examAccountService = examAccountService;
     }
 
-    public PaperDetail getPaperDetail(int paperId, int viewType, int resultId) {
-        long loginUser = UserContext.getUser();
-        int role = examAccountService.getExamRole(loginUser);
+    private int getRole() {
+        int role = -1;
+        if (UserContext.getUserRoles().contains(AccountRole.examAdmin.getValue())) {
+            role = 1;
+        } else if (UserContext.getUserRoles().contains(AccountRole.examUser.getValue())) {
+            role = 2;
+        }
+        return role;
+    }
 
+    public PaperDetail getPaperDetail(int paperId, int viewType, int resultId) {
+        long loginUser = UserContext.getUserId();
+        int role = getRole();
         Paper paper = paperMapper.findById(paperId);
         Map<Long, QuestionAnswer> paperAnswers;
         if (viewType == PaperViewType.PaperPreview.getCode()) {

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/service/QuestionService.java

@@ -134,7 +134,7 @@ public class QuestionService {
         int level = question.getLevel();
         String levelStr = QuestionLevel.getDescByCode(level);
 
-        String createBy = UserContext.getUser() + "";
+        String createBy = UserContext.getUserId() + "";
         String createAt = DateTimeConverter.format(question.getCreateTime());
         return new QuestionView(questionId, subject.getName(), typeStr, type, levelStr, question.getContent(), createBy, createAt);
     }

+ 5 - 22
content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/web/ExamAccountInterceptor.java → content/content-service/src/main/java/cn/reghao/tnb/content/app/exam/web/ExamRoleInterceptor.java

@@ -1,9 +1,8 @@
 package cn.reghao.tnb.content.app.exam.web;
 
 import cn.reghao.jutil.web.WebResult;
-import cn.reghao.tnb.account.api.dto.ExamAccount;
+import cn.reghao.tnb.account.api.constant.AccountRole;
 import cn.reghao.tnb.common.auth.UserContext;
-import cn.reghao.tnb.content.app.exam.service.ExamAccountService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.lang.Nullable;
 import org.springframework.stereotype.Component;
@@ -16,40 +15,24 @@ import java.io.IOException;
 import java.io.PrintWriter;
 
 /**
- * 只放行具有 ExamAccount 的请求
+ * 只放行拥有 ROLE_EXAM_ADMIN 或 ROLE_EXAM_USER 角色的请求
  *
  * @author reghao
  * @date 2025-07-18 09:18:16
  */
 @Slf4j
 @Component
-public class ExamAccountInterceptor implements HandlerInterceptor {
-    private final ExamAccountService examAccountService;
-
-    public ExamAccountInterceptor(ExamAccountService examAccountService) {
-        this.examAccountService = examAccountService;
-    }
-
+public class ExamRoleInterceptor implements HandlerInterceptor {
     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
             throws Exception {
         String uri = request.getRequestURI();
         String method = request.getMethod();
-        String userAgent = request.getHeader("user-agent");
-        String ipv4 = request.getRemoteAddr();
         if (uri.startsWith("/api/content/exam")) {
-            long loginUser = UserContext.getUser();
-            ExamAccount examAccount = examAccountService.getExamAccount(loginUser);
-            if (!examAccount.isExist()) {
-                String msg = "Current user not ExamAccount";
-                writeResponse(response, msg);
-                return false;
-            }
-
             if (uri.startsWith("/api/content/exam/subject")
                     || uri.startsWith("/api/content/exam/question")
                     || uri.startsWith("/api/content/exam/paper")) {
-                if (!examAccount.isExamAdmin()) {
+                if (!UserContext.getUserRoles().contains(AccountRole.examAdmin.getValue())) {
                     String msg = "Current user not ExamAdmin";
                     writeResponse(response, msg);
                     return false;
@@ -57,7 +40,7 @@ public class ExamAccountInterceptor implements HandlerInterceptor {
             }
 
             if (uri.startsWith("/api/content/exam/eval")) {
-                if (examAccount.isExamAdmin()) {
+                if (!UserContext.getUserRoles().contains(AccountRole.examUser.getValue())) {
                     String msg = "Current user not ExamUser";
                     writeResponse(response, msg);
                     return false;

+ 2 - 2
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/model/po/GeoPoint.java

@@ -33,7 +33,7 @@ public class GeoPoint extends BaseObject<Integer> {
         this.longitude = BigDecimal.valueOf(mapPoint.getLng());
         this.latitude = BigDecimal.valueOf(mapPoint.getLat());
         this.deviceId = "xxx";
-        this.createBy = UserContext.getUser();
+        this.createBy = UserContext.getUserId();
         this.createAt = DateTimeConverter.localDateTime(System.currentTimeMillis());
     }
 
@@ -42,7 +42,7 @@ public class GeoPoint extends BaseObject<Integer> {
         this.longitude = BigDecimal.valueOf(mapPoint.getLng());
         this.latitude = BigDecimal.valueOf(mapPoint.getLat());
         this.deviceId = "xxx";
-        this.createBy = UserContext.getUser();
+        this.createBy = UserContext.getUserId();
         this.createAt = DateTimeConverter.localDateTime(System.currentTimeMillis());
     }
 }

+ 2 - 2
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/service/MapService.java

@@ -66,7 +66,7 @@ public class MapService {
                 .map(GeoPoint::new)
                 .collect(Collectors.toList());
         if (!geoPointList.isEmpty()) {
-            long loginUser = UserContext.getUser();
+            long loginUser = UserContext.getUserId();
             geoPointMapper.deleteByPositionType(loginUser, 2);
             geoPointMapper.saveAll(geoPointList);
         }
@@ -86,7 +86,7 @@ public class MapService {
     }
 
     private List<GeoPoint> getMyGeoPoints() {
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
         List<GeoPoint> list = geoPointMapper.findByPositionType(userId, 2);
         return list;
     }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/geo/service/PhotoMapService.java

@@ -93,7 +93,7 @@ public class PhotoMapService {
     }
 
     public List<MapMarker> getMapDistance(int distance) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         List<GeoPoint> geoPointList = geoPointMapper.findByPositionType(loginUser, 1);
         if (geoPointList.isEmpty()) {
             return Collections.emptyList();

+ 3 - 3
content/content-service/src/main/java/cn/reghao/tnb/content/app/mall/controller/CartController.java

@@ -36,7 +36,7 @@ public class CartController {
     @AuthUser
     @PostMapping("")
     public String addCart(@RequestBody @Validated CartDto cartDto) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         long itemId = cartDto.getItemId();
         int num = cartDto.getNum();
         cartService.addCartItem(loginUser, itemId, num);
@@ -47,7 +47,7 @@ public class CartController {
     @AuthUser
     @DeleteMapping("/{itemId}")
     public String deleteItem(@PathVariable("itemId") Long itemId) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         cartService.deleteCartItem(loginUser, itemId);
         return WebResult.success();
     }
@@ -56,7 +56,7 @@ public class CartController {
     @AuthUser
     @GetMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getCartItems() {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         List<CartCard> list = cartService.getUserCart(loginUser);
         return WebResult.success(list);
     }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/mall/controller/DeliveryController.java

@@ -44,7 +44,7 @@ public class DeliveryController {
     @AuthUser
     @GetMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getDeliveryAddress() {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         List<Delivery> list = deliveryService.getUserAddresses(loginUser);
         return WebResult.success(list);
     }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/mall/controller/LogisticsController.java

@@ -48,7 +48,7 @@ public class LogisticsController {
     @AuthUser
     @GetMapping(value = "/order/{orderId}", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getOrderLogistics(@PathVariable("orderId") Long orderId) {
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
         List<LogisticsProgress> list = logisticsService.getOrderLogistics(userId, orderId);
         return WebResult.success(list);
     }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/mall/model/po/Product.java

@@ -44,6 +44,6 @@ public class Product extends BaseObject<Integer> {
         this.picUrl = coverUrl;
         this.price = productAddDto.getPrice();
         this.stock = productAddDto.getAmount();
-        this.sellerId = UserContext.getUser();
+        this.sellerId = UserContext.getUserId();
     }
 }

+ 2 - 2
content/content-service/src/main/java/cn/reghao/tnb/content/app/mall/service/BuyService.java

@@ -48,7 +48,7 @@ public class BuyService {
         }
 
         double price = product.getPrice();
-        BuyDto buyDto = new BuyDto(productId, price, amount, deliveryId, UserContext.getUser());
+        BuyDto buyDto = new BuyDto(productId, price, amount, deliveryId, UserContext.getUserId());
 
         // TODO 创建订单和修改库存是一个分布式事务
         long orderId = newOrderService.createOrder(buyDto);
@@ -68,7 +68,7 @@ public class BuyService {
             });
         });
 
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         map.forEach((shopId, items) -> {
             items.forEach(item -> {
                 long itemId = item.getItemId();

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/controller/CategoryController.java

@@ -34,7 +34,7 @@ public class CategoryController {
     @Operation(summary = "获取视频分区", description = "N")
     @GetMapping(value = "/categories", produces = MediaType.APPLICATION_JSON_VALUE)
     public String videoCategories() {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         boolean vip = userService.isVip(loginUser);
         List<VideoRegion> list1 = categoryService.getCategories(vip);
         return WebResult.success(list1);

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/controller/RecommendController.java

@@ -43,7 +43,7 @@ public class RecommendController {
             return WebResult.success(Collections.emptyList());
         }
 
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
         List<VideoCard> list = recommendService.getRecommendVideos(userId, nextId);
         return WebResult.success(list);
     }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/controller/VideoPlayController.java

@@ -39,7 +39,7 @@ public class VideoPlayController {
     @Operation(summary = "获取某个用户的视频播放记录", description = "N")
     @GetMapping(value = "/visit", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getVisitedVideo(@RequestParam("nextId") long nextId) {
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
         PageScroll<VideoRecordCard> pager = videoPlayService.getPlayRecord(nextId, userId);
         return WebResult.success(pager);
     }

+ 3 - 2
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/controller/VideoQueryController.java

@@ -2,6 +2,7 @@ package cn.reghao.tnb.content.app.vod.controller;
 
 import cn.reghao.jutil.jdk.db.PageList;
 import cn.reghao.jutil.web.WebResult;
+import cn.reghao.tnb.account.api.constant.AccountRole;
 import cn.reghao.tnb.account.api.iface.AccountQuery;
 import cn.reghao.tnb.common.auth.AuthUser;
 import cn.reghao.tnb.common.auth.UserContext;
@@ -102,7 +103,7 @@ public class VideoQueryController {
     @Operation(summary = "获取用户的视频时间线", description = "N")
     @GetMapping(value = "/timeline", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getVideoTimeline(@RequestParam("nextId") String nextId) {
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
         PageScroll<VideoCard> pageScroll = videoQueryService.getVideoTimeline(userId, nextId);
         return WebResult.success(pageScroll);
     }
@@ -115,7 +116,7 @@ public class VideoQueryController {
             return WebResult.success(Collections.emptyList());
         }
 
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
         List<VideoCard> list = recommendService.getRecommendVideos(userId, nextId);
         return WebResult.success(list);
     }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/model/po/Favlist.java

@@ -22,6 +22,6 @@ public class Favlist extends BaseObject<Integer> {
         this.favlistId = favlistId;
         this.favlistName = favlistName;
         this.contentType = contentType;
-        this.createBy = UserContext.getUser();
+        this.createBy = UserContext.getUserId();
     }
 }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/model/po/PostAlbum.java

@@ -32,6 +32,6 @@ public class PostAlbum extends BaseObject<Integer> {
         this.postType = PostType.Video.getCode();
         this.total = 0;
         this.scope = PostScope.PRIVATE.getCode();
-        this.createBy = UserContext.getUser();
+        this.createBy = UserContext.getUserId();
     }
 }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/model/po/SearchRecord.java

@@ -24,7 +24,7 @@ public class SearchRecord extends BaseObject<Integer> {
 
     public SearchRecord(String keyword) {
         this.keyword = keyword;
-        this.searchBy = UserContext.getUser();
+        this.searchBy = UserContext.getUserId();
         this.searchAt = LocalDateTime.now();
     }
 }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/model/po/UserComment.java

@@ -56,6 +56,6 @@ public class UserComment extends BaseObject<String> {
         this.likes = 0;
         this.liked = false;
         this.publishAt = System.currentTimeMillis();
-        this.publishBy = UserContext.getUser();
+        this.publishBy = UserContext.getUserId();
     }
 }

+ 2 - 2
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/model/po/VideoPost.java

@@ -50,7 +50,7 @@ public class VideoPost extends BaseObject<Integer> {
         this.scope = video.getScope();
         this.status = status;
         this.publishAt = DateTimeConverter.localDateTime(publishAt);
-        this.publishBy = UserContext.getUser();
+        this.publishBy = UserContext.getUserId();
     }
 
     public VideoPost(String videoId, String title, VideoFile videoInfo) {
@@ -61,7 +61,7 @@ public class VideoPost extends BaseObject<Integer> {
         this.scope = PostScope.PRIVATE.getCode();
         this.status = VideoStatus.censor.getCode();
         this.publishAt = DateTimeConverter.localDateTime(System.currentTimeMillis());
-        this.publishBy = UserContext.getUser();
+        this.publishBy = UserContext.getUserId();
     }
 
     @Deprecated

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/model/query/AlbumQuery.java

@@ -20,7 +20,7 @@ public class AlbumQuery {
     private Integer pn;
 
     public AlbumQuery() {
-        this.createBy = UserContext.getUser();
+        this.createBy = UserContext.getUserId();
         this.pn = 1;
     }
 

+ 5 - 5
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/AlbumService.java

@@ -67,7 +67,7 @@ public class AlbumService {
     }
 
     public Result doAlbumAction(AlbumActionDto albumActionDto) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         int action = albumActionDto.getAction();
         long albumId = albumActionDto.getAlbumId();
         String postId = albumActionDto.getPostId();
@@ -99,7 +99,7 @@ public class AlbumService {
     public PageList<AlbumInfo> getUserAlbums(String userIdStr, int pn) {
         long userId = accountQuery.getUserIdLong(userIdStr);
         List<Integer> scopes = contentPermission.getUserScopes();
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         if (loginUser == userId) {
             scopes.add(PostScope.PRIVATE.getCode());
         }
@@ -134,7 +134,7 @@ public class AlbumService {
     }
 
     public String getAlbumContent(Long albumId, Integer pn) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         AlbumQuery albumQuery;
         if (albumId == null) {
             albumQuery = new AlbumQuery.Builder().createBy(loginUser).build();
@@ -182,7 +182,7 @@ public class AlbumService {
     }
 
     public List<SelectOption> getSelectOptions() {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         AlbumQuery albumQuery = new AlbumQuery.Builder()
                 .createBy(loginUser)
                 .build();
@@ -221,7 +221,7 @@ public class AlbumService {
         PostAlbum postAlbum = list.get(0);
         long owner = postAlbum.getCreateBy();
         int scope = postAlbum.getScope();
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         if (scope == PostScope.PRIVATE.getCode() && owner != loginUser) {
             return WebResult.notFound();
         }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/CommentService.java

@@ -127,7 +127,7 @@ public class CommentService {
             commentUser.setAvatar("avatar.jpg");
         }
 
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         if (loginUser == userId) {
             commentUser.setAuthor(true);
         }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/ContentPermission.java

@@ -19,7 +19,7 @@ public class ContentPermission {
     private UserService userService;
 
     public List<Integer> getUserScopes() {
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
         return getUserScopes(userId);
     }
 

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/ContentService.java

@@ -32,7 +32,7 @@ public class ContentService {
     }
 
     public UserContentData getUserContentData(long userId) {
-        long owner = UserContext.getUser();
+        long owner = UserContext.getUserId();
         VideoQuery videoQuery;
         if (owner == userId) {
             videoQuery = new VideoQuery.Builder().userId(userId).build();

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/VideoEditService.java

@@ -45,7 +45,7 @@ public class VideoEditService {
     }
 
     public Result errorReport(VideoErrorReport videoErrorReport) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         if (!adminUsers.contains(loginUser)) {
             return Result.fail("no permission");
         }

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/VideoService.java

@@ -43,7 +43,7 @@ public class VideoService {
     }
 
     public DownloadUrl downloadVideo(String videoId) {
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
         VideoPost videoPost = videoPostMapper.findByVideoId(videoId);
         if (videoPost == null) {
             return null;

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/impl/SearchServiceImpl.java

@@ -98,7 +98,7 @@ public class SearchServiceImpl implements SearchService {
     }
 
     public PageList<VideoCard> searchKeywordInLucene(String keyword, int pageNumber) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         List<Integer> userScopes = contentPermission.getUserScopes(loginUser);
         PageList<VideoSummary> pageList = dataSearchService.searchVideo(keyword, userScopes, pageNumber);
         List<VideoSummary> videoSummaryList = pageList.getList();

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/impl/VideoPlayServiceImpl.java

@@ -68,7 +68,7 @@ public class VideoPlayServiceImpl implements VideoPlayService {
 
     public VideoUrls getVideoPlayData(String videoId) {
         double currentTime = 0.0;
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         if (loginUser != -1) {
             currentTime = getCurrentTime(loginUser, videoId);
         }

+ 5 - 5
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/impl/VideoPostQueryImpl.java

@@ -132,7 +132,7 @@ public class VideoPostQueryImpl implements VideoPostQuery {
     }
 
     private String getRandomVideoId() {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         List<Integer> userScopes = contentPermission.getUserScopes(loginUser);
         List<String> videoIds = videoRepository.getShortVideoIds(userScopes);
         if (videoIds.isEmpty()) {
@@ -173,7 +173,7 @@ public class VideoPostQueryImpl implements VideoPostQuery {
             return PageList.empty();
         }
 
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         List<Integer> userScopes = contentPermission.getUserScopes(loginUser);
         String tagId = videoTag.getTagId();
         int total = videoPostTagMapper.countVideosByTag(tagId, userScopes);
@@ -189,7 +189,7 @@ public class VideoPostQueryImpl implements VideoPostQuery {
 
     public PageList<VideoCard> getUserVideos(long userId, int page) {
         VideoQuery videoQuery;
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         if (loginUser == userId) {
             videoQuery = new VideoQuery.Builder().status(getVideoStatusList()).userId(userId).build();
         } else {
@@ -244,7 +244,7 @@ public class VideoPostQueryImpl implements VideoPostQuery {
             return WebResult.notFound();
         }
 
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         long owner = videoPost.getPublishBy();
         int scope = videoPost.getScope();
         if (scope == PostScope.PRIVATE.getCode() && owner != loginUser) {
@@ -356,7 +356,7 @@ public class VideoPostQueryImpl implements VideoPostQuery {
      */
     public PageList<UserVideoPost> getUserVideoPost(int pageNumber) {
         Page page1 = new Page(pageNumber, pageSize);
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
 
         VideoQuery videoQuery = new VideoQuery.Builder().status(getStatusList()).userId(userId).build();
         int total = videoPostMapper.countByCriteria(videoQuery);

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/vod/service/impl/VideoPostServiceImpl.java

@@ -321,7 +321,7 @@ public class VideoPostServiceImpl implements VideoPostService {
     public void deleteVideo(String videoId) {
         VideoPost videoPost = videoPostMapper.findByVideoId(videoId);
         long owner = videoPost.getPublishBy();
-        if (owner == UserContext.getUser()) {
+        if (owner == UserContext.getUserId()) {
             // 删除 videoId 关联的所有数据, 包括观看记录, 用户收藏, 视频数据, 视频标签, 推荐数据等
             videoPostMapper.deleteByVideoId(videoId);
 

+ 1 - 1
file/file-service/src/main/java/cn/reghao/tnb/file/app/service/AvatarService.java

@@ -28,7 +28,7 @@ public class AvatarService {
         ImageInfo imageInfo = ossService.getImageInfo(channelId, uploadId);
         if (imageInfo != null) {
             String avatarUrl = imageInfo.getUrl();
-            long loginUser = UserContext.getUser();
+            long loginUser = UserContext.getUserId();
             accountQuery.updateAvatar(loginUser, avatarUrl);
             return avatarUrl;
         }

+ 2 - 2
file/file-service/src/main/java/cn/reghao/tnb/file/app/service/OrderService.java

@@ -45,7 +45,7 @@ public class OrderService {
         if (order != null && order.getStatus() == OrderStatus.toPay.getCode()) {
             long sellerId = mallService.getSellerId(order.getProductId());
             int amount = order.getAmount();
-            long loginUser = UserContext.getUser();
+            long loginUser = UserContext.getUserId();
             double quantity = amount*order.getPrice();
 
             // TODO 支付订单和更新订单状态是一个分布式事务
@@ -74,7 +74,7 @@ public class OrderService {
     }
 
     public List<OrderDetail> getOrders(int pageNumber) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         int pageSize = 100;
         List<Order> list = orderMapper.findByOwner(pageSize, loginUser);
         return list.stream().map(order -> {

+ 15 - 1
file/file-service/src/test/java/FileTest.java

@@ -1,12 +1,13 @@
 import cn.reghao.tnb.file.app.FileApplication;
 import cn.reghao.tnb.file.app.db.mapper.StoreConfigMapper;
 import cn.reghao.tnb.file.app.model.po.StoreConfig;
+import com.netflix.discovery.EurekaClient;
+import com.netflix.discovery.shared.Applications;
 import lombok.extern.slf4j.Slf4j;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.junit4.SpringRunner;
 
 import java.util.List;
 
@@ -49,4 +50,17 @@ public class FileTest {
         List<StoreConfig> list = List.of(storeConfig, storeConfig1, storeConfig2);
         storeConfigMapper.saveAll(list);
     }
+
+    @Autowired
+    EurekaClient eurekaClient;
+    @Test
+    public void eurekaClientTest() {
+        Applications applications = eurekaClient.getApplications();
+        applications.getRegisteredApplications().forEach(application -> {
+            String name = application.getName();
+            application.getInstances().forEach(instanceInfo -> {
+                String instanceId = instanceInfo.getInstanceId();
+            });
+        });
+    }
 }

+ 2 - 2
gateway/src/main/java/cn/reghao/tnb/gateway/config/RedisKeys.java

@@ -9,7 +9,7 @@ public class RedisKeys {
         return String.format("tnb:auth:jwt:rsa:%s", key);
     }
 
-    public static String getJwtBlacklistKey(String key) {
-        return String.format("tnb:auth:jwt:blacklist:%s", key);
+    public static String getAuthTokenKey(long userId, String loginId) {
+        return String.format("tnb:auth:login:success:%s:%s:auth_token", userId, loginId);
     }
 }

+ 14 - 21
gateway/src/main/java/cn/reghao/tnb/gateway/token/GlobalTokenFilter.java

@@ -1,7 +1,6 @@
 package cn.reghao.tnb.gateway.token;
 
 import cn.reghao.jutil.jdk.security.RsaCryptor;
-import cn.reghao.jutil.jdk.string.IDObfuscation;
 import cn.reghao.jutil.tool.jwt.Jwt;
 import cn.reghao.tnb.gateway.token.model.UserData;
 import cn.reghao.tnb.gateway.token.model.UserLogin;
@@ -43,11 +42,9 @@ import java.util.stream.Collectors;
 public class GlobalTokenFilter implements GlobalFilter, Ordered {
     private final String cookieName = "USERDATA";
     private final RedisTemplate<String, String> redisTemplate;
-    private final IDObfuscation userIdObfuscation;
 
-    public GlobalTokenFilter(RedisTemplate<String, String> redisTemplate, IDObfuscation userIdObfuscation) {
+    public GlobalTokenFilter(RedisTemplate<String, String> redisTemplate) {
         this.redisTemplate = redisTemplate;
-        this.userIdObfuscation = userIdObfuscation;
     }
 
     @Override
@@ -88,8 +85,9 @@ public class GlobalTokenFilter implements GlobalFilter, Ordered {
 
         final UserLogin userLogin1 = userLogin;
         Consumer<HttpHeaders> headers = header -> {
-            header.set("x-user-id", userLogin1.getUserId());
+            header.set("x-user-id", ""+userLogin1.getUserId());
             header.set("x-login-id", userLogin1.getLoginId());
+            header.set("x-user-roles", userLogin1.getRoles());
         };
         exchange.getRequest().mutate().headers(headers).build();
         return chain.filter(exchange);
@@ -122,31 +120,26 @@ public class GlobalTokenFilter implements GlobalFilter, Ordered {
     }
 
     private UserLogin getUserLoginByToken(String jwtToken) {
-        RSAPublicKey signKey = getPublicKey();
-        Claims claims = Jwts.parser().setSigningKey(signKey).parseClaimsJws(jwtToken).getBody();
+        RSAPublicKey signKeyPublic = getPublicKey();
+        Claims claims = Jwts.parser().setSigningKey(signKeyPublic).parseClaimsJws(jwtToken).getBody();
         // TODO 帐号登出后, 已颁发 token 的 jti 会放到 blacklist 中, 需要判断当前 token 是否在 blacklist 中
         String jti = (String) claims.get("jti");
-
-        Integer plat = (Integer) claims.get("plat");
+        long userId = Long.parseLong(claims.getSubject());
         String loginId = (String) claims.get("loginId");
-        int loginType = (int) claims.get("loginType");
-        String userId = claims.getSubject();
-        if (plat == null || loginId == null || userId == null) {
-            return new UserLogin();
+        String roles = (String) claims.get("authorities");
+        String rolesStr = roles.replace("[", "").replace("]", "").replace(" ", "");
+        Boolean exist = redisTemplate.hasKey(RedisKeys.getAuthTokenKey(userId, loginId));
+        if (exist != null && exist) {
+            return new UserLogin(userId, loginId, rolesStr);
         }
 
-        return new UserLogin(""+userId, loginId);
+        return new UserLogin();
     }
 
     private RSAPublicKey getPublicKey() {
         String key = RedisKeys.getJwtSignKey("pubkey");
         ValueOperations<String, String> operations = redisTemplate.opsForValue();
-        Boolean hasKey = redisTemplate.hasKey(key);
-        if (hasKey != null && hasKey) {
-            String pubkey = operations.get(key);
-            return RsaCryptor.getRSAPublicKey(pubkey);
-        }
-
-        return null;
+        String pubkey = operations.get(key);
+        return pubkey != null ? RsaCryptor.getRSAPublicKey(pubkey) : null;
     }
 }

+ 4 - 2
gateway/src/main/java/cn/reghao/tnb/gateway/token/model/UserLogin.java

@@ -10,11 +10,13 @@ import lombok.Getter;
 @AllArgsConstructor
 @Getter
 public class UserLogin {
-    private String userId;
+    private long userId;
     private String loginId;
+    private String roles;
 
     public UserLogin() {
-        this.userId = "-1";
+        this.userId = -1;
         this.loginId = "-1";
+        this.roles = "";
     }
 }

+ 1 - 1
user/user-service/src/main/java/cn/reghao/tnb/user/app/controller/UserContactController.java

@@ -95,7 +95,7 @@ public class UserContactController {
     @Operation(summary = "获取联系人列表", description = "N")
     @GetMapping(value = "/list", produces = MediaType.APPLICATION_JSON_VALUE)
     public String contactList() {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         List<ContactInfo> list = contactService.getContactList(loginUser);
         return WebResult.success(list);
     }

+ 2 - 2
user/user-service/src/main/java/cn/reghao/tnb/user/app/controller/UserMessageController.java

@@ -29,7 +29,7 @@ public class UserMessageController {
     @Operation(summary = "获取未读消息数量", description = "N")
     @GetMapping(value = "/unread", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getUnreadCount() {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         int total = userMessageService.getUnreadCount(loginUser);
         return WebResult.success(Map.of("total", total));
     }
@@ -37,7 +37,7 @@ public class UserMessageController {
     @Operation(summary = "获取未读消息列表", description = "N")
     @GetMapping(value = "/unread/list", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getUnreadMessages() {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         List<UserMessage> list = userMessageService.getMessages(loginUser);
         return WebResult.success(list);
     }

+ 3 - 3
user/user-service/src/main/java/cn/reghao/tnb/user/app/controller/UserRelationController.java

@@ -34,7 +34,7 @@ public class UserRelationController {
     @PostMapping("/follow/{followingId}")
     public String followUser(@PathVariable("followingId") String followingId) {
         long followingId1 = accountQuery.getUserIdLong(followingId);
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         userRelationService.followUser(loginUser, followingId1);
         return WebResult.success();
     }
@@ -44,7 +44,7 @@ public class UserRelationController {
     @PostMapping("/unfollow/{followingId}")
     public String unfollowUser(@PathVariable("followingId") String followingId) {
         long followingId1 = accountQuery.getUserIdLong(followingId);
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         userRelationService.unfollowUser(loginUser, followingId1);
         return WebResult.success();
     }
@@ -53,7 +53,7 @@ public class UserRelationController {
     @GetMapping("/check/{userId}")
     public String check(@PathVariable("userId") String userId) {
         long userId1 = accountQuery.getUserIdLong(userId);
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         boolean followed;
         if (loginUser == -1) {
             followed = false;

+ 3 - 3
user/user-service/src/main/java/cn/reghao/tnb/user/app/controller/UserWalletController.java

@@ -37,7 +37,7 @@ public class UserWalletController {
     @AuthUser
     @GetMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getUserWallet() {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         Wallet wallet = walletService.getUserWallet(loginUser);
         return WebResult.success(wallet);
     }
@@ -46,7 +46,7 @@ public class UserWalletController {
     @AuthUser
     @GetMapping(value = "/bill", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getWalletBill() {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         List<BillRecord> list = walletService.getWalletBill(loginUser);
         return WebResult.success(list);
     }
@@ -64,7 +64,7 @@ public class UserWalletController {
     @PostMapping("/pay")
     public String pay(@RequestBody @Validated WalletDto walletDto) throws Exception {
         double quantity = 1.2;
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         walletService.pay(quantity, loginUser);
         return WebResult.success();
     }

+ 1 - 1
user/user-service/src/main/java/cn/reghao/tnb/user/app/model/po/WalletCharge.java

@@ -23,7 +23,7 @@ public class WalletCharge extends BaseObject<Integer> {
     public WalletCharge(long chargeId, ChargeReq chargeReq) {
         this.chargeId = chargeId;
         this.quantity = chargeReq.getQuantity();
-        this.owner = UserContext.getUser();
+        this.owner = UserContext.getUserId();
         this.status = 1;
     }
 }

+ 7 - 7
user/user-service/src/main/java/cn/reghao/tnb/user/app/service/ContactService.java

@@ -58,7 +58,7 @@ public class ContactService {
         UserInfo userInfo = userProfileService.getUserInfo(userId);
         ContactInfoResult contactInfoResult = new ContactInfoResult(userInfo);
 
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         if (friendId == loginUser) {
             contactInfoResult.setFriendApply(ApplyStatus.acceptApply.getValue());
             contactInfoResult.setFriendStatus(FriendStatus.normal.getValue());
@@ -85,7 +85,7 @@ public class ContactService {
     }
 
     public Result createApply(ContactAdd contactAdd) {
-        long applyUser = UserContext.getUser();
+        long applyUser = UserContext.getUserId();
         long appliedUser = contactAdd.getFriendId();
         if (userContactRecordMapper.findByUserIdAndFriendId(applyUser, appliedUser) != null) {
             return Result.success("已发送申请, 请等待结果");
@@ -104,13 +104,13 @@ public class ContactService {
     }
 
     public UnreadNum getApplyCount() {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         int total = userContactRecordMapper.countNewApply(loginUser);
         return new UnreadNum(total);
     }
 
     public ContactApplyList getApplyList(int pageNumber) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         List<ContactApplyInfo> list = userContactRecordMapper.findByNewApply(loginUser);
         list.forEach(contactApplyInfo -> {
             long userId = contactApplyInfo.getUserId();
@@ -135,7 +135,7 @@ public class ContactService {
     }
 
     public void acceptApply(ContactAddRespond contactAddRespond) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         int applyId = contactAddRespond.getApplyId();
         String nicknameRemark = contactAddRespond.getRemark();
 
@@ -159,7 +159,7 @@ public class ContactService {
     }
 
     public void declineApply(ContactAddRespond contactAddRespond) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         int applyId = contactAddRespond.getApplyId();
         String remark = contactAddRespond.getRemark();
         userContactRecordMapper.updateContactApply(applyId, loginUser, ApplyStatus.declineApply.getValue());
@@ -178,7 +178,7 @@ public class ContactService {
     public void updateContactRemark(ContactRemark contactRemark) {
         long friendId = contactRemark.getFriendId();
         String remarkName = contactRemark.getRemarkName();
-        long owner = UserContext.getUser();
+        long owner = UserContext.getUserId();
         userContactMapper.updateContactRemark(friendId, remarkName, owner);
     }
 }

+ 3 - 3
user/user-service/src/main/java/cn/reghao/tnb/user/app/service/GroupInfoService.java

@@ -32,7 +32,7 @@ public class GroupInfoService {
     }
 
     public CreateGroupRet createGroup(CreateGroup createGroup) {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         GroupInfo groupInfo = new GroupInfo(createGroup, loginUser);
         groupInfoMapper.save(groupInfo);
 
@@ -46,7 +46,7 @@ public class GroupInfoService {
     }
 
     public GroupDetailRet getGroupDetail(long groupId) {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         GroupMember groupMember = groupMemberMapper.findByGroupAndUserId(groupId, loginUser);
         if (groupMember == null) {
             // TODO 只有群组成员才可获取群信息
@@ -73,7 +73,7 @@ public class GroupInfoService {
     }
 
     public void editGroupDetail(GroupSetting groupSetting) {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         int groupId = groupSetting.getGroupId();
         GroupInfo groupInfo = groupInfoMapper.findByGroupId(groupId);
         long ownerId = groupInfo.getOwnerId();

+ 6 - 6
user/user-service/src/main/java/cn/reghao/tnb/user/app/service/GroupMemberService.java

@@ -37,7 +37,7 @@ public class GroupMemberService {
     }
 
     public GroupInfoRetList getGroups() {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         List<GroupInfoRet> rows = groupInfoMapper.findGroupsByUserId(loginUser);
         rows.forEach(groupInfoRet -> {
             if (groupInfoRet.isOwner()) {
@@ -78,14 +78,14 @@ public class GroupMemberService {
     }
 
     public void setNicknameInGroup(MemberRemark memberRemark) {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         long groupId = memberRemark.getGroupId();
         String remarkName = memberRemark.getVisitCard();
         groupMemberMapper.updateSetMemberRemark(groupId, loginUser, remarkName);
     }
 
     public List<ContactInfo> getInvitedUsers(long groupId) {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         List<UserContact> list = new ArrayList<>();
         /*if (groupId == 0) {
             list = userContactMapper.findByUserId(loginUser);
@@ -103,7 +103,7 @@ public class GroupMemberService {
     }
 
     public void inviteUsers(GroupInvite groupInvite) {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         long groupId = groupInvite.getGroupId();
         GroupMember groupMember = groupMemberMapper.findByGroupAndUserId(groupId, loginUser);
         if (groupMember == null) {
@@ -118,7 +118,7 @@ public class GroupMemberService {
     }
 
     public void leaveGroup(SecedeGroup secedeGroup) {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         long groupId = secedeGroup.getGroupId();
         GroupInfo groupInfo = groupInfoMapper.findByGroupId(groupId);
         long ownerId = groupInfo.getOwnerId();
@@ -132,7 +132,7 @@ public class GroupMemberService {
     }
 
     public void removeMembers(RemoveMember removeMember) {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         long groupId = removeMember.getGroupId();
         GroupInfo groupInfo = groupInfoMapper.findByGroupId(groupId);
         long ownerId = groupInfo.getOwnerId();

+ 2 - 2
user/user-service/src/main/java/cn/reghao/tnb/user/app/service/GroupNoticeService.java

@@ -29,7 +29,7 @@ public class GroupNoticeService {
     }
 
     public void createOrUpdateNotice(EditGroupNotice editGroupNotice) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         int noticeId = editGroupNotice.getNoticeId();
         GroupNotice groupNotice = new GroupNotice(editGroupNotice, loginUser);
         if (noticeId == 0) {
@@ -45,7 +45,7 @@ public class GroupNoticeService {
     }
 
     public NoticeListRet getNoticeList(long groupId) {
-        long loginUser = UserContext.getUser();;
+        long loginUser = UserContext.getUserId();;
         GroupMember groupMember = groupMemberMapper.findByGroupAndUserId(groupId, loginUser);
         if (groupMember == null) {
             // TODO 不是该组成员, 没有权限查看群公告

+ 2 - 2
user/user-service/src/main/java/cn/reghao/tnb/user/app/service/UserProfileService.java

@@ -37,7 +37,7 @@ public class UserProfileService {
     }
 
     public void updateUserProfile(UserProfileUpdate userProfileUpdate) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         int type = userProfileUpdate.getType();
         String content = userProfileUpdate.getContent();
 
@@ -70,7 +70,7 @@ public class UserProfileService {
     }
 
     public UserCard getUserCard(long userId) {
-        long loginUser = UserContext.getUser();
+        long loginUser = UserContext.getUserId();
         UserInfo userInfo = getUserInfo(userId);
         boolean followed = isFollowing(loginUser, userId);
         String userIdStr = accountQuery.getUserIdStr(userId);

+ 2 - 2
user/user-service/src/main/java/cn/reghao/tnb/user/app/service/UserVipService.java

@@ -32,7 +32,7 @@ public class UserVipService {
     }
 
     public MyVip getMyVip() {
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
         UserVip userVip = userVipMapper.findByUserId(userId);
         if (userVip == null) {
             return new MyVip();
@@ -64,7 +64,7 @@ public class UserVipService {
             return Result.fail("vip 计划不存在");
         }
 
-        long userId = UserContext.getUser();
+        long userId = UserContext.getUserId();
         try {
             double price = vipPlan.getPrice();
             walletService.pay(price, userId);