Browse Source

组卷接口隐藏答案返回

master
luoweijian 1 month ago
parent
commit
1fcb43e457
  1. 65
      src/main/java/com/project/base/domain/utils/ServletUtils.java
  2. 15
      src/main/java/com/project/exam/domain/service/impl/AssemblePaperDomainServiceImpl.java

65
src/main/java/com/project/base/domain/utils/ServletUtils.java

@ -0,0 +1,65 @@
package com.project.base.domain.utils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
* 客户端请求工具类 (Spring Boot 3 / Jakarta EE )
*/
public class ServletUtils {
/**
* 获取当前请求对象 HttpServletRequest
*/
public static HttpServletRequest getRequest() {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return attributes != null ? attributes.getRequest() : null;
}
/**
* 获取当前响应对象 HttpServletResponse
*/
public static HttpServletResponse getResponse() {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return attributes != null ? attributes.getResponse() : null;
}
/**
* 获取请求头信息
*/
public static String getHeader(String name) {
HttpServletRequest request = getRequest();
return request != null ? request.getHeader(name) : null;
}
/**
* 获取客户端真实 IP
* 考虑了 Nginx/网关 代理的情况
*/
public static String getClientIp() {
HttpServletRequest request = getRequest();
if (request == null) return "unknown";
// 处理常用的代理 Header
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ip != null && ip.length() > 15) {
if (ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(","));
}
}
return ip;
}
}

15
src/main/java/com/project/exam/domain/service/impl/AssemblePaperDomainServiceImpl.java

@ -1,8 +1,12 @@
package com.project.exam.domain.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.project.base.domain.exception.BusinessErrorException;
import com.project.base.domain.utils.ServletUtils;
import com.project.ding.domain.enums.UserRoleEnum;
import com.project.ding.utils.SecurityUtils;
import com.project.exam.domain.service.AssemblePaperDomainService;
import com.project.exam.domain.service.BuildExamRecordDomainService;
import com.project.question.domain.dto.QuestionDTO;
@ -79,8 +83,12 @@ public class AssemblePaperDomainServiceImpl implements AssemblePaperDomainServic
@Autowired
private QuestionInventoryDomainService questionInventoryDomainService;
private final static String X_DEBUG_MODE_HEADER = "X-Debug-Mode";
private final static String X_DEBUG_MODE_VALUE = "true";
@Override
@Transactional(rollbackFor = Exception.class)
public ExamRecordDTO assemblePaper(Long taskId, String userId) throws Exception {
@ -161,6 +169,13 @@ public class AssemblePaperDomainServiceImpl implements AssemblePaperDomainServic
QuestionDTO.QuestionDetailDTO detail = questionDTO.getQuestionDetailDTO();
ExamRecordDTO.QuestionSnapshotDTO snapshot = new ExamRecordDTO.QuestionSnapshotDTO();
BeanUtils.copyProperties(detail , snapshot);
// 拥有admin权限且请求头有特殊标识才在此接口返回答案和解析
boolean isDebugMode = SecurityUtils.hasRole(UserRoleEnum.ROLE_ADMIN.name())
&& StrUtil.equals(X_DEBUG_MODE_VALUE , ServletUtils.getHeader(X_DEBUG_MODE_HEADER));
if (!isDebugMode) {
detail.setRightAnswer(null);
detail.setAnalysis(null);
}
return snapshot;
}).toList();
}

Loading…
Cancel
Save