前言:
我希望我的希望不再是希望
正文:
优化之前
在考试配置会统一设立考试科目在同一时间点的考试,比如本科目考试为语文,语文老师要求时长为120分钟,考试时间为2018-7-31 8:00-10:00,学生必须在此时间段内来考试,如果某个学生因特殊来晚,或者在考试过程中出现机子等问题,需要延长考试时间,当修改了考试配置的考试时间,就意味着所有人的考试时间都会延长。每个学生的考试时长读取的是考试配置的统一时间。
优化之后
考试配置设立的时间为考试科目的时间段,比如本科目考试为语文,语文老师要求时长为120分钟,考试时间为2018-7-31上午, 考试配置既可以设置准点开考,准点结束,也就是与优化之前的一致:8:00-10:00。同时也可以设置:8:00-12:00,只要此学生在上午时间来考试即可,但考试时长是固定的。比如此学生是11:00来考试,那此学生的考试时长便会是一个小时,如果是10:00来考试,考试时长为2个小时,12:00结束。考试来考试的时间不能超过考试配置的时间。
优化思路
1.考试时长直接读取考试配置的固定时长
2.每个学生的交卷时间:抽题时间+考试时长=实际交卷时间
3.考试时长:实际交卷时间与考试配置结束时间做比较:
(1)如果实际交卷时间<考试配置结束时间,剩余考试时长:实际交卷时间-数据库的现在时间
(2)如果实际交卷时间>考试配置结束时间,剩余考试时长:考试配置结束时间-数据库的现在时间
4.在考生安排表中,加入两个字段:抽题时间 实际交卷时间
具体功能实现步骤
一。修改后端业务逻辑
1.写一个接口:查询考试时长
(1)(exam------OnlineExamServiceImpl)
public long getExamDuration(String paperOrTemplateID){
examDuration = templatePaperDao.findExamDuration(paperOrTemplateID);
System.out.println(examDuration);
return examDuration;
}
(2)(exam-------TemplatePaperDao.java)
long findExamDuration(String paperOrTemplateID);
(3)(exam-------TemplatePaperMapper.xml)
<select id="findExamDuration" parameterType="java.lang.String" resultType="java.lang.Long">
SELECT
tp.examination_time_length AS examinationTimeLength
FROM te_template_paper tp
WHERE
id = #{paperOrTemplateID}
</select>
2.修改获取考试时长的接口(exam------OnlineExamServiceImpl)
@Override
public long getExamRemainTime(String studentId) {
long remainDate = 0;
ExamInfoModel infoModel = findExamByStudentIdFromRedis(studentId);
if (infoModel != null && infoModel.getExaminationEntity() != null) {
//获取考试配置结束时间
Date endTime = infoModel.getExaminationEntity().getEndingDate();
long deadline = endTime.getTime();
//实际试卷时间
String endDate = infoModel.getExamineeEntity().getShouldSubmitPaperTime();
try{
Date endDateTime = formatter.parse(endDate);
long realEndTime = endDateTime.getTime();
//考试配置结束时间和实际交卷时间做比较,总是取得值小的然后
if (deadline >= realEndTime){
remainDate = (realEndTime - infoModel.getPresentTime().getTime());
}else{
remainDate = (deadline - infoModel.getPresentTime().getTime());
}
}catch (Exception e){
}
}
System.out.println(remainDate);
return remainDate;
}
3.查询试卷详情的接口中添加调取考试时长的方法 + 修改更新数据库考试状态的参数
findPaperByStudentIdForOnLineExam(String studentId, String ip, String sessionId)
//根据试卷或模板ID查询考试时长
String paperOrTemplateID = examInfoModel.getExaminationEntity().getPaperOrTemplateId();
getExamDuration(paperOrTemplateID);
//更新数据库考试状态为已抽题 ----------传入考试时长,以计算实际交卷时间
updateExamStateForSelecteById(examineeId, ip, examDuration);
4.在更新数据库考试状态的同时,插入抽题时间和实际交卷时间
private boolean updateExamStateForSelecteById(String examineeId, String ip,long diffTime) {
//更新考试状态为已抽题
ExamineeEntity examineeEntity = new ExamineeEntity();
examineeEntity.setStudentIp(ip);//设置登陆IP
examineeEntity.setStudentExamState(EXAMINATION_SELECT_QUESTION_STATE.trim());//设置 考生状态为已抽题
examineeEntity.setGetStemTime(new Date());//设置抽题时间----------
// 抽题时间+考试时长=理论交卷时间----
Date stemTime = examineeEntity.getGetStemTime();
long shouldSubmitPaperTime = stemTime.getTime() + (diffTime * (1000 * 60));
Date shouldSubmitPaperDate = new Date(shouldSubmitPaperTime);
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String shouldSubmitPaperDateTime = sd.format(shouldSubmitPaperDate);
examineeEntity.setShouldSubmitPaperTime(shouldSubmitPaperDateTime);//更新理论交卷时间--
ExamineeExample examineeExample = new ExamineeExample();
ExamineeCriteria criteria = examineeExample.createCriteria();
criteria.andIdEqualTo(examineeId);
criteria.andIsDeleteEqualTo((byte) 0);
int result = examineeDao.updateByExample(examineeEntity, examineeExample);//更新 考生考试状态
if (result < 0) {
return false;
}
return true;
}
二。修改前端业务逻辑
1.online-exam初始化加载不再同时调用获得试卷和获得当前考试剩余时间的接口,仅调用获得试卷接口
student-online-exam\online-exam\online-exam.component.ts
ngOnInit() {
this.getExamPaper(); // 获得试卷
// this.getExamTimeLength(); // 获得当前考试剩余时间
}
原因:优化之后,考试剩余时间跟试卷有关,从每个学生抽题开始计算考试时长
2.exam-control初始化加载不再同时调用获取考试资源信息和获取考试提醒,仅调用获取考试资源信息
student-online-exam\exam-control\exam-control.component.ts
ngOnInit() {
this.getSingleDatumById(); // 获取考试资源信息
// this.getRestTimeUrl(); // 获取
}
3.
/* 组件输入值变化时改变时间差 */
ngOnChanges(changes: SimpleChanges) {
if (changes['examTimeLength'] && this.examTimeLength) {
this.diff = this.examTimeLength / 1000;
//接收到父组件传递过来的考试时长后,如果考试时间已到,在最初加载的时候,就直接交卷
if (Math.floor(this._diff / 3600) == 0 && Math.floor((this._diff % 3600) / 60) == 0) {
clearInterval(this.examTimer);
this.submitToBackEnd(); // 直接交卷
}
this.getRestTimeUrl();
console.log('时间差改变' + this.diff)
this.startTimer();
this.startTimerSyconize();
}
}
4.修改计时业务逻辑----------优化之后,考试时间不再显示秒,以分钟计时
/* 开始计时 */
startTimer() {
this.examTimer = setInterval(() => {
this.diff = this.diff - 1;
if (this.diff == -1) {
clearInterval(this.examTimer);
}
console.log(this.diff);
//优化之后不再此方法内做此判断
// // 监测考试剩余时间171
// if (this.hour == 0 && (this.minute) * 60 == (this.restTime) * 60){
// this.display=true;
// this.message="距离考试结束还剩"+ this.restTime +"分钟";
// }
// if (this.diff == 0) {
// clearInterval(this.examTimer);
// this.submitToBackEnd(); // 直接交卷
// }
}, 1000);
}
5.修改考试提醒---------------监测考试剩余时间放在单独的方法内
// 从后端或得的剩余考试提醒时间
restTime: number;
getRestTimeUrl() {
let restTimeUrl = `exam-web/onlineExam/getRestTime`;
this.http.get(restTimeUrl).subscribe(
res => {
if (res.json().code === '0000' && res.json().data != null) {
if (this.examTimer) {
clearInterval(this.examTimer);
}
this.restTime = res.json().data;
if (this.hour == 0 && this.minute == this.restTime) {
this.display = true;
this.message = "距离考试结束还剩" + this.minute + "分钟";
}
if (!this.examTimer) {
this.startTimer();
}
}
}
);
};
6.修改获取考试时长业务逻辑------(考试时长由从后端获取的分钟修改为直接获取毫秒)
/* 获得考试时长 */
getExamTimeLength() {
const url = `exam-web/onlineExam/getExamRemainTime/${this.studentId}`;
console.log(url);
this.http.get(url).subscribe(
res => {
if (res.json().code == '0000') {
this.examTimeLength = res.json().data;
console.log('考试时长' + this.examTimeLength);
this.diff = this.examTimeLength / 1000;
this.startTimer();
console.log('时间差' + this.diff)
if (Math.floor(this._diff / 3600) == 0 && Math.floor((this._diff % 3600) / 60) == 0) {
clearInterval(this.examTimer);
this.submitToBackEnd(); // 直接交卷
}
this.getRestTimeUrl();
}
}
);
}
说明:修改考试时长涉及考试提醒、考试交卷
结语:
终于开始撸后端代码了。