package com.qmth.distributed.print.api;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.deepoove.poi.XWPFTemplate;
import com.google.gson.reflect.TypeToken;
import com.qmth.boot.api.annotation.Aac;
import com.qmth.boot.api.constant.ApiConstant;
import com.qmth.boot.api.exception.ApiException;
import com.qmth.boot.core.rateLimit.annotation.RateLimit;
import com.qmth.distributed.print.business.bean.dto.CourseWeightDetailDto;
import com.qmth.distributed.print.business.bean.dto.CourseWeightDto;
import com.qmth.distributed.print.business.bean.dto.TCUsualScoreDto;
import com.qmth.distributed.print.business.bean.dto.report.*;
import com.qmth.distributed.print.business.bean.result.CourseWeightResult;
import com.qmth.distributed.print.business.bean.result.ScoreResult;
import com.qmth.distributed.print.business.bean.result.report.PaperStructDimensionResult;
import com.qmth.distributed.print.business.bean.result.report.ReportChangeResult;
import com.qmth.distributed.print.business.bean.result.report.ReportResult;
import com.qmth.distributed.print.business.bean.result.report.word.CourseBasicBean;
import com.qmth.distributed.print.business.bean.result.report.word.CourseReportBean;
import com.qmth.distributed.print.business.entity.TCPaperStruct;
import com.qmth.distributed.print.business.entity.TCUsualScore;
import com.qmth.distributed.print.business.entity.TRBasicInfo;
import com.qmth.distributed.print.business.entity.TRExamStudent;
import com.qmth.distributed.print.business.service.*;
import com.qmth.teachcloud.common.annotation.OperationLogDetail;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicSchool;
import com.qmth.teachcloud.common.entity.SysConfig;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.FieldUniqueEnum;
import com.qmth.teachcloud.common.enums.ImportTemplateEnum;
import com.qmth.teachcloud.common.enums.log.OperationTypeEnum;
import com.qmth.teachcloud.common.service.CommonCacheService;
import com.qmth.teachcloud.common.service.FileUploadService;
import com.qmth.teachcloud.common.util.*;
import com.qmth.teachcloud.mark.entity.MarkPaper;
import io.swagger.annotations.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 报告基本情况表 前端控制器
 * </p>
 *
 * @author wangliang
 * @since 2024-02-18
 */
@Api(tags = "课程目标达成度-报告基本情况Controller")
@RestController
@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_COURSE_DEGREE)
public class TRBasicInfoController {
    private final static Logger log = LoggerFactory.getLogger(TRBasicInfoController.class);

    @Resource
    PrintCommonService printCommonService;

    @Resource
    TRBasicInfoService trBasicInfoService;

    @Resource
    TRExamStudentService trExamStudentService;

    @Resource
    CommonCacheService commonCacheService;

    @Resource
    FileUploadService fileUploadService;

    @Resource
    TCPaperStructService tcPaperStructService;

    @Resource
    TCUsualScoreService tcUsualScoreService;

    @ApiOperation(value = "报告管理列表")
    @RequestMapping(value = "/report/list", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "分页查询", response = ScoreResult.class)})
    public Result reportList(@ApiParam(value = "学期ID", required = true) @RequestParam(required = false) Long semesterId,
                             @ApiParam(value = "考试ID", required = true) @RequestParam(required = false) Long examId,
                             @ApiParam(value = "课程编码") @RequestParam(required = false) String courseCode,
                             @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
                             @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
        if (semesterId == null) {
            throw ExceptionResultEnum.SEMESTER_ID_IS_NULL.exception();
        }
        if (examId == null) {
            throw ExceptionResultEnum.EXAM_ID_IS_NULL.exception();
        }
        return ResultUtil.ok(printCommonService.scoreList(new Page<>(pageNumber, pageSize), examId, courseCode));
    }

    @ApiOperation(value = "查看报告")
    @RequestMapping(value = "/report/view", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "查看报告", response = ReportResult.class)})
    @Transactional
    public Result reportView(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
                             @ApiParam(value = "科目编码", required = true) @RequestParam String courseCode,
                             @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber,
                             @ApiParam(value = "教学课程id", required = true) @RequestParam Long teachCourseId) {
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        TRBasicInfo trBasicInfo = trBasicInfoService.queryBasicInfo(examId, courseCode, paperNumber, teachCourseId);

        CourseWeightResult courseWeightResult = trBasicInfoService.findCourseWeightResultRmi(teachCourseId);
        TCPaperStruct tcPaperStruct = tcPaperStructService.queryPaperStruct(examId, courseCode, paperNumber, teachCourseId);
        if (Objects.nonNull(tcPaperStruct) && Objects.nonNull(tcPaperStruct.getPaperStructDimension())) {
            List<PaperStructDimensionResult> paperStructDimensionResultList = GsonUtil.fromJson(tcPaperStruct.getPaperStructDimension(), new TypeToken<List<PaperStructDimensionResult>>() {
            }.getType());
            for (CourseWeightDto c : courseWeightResult.getSubmitForm()) {
                Double score = paperStructDimensionResultList.stream().filter(s -> Objects.equals(s.getCourseTargetName(), c.getCourseTargetName())).mapToDouble(PaperStructDimensionResult::getScore).sum();
                Objects.requireNonNull(c.getTotalWeight(), "[" + c.getCourseTargetName() + "]未设置权重");
                Objects.requireNonNull(c.getTotalScore(), "[" + c.getCourseTargetName() + "]未设置目标分值");
                if (new BigDecimal(score).compareTo(c.getTotalWeight()) == 1) {
                    trBasicInfoService.clearReportData(examId, courseCode, paperNumber, teachCourseId, false);
                    throw ExceptionResultEnum.ERROR.exception("[" + c.getCourseTargetName() + "]包含的小题总分与权重设置不一致，请到期末成绩--试卷蓝图设置里调整");
                }
            }
        }

        MarkPaper markPaper = printCommonService.getMarkPaper(examId, courseCode, tcPaperStruct.getPaperNumber());
        if (Objects.isNull(trBasicInfo)) {
            trBasicInfo = trBasicInfoService.getReportView(trBasicInfo, markPaper, sysUser.getId(), courseWeightResult, teachCourseId);
        } else {
            ReportCourseEvaluationResultDto reportCourseEvaluationResultDto = Objects.nonNull(trBasicInfo.getCourseEvaluationResult()) ? JSONObject.parseObject(trBasicInfo.getCourseEvaluationResult(), ReportCourseEvaluationResultDto.class) : null;
            if (Objects.nonNull(reportCourseEvaluationResultDto.getWeightSettingSign()) && reportCourseEvaluationResultDto.getWeightSettingSign().longValue() != courseWeightResult.getWeightSettingSign().longValue()) {
                trBasicInfoService.clearReportData(examId, courseCode, paperNumber, teachCourseId, Objects.nonNull(tcPaperStruct) && Objects.nonNull(tcPaperStruct.getDimensionSign()) && tcPaperStruct.getDimensionSign().longValue() != courseWeightResult.getDimensionSign().longValue() ? true : false);
                trBasicInfo = trBasicInfoService.getReportView(trBasicInfo, markPaper, sysUser.getId(), courseWeightResult, teachCourseId);
            } else {
                ReportCourseBasicInfoDto reportCourseBasicInfoDto = new ReportCourseBasicInfoDto(trBasicInfo);
                ReportCourseEvaluationSpreadDto reportCourseEvaluationSpreadDto = Objects.nonNull(trBasicInfo.getCourseEvaluationSpread()) ? JSONObject.parseObject(trBasicInfo.getCourseEvaluationSpread(), ReportCourseEvaluationSpreadDto.class) : null;
                ReportCourseEvaluationResultDetailDto reportCourseEvaluationResultDetailDto = null;
                List<TRExamStudent> trExamStudentList = trExamStudentService.list(new QueryWrapper<TRExamStudent>().lambda().eq(TRExamStudent::getrBasicInfoId, trBasicInfo.getId()));
                if (!CollectionUtils.isEmpty(trExamStudentList)) {
                    List<ReportExamStudentDto> examStudentList = new ArrayList<>(trExamStudentList.size());
                    for (TRExamStudent trExamStudent : trExamStudentList) {
                        examStudentList.add(new ReportExamStudentDto(trExamStudent));
                    }
                    reportCourseEvaluationResultDetailDto = new ReportCourseEvaluationResultDetailDto(examStudentList);
                }
                trBasicInfo.setReportResult(new ReportResult(new ReportCommonDto(examId, courseCode, markPaper.getCourseName(), paperNumber), reportCourseBasicInfoDto, reportCourseEvaluationSpreadDto, reportCourseEvaluationResultDto, reportCourseEvaluationResultDetailDto));
            }
        }
        trBasicInfo.updateInfo(sysUser.getId());
        //课程目标达成评价明细结果-课程目标达成评价值图
        trBasicInfoService.saveOrUpdate(trBasicInfo);
        return ResultUtil.ok(trBasicInfo.getReportResult());
    }

    @ApiOperation(value = "保存报告")
    @RequestMapping(value = "/report/save", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.UPDATE)
    @ApiResponses({@ApiResponse(code = 200, message = "保存报告", response = Object.class)})
    @Transactional
    public Result reportSave(@ApiParam(value = "保存报告结构", required = true) @Valid @RequestBody TRBasicInfo trBasicInfo, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
        }
        SysUser sysUser = (SysUser) ServletUtil.getRequestUser();
        TRBasicInfo trBasicInfoDb = null;
        try {
            trBasicInfoDb = trBasicInfoService.queryBasicInfo(trBasicInfo.getExamId(), trBasicInfo.getCourseCode(), trBasicInfo.getPaperNumber(), trBasicInfo.getTeachCourseId());
            if (Objects.isNull(trBasicInfoDb)) {
                trBasicInfoDb = new TRBasicInfo(trBasicInfo, sysUser.getId());
                TCPaperStruct tcPaperStruct = tcPaperStructService.queryPaperStruct(trBasicInfo.getExamId(), trBasicInfo.getCourseCode(), trBasicInfo.getPaperNumber(), trBasicInfo.getTeachCourseId());
                MarkPaper markPaper = printCommonService.getMarkPaper(trBasicInfo.getExamId(), trBasicInfo.getCourseCode(), Objects.nonNull(tcPaperStruct) ? tcPaperStruct.getPaperNumber() : trBasicInfo.getPaperNumber());
                trBasicInfoDb = trBasicInfoService.getReportView(trBasicInfoDb, markPaper, sysUser.getId(), trBasicInfoService.findCourseWeightResultRmi(trBasicInfo.getTeachCourseId()), trBasicInfo.getTeachCourseId());
            } else {
                trBasicInfoDb.updateInfo(trBasicInfo, sysUser.getId());
            }
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            if (e instanceof DuplicateKeyException) {
                String errorColumn = e.getCause().toString();
                String columnStr = errorColumn.substring(errorColumn.lastIndexOf("key") + 3, errorColumn.length()).replaceAll("'", "");
                throw ExceptionResultEnum.SQL_ERROR.exception("[" + FieldUniqueEnum.convertToTitle(columnStr) + "]数据不允许重复插入");
            } else if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        }
        return ResultUtil.ok(trBasicInfoService.saveOrUpdate(trBasicInfoDb));
    }

    @ApiOperation(value = "导出报告")
    @RequestMapping(value = "/report/export", method = RequestMethod.POST)
    @OperationLogDetail(operationType = OperationTypeEnum.EXPORT)
    @ApiResponses({@ApiResponse(code = 200, message = "下载成功", response = Object.class)})
    @Aac(rateLimit = @RateLimit(count = 1, period = 1000L))
    public void reportExport(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
                             @ApiParam(value = "科目编码", required = true) @RequestParam String courseCode,
                             @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber,
                             @ApiParam(value = "教学课程id", required = true) @RequestParam Long teachCourseId) throws IOException {
        File txtFileTemp = null, fileTemp = null;
        try {
            Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString());
            BasicSchool basicSchool = commonCacheService.schoolCache(schoolId);

            TRBasicInfo trBasicInfo = trBasicInfoService.queryBasicInfo(examId, courseCode, paperNumber, teachCourseId);
            Objects.requireNonNull(trBasicInfo, "没有报告信息");
            Objects.requireNonNull(trBasicInfo.getCourseEvaluationResult(), "没有课程目标信息");
            Objects.requireNonNull(trBasicInfo.getCourseEvaluationResultDetail(), "没有课程考生信息");

            CourseWeightResult courseWeightResult = trBasicInfoService.findCourseWeightResultRmi(teachCourseId);
            TCPaperStruct tcPaperStruct = tcPaperStructService.queryPaperStruct(examId, courseCode, paperNumber, teachCourseId);
            if (Objects.nonNull(tcPaperStruct) && Objects.nonNull(tcPaperStruct.getPaperStructDimension())) {
                List<PaperStructDimensionResult> paperStructDimensionResultList = GsonUtil.fromJson(tcPaperStruct.getPaperStructDimension(), new TypeToken<List<PaperStructDimensionResult>>() {
                }.getType());
                for (CourseWeightDto c : courseWeightResult.getSubmitForm()) {
                    Double score = paperStructDimensionResultList.stream().filter(s -> Objects.equals(s.getCourseTargetName(), c.getCourseTargetName())).mapToDouble(PaperStructDimensionResult::getScore).sum();
                    Objects.requireNonNull(c.getTotalWeight(), "[" + c.getCourseTargetName() + "]未设置权重");
                    Objects.requireNonNull(c.getTotalScore(), "[" + c.getCourseTargetName() + "]未设置目标分值");
                    if (new BigDecimal(score).compareTo(c.getTotalWeight()) == 1) {
                        trBasicInfoService.clearReportData(examId, courseCode, paperNumber, teachCourseId, false);
                        throw ExceptionResultEnum.ERROR.exception("[" + c.getCourseTargetName() + "]包含的小题总分与权重设置不一致，请到期末成绩--试卷蓝图设置里调整");
                    }
                }
            }

            ReportCourseEvaluationResultDto reportCourseEvaluationResultDto = JSONObject.parseObject(trBasicInfo.getCourseEvaluationResult(), ReportCourseEvaluationResultDto.class);
            if (Objects.nonNull(reportCourseEvaluationResultDto.getWeightSettingSign()) && reportCourseEvaluationResultDto.getWeightSettingSign().longValue() != courseWeightResult.getWeightSettingSign().longValue()) {
                trBasicInfoService.clearReportData(examId, courseCode, paperNumber, teachCourseId, Objects.nonNull(tcPaperStruct) && Objects.nonNull(tcPaperStruct.getDimensionSign()) && tcPaperStruct.getDimensionSign().longValue() != courseWeightResult.getDimensionSign().longValue() ? true : false);
                this.reportView(examId, courseCode, paperNumber, teachCourseId);
                this.reportExport(examId, courseCode, paperNumber, teachCourseId);
            } else {
                //评价样本的基本信息
                String period = Objects.nonNull(trBasicInfo.getPeriod()) ? trBasicInfo.getPeriod() : null;
                String credit = Objects.nonNull(trBasicInfo.getCredit()) ? trBasicInfo.getCredit() : null;
                period = Objects.nonNull(credit) ? period + "/" + credit : period;

                JSONObject jsonObject = JSONObject.parseObject(trBasicInfo.getCourseEvaluationResultDetail());
                List<CourseTargetWordDto> courseTargetWordDtoList = JSONArray.parseArray(jsonObject.get("targetWordMap").toString(), CourseTargetWordDto.class);

                StringJoiner courseTarget = new StringJoiner("");
                courseTargetWordDtoList.stream().peek(s -> {
                    courseTarget.add("      ").add(s.getTargetName()).add("——").add(s.getGraduationRequirementPoint()).add("\r\n");
                }).collect(Collectors.toList());

                CourseBasicBean courseBasicBean = new CourseBasicBean(trBasicInfo.getCourseName(),
                        trBasicInfo.getCourseCode(), null, trBasicInfo.getCourseType(),
                        period, null, null, trBasicInfo.getDirector(),
                        DateUtil.format(new Date(trBasicInfo.getCreateTime()), SystemConstant.DEFAULT_DATE_PATTERN),
                        courseTarget.toString(), reportCourseEvaluationResultDto.getTargetList().size());

                CourseReportBean courseReportBean = new CourseReportBean(trBasicInfo.getOpenTime() + "《" + trBasicInfo.getCourseName() + "》", courseBasicBean);
                //table1-课程目标目标与毕业要求指标点的对应关系
                courseReportBean.setCourseTargetTable1(trBasicInfoService.buildWordTable1(courseTargetWordDtoList));

                //table2-课程目标达成评价依据
                courseReportBean.setCourseTargetTable2(trBasicInfoService.buildWordTable2(courseTargetWordDtoList));

                //table3-课程课后作业考核/评价内容及目标分值
                courseReportBean.setCourseTargetTable3(trBasicInfoService.buildWordTable3(courseTargetWordDtoList));

                //table4-课程期末考试考核/评价内容及目标分值
                courseReportBean.setCourseTargetTable4(trBasicInfoService.buildWordTable4(courseTargetWordDtoList));

                //examstudent-课程目标达成评价依据-考生
                courseReportBean.setExamStudentTable1(trBasicInfoService.buildWordTable5(trBasicInfo, courseReportBean));

                InputStream inputStream = null;
                txtFileTemp = SystemConstant.getFileTempVar(SystemConstant.WORD_PREFIX);
                SysConfig sysConfig = commonCacheService.addSysConfigCache(schoolId, SystemConstant.SCHOOL_COURSE_DEGREE_TEMPLATE);
                if (Objects.isNull(sysConfig)) {
                    inputStream = FileUtil.getStream("static/" + ImportTemplateEnum.STATIC_COURSE_DEGREE_REPORT.getTemplateName());
                } else {
                    fileTemp = SystemConstant.getFileTempVar(SystemConstant.WORD_PREFIX);
                    fileTemp = fileUploadService.downloadFile(Long.parseLong(sysConfig.getConfigValue()), fileTemp.getPath());
                    inputStream = new FileInputStream(fileTemp);
                }
                FileUtils.copyInputStreamToFile(inputStream, txtFileTemp);
                XWPFTemplate template = XWPFTemplate.compile(txtFileTemp.getAbsolutePath()).render(courseReportBean);
                template.writeToFile(txtFileTemp.getAbsolutePath());
                // 导出
                String fileName = Objects.nonNull(basicSchool) ? basicSchool.getName() + "_" + courseReportBean.getTitle1() + "_" + ImportTemplateEnum.STATIC_COURSE_DEGREE_REPORT.getFileName() + SystemConstant.WORD_PREFIX : courseReportBean.getTitle1() + "_" + ImportTemplateEnum.STATIC_COURSE_DEGREE_REPORT.getFileName() + SystemConstant.WORD_PREFIX;
                FileUtil.outputFile(ServletUtil.getResponse(), new FileInputStream(txtFileTemp), fileName);
//            XWPFTemplate template = XWPFTemplate.compile("/Users/king/git/teachcloud-server/distributed-print/src/main/resources/static/course_degree_report.docx").render(courseReportBean);
//            template.writeToFile("/Users/king/Downloads/demo_course_degree_report.docx");
            }
        } catch (Exception e) {
            if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, ((ApiException) e).getCode(), e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        } finally {
            if (Objects.nonNull(txtFileTemp)) {
                txtFileTemp.delete();
            }
            if (Objects.nonNull(fileTemp)) {
                fileTemp.delete();
            }
        }
    }

    @ApiOperation(value = "报告发生改变")
    @RequestMapping(value = "/report/change", method = RequestMethod.POST)
    @ApiResponses({@ApiResponse(code = 200, message = "下载成功", response = Object.class)})
    public Result reportDataChange(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
                                   @ApiParam(value = "科目编码", required = true) @RequestParam String courseCode,
                                   @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber,
                                   @ApiParam(value = "true：报告，false：成绩管理", required = true) @RequestParam boolean report,
                                   @ApiParam(value = "教学课程id", required = true) @RequestParam Long teachCourseId) throws IOException {
        ReportChangeResult reportChangeResult = new ReportChangeResult();
        List<TCUsualScore> tcUsualScoreList = tcUsualScoreService.queryUsualScore(examId, courseCode, paperNumber, teachCourseId);
        if (CollectionUtils.isNotEmpty(tcUsualScoreList)) {
            Set<String> usualScoreCourseSet = new LinkedHashSet<>();
            TCUsualScore tcUsualScore = tcUsualScoreList.get(0);
            List<TCUsualScoreDto> tcUsualScoreDtoList = JSONArray.parseArray(tcUsualScore.getScore(), TCUsualScoreDto.class);
            List<String> usualScoreList = tcUsualScoreDtoList.stream().map(s -> s.getName()).collect(Collectors.toList());

            List<CourseWeightDto> courseWeightDtoList = trBasicInfoService.findCourseWeightDtoRmi(teachCourseId);
            List<String> courseTargetList = new ArrayList<>(courseWeightDtoList.size());
            if (CollectionUtils.isNotEmpty(courseWeightDtoList)) {
                courseWeightDtoList.stream().peek(e -> {
                    courseTargetList.add(e.getCourseTargetName());
                    List<CourseWeightDetailDto> courseWeightDetailDtoList = e.getEvaluationList();
                    courseWeightDetailDtoList.stream().peek(s -> {
                        if (Objects.nonNull(s.getEnable()) && s.getEnable() && !Objects.equals(s.getEvaluationName(), SystemConstant.FINAL_SCORE_STR)) {
                            usualScoreCourseSet.add(s.getEvaluationName());
                        }
                    }).collect(Collectors.toList());
                }).collect(Collectors.toList());
            }

            if (CollectionUtils.isNotEmpty(usualScoreList) && CollectionUtils.isNotEmpty(usualScoreCourseSet)) {
                List<String> usualScoreCourseList = new ArrayList<>(usualScoreCourseSet);
                Collections.sort(usualScoreList);
                Collections.sort(usualScoreCourseList);
                if (!CollectionUtils.isEqualCollection(usualScoreList, usualScoreCourseList)) {
                    reportChangeResult.setEvaluationChange(true);
                }
            }

            TRBasicInfo trBasicInfo = trBasicInfoService.queryBasicInfo(examId, courseCode, paperNumber, teachCourseId);
            if (Objects.nonNull(trBasicInfo) && Objects.nonNull(trBasicInfo.getCourseEvaluationResultDetail())) {
                JSONObject jsonObject = JSONObject.parseObject(trBasicInfo.getCourseEvaluationResultDetail());
                List<CourseTargetWordDto> courseTargetWordDtoList = JSONArray.parseArray(jsonObject.get("targetWordMap").toString(), CourseTargetWordDto.class);
                List<String> courseTargetDbList = courseTargetWordDtoList.stream().map(s -> s.getTargetName()).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(courseTargetList) && CollectionUtils.isNotEmpty(courseTargetDbList)) {
                    Collections.sort(courseTargetList);
                    Collections.sort(courseTargetDbList);
                    if (!CollectionUtils.isEqualCollection(courseTargetList, courseTargetDbList)) {
                        reportChangeResult.setCourseTargetChange(true);
                    }
                }
            }

            if (!report) {
                TCPaperStruct tcPaperStruct = tcPaperStructService.queryPaperStruct(examId, courseCode, paperNumber, teachCourseId);
                if (Objects.nonNull(tcPaperStruct) && Objects.nonNull(tcPaperStruct.getPaperStructDimension())) {
                    List<PaperStructDimensionResult> paperStructDimensionResultList = GsonUtil.fromJson(tcPaperStruct.getPaperStructDimension(), new TypeToken<List<PaperStructDimensionResult>>() {
                    }.getType());
                    StringJoiner stringJoiner = new StringJoiner("");
                    for (CourseWeightDto c : courseWeightDtoList) {
                        Double score = paperStructDimensionResultList.stream().filter(s -> Objects.equals(s.getCourseTargetName(), c.getCourseTargetName())).mapToDouble(PaperStructDimensionResult::getScore).sum();
                        if (Objects.isNull(c.getTotalWeight())) {
                            reportChangeResult.setTargetScoreChange(true);
                            stringJoiner.add("[").add(c.getCourseTargetName()).add("]").add("未设置权重").add("\r\n");
                        } else if (Objects.isNull(c.getTotalScore())) {
                            reportChangeResult.setTargetScoreChange(true);
                            stringJoiner.add("[").add(c.getCourseTargetName()).add("]").add("未设置目标分值").add("\r\n");
                        } else if (new BigDecimal(score).compareTo(c.getTotalWeight()) == 1) {
                            reportChangeResult.setTargetScoreChange(true);
                            stringJoiner.add("[").add(c.getCourseTargetName()).add("]").add("包含的小题总分与权重设置不一致，请到期末成绩--试卷蓝图设置里调整").add("\r\n");
                        }
                    }
                    if (reportChangeResult.isTargetScoreChange()) {
                        trBasicInfoService.clearReportData(examId, courseCode, paperNumber, teachCourseId, false);
                        reportChangeResult.setTargetScoreChangeStr(stringJoiner.toString());
                    }
                }
            }
        }
        return ResultUtil.ok(reportChangeResult);
    }
}
