Codex Assistant
1 天以前 afeeed281e60466b576fbe74d339634cc5d07b82
backend/src/main/java/com/rongyichuang/common/util/UserContextUtil.java
@@ -1,5 +1,8 @@
package com.rongyichuang.common.util;
import com.rongyichuang.auth.util.JwtUtil;
import com.rongyichuang.employee.entity.Employee;
import com.rongyichuang.employee.repository.EmployeeRepository;
import com.rongyichuang.judge.entity.Judge;
import com.rongyichuang.judge.repository.JudgeRepository;
import org.slf4j.Logger;
@@ -8,7 +11,10 @@
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Optional;
/**
@@ -23,30 +29,179 @@
    @Autowired
    private JudgeRepository judgeRepository;
    @Autowired
    private EmployeeRepository employeeRepository;
    @Autowired
    private JwtUtil jwtUtil;
    /**
     * 获取当前登录用户ID
     * 注意:当前系统暂时使用固定用户ID,后续需要根据实际认证机制修改
     * 获取当前登录用户ID(包括匿名用户)
     * 从JWT token中解析用户ID,包括负数的匿名用户ID
     * 
     * @return 用户ID
     * @return 用户ID,包括匿名用户的负数ID
     */
    public Long getCurrentUserId() {
    public Long getCurrentUserIdIncludingAnonymous() {
        try {
            // 首先尝试从HTTP请求头中获取JWT token
            String token = getTokenFromRequest();
            if (token != null && jwtUtil.validateToken(token)) {
                Long userId = jwtUtil.getUserIdFromToken(token);
                logger.debug("从JWT token中获取到用户ID(包括匿名用户): {}", userId);
                return userId;
            }
            if (token == null) {
                logger.debug("未能从请求头获取到JWT token");
            } else {
                logger.debug("从请求头获取到token但校验失败");
            }
            // 如果没有有效的JWT token,尝试从Spring Security上下文获取
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.isAuthenticated() &&
                !"anonymousUser".equals(authentication.getPrincipal())) {
                // TODO: 从认证信息中获取真实的用户ID
                // 这里需要根据实际的认证机制来实现
                // 例如:从JWT token中解析用户ID,或从UserDetails中获取
                logger.debug("获取到认证用户: {}", authentication.getName());
                return 1L; // 临时返回固定用户ID
            if (authentication != null && authentication.isAuthenticated()) {
                String principal = authentication.getName();
                logger.debug("获取到认证用户: {}", principal);
                // 检查是否为匿名用户
                if ("anonymousUser".equals(principal)) {
                    logger.debug("检测到Spring默认匿名用户,返回null");
                    return null;
                } else if (principal.startsWith("anonymous_")) {
                    // 从 "anonymous_-833488" 中提取用户ID
                    try {
                        String userIdStr = principal.substring("anonymous_".length());
                        Long userId = Long.parseLong(userIdStr);
                        logger.debug("从匿名认证中解析到用户ID: {}", userId);
                        return userId;
                    } catch (NumberFormatException e) {
                        logger.warn("无法从匿名认证信息中解析用户ID: {}", principal);
                    }
                }
                // 从Spring Security上下文中获取用户ID
                try {
                    return Long.parseLong(principal);
                } catch (NumberFormatException e) {
                    logger.warn("无法从认证信息中解析用户ID: {}", principal);
                }
            }
        } catch (Exception e) {
            logger.warn("获取当前用户ID时发生异常: {}", e.getMessage());
        }
        
        // 如果没有认证信息,返回默认用户ID(开发阶段使用)
        logger.debug("未找到认证信息,使用默认用户ID");
        return 1L;
        // 如果没有有效的认证信息,返回null
        logger.debug("没有有效的认证信息,返回null");
        return null;
    }
    /**
     * 获取当前登录用户ID
     * 从JWT token中解析用户ID
     *
     * @return 用户ID,如果是匿名用户则返回null
     */
    public Long getCurrentUserId() {
        try {
            // 首先尝试从HTTP请求头中获取JWT token
            String token = getTokenFromRequest();
            if (token != null && jwtUtil.validateToken(token)) {
                Long userId = jwtUtil.getUserIdFromToken(token);
                logger.debug("从JWT token中获取到用户ID: {}", userId);
                // 检查是否为匿名用户(负数用户ID)
                if (userId != null && userId < 0) {
                    logger.debug("检测到匿名用户,返回null");
                    return null;
                }
                return userId;
            }
            if (token == null) {
                logger.debug("未能从请求头获取到JWT token");
            } else {
                logger.debug("从请求头获取到token但校验失败");
            }
            // 如果没有有效的JWT token,尝试从Spring Security上下文获取
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            if (authentication != null && authentication.isAuthenticated()) {
                String principal = authentication.getName();
                logger.debug("获取到认证用户: {}", principal);
                // 检查是否为匿名用户
                if ("anonymousUser".equals(principal) || principal.startsWith("anonymous_")) {
                    logger.debug("检测到匿名用户认证,返回null");
                    return null;
                }
                // 从Spring Security上下文中获取用户ID
                try {
                    return Long.parseLong(principal);
                } catch (NumberFormatException e) {
                    logger.warn("无法从认证信息中解析用户ID: {}", principal);
                }
            }
        } catch (Exception e) {
            logger.warn("获取当前用户ID时发生异常: {}", e.getMessage());
        }
        // 如果没有有效的认证信息,返回null(支持匿名访问)
        logger.debug("没有有效的认证信息,返回null(匿名用户)");
        return null;
    }
    /**
     * 从HTTP请求中获取JWT token
     */
    public String getTokenFromRequest() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if (attributes == null) {
                logger.warn("RequestContextHolder中无ServletRequestAttributes,可能为异步执行或非Servlet环境");
            } else {
                HttpServletRequest request = attributes.getRequest();
                String authHeader = request.getHeader("Authorization");
                logger.debug("读取到Authorization头: {}", authHeader);
                if (authHeader != null && authHeader.startsWith("Bearer ")) {
                    String token = authHeader.substring(7);
                    logger.debug("从Authorization头提取到Bearer token,长度: {}", token != null ? token.length() : 0);
                    return token;
                } else {
                    logger.debug("Authorization头不存在或不以Bearer开头");
                }
            }
        } catch (Exception e) {
            logger.debug("获取JWT token时发生异常: {}", e.getMessage());
        }
        return null;
    }
    /**
     * 获取当前用户关联的员工信息
     *
     * @return 员工信息,如果当前用户不是员工则返回空
     */
    public Optional<Employee> getCurrentEmployee() {
        Long userId = getCurrentUserId();
        if (userId == null) {
            logger.warn("无法获取当前用户ID");
            return Optional.empty();
        }
        try {
            Optional<Employee> employee = employeeRepository.findByUserId(userId);
            if (employee.isPresent()) {
                logger.debug("找到当前用户关联的员工: {}", employee.get().getName());
            } else {
                logger.debug("当前用户(ID: {})不是员工", userId);
            }
            return employee;
        } catch (Exception e) {
            logger.error("查询员工信息时发生异常: {}", e.getMessage(), e);
            return Optional.empty();
        }
    }
    /**
@@ -76,6 +231,15 @@
    }
    /**
     * 获取当前用户关联的员工ID
     *
     * @return 员工ID,如果当前用户不是员工则返回null
     */
    public Long getCurrentEmployeeId() {
        return getCurrentEmployee().map(Employee::getId).orElse(null);
    }
    /**
     * 获取当前用户关联的评委ID
     * 
     * @return 评委ID,如果当前用户不是评委则返回null
@@ -85,6 +249,15 @@
    }
    /**
     * 检查当前用户是否为员工
     *
     * @return true如果当前用户是员工,否则false
     */
    public boolean isCurrentUserEmployee() {
        return getCurrentEmployee().isPresent();
    }
    /**
     * 检查当前用户是否为评委
     * 
     * @return true如果当前用户是评委,否则false