package cn.com.qmth.stmms.api.controller;

import cn.com.qmth.stmms.api.dto.MenualAbsentDTO;
import cn.com.qmth.stmms.api.exception.ApiException;
import cn.com.qmth.stmms.api.utils.AESUtil;
import cn.com.qmth.stmms.biz.exam.model.*;
import cn.com.qmth.stmms.biz.exam.query.ExamStudentSearchQuery;
import cn.com.qmth.stmms.biz.exam.service.*;
import cn.com.qmth.stmms.biz.file.service.FileService;
import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
import cn.com.qmth.stmms.biz.mark.model.TrialLibrary;
import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
import cn.com.qmth.stmms.biz.user.model.User;
import cn.com.qmth.stmms.biz.user.service.UserService;
import cn.com.qmth.stmms.biz.utils.BatchGetDataUtil;
import cn.com.qmth.stmms.biz.utils.ScoreItem;
import cn.com.qmth.stmms.common.annotation.Logging;
import cn.com.qmth.stmms.common.annotation.RoleRequire;
import cn.com.qmth.stmms.common.domain.ApiUser;
import cn.com.qmth.stmms.common.enums.*;
import cn.com.qmth.stmms.common.utils.RequestUtils;

import com.google.common.base.Strings;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;

import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

@Controller("examStudentApiController")
@RequestMapping("/api")
public class ExamStudentController extends BaseApiController {

    protected static Logger logger = LoggerFactory.getLogger(ExamStudentController.class);

    @Autowired
    private ExamStudentService studentService;

    @Autowired
    private ExamService examService;

    @Autowired
    private ExamQuestionService questionService;

    @Autowired
    private MarkLibraryService libraryService;

    @Autowired
    private UserService userService;

    @Autowired
    private FileService fileService;

    @Autowired
    private ExamSubjectService examSubjectService;

    @Autowired
    private InspectHistoryService inspectHistoryService;

    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCANNER })
    @RequestMapping(value = "/student/check", method = RequestMethod.POST)
    @ResponseBody
    public JSONObject checkStudent(HttpServletRequest request, @RequestBody ExamStudent examStudent) {
        JSONObject obj = new JSONObject();
        ExamStudent student = studentService.findByExamIdAndExamNumber(examStudent.getExamId(),
                examStudent.getExamNumber());
        if (student != null) {
            obj.accumulate("examId", examStudent.getExamId());
            obj.accumulate("campusCode", "0");
            obj.accumulate("campusName", StringUtils.trimToEmpty(student.getCampusName()));
            obj.accumulate("examNumber", student.getExamNumber());
            obj.accumulate("secretNumber", student.getSecretNumber());
            obj.accumulate("name", student.getName());
            obj.accumulate("studentId", String.valueOf(student.getId()));
            obj.accumulate("studentCode", student.getStudentCode());
            obj.accumulate("subjectCode", student.getSubjectCode());
            obj.accumulate("subjectName", student.getSubjectName());
            obj.accumulate("examSite", StringUtils.trimToEmpty(student.getExamSite()));
            obj.accumulate("college", StringUtils.trimToEmpty(student.getCollege()));
        } else {
            obj.accumulate("examId", examStudent.getExamId());
            obj.accumulate("campusCode", "");
            obj.accumulate("campusName", "");
            obj.accumulate("examNumber", examStudent.getExamNumber());
            obj.accumulate("name", "");
            obj.accumulate("studentId", "");
            obj.accumulate("studentCode", "");
            obj.accumulate("subjectCode", "");
            obj.accumulate("subjectName", "");
            obj.accumulate("examSite", "");
            obj.accumulate("college", "");
        }
        return obj;
    }

    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCANNER })
    @RequestMapping("/exam/students/count")
    @ResponseBody
    public long getStudentCount(HttpServletRequest request, ExamStudentSearchQuery query) {
        ApiUser user = RequestUtils.getApiUser(request);
        Exam exam = query.getExamId() != null ? examService.findById(query.getExamId()) : null;
        if (exam != null && exam.getSchoolId().equals(user.getSchoolId())) {
            return studentService.countByQuery(query);
        }
        return 0;
    }

    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCANNER })
    @RequestMapping("/exam/students")
    @ResponseBody
    public JSONArray getStudent(HttpServletRequest request, ExamStudentSearchQuery query,
            @RequestParam(required = false) Boolean withScoreDetail,
            @RequestParam(required = false) Boolean withMarkTrack,
            @RequestParam(required = false) Boolean withGroupScoreTrack,
            @RequestParam(required = false) Boolean withSheetUrl,
            @RequestParam(required = false) Boolean sliceConfigFix) {
        ApiUser user = RequestUtils.getApiUser(request);
        JSONArray array = new JSONArray();
        if (query.getExamId() == null) {
            return array;
        }
        Exam exam = examService.findById(query.getExamId());
        if (exam != null && exam.getSchoolId().equals(user.getSchoolId())) {
            DecimalFormat format = new DecimalFormat("####.###");
            studentService.findByQuery(query);
            for (ExamStudent student : query.getResult()) {
                JSONObject obj = new JSONObject();
                obj.accumulate("id", student.getId());
                obj.accumulate("schoolId", student.getSchoolId());
                obj.accumulate("examNumber", student.getExamNumber());
                obj.accumulate("secretNumber", student.getSecretNumber());
                obj.accumulate("campusCode", "0");
                obj.accumulate("campusName", StringUtils.trimToEmpty(student.getCampusName()));
                obj.accumulate("subjectCode", student.getSubjectCode());
                obj.accumulate("subjectName", student.getSubjectName());
                obj.accumulate("name", student.getName());
                obj.accumulate("studentCode", student.getStudentCode());
                obj.accumulate("packageCode", StringUtils.trimToEmpty(student.getPackageCode()));
                obj.accumulate("paperType", StringUtils.trimToEmpty(student.getPaperType()));
                obj.accumulate("batchCode", StringUtils.trimToEmpty(student.getBatchCode()));
                obj.accumulate("sheetCount", student.getSheetCount() != null ? student.getSheetCount() : 0);
                obj.accumulate("sliceCount", student.getSliceCount() != null ? student.getSliceCount() : 0);
                obj.accumulate("answers", StringUtils.trimToEmpty(student.getAnswers()));
                obj.accumulate("upload", student.isUpload());
                obj.accumulate("absent", student.isAbsent());
                obj.accumulate("manualAbsent", student.isManualAbsent());
                obj.accumulate("breach", student.isBreach());
                obj.accumulate("objectiveScore",
                        student.getObjectiveScore() == null ? "" : format.format(student.getObjectiveScore()));
                obj.accumulate("subjectiveScore",
                        student.getSubjectiveScore() == null ? "" : format.format(student.getSubjectiveScore()));
                obj.accumulate("subjectiveStatus", student.getSubjectiveStatus().toString());
                obj.accumulate("examSite", StringUtils.trimToEmpty(student.getExamSite()));
                obj.accumulate("examRoom", StringUtils.trimToEmpty(student.getExamRoom()));
                obj.accumulate("remark", StringUtils.trimToEmpty(student.getRemark()));
                obj.accumulate("college", StringUtils.trimToEmpty(student.getCollege()));
                obj.accumulate("className", StringUtils.trimToEmpty(student.getClassName()));
                obj.accumulate("teacher", StringUtils.trimToEmpty(student.getTeacher()));
                if (student.getInspectorId() != null) {
                    obj.accumulate("inspector", getInspector(student.getId()));
                }

                try {
                    if (withScoreDetail != null && withScoreDetail.booleanValue()) {
                        // 构造客观题得分明细
                        JSONArray objective = new JSONArray();
                        List<ScoreItem> scoreList = student.getScoreList(true);
                        List<ExamQuestion> questionList = questionService.findByExamAndSubjectAndObjectiveAndPaperType(
                                student.getExamId(), student.getSubjectCode(), true, student.getPaperType());
                        int i = 0;
                        for (ScoreItem item : scoreList) {
                            i++;
                            if (questionList.size() < i) {
                                break;
                            }
                            ExamQuestion question = questionList.get(i - 1);
                            if (question.getTotalScore() == null || question.getTotalScore() == 0) {
                                continue;
                            }
                            JSONObject detail = new JSONObject();
                            detail.accumulate("mainNumber", question.getMainNumber());
                            detail.accumulate("subNumber", question.getSubNumber());
                            detail.accumulate("score", item.getScore());
                            detail.accumulate("answer", item.getAnswer());
                            objective.add(detail);
                        }
                        obj.accumulate("objectiveScoreDetail", objective);

                        // 构造主观题得分明细
                        JSONArray subjective = new JSONArray();
                        scoreList = student.getScoreList(false);
                        questionList = questionService.findByExamAndSubjectAndObjective(student.getExamId(),
                                student.getSubjectCode(), false);
                        i = 0;
                        for (ScoreItem item : scoreList) {
                            i++;
                            if (questionList.size() < i) {
                                break;
                            }
                            ExamQuestion question = questionList.get(i - 1);
                            if (question.getTotalScore() == null || question.getTotalScore() == 0) {
                                continue;
                            }
                            JSONObject detail = new JSONObject();
                            detail.accumulate("mainNumber", question.getMainNumber());
                            detail.accumulate("subNumber", question.getSubNumber());
                            detail.accumulate("score", item.getScore());
                            detail.accumulate("marker", getMarkerNames(student, question.getGroupNumber()));
                            String header = getHeaderName(student, question.getGroupNumber());
                            if (header != null) {
                                detail.accumulate("header", header);
                            }
                            detail.accumulate("groupNumber", question.getGroupNumber());
                            detail.accumulate("mainTitle", question.getMainTitle());
                            subjective.add(detail);
                        }
                        obj.accumulate("subjectiveScoreDetail", subjective);
                    }
                    // 返回评卷标记
                    if (withMarkTrack != null && withMarkTrack.booleanValue()) {
                        obj.accumulate("tags",
                                studentService.buildSheetTags(student,
                                        withGroupScoreTrack != null && withGroupScoreTrack.booleanValue(),
                                        sliceConfigFix != null && sliceConfigFix.booleanValue()));
                    }
                    // 返回原图下载地址
                    if (withSheetUrl != null && withSheetUrl.booleanValue()) {
                        obj.accumulate("sheetUrls", fileService
                                .getSheetUris(student.getExamId(), student.getExamNumber(), 1, student.getSheetCount())
                                .stream().map(uri -> fileService.getFileServer().concat(uri))
                                .collect(Collectors.toList()));
                    }
                    array.add(obj);
                } catch (Exception e) {
                    logger.error("student api error", e);
                }
            }
        }
        return array;
    }

    private JSONArray getInspector(Integer studentId) {
        List<InspectHistory> historyList = inspectHistoryService.findByStudentId(studentId);
        JSONArray array = new JSONArray();
        if (!historyList.isEmpty()) {
            for (InspectHistory h : historyList) {
                User u = userService.findById(h.getInspectorId());
                JSONObject obj = new JSONObject();
                obj.accumulate("loginName", u.getLoginName());
                obj.accumulate("name", u.getName());
                array.add(obj);
            }
        }
        return array;
    }

    private String getMarkerNames(ExamStudent student, Integer groupNumber) {
        List<String> markerNames = new LinkedList<>();
        List<MarkLibrary> list = libraryService.findByStudentAndGroup(student.getId(), groupNumber);
        for (MarkLibrary library : list) {
            if (library.getMarkerId() == null) {
                continue;
            }
            User user = userService.findByMarkerId(library.getMarkerId());
            if (user != null) {
                markerNames.add(user.getName());
            }
        }
        return StringUtils.join(markerNames, ",");
    }

    private String getHeaderName(ExamStudent student, Integer groupNumber) {
        List<MarkLibrary> list = libraryService.findByStudentAndGroup(student.getId(), groupNumber);
        for (MarkLibrary library : list) {
            if (library.getHeaderId() == null) {
                continue;
            }
            User user = userService.findById(library.getHeaderId());
            if (user != null) {
                return user.getName();
            }
        }
        return null;
    }

    @RequestMapping(value = "/score/school/{schoolId}", method = RequestMethod.POST)
    @ResponseBody
    public String getScore(@PathVariable Integer schoolId, @RequestParam String studentCode,
            @RequestParam String subjectCode, @RequestParam(required = false, defaultValue = "true") boolean encrypt,
            @RequestParam(required = false) String examSeqCode, @RequestParam(required = false) Integer examId,
            @RequestParam(required = false, defaultValue = "false") boolean detail) {
        JSONObject obj = new JSONObject();
        ExamStudent student = null;
        try {
            if (StringUtils.isNotBlank(examSeqCode)) {
                student = studentService.findBySchoolIdAndSubjectCodeAndStudentCodeAndRemark(schoolId, subjectCode,
                        studentCode, examSeqCode);
            } else if (examId != null) {
                student = studentService.findBySchoolIdAndExamIdAndSubjectCodeAndStudentCode(schoolId, examId,
                        subjectCode, studentCode);
            } else {
                student = studentService.findBySchoolIdAndSubjectCodeAndStudentCode(schoolId, subjectCode, studentCode);
            }
            if (student != null) {
                DecimalFormat df = new DecimalFormat("####.###");
                obj.accumulate("exist", true);
                obj.accumulate("examId", String.valueOf(student.getExamId()));
                obj.accumulate("upload", student.isUpload() && !student.isAbsent());
                if (student.isUpload() && !student.isAbsent()) {// 缺考
                    ExamSubject examSubject = examSubjectService.find(student.getExamId(), student.getSubjectCode());
                    int objectiveStatus = getObjectiveStatus(examSubject, student);
                    obj.accumulate("objectiveStatus", objectiveStatus);
                    int subjectiveStatus = getSubjectiveStatus(examSubject, student);
                    obj.accumulate("subjectiveStatus", subjectiveStatus);
                    double objectiveScore = objectiveStatus == 2 ? student.getObjectiveScore() : 0;
                    obj.accumulate("objectiveScore", df.format(objectiveScore));
                    double subjectiveScore = subjectiveStatus == 2 ? student.getSubjectiveScore() : 0;
                    obj.accumulate("subjectiveScore", df.format(subjectiveScore));
                    obj.accumulate("totalScore", df.format(objectiveScore + subjectiveScore));
                    if (detail) {
                        obj.accumulate("subjectiveScoreList",
                                subjectiveStatus == 2 ? StringUtils.trimToEmpty(student.getSubjectiveScoreList()) : "");
                    }
                } else {
                    absentSetObj(detail, obj);
                }
                obj.accumulate("absent", student.isAbsent());
            } else {
                obj.accumulate("exist", false);
                obj.accumulate("examId", "");
                obj.accumulate("upload", false);
                obj.accumulate("absent", true);
                absentSetObj(detail, obj);
            }
            if (!Strings.isNullOrEmpty(examSeqCode)) {
                obj.accumulate("examSeqCode", examSeqCode);
            }
            obj.accumulate("studentCode", studentCode);
            obj.accumulate("subjectCode", subjectCode);
        } catch (Exception e) {
            e.printStackTrace();
            obj.accumulate("exception", "500");
        }
        String result = obj.toString();
        return encrypt ? AESUtil.encrypt(result) : result;
    }

    private int getSubjectiveStatus(ExamSubject examSubject, ExamStudent student) {
        if (examSubject.getSubjectiveScore() == null || examSubject.getSubjectiveScore() == 0) {
            return 0;
        } else {
            if (StringUtils.isNotEmpty(student.getSubjectiveScoreList())
                    && student.getSubjectiveStatus().equals(SubjectiveStatus.MARKED)) {
                return 2;
            } else {
                return 1;
            }
        }
    }

    private int getObjectiveStatus(ExamSubject examSubject, ExamStudent student) {
        if (examSubject.getObjectiveScore() == null || examSubject.getObjectiveScore() == 0) {
            return 0;
        } else {
            if (StringUtils.isEmpty(student.getObjectiveScoreList())) {
                return 1;
            } else {
                return 2;
            }
        }
    }

    private void absentSetObj(boolean detail, JSONObject obj) {
        obj.accumulate("objectiveStatus", "");
        obj.accumulate("subjectiveStatus", "");
        obj.accumulate("objectiveScore", "");
        obj.accumulate("subjectiveScore", "");
        obj.accumulate("totalScore", "");
        if (detail) {
            obj.accumulate("subjectiveScoreList", "");
        }
    }

    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCANNER })
    @RequestMapping("/exam/students/slice")
    @ResponseBody
    public JSONArray getStudentsSlice(HttpServletRequest request, ExamStudentSearchQuery query,
            @RequestParam(required = false) Boolean withScoreDetail,
            @RequestParam(required = false) Boolean withMarkTrack,
            @RequestParam(required = false) Boolean withGroupScoreTrack,
            @RequestParam(required = false) Boolean withSliceUrl) {
        ApiUser user = RequestUtils.getApiUser(request);
        JSONArray array = new JSONArray();
        if (query.getExamId() == null) {
            return array;
        }
        Exam exam = examService.findById(query.getExamId());
        if (exam != null && exam.getSchoolId().equals(user.getSchoolId())) {
            DecimalFormat format = new DecimalFormat("####.###");
            studentService.findByQuery(query);
            for (ExamStudent student : query.getResult()) {
                JSONObject obj = new JSONObject();
                obj.accumulate("id", student.getId());
                obj.accumulate("schoolId", student.getSchoolId());
                obj.accumulate("examNumber", student.getExamNumber());
                obj.accumulate("campusCode", "0");
                obj.accumulate("campusName", StringUtils.trimToEmpty(student.getCampusName()));
                obj.accumulate("subjectCode", student.getSubjectCode());
                obj.accumulate("subjectName", student.getSubjectName());
                obj.accumulate("name", student.getName());
                obj.accumulate("studentCode", student.getStudentCode());
                obj.accumulate("packageCode", StringUtils.trimToEmpty(student.getPackageCode()));
                obj.accumulate("paperType", StringUtils.trimToEmpty(student.getPaperType()));
                obj.accumulate("batchCode", StringUtils.trimToEmpty(student.getBatchCode()));
                obj.accumulate("sheetCount", student.getSheetCount() != null ? student.getSheetCount() : 0);
                obj.accumulate("sliceCount", student.getSliceCount() != null ? student.getSliceCount() : 0);
                obj.accumulate("answers", StringUtils.trimToEmpty(student.getAnswers()));
                obj.accumulate("upload", student.isUpload());
                obj.accumulate("absent", student.isAbsent());
                obj.accumulate("manualAbsent", student.isManualAbsent());
                obj.accumulate("breach", student.isBreach());
                obj.accumulate("objectiveScore",
                        student.getObjectiveScore() == null ? "" : format.format(student.getObjectiveScore()));
                obj.accumulate("subjectiveScore",
                        student.getSubjectiveScore() == null ? "" : format.format(student.getSubjectiveScore()));
                obj.accumulate("subjectiveStatus", student.getSubjectiveStatus().toString());
                obj.accumulate("examSite", StringUtils.trimToEmpty(student.getExamSite()));
                obj.accumulate("examRoom", StringUtils.trimToEmpty(student.getExamRoom()));
                obj.accumulate("remark", StringUtils.trimToEmpty(student.getRemark()));
                obj.accumulate("college", StringUtils.trimToEmpty(student.getCollege()));
                obj.accumulate("className", StringUtils.trimToEmpty(student.getClassName()));
                obj.accumulate("teacher", StringUtils.trimToEmpty(student.getTeacher()));
                if (student.getInspectorId() != null) {
                    obj.accumulate("inspector", getInspector(student.getId()));
                }

                try {
                    if (withScoreDetail != null && withScoreDetail.booleanValue()) {
                        // 构造客观题得分明细
                        JSONArray objective = new JSONArray();
                        List<ScoreItem> scoreList = student.getScoreList(true);
                        List<ExamQuestion> questionList = questionService.findByExamAndSubjectAndObjectiveAndPaperType(
                                student.getExamId(), student.getSubjectCode(), true, student.getPaperType());
                        int i = 0;
                        for (ScoreItem item : scoreList) {
                            i++;
                            if (questionList.size() < i) {
                                break;
                            }
                            ExamQuestion question = questionList.get(i - 1);
                            if (question.getTotalScore() == null || question.getTotalScore() == 0) {
                                continue;
                            }
                            JSONObject detail = new JSONObject();
                            detail.accumulate("mainNumber", question.getMainNumber());
                            detail.accumulate("subNumber", question.getSubNumber());
                            detail.accumulate("score", item.getScore());
                            detail.accumulate("answer", item.getAnswer());
                            objective.add(detail);
                        }
                        obj.accumulate("objectiveScoreDetail", objective);

                        // 构造主观题得分明细
                        JSONArray subjective = new JSONArray();
                        scoreList = student.getScoreList(false);
                        questionList = questionService.findByExamAndSubjectAndObjective(student.getExamId(),
                                student.getSubjectCode(), false);
                        i = 0;
                        for (ScoreItem item : scoreList) {
                            i++;
                            if (questionList.size() < i) {
                                break;
                            }
                            ExamQuestion question = questionList.get(i - 1);
                            if (question.getTotalScore() == null || question.getTotalScore() == 0) {
                                continue;
                            }
                            JSONObject detail = new JSONObject();
                            detail.accumulate("mainNumber", question.getMainNumber());
                            detail.accumulate("subNumber", question.getSubNumber());
                            detail.accumulate("score", item.getScore());
                            detail.accumulate("marker", getMarkerNames(student, question.getGroupNumber()));
                            String header = getHeaderName(student, question.getGroupNumber());
                            if (header != null) {
                                detail.accumulate("header", header);
                            }
                            detail.accumulate("groupNumber", question.getGroupNumber());
                            detail.accumulate("mainTitle", question.getMainTitle());
                            subjective.add(detail);
                        }
                        obj.accumulate("subjectiveScoreDetail", subjective);
                    }
                    // 返回评卷标记
                    if (withMarkTrack != null && withMarkTrack.booleanValue()) {
                        obj.accumulate("tags", studentService.buildSliceTags(student,
                                withGroupScoreTrack != null && withGroupScoreTrack.booleanValue()));
                    }
                    // 返回原图下载地址
                    if (withSliceUrl != null && withSliceUrl.booleanValue()) {
                        obj.accumulate("sliceUrls", fileService
                                .getSliceUris(student.getExamId(), student.getSecretNumber(), 1,
                                        student.getSliceCount())
                                .stream().map(uri -> fileService.getFileServer().concat(uri))
                                .collect(Collectors.toList()));
                    }
                    array.add(obj);
                } catch (Exception e) {
                    logger.error("student api error", e);
                }
            }
        }
        return array;
    }

    @Logging(menu = "扫描端-缺考名单上传", type = LogType.UPDATE)
    @RoleRequire({ Role.SCHOOL_ADMIN, Role.SCAN_ADMIN, Role.SCANNER })
    @RequestMapping(value = "/student/manualAbsent/{examId}", method = RequestMethod.POST)
    @ResponseBody
    public Object updateManualAbsent(HttpServletRequest request, @PathVariable Integer examId,
            @RequestParam MultipartFile file) {
        ApiUser user = RequestUtils.getApiUser(request);
        Exam exam = examService.findById(examId);
        JSONArray array = new JSONArray();
        // 判断上传权限
        if (exam == null || !exam.getSchoolId().equals(user.getSchoolId()) || !ExamStatus.START.equals(exam.getStatus())
                || !ExamType.SCAN_IMAGE.equals(exam.getType())) {
            throw ApiException.EXAM_NOT_ACCESSIBLED;
        }
        studentService.clearManualAbsent(examId);
        List<String> lineList = null;
        try {
            lineList = IOUtils.readLines(file.getInputStream(), "UTF-8");
            if (lineList != null && lineList.size() > 0) {
                List<ExamStudent> studentList = new BatchGetDataUtil<ExamStudent, String>() {
                    @Override
                    protected List<ExamStudent> getData(List<String> dataList) {
                        List<ExamStudent> list = studentService.findByExamIdAndExamNumberIn(examId, dataList);
                        List<Integer> studentIds = list.stream().map(ExamStudent::getId).collect(Collectors.toList());
                        studentService.updateManualAbsent(studentIds, true);
                        return list;
                    }
                }.getDataForBatch(lineList, 500);
                for (ExamStudent student : studentList) {
                    JSONObject obj = new JSONObject();
                    obj.accumulate("examNumber", student.getExamNumber());
                    array.add(obj);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return array;
    }
}
