【新增】 学生作答过程中,记录错题

This commit is contained in:
dlaren
2025-08-26 11:00:55 +08:00
parent 7664636df7
commit ca30589633
18 changed files with 484 additions and 45 deletions

View File

@@ -3,8 +3,10 @@ package com.example.exam.exam.dal;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
import java.util.List;
/**
@@ -15,6 +17,7 @@ import java.util.List;
@TableName(value = "exam_error_question", autoResultMap = true)
@Accessors(chain = true)
@Data
public class ExamErrorQuestion {
@@ -74,22 +77,6 @@ public class ExamErrorQuestion {
*/
private String keywords;
/**
* 是否人工0否1是简答题专用
*/
private String manual;
/**
* 状态0启用1禁用
*/
private String status;
/**
* 审核
*/
private String audit;
/**
* 课程类别
*/
@@ -128,4 +115,12 @@ public class ExamErrorQuestion {
@TableField(exist = false)
private List<ExamQuestionKeyword> questionKeywords;
private LocalDateTime createTime;
private String creator;
/**
* 租户id
*/
private long tenantId;
}

View File

@@ -4,15 +4,16 @@ import com.example.exam.exam.dal.ExamQuestion;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface EducationPaperMapper {
/**
* 根据试卷id返回 该试卷下的试题和试题答案 按顺序
*
* @param paperId
* @return
*/
List<ExamQuestion> selectPaperQuByPaperId(String paperId);
}

View File

@@ -1,5 +1,7 @@
package com.example.exam.exam.mapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.exam.exam.dal.ExamErrorQuestion;
import com.example.exam.exam.dal.ExamQuestion;
@@ -7,13 +9,19 @@ import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 试题(hyc)Mapper接口
* 错题集Mapper接口
*
* @author pengchen
* @date 2025-03-13
*/
@Mapper
public interface ExamErrorQuestionMapper extends BaseMapper<ExamErrorQuestion>
{
default ExamErrorQuestion selectByIdAndUserId(String quId, String userId, String tenantId) {
LambdaQueryWrapper<ExamErrorQuestion> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ExamErrorQuestion::getQuId, quId);
wrapper.eq(ExamErrorQuestion::getCreator, userId);
wrapper.eq(ExamErrorQuestion::getTenantId, tenantId);
return selectOne(wrapper);
}
}

View File

@@ -6,11 +6,13 @@ import com.example.exam.exam.mapper.EducationPaperMapper;
import com.example.exam.exam.mapper.EducationPaperQuMapper;
import com.example.exam.exam.mapper.EducationPaperSchemeMapper;
import com.example.exam.exam.service.c.JudgementService;
import com.example.exam.exam.service.error.IExamErrorQuestionService;
import com.example.exam.exam.service.question.IExamQuestionService;
import com.example.exam.exam.service.stupaperscore.StuPaperScoreService;
import com.example.exam.exam.service.tenant.SystemTenantService;
import com.example.exam.exam.utils.HtmlAppender;
import com.example.exam.exam.utils.c.LogFileUtils;
import com.example.exam.exam.utils.error_question.ErrorQuestion;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
@@ -36,8 +38,10 @@ public class AutoForWinEmailSettingServiceImpl implements AutoForWinEmailSetting
StuPaperScoreService stuPaperScoreService;
@Resource
SystemTenantService systemTenantService;
@Autowired
private EducationPaperMapper educationPaperMapper;
@Resource
EducationPaperMapper educationPaperMapper;
@Resource
IExamErrorQuestionService examErrorQuestionService;
/**
* 自动判题邮箱
@@ -124,7 +128,7 @@ public class AutoForWinEmailSettingServiceImpl implements AutoForWinEmailSetting
File jsonFile = new File(file.getPath());
ObjectMapper objectMapper = new ObjectMapper();
if (jsonFile.exists()) {
Double oneScore = 0.0;
double oneScore = 0.0;
String quId = file.getName().split("@")[0];
List<EducationPaperQu> educationPaperQus = educationPaperQuMapper.selectPaperQuListByPaperId(stuInfoVo.getPaperId());
Optional<EducationPaperQu> resultss = educationPaperQus.stream().filter(entry -> entry.getQuId().equals(quId))
@@ -136,6 +140,7 @@ public class AutoForWinEmailSettingServiceImpl implements AutoForWinEmailSetting
List<EducationPaperScheme> educationPaperSchemeList = educationPaperSchemeMapper.selectEducationPaperTaskByPaperId(stuInfoVo.getPaperId());
Optional<EducationPaperScheme> result = educationPaperSchemeList.stream().filter(quLists -> quLists.getSpName().equals("邮箱")).findFirst();
String quScore = result.get().getQuScores();
String taskId = result.get().getTaskId();
// 根据ID查询试题
ExamQuestion examQuestion = examQuestionService.selectExamQuestionByQuId(quId);
@@ -198,6 +203,18 @@ public class AutoForWinEmailSettingServiceImpl implements AutoForWinEmailSetting
insertInfo.setTemporaryId(stuInfoVo.getTemporaryId());
insertInfo.setTrueScore(new BigDecimal(quScore));
stuPaperScoreService.insertStuPaperScore(insertInfo);
// 判断是否进入错题集
ExamErrorQuestion examErrorQuestion = ErrorQuestion.insertErrorQuestion(quId, examQuestion, taskId, systemTenant, stuInfoVo, isTrue);
boolean isInsert = examErrorQuestionService.isExamErrorQuestion(quId,
String.valueOf(stuInfoVo.getStuId()),
String.valueOf(systemTenant.getId()));
if (!isInsert) {
if (examErrorQuestion != null) {
examErrorQuestionService.insertExamErrorQuestion(examErrorQuestion);
}
}
// 关闭文件输入流
if (fileInputStream != null) {
try {
fileInputStream.close();
@@ -224,6 +241,7 @@ public class AutoForWinEmailSettingServiceImpl implements AutoForWinEmailSetting
List<EducationPaperScheme> educationPaperSchemeList = educationPaperSchemeMapper.selectEducationPaperTaskByPaperId(stuInfoVo.getPaperId());
Optional<EducationPaperScheme> result = educationPaperSchemeList.stream().filter(quLists -> quLists.getSpName().equals("邮箱")).findFirst();
String quScore = result.get().getQuScores();
String taskId = result.get().getTaskId();
// 根据ID查询试题
ExamQuestion examQuestion = examQuestionService.selectExamQuestionByQuId(quId);
String judgementStr = "<p>-----------------------------------------------------------</p>";
@@ -247,6 +265,16 @@ public class AutoForWinEmailSettingServiceImpl implements AutoForWinEmailSetting
insertInfo.setTemporaryId(stuInfoVo.getTemporaryId());
insertInfo.setTrueScore(new BigDecimal(quScore));
stuPaperScoreService.insertStuPaperScore(insertInfo);
// 判断是否进入错题集
ExamErrorQuestion examErrorQuestion = ErrorQuestion.insertErrorQuestion(quId, examQuestion, taskId, systemTenant, stuInfoVo, 1);
boolean isInsert = examErrorQuestionService.isExamErrorQuestion(quId,
String.valueOf(stuInfoVo.getStuId()),
String.valueOf(systemTenant.getId()));
if (!isInsert) {
if (examErrorQuestion != null) {
examErrorQuestionService.insertExamErrorQuestion(examErrorQuestion);
}
}
}
return score.setScale(1, BigDecimal.ROUND_HALF_UP);
}

View File

@@ -6,15 +6,16 @@ import com.example.exam.exam.mapper.EducationPaperMapper;
import com.example.exam.exam.mapper.EducationPaperQuMapper;
import com.example.exam.exam.mapper.EducationPaperSchemeMapper;
import com.example.exam.exam.service.c.JudgementService;
import com.example.exam.exam.service.error.IExamErrorQuestionService;
import com.example.exam.exam.service.question.IExamQuestionService;
import com.example.exam.exam.service.stupaperscore.StuPaperScoreService;
import com.example.exam.exam.service.tenant.SystemTenantService;
import com.example.exam.exam.utils.HtmlAppender;
import com.example.exam.exam.utils.c.LogFileUtils;
import com.example.exam.exam.utils.error_question.ErrorQuestion;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.*;
@@ -36,8 +37,10 @@ public class AutoForWinEdgeSettingServiceImpl implements AutoForWinEdgeSettingSe
StuPaperScoreService stuPaperScoreService;
@Resource
SystemTenantService systemTenantService;
@Autowired
private EducationPaperMapper educationPaperMapper;
@Resource
EducationPaperMapper educationPaperMapper;
@Resource
IExamErrorQuestionService examErrorQuestionService;
/**
* 自动判题Edge
@@ -124,21 +127,20 @@ public class AutoForWinEdgeSettingServiceImpl implements AutoForWinEdgeSettingSe
File jsonFile = new File(file.getPath());
ObjectMapper objectMapper = new ObjectMapper();
if (jsonFile.exists()) {
Double oneScore = 0.0;
double oneScore = 0.0;
String quId = file.getName().split("@")[0];
List<EducationPaperQu> educationPaperQus = educationPaperQuMapper.selectPaperQuListByPaperId(stuInfoVo.getPaperId());
Optional<EducationPaperQu> resultss = educationPaperQus.stream().filter(entry -> entry.getQuId().equals(quId))
.findFirst();
// 获取排序
EducationPaperQu educationPaperQu = resultss.get();
// 试题分数
List<EducationPaperScheme> educationPaperSchemeList = educationPaperSchemeMapper.selectEducationPaperTaskByPaperId(stuInfoVo.getPaperId());
Optional<EducationPaperScheme> result = educationPaperSchemeList.stream().filter(quLists -> quLists.getSpName().equals("windows网络设置")).findFirst();
String quScore = result.get().getQuScores();
String taskId = result.get().getTaskId();
// 根据ID查询试题
ExamQuestion examQuestion = examQuestionService.selectExamQuestionByQuId(quId);
// 读取学生文件
try (FileInputStream fileInputStream = new FileInputStream(jsonFile)) {
// 读取文件并转换为 JsonNode
@@ -198,6 +200,17 @@ public class AutoForWinEdgeSettingServiceImpl implements AutoForWinEdgeSettingSe
insertInfo.setTemporaryId(stuInfoVo.getTemporaryId());
insertInfo.setTrueScore(new BigDecimal(quScore));
stuPaperScoreService.insertStuPaperScore(insertInfo);
// 判断是否进入错题集
ExamErrorQuestion examErrorQuestion = ErrorQuestion.insertErrorQuestion(quId, examQuestion, taskId, systemTenant, stuInfoVo, isTrue);
boolean isInsert = examErrorQuestionService.isExamErrorQuestion(quId,
String.valueOf(stuInfoVo.getStuId()),
String.valueOf(systemTenant.getId()));
if (!isInsert) {
if (examErrorQuestion != null) {
examErrorQuestionService.insertExamErrorQuestion(examErrorQuestion);
}
}
// 关闭文件输入流
if (fileInputStream != null) {
try {
fileInputStream.close();
@@ -219,11 +232,11 @@ public class AutoForWinEdgeSettingServiceImpl implements AutoForWinEdgeSettingSe
.findFirst();
// 获取排序
EducationPaperQu educationPaperQu = resultss.get();
// 试题分数
List<EducationPaperScheme> educationPaperSchemeList = educationPaperSchemeMapper.selectEducationPaperTaskByPaperId(stuInfoVo.getPaperId());
Optional<EducationPaperScheme> result = educationPaperSchemeList.stream().filter(quLists -> quLists.getSpName().equals("windows网络设置")).findFirst();
String quScore = result.get().getQuScores();
String quScore = result.get().getQuScores(); // 分数
String taskId = result.get().getTaskId(); // 任务ID
// 根据ID查询试题
ExamQuestion examQuestion = examQuestionService.selectExamQuestionByQuId(quId);
String judgementStr = "<p>-----------------------------------------------------------</p>";
@@ -247,6 +260,16 @@ public class AutoForWinEdgeSettingServiceImpl implements AutoForWinEdgeSettingSe
insertInfo.setTemporaryId(stuInfoVo.getTemporaryId());
insertInfo.setTrueScore(new BigDecimal(quScore));
stuPaperScoreService.insertStuPaperScore(insertInfo);
// 判断是否进入错题集
ExamErrorQuestion examErrorQuestion = ErrorQuestion.insertErrorQuestion(quId, examQuestion, taskId, systemTenant, stuInfoVo, 1);
boolean isInsert = examErrorQuestionService.isExamErrorQuestion(quId,
String.valueOf(stuInfoVo.getStuId()),
String.valueOf(systemTenant.getId()));
if (!isInsert) {
if (examErrorQuestion != null) {
examErrorQuestionService.insertExamErrorQuestion(examErrorQuestion);
}
}
}
return score.setScale(1, BigDecimal.ROUND_HALF_UP);
}

View File

@@ -5,10 +5,12 @@ import com.example.exam.exam.dal.*;
import com.example.exam.exam.mapper.EducationPaperQuMapper;
import com.example.exam.exam.mapper.EducationPaperSchemeMapper;
import com.example.exam.exam.service.brower.JudgementBrowerService;
import com.example.exam.exam.service.error.IExamErrorQuestionService;
import com.example.exam.exam.service.question.IExamQuestionService;
import com.example.exam.exam.service.stupaperscore.StuPaperScoreService;
import com.example.exam.exam.service.tenant.SystemTenantService;
import com.example.exam.exam.service.winfile.IFileServerice;
import com.example.exam.exam.utils.error_question.ErrorQuestion;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@@ -34,6 +36,8 @@ public class AutoForBrowerServiceImpl implements AutoForBrowerService {
StuPaperScoreService stuPaperScoreService;
@Resource
SystemTenantService systemTenantService;
@Resource
IExamErrorQuestionService examErrorQuestionService;
/**
* 自动判题文件处理
@@ -66,13 +70,13 @@ public class AutoForBrowerServiceImpl implements AutoForBrowerService {
String quId = examQuestion.getQuId();
File[] wjFiles = stFile.listFiles();
for (File wjFile : wjFiles) {
// 3、根据题号进行查询试题的相关信息
Optional<EducationPaperScheme> result = educationPaperSchemeList.stream().filter(quLists -> quLists.getSpName().equals(name)).findFirst();
Optional<EducationPaperQu> results = educationPaperQus.stream().filter(quLists -> quLists.getQuId().equals(quId)).findFirst();
EducationPaperScheme educationPaperScheme = result.get();
EducationPaperQu educationPaperQu = results.get();
String quScore = educationPaperScheme.getQuScores();
String taskId = educationPaperScheme.getTaskId();
String judgementStr = "<p>-----------------------------------------------------------</p>";
judgementStr += "<h3>试题序号:" + educationPaperQu.getSort() + "</h3>";
judgementStr += "<h3>试题编号:" + examQuestion.getQuNum() + "</h3>";
@@ -97,6 +101,17 @@ public class AutoForBrowerServiceImpl implements AutoForBrowerService {
insertInfo.setTemporaryId(stuInfoVo.getTemporaryId());
insertInfo.setIsTrue(cpojo.getScore() == 0 ? 1 : cpojo.getScore() == Double.parseDouble(quScore) ? 0 : 2);
stuPaperScoreService.insertStuPaperScore(insertInfo);
// 判断是否进入错题集
int isError = cpojo.getScore() == 0 ? 1 : cpojo.getScore() >= Double.parseDouble(quScore) ? 0 : 2;
ExamErrorQuestion examErrorQuestion = ErrorQuestion.insertErrorQuestion(quId, examQuestion, taskId, systemTenant, stuInfoVo, isError);
boolean isInsert = examErrorQuestionService.isExamErrorQuestion(quId,
String.valueOf(stuInfoVo.getStuId()),
String.valueOf(systemTenant.getId()));
if (!isInsert) {
if (examErrorQuestion != null) {
examErrorQuestionService.insertExamErrorQuestion(examErrorQuestion);
}
}
break;
}
}

View File

@@ -5,16 +5,20 @@ import com.example.exam.exam.dal.*;
import com.example.exam.exam.mapper.EducationPaperQuMapper;
import com.example.exam.exam.mapper.EducationPaperSchemeMapper;
import com.example.exam.exam.service.c.JudgementService;
import com.example.exam.exam.service.error.IExamErrorQuestionService;
import com.example.exam.exam.service.question.IExamQuestionService;
import com.example.exam.exam.service.stupaperscore.StuPaperScoreService;
import com.example.exam.exam.service.tenant.SystemTenantService;
import com.example.exam.exam.utils.HtmlAppender;
import com.example.exam.exam.utils.error_question.ErrorQuestion;
import com.example.exam.exam.utils.snowflake.SnowflakeId;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
@@ -33,6 +37,8 @@ public class AutoForCServiceImpl implements AutoForCService {
StuPaperScoreService stuPaperScoreService;
@Resource
SystemTenantService systemTenantService;
@Resource
IExamErrorQuestionService examErrorQuestionService;
/**
* 自动判题C语言
@@ -71,6 +77,7 @@ public class AutoForCServiceImpl implements AutoForCService {
EducationPaperScheme educationPaperScheme = result.get();
EducationPaperQu educationPaperQu = results.get();
String quScore = educationPaperScheme.getQuScores();
String taskId = educationPaperScheme.getTaskId();
if (wjFile.getName().contains(".c")) {
String judgementStr = "<p>-----------------------------------------------------------</p>";
judgementStr += "<h3>试题序号:" + educationPaperQu.getSort() + "</h3>";
@@ -102,10 +109,14 @@ public class AutoForCServiceImpl implements AutoForCService {
stuPaperScoreService.insertStuPaperScore(insertInfo);
// 判断是否进入错题集
int isError = cpojo.getScore() == 0 ? 1 : cpojo.getScore() >= Double.parseDouble(quScore) ? 0 : 2;
if (isError != 0) {
// 如果不是全对得话进入错题集
System.out.println("进入错题集" + quId);
ExamErrorQuestion examErrorQuestion = new ExamErrorQuestion();
ExamErrorQuestion examErrorQuestion = ErrorQuestion.insertErrorQuestion(quId, examQuestion, taskId, systemTenant, stuInfoVo, isError);
boolean isInsert = examErrorQuestionService.isExamErrorQuestion(quId,
String.valueOf(stuInfoVo.getStuId()),
String.valueOf(systemTenant.getId()));
if (!isInsert) {
if (examErrorQuestion != null) {
examErrorQuestionService.insertExamErrorQuestion(examErrorQuestion);
}
}
break;
}

View File

@@ -6,10 +6,12 @@ import com.example.exam.exam.mapper.EducationPaperMapper;
import com.example.exam.exam.mapper.EducationPaperQuMapper;
import com.example.exam.exam.mapper.EducationPaperSchemeMapper;
import com.example.exam.exam.service.c.JudgementService;
import com.example.exam.exam.service.error.IExamErrorQuestionService;
import com.example.exam.exam.service.question.IExamQuestionService;
import com.example.exam.exam.service.stupaperscore.StuPaperScoreService;
import com.example.exam.exam.service.tenant.SystemTenantService;
import com.example.exam.exam.utils.c.LogFileUtils;
import com.example.exam.exam.utils.error_question.ErrorQuestion;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
@@ -36,8 +38,10 @@ public class AutoForChoiceServiceImpl implements AutoForChoiceService {
StuPaperScoreService stuPaperScoreService;
@Resource
SystemTenantService systemTenantService;
@Autowired
private EducationPaperMapper educationPaperMapper;
@Resource
EducationPaperMapper educationPaperMapper;
@Resource
IExamErrorQuestionService examErrorQuestionService;
/**
* 自动判题选择题
@@ -65,7 +69,7 @@ public class AutoForChoiceServiceImpl implements AutoForChoiceService {
@Override
public Double autoForChoice(StuInfoVo stuInfoVo) throws IOException {
SystemTenant systemTenant = systemTenantService.getId(stuInfoVo.getSchoolName());
Double score = 0.0;
double score = 0.0;
// 文件路径
String filePath = stuInfoVo.getFilePath() + "/Choice.json";
// 读取JSON文件
@@ -75,6 +79,7 @@ public class AutoForChoiceServiceImpl implements AutoForChoiceService {
List<EducationPaperScheme> educationPaperSchemeList = educationPaperSchemeMapper.selectEducationPaperTaskByPaperId(stuInfoVo.getPaperId());
Optional<EducationPaperScheme> result = educationPaperSchemeList.stream().filter(quLists -> quLists.getSpName().equals("选择题")).findFirst();
String quScore = result.get().getQuScores();
String taskId = result.get().getTaskId();
List<EducationPaperQu> educationPaperQus = educationPaperQuMapper.selectPaperQuListByPaperId(stuInfoVo.getPaperId());
// 获取Paper下的所有选择题ID
List<ExamQuestion> examQuestions = educationPaperMapper.selectPaperQuByPaperId(stuInfoVo.getPaperId());
@@ -153,6 +158,17 @@ public class AutoForChoiceServiceImpl implements AutoForChoiceService {
insertInfo.setTemporaryId(stuInfoVo.getTemporaryId());
insertInfo.setTrueScore(new BigDecimal(quScore));
stuPaperScoreService.insertStuPaperScore(insertInfo);
// 判断是否进入错题集
int isError = isRight ? 0 : 1;
ExamErrorQuestion examErrorQuestion = ErrorQuestion.insertErrorQuestion(quId, examQuestion, taskId, systemTenant, stuInfoVo, isError);
boolean isInsert = examErrorQuestionService.isExamErrorQuestion(quId,
String.valueOf(stuInfoVo.getStuId()),
String.valueOf(systemTenant.getId()));
if (!isInsert) {
if (examErrorQuestion != null) {
examErrorQuestionService.insertExamErrorQuestion(examErrorQuestion);
}
}
} else {
// 根据ID查询试题
ExamQuestion examQuestion = examQuestionService.selectExamQuestionByQuId(quId);
@@ -185,6 +201,16 @@ public class AutoForChoiceServiceImpl implements AutoForChoiceService {
insertInfo.setTemporaryId(stuInfoVo.getTemporaryId());
insertInfo.setTrueScore(new BigDecimal(quScore));
stuPaperScoreService.insertStuPaperScore(insertInfo);
// 判断是否进入错题集
ExamErrorQuestion examErrorQuestion = ErrorQuestion.insertErrorQuestion(quId, examQuestion, taskId, systemTenant, stuInfoVo, 1);
boolean isInsert = examErrorQuestionService.isExamErrorQuestion(quId,
String.valueOf(stuInfoVo.getStuId()),
String.valueOf(systemTenant.getId()));
if (!isInsert) {
if (examErrorQuestion != null) {
examErrorQuestionService.insertExamErrorQuestion(examErrorQuestion);
}
}
}
}
if (fileInputStream != null) {
@@ -235,6 +261,16 @@ public class AutoForChoiceServiceImpl implements AutoForChoiceService {
insertInfo.setTemporaryId(stuInfoVo.getTemporaryId());
insertInfo.setTrueScore(new BigDecimal(quScore));
stuPaperScoreService.insertStuPaperScore(insertInfo);
// 判断是否进入错题集
ExamErrorQuestion examErrorQuestion = ErrorQuestion.insertErrorQuestion(quId, examQuestion, taskId, systemTenant, stuInfoVo, 1);
boolean isInsert = examErrorQuestionService.isExamErrorQuestion(quId,
String.valueOf(stuInfoVo.getStuId()),
String.valueOf(systemTenant.getId()));
if (!isInsert) {
if (examErrorQuestion != null) {
examErrorQuestionService.insertExamErrorQuestion(examErrorQuestion);
}
}
}
}
return score;

View File

@@ -5,12 +5,14 @@ import com.example.exam.exam.dal.*;
import com.example.exam.exam.mapper.EducationPaperQuMapper;
import com.example.exam.exam.mapper.EducationPaperSchemeMapper;
import com.example.exam.exam.service.c.JudgementService;
import com.example.exam.exam.service.error.IExamErrorQuestionService;
import com.example.exam.exam.service.mysql.IMysqlLocalService;
import com.example.exam.exam.service.question.IExamQuestionService;
import com.example.exam.exam.service.stupaperscore.StuPaperScoreService;
import com.example.exam.exam.service.tenant.SystemTenantService;
import com.example.exam.exam.service.winfile.IFileServerice;
import com.example.exam.exam.utils.c.LogFileUtils;
import com.example.exam.exam.utils.error_question.ErrorQuestion;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@@ -40,6 +42,8 @@ public class AutoForFileServiceImpl implements AutoForFileService {
StuPaperScoreService stuPaperScoreService;
@Resource
SystemTenantService systemTenantService;
@Resource
IExamErrorQuestionService examErrorQuestionService;
/**
* 自动判题文件处理
@@ -79,6 +83,7 @@ public class AutoForFileServiceImpl implements AutoForFileService {
EducationPaperScheme educationPaperScheme = result.get();
EducationPaperQu educationPaperQu = results.get();
String quScore = educationPaperScheme.getQuScores();
String taskId = educationPaperScheme.getTaskId();
String judgementStr = "<p>-----------------------------------------------------------</p>";
judgementStr += "<h3>试题序号:" + educationPaperQu.getSort() + "</h3>";
judgementStr += "<h3>试题编号:" + examQuestion.getQuNum() + "</h3>";
@@ -103,6 +108,17 @@ public class AutoForFileServiceImpl implements AutoForFileService {
insertInfo.setTemporaryId(stuInfoVo.getTemporaryId());
insertInfo.setIsTrue(cpojo.getScore() == 0 ? 1 : cpojo.getScore() == Double.parseDouble(quScore) ? 0 : 2);
stuPaperScoreService.insertStuPaperScore(insertInfo);
// 判断是否进入错题集
int isError = cpojo.getScore() == 0 ? 1 : cpojo.getScore() >= Double.parseDouble(quScore) ? 0 : 2;
ExamErrorQuestion examErrorQuestion = ErrorQuestion.insertErrorQuestion(quId, examQuestion, taskId, systemTenant, stuInfoVo, isError);
boolean isInsert = examErrorQuestionService.isExamErrorQuestion(quId,
String.valueOf(stuInfoVo.getStuId()),
String.valueOf(systemTenant.getId()));
if (!isInsert) {
if (examErrorQuestion != null) {
examErrorQuestionService.insertExamErrorQuestion(examErrorQuestion);
}
}
break;
}
}

View File

@@ -5,10 +5,12 @@ import com.example.exam.exam.dal.*;
import com.example.exam.exam.mapper.EducationPaperQuMapper;
import com.example.exam.exam.mapper.EducationPaperSchemeMapper;
import com.example.exam.exam.service.c.JudgementService;
import com.example.exam.exam.service.error.IExamErrorQuestionService;
import com.example.exam.exam.service.mysql.IMysqlLocalService;
import com.example.exam.exam.service.question.IExamQuestionService;
import com.example.exam.exam.service.stupaperscore.StuPaperScoreService;
import com.example.exam.exam.service.tenant.SystemTenantService;
import com.example.exam.exam.utils.error_question.ErrorQuestion;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@@ -34,6 +36,8 @@ public class AutoForMysqlServiceImpl implements AutoForMysqlService {
StuPaperScoreService stuPaperScoreService;
@Resource
SystemTenantService systemTenantService;
@Resource
IExamErrorQuestionService examErrorQuestionService;
/**
* 自动判题C语言
@@ -75,8 +79,8 @@ public class AutoForMysqlServiceImpl implements AutoForMysqlService {
EducationPaperScheme educationPaperScheme = result.get();
EducationPaperQu educationPaperQu = results.get();
String quScore = educationPaperScheme.getQuScores();
String taskId = educationPaperScheme.getTaskId();
if (wjFile.getName().contains(".sql")) {
String judgementStr = "<p>-----------------------------------------------------------</p>";
judgementStr += "<h3>试题序号:" + educationPaperQu.getSort() + "</h3>";
judgementStr += "<h3>试题编号:" + examQuestion.getQuNum() + "</h3>";
@@ -101,7 +105,17 @@ public class AutoForMysqlServiceImpl implements AutoForMysqlService {
insertInfo.setTemporaryId(stuInfoVo.getTemporaryId());
insertInfo.setIsTrue(cpojo.getScore() == 0 ? 1 : cpojo.getScore() == Double.parseDouble(quScore) ? 0 : 2);
stuPaperScoreService.insertStuPaperScore(insertInfo);
System.out.println(judgementStr);
// 判断是否进入错题集
int isError = cpojo.getScore() == 0 ? 1 : cpojo.getScore() >= Double.parseDouble(quScore) ? 0 : 2;
ExamErrorQuestion examErrorQuestion = ErrorQuestion.insertErrorQuestion(quId, examQuestion, taskId, systemTenant, stuInfoVo, isError);
boolean isInsert = examErrorQuestionService.isExamErrorQuestion(quId,
String.valueOf(stuInfoVo.getStuId()),
String.valueOf(systemTenant.getId()));
if (!isInsert) {
if (examErrorQuestion != null) {
examErrorQuestionService.insertExamErrorQuestion(examErrorQuestion);
}
}
}
break;
}

View File

@@ -4,11 +4,13 @@ import com.example.exam.exam.controller.auto.vo.StuInfoVo;
import com.example.exam.exam.dal.*;
import com.example.exam.exam.mapper.EducationPaperQuMapper;
import com.example.exam.exam.mapper.EducationPaperSchemeMapper;
import com.example.exam.exam.service.error.IExamErrorQuestionService;
import com.example.exam.exam.service.mysql.IMysqlLocalService;
import com.example.exam.exam.service.ps.PsService;
import com.example.exam.exam.service.question.IExamQuestionService;
import com.example.exam.exam.service.stupaperscore.StuPaperScoreService;
import com.example.exam.exam.service.tenant.SystemTenantService;
import com.example.exam.exam.utils.error_question.ErrorQuestion;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@@ -33,6 +35,8 @@ public class AutoForPsServiceImpl implements AutoForPsService {
StuPaperScoreService stuPaperScoreService;
@Resource
SystemTenantService systemTenantService;
@Resource
IExamErrorQuestionService examErrorQuestionService;
@Override
public BigDecimal autoForPs(StuInfoVo stuInfoVo) throws IOException {
@@ -66,6 +70,7 @@ public class AutoForPsServiceImpl implements AutoForPsService {
EducationPaperScheme educationPaperScheme = result.get();
EducationPaperQu educationPaperQu = results.get();
String quScore = educationPaperScheme.getQuScores();
String taskId = educationPaperScheme.getTaskId();
if (wjFile.getName().contains("原始")) {
String filePaths = wjFile.getParent();
String judgementStr = "<p>-----------------------------------------------------------</p>";
@@ -92,6 +97,17 @@ public class AutoForPsServiceImpl implements AutoForPsService {
insertInfo.setTemporaryId(stuInfoVo.getTemporaryId());
insertInfo.setIsTrue(wordpojo.getScore() == 0 ? 1 : wordpojo.getScore() == Double.parseDouble(quScore) ? 0 : 2);
stuPaperScoreService.insertStuPaperScore(insertInfo);
// 判断是否进入错题集
int isError = wordpojo.getScore() == 0 ? 1 : wordpojo.getScore() >= Double.parseDouble(quScore) ? 0 : 2;
ExamErrorQuestion examErrorQuestion = ErrorQuestion.insertErrorQuestion(quId, examQuestion, taskId, systemTenant, stuInfoVo, isError);
boolean isInsert = examErrorQuestionService.isExamErrorQuestion(quId,
String.valueOf(stuInfoVo.getStuId()),
String.valueOf(systemTenant.getId()));
if (!isInsert) {
if (examErrorQuestion != null) {
examErrorQuestionService.insertExamErrorQuestion(examErrorQuestion);
}
}
break;
}
}

View File

@@ -3,6 +3,7 @@ package com.example.exam.exam.service.error;
import com.example.exam.exam.dal.*;
import com.example.exam.exam.mapper.*;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -16,11 +17,16 @@ import java.util.List;
@Service
public class ExamErrorQuestionServiceImpl implements IExamErrorQuestionService
{
@Autowired
@Resource
ExamErrorQuestionMapper examErrorQuestionMapper;
@Override
public int insertExamErrorQuestion(ExamErrorQuestion examErrorQuestion) {
return examErrorQuestionMapper.insert(examErrorQuestion);
}
@Override
public boolean isExamErrorQuestion(String quId, String userId, String tenantId) {
return examErrorQuestionMapper.selectByIdAndUserId(quId, userId, tenantId) != null;
}
}

View File

@@ -13,4 +13,9 @@ public interface IExamErrorQuestionService {
* 新增错题集数据
*/
public int insertExamErrorQuestion(ExamErrorQuestion examErrorQuestion);
/**
* 判断错题是否存在
*/
boolean isExamErrorQuestion(String quId, String userId, String tenantId);
}

View File

@@ -6,10 +6,12 @@ import com.example.exam.exam.dal.*;
import com.example.exam.exam.mapper.EducationPaperQuMapper;
import com.example.exam.exam.mapper.EducationPaperSchemeMapper;
import com.example.exam.exam.service.c.JudgementService;
import com.example.exam.exam.service.error.IExamErrorQuestionService;
import com.example.exam.exam.service.question.IExamQuestionService;
import com.example.exam.exam.service.stupaperscore.StuPaperScoreService;
import com.example.exam.exam.service.tenant.SystemTenantService;
import com.example.exam.exam.service.wpsexcel.JudgementWpsExcelService;
import com.example.exam.exam.utils.error_question.ErrorQuestion;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@@ -38,6 +40,8 @@ public class JudgementForExcelServiceImpl implements JudgementForExcelService {
JudgementWpsExcelService judgementWpsExcelService;
@Resource
SystemTenantService systemTenantService;
@Resource
IExamErrorQuestionService examErrorQuestionService;
@Override
public BigDecimal autoForWpsExcel(StuInfoVo stuInfoVo) throws Exception {
@@ -70,7 +74,7 @@ public class JudgementForExcelServiceImpl implements JudgementForExcelService {
EducationPaperScheme educationPaperScheme = result.get();
EducationPaperQu educationPaperQu = results.get();
String quScore = educationPaperScheme.getQuScores();
System.out.println(wjFile.getName());
String taskId = educationPaperScheme.getTaskId();
if (wjFile.getName().contains("文档")) {
String judgementStr = "<p>-----------------------------------------------------------</p>";
judgementStr += "<h3>试题序号:" + educationPaperQu.getSort() + "</h3>";
@@ -97,6 +101,17 @@ public class JudgementForExcelServiceImpl implements JudgementForExcelService {
insertInfo.setTemporaryId(stuInfoVo.getTemporaryId());
insertInfo.setIsTrue(excelpojo.getScore() == 0 ? 1 : excelpojo.getScore() >= Double.parseDouble(quScore) ? 0 : 2);
stuPaperScoreService.insertStuPaperScore(insertInfo);
// 判断是否进入错题集
int isError = excelpojo.getScore() == 0 ? 1 : excelpojo.getScore() >= Double.parseDouble(quScore) ? 0 : 2;
ExamErrorQuestion examErrorQuestion = ErrorQuestion.insertErrorQuestion(quId, examQuestion, taskId, systemTenant, stuInfoVo, isError);
boolean isInsert = examErrorQuestionService.isExamErrorQuestion(quId,
String.valueOf(stuInfoVo.getStuId()),
String.valueOf(systemTenant.getId()));
if (!isInsert) {
if (examErrorQuestion != null) {
examErrorQuestionService.insertExamErrorQuestion(examErrorQuestion);
}
}
break;
}
}

View File

@@ -6,12 +6,12 @@ import com.example.exam.exam.dal.*;
import com.example.exam.exam.mapper.EducationPaperQuMapper;
import com.example.exam.exam.mapper.EducationPaperSchemeMapper;
import com.example.exam.exam.service.c.JudgementService;
import com.example.exam.exam.service.error.IExamErrorQuestionService;
import com.example.exam.exam.service.question.IExamQuestionService;
import com.example.exam.exam.service.stupaperscore.StuPaperScoreService;
import com.example.exam.exam.service.tenant.SystemTenantService;
import com.example.exam.exam.service.wpspptx.JudgementWpsPptxService;
import com.example.exam.exam.service.wpsword.JudgementWpsWordService;
import com.example.exam.exam.service.wpsword.word.JudgementForWordService;
import com.example.exam.exam.utils.error_question.ErrorQuestion;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
@@ -40,6 +40,8 @@ public class JudgementForPptxServiceImpl implements JudgementForPptxService {
JudgementWpsPptxService judgementWpsPptxService;
@Resource
SystemTenantService systemTenantService;
@Resource
IExamErrorQuestionService examErrorQuestionService;
@Override
public BigDecimal autoForWpsPptx(StuInfoVo stuInfoVo) throws Exception {
@@ -72,6 +74,7 @@ public class JudgementForPptxServiceImpl implements JudgementForPptxService {
EducationPaperScheme educationPaperScheme = result.get();
EducationPaperQu educationPaperQu = results.get();
String quScore = educationPaperScheme.getQuScores();
String taskId = educationPaperScheme.getTaskId();
if (wjFile.getName().contains("文档")) {
String judgementStr = "<p>-----------------------------------------------------------</p>";
judgementStr += "<h3>试题序号:" + educationPaperQu.getSort() + "</h3>";
@@ -98,6 +101,17 @@ public class JudgementForPptxServiceImpl implements JudgementForPptxService {
insertInfo.setTemporaryId(stuInfoVo.getTemporaryId());
insertInfo.setIsTrue(pptxpojo.getScore() == 0 ? 1 : pptxpojo.getScore() >= Double.parseDouble(quScore) ? 0 : 2);
stuPaperScoreService.insertStuPaperScore(insertInfo);
// 判断是否进入错题集
int isError = pptxpojo.getScore() == 0 ? 1 : pptxpojo.getScore() >= Double.parseDouble(quScore) ? 0 : 2;
ExamErrorQuestion examErrorQuestion = ErrorQuestion.insertErrorQuestion(quId, examQuestion, taskId, systemTenant, stuInfoVo, isError);
boolean isInsert = examErrorQuestionService.isExamErrorQuestion(quId,
String.valueOf(stuInfoVo.getStuId()),
String.valueOf(systemTenant.getId()));
if (!isInsert) {
if (examErrorQuestion != null) {
examErrorQuestionService.insertExamErrorQuestion(examErrorQuestion);
}
}
break;
}
}

View File

@@ -6,15 +6,20 @@ import com.example.exam.exam.dal.*;
import com.example.exam.exam.mapper.EducationPaperQuMapper;
import com.example.exam.exam.mapper.EducationPaperSchemeMapper;
import com.example.exam.exam.service.c.JudgementService;
import com.example.exam.exam.service.error.IExamErrorQuestionService;
import com.example.exam.exam.service.question.IExamQuestionService;
import com.example.exam.exam.service.stupaperscore.StuPaperScoreService;
import com.example.exam.exam.service.tenant.SystemTenantService;
import com.example.exam.exam.service.wpsword.JudgementWpsWordService;
import com.example.exam.exam.utils.error_question.ErrorQuestion;
import com.example.exam.exam.utils.snowflake.SnowflakeId;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.io.File;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
@@ -38,6 +43,9 @@ public class JudgementForWordServiceImpl implements JudgementForWordService {
JudgementWpsWordService judgementWpsWordService;
@Resource
SystemTenantService systemTenantService;
@Resource
IExamErrorQuestionService examErrorQuestionService;
@Override
public BigDecimal autoForWpsWord(StuInfoVo stuInfoVo) throws Exception {
SystemTenant systemTenant = systemTenantService.getId(stuInfoVo.getSchoolName());
@@ -69,6 +77,7 @@ public class JudgementForWordServiceImpl implements JudgementForWordService {
EducationPaperScheme educationPaperScheme = result.get();
EducationPaperQu educationPaperQu = results.get();
String quScore = educationPaperScheme.getQuScores();
String taskId = educationPaperScheme.getTaskId();
if (wjFile.getName().contains("文档")) {
String judgementStr = "<p>-----------------------------------------------------------</p>";
judgementStr += "<h3>试题序号:" + educationPaperQu.getSort() + "</h3>";
@@ -95,6 +104,17 @@ public class JudgementForWordServiceImpl implements JudgementForWordService {
insertInfo.setTemporaryId(stuInfoVo.getTemporaryId());
insertInfo.setIsTrue(wordpojo.getScore() == 0 ? 1 : wordpojo.getScore() >= Double.parseDouble(quScore) ? 0 : 2);
stuPaperScoreService.insertStuPaperScore(insertInfo);
// 判断是否进入错题集
int isError = wordpojo.getScore() == 0 ? 1 : wordpojo.getScore() >= Double.parseDouble(quScore) ? 0 : 2;
ExamErrorQuestion examErrorQuestion = ErrorQuestion.insertErrorQuestion(quId, examQuestion, taskId, systemTenant, stuInfoVo, isError);
boolean isInsert = examErrorQuestionService.isExamErrorQuestion(quId,
String.valueOf(stuInfoVo.getStuId()),
String.valueOf(systemTenant.getId()));
if (!isInsert) {
if (examErrorQuestion != null) {
examErrorQuestionService.insertExamErrorQuestion(examErrorQuestion);
}
}
break;
}
}

View File

@@ -0,0 +1,36 @@
package com.example.exam.exam.utils.error_question;
import com.example.exam.exam.controller.auto.vo.StuInfoVo;
import com.example.exam.exam.dal.ExamErrorQuestion;
import com.example.exam.exam.dal.ExamQuestion;
import com.example.exam.exam.dal.SystemTenant;
import com.example.exam.exam.utils.snowflake.SnowflakeId;
import org.springframework.beans.BeanUtils;
import java.time.LocalDateTime;
public class ErrorQuestion {
public static ExamErrorQuestion insertErrorQuestion(String questionId,
ExamQuestion examQuestion,
String taskId,
SystemTenant systemTenant,
StuInfoVo stuInfoVo,
int isError) {
// 判断是否进入错题集
if (isError != 0) {
// 如果不是全对得话进入错题集
System.out.println("进入错题集" + questionId);
ExamErrorQuestion examErrorQuestion = new ExamErrorQuestion();
BeanUtils.copyProperties(examQuestion, examErrorQuestion);
examErrorQuestion.setTaskId(taskId);
SnowflakeId idWorker = new SnowflakeId(0, 31);
examErrorQuestion.setId(idWorker.nextIdStr());
examErrorQuestion.setTenantId(systemTenant.getId());
examErrorQuestion.setCreator(String.valueOf(stuInfoVo.getStuId()));
examErrorQuestion.setCreateTime(LocalDateTime.now());
return examErrorQuestion;
}
return null;
}
}

View File

@@ -0,0 +1,180 @@
package com.example.exam.exam.utils.snowflake;
import java.time.Instant;
/**
* 雪花算法 ID 生成器64bit
* 结构1bit 符号位 | 41bit 时间戳(ms) | 5bit 数据中心 | 5bit 工作节点 | 12bit 序列
* 默认 epoch2025-01-01T00:00:00Z
*/
public class SnowflakeId {
// ---- 位宽定义 ----
private static final long WORKER_ID_BITS = 5L; // 0-31
private static final long DATACENTER_ID_BITS = 5L; // 0-31
private static final long SEQUENCE_BITS = 12L; // 0-4095
private static final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS); // 31
private static final long MAX_DATACENTER_ID = ~(-1L << DATACENTER_ID_BITS); // 31
private static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS); // 4095
private static final long WORKER_ID_SHIFT = SEQUENCE_BITS; // 12
private static final long DATACENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS; // 17
private static final long TIMESTAMP_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATACENTER_ID_BITS; // 22
// ---- 配置 ----
private final long epoch; // 自定义纪元(毫秒)
private final long datacenterId; // 0..31
private final long workerId; // 0..31
// ---- 运行时状态 ----
private long lastTimestamp = -1L; // 上次生成的时间戳
private long sequence = 0L; // 当前毫秒内的序列
/**
* 构造器
* @param datacenterId 0..31
* @param workerId 0..31
* @param epochMillis 自定义纪元(毫秒),建议固定且小于当前时间
*/
public SnowflakeId(long datacenterId, long workerId, long epochMillis) {
if (datacenterId < 0 || datacenterId > MAX_DATACENTER_ID) {
throw new IllegalArgumentException("datacenterId out of range: 0.." + MAX_DATACENTER_ID);
}
if (workerId < 0 || workerId > MAX_WORKER_ID) {
throw new IllegalArgumentException("workerId out of range: 0.." + MAX_WORKER_ID);
}
this.datacenterId = datacenterId;
this.workerId = workerId;
this.epoch = epochMillis;
}
/**
* 使用默认纪元2020-01-01T00:00:00Z
*/
public SnowflakeId(long datacenterId, long workerId) {
this(datacenterId, workerId, Instant.parse("2020-01-01T00:00:00Z").toEpochMilli());
}
/**
* 生成下一个 ID线程安全
*/
public synchronized long nextId() {
long now = currentTime();
// 处理时钟回拨
if (now < lastTimestamp) {
long offset = lastTimestamp - now;
// 小回拨:尝试等待一个回拨差值的时长
if (offset <= 5) {
sleepMs(offset);
now = currentTime();
if (now < lastTimestamp) {
// 仍小于:采用“借用序列”的容错策略(把时间当作 lastTimestamp
now = lastTimestamp;
}
} else {
// 大回拨:直接使用 lastTimestamp保序或抛出异常
// 为了高可用,这里选择保序;如需严格,可改为抛出异常
now = lastTimestamp;
}
}
if (now == lastTimestamp) {
// 同一毫秒内自增序列
sequence = (sequence + 1) & SEQUENCE_MASK;
if (sequence == 0) {
// 序列溢出,等待到下一毫秒
now = waitUntilNextMillis(lastTimestamp);
}
} else {
// 新毫秒,序列重置为 0也可随机起步以降低热点
sequence = 0L;
}
lastTimestamp = now;
long timestampPart = (now - epoch) << TIMESTAMP_SHIFT;
long datacenterPart = (datacenterId << DATACENTER_ID_SHIFT);
long workerPart = (workerId << WORKER_ID_SHIFT);
long sequencePart = sequence;
return timestampPart | datacenterPart | workerPart | sequencePart;
}
/**
* 生成字符串形式的 ID十进制
*/
public String nextIdStr() {
return Long.toUnsignedString(nextId());
}
/**
* 解析:从 ID 中还原出时间戳(绝对毫秒)
*/
public long extractTimestamp(long id) {
long ts = (id >>> TIMESTAMP_SHIFT) + epoch;
return ts;
}
/**
* 解析:数据中心 ID
*/
public long extractDatacenterId(long id) {
return (id >>> DATACENTER_ID_SHIFT) & MAX_DATACENTER_ID;
}
/**
* 解析:工作节点 ID
*/
public long extractWorkerId(long id) {
return (id >>> WORKER_ID_SHIFT) & MAX_WORKER_ID;
}
/**
* 解析:序列
*/
public long extractSequence(long id) {
return id & SEQUENCE_MASK;
}
private long waitUntilNextMillis(long lastTs) {
long ts = currentTime();
while (ts <= lastTs) {
ts = currentTime();
}
return ts;
}
private long currentTime() {
return System.currentTimeMillis();
}
private void sleepMs(long ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
}
}
// ---- 简易单例 ----
private static class Holder {
// 默认:数据中心 0工作节点 0可按需修改
private static final SnowflakeId INSTANCE = new SnowflakeId(0, 0);
}
/** 获取全局单例(如项目只需一个生成器时使用) */
public static SnowflakeId getInstance() {
return Holder.INSTANCE;
}
// ---- DEMO ----
public static void main(String[] args) {
SnowflakeId gen = new SnowflakeId(1, 3); // 数据中心=1工作节点=3
for (int i = 0; i < 5; i++) {
long id = gen.nextId();
System.out.println(id + " ts=" + Instant.ofEpochMilli(gen.extractTimestamp(id)));
}
}
}