package com.qmth.distributed.print.api; 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.ObeCourseWeightResult; import com.qmth.distributed.print.business.bean.result.ObeScoreResult; 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.*; 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.BasicCourse; 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.BasicCourseService; 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.InputStream; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; /** *

* 报告基本情况表 前端控制器 *

* * @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; @Resource ObeCourseOutlineService obeCourseOutlineService; @Resource BasicCourseService basicCourseService; @ApiOperation(value = "报告管理列表") @RequestMapping(value = "/report/list", method = RequestMethod.POST) @ApiResponses({@ApiResponse(code = 200, message = "分页查询", response = ObeScoreResult.class)}) public Result reportList(@ApiParam(value = "培养方案ID", required = true) @RequestParam Long cultureProgramId, @ApiParam(value = "学期ID") @RequestParam(required = false) Long semesterId, @ApiParam(value = "课程id", required = true) Long courseId, @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) { return ResultUtil.ok( printCommonService.scoreList(new Page<>(pageNumber, pageSize), cultureProgramId, semesterId, courseId)); } @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 cultureProgramId, @ApiParam(value = "课程id", required = true) @RequestParam Long courseId, @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber) { SysUser sysUser = (SysUser) ServletUtil.getRequestUser(); BasicCourse basicCourse = basicCourseService.getById(courseId); TRBasicInfo trBasicInfo = trBasicInfoService.queryBasicInfo(cultureProgramId, courseId, paperNumber); ObeCourseOutline obeCourseOutline = obeCourseOutlineService.findByCultureProgramIdAndCourseId(cultureProgramId, courseId); ObeCourseWeightResult obeCourseWeightResult = trBasicInfoService.findCourseWeightResultRmi(obeCourseOutline.getId()); log.info("ObeCourseWeightResult:{}", JacksonUtil.parseJson(obeCourseWeightResult)); TCPaperStruct tcPaperStruct = tcPaperStructService.queryPaperStruct(cultureProgramId, courseId, paperNumber); if (Objects.isNull(tcPaperStruct) || Objects.isNull(tcPaperStruct.getPaperStructDimension())) { throw ExceptionResultEnum.ERROR.exception("未找到试卷蓝图信息"); } MarkPaper markPaper = printCommonService.getMarkPaper(null, basicCourse.getCode(), tcPaperStruct.getPaperNumber(), courseId); if (Objects.isNull(trBasicInfo)) { trBasicInfo = trBasicInfoService.getReportView(trBasicInfo, markPaper, sysUser.getId(), obeCourseWeightResult, cultureProgramId, courseId); } else { ReportCourseEvaluationResultDto reportCourseEvaluationResultDto = Objects.nonNull(trBasicInfo.getCourseEvaluationResult()) ? JSONObject.parseObject(trBasicInfo.getCourseEvaluationResult(), ReportCourseEvaluationResultDto.class) : null; if (Objects.nonNull(reportCourseEvaluationResultDto.getWeightSettingSign()) && reportCourseEvaluationResultDto.getWeightSettingSign().longValue() != obeCourseWeightResult.getWeightSettingSign().longValue()) { trBasicInfoService.clearReportData(cultureProgramId, courseId, paperNumber, Objects.nonNull(tcPaperStruct.getDimensionSign()) && tcPaperStruct.getDimensionSign().longValue() != obeCourseWeightResult.getDimensionSign().longValue()); trBasicInfo = trBasicInfoService.getReportView(trBasicInfo, markPaper, sysUser.getId(), obeCourseWeightResult, cultureProgramId, courseId); } else { ReportCourseBasicInfoDto reportCourseBasicInfoDto = new ReportCourseBasicInfoDto(trBasicInfo); ReportCourseEvaluationSpreadDto reportCourseEvaluationSpreadDto = Objects.nonNull(trBasicInfo.getCourseEvaluationSpread()) ? JSONObject.parseObject(trBasicInfo.getCourseEvaluationSpread(), ReportCourseEvaluationSpreadDto.class) : null; ReportCourseEvaluationResultDetailDto reportCourseEvaluationResultDetailDto = null; List trExamStudentList = trExamStudentService.list( new QueryWrapper().lambda().eq(TRExamStudent::getrBasicInfoId, trBasicInfo.getId())); if (!CollectionUtils.isEmpty(trExamStudentList)) { List examStudentList = new ArrayList<>(trExamStudentList.size()); for (TRExamStudent trExamStudent : trExamStudentList) { examStudentList.add(new ReportExamStudentDto(trExamStudent)); } reportCourseEvaluationResultDetailDto = new ReportCourseEvaluationResultDetailDto(examStudentList); } trBasicInfo.setReportResult(new ReportResult(new ReportCommonDto(null, basicCourse.getCode(), markPaper.getCourseName(), paperNumber), reportCourseBasicInfoDto, reportCourseEvaluationSpreadDto, reportCourseEvaluationResultDto, reportCourseEvaluationResultDetailDto, trBasicInfo)); } } 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.getCultureProgramId(), trBasicInfo.getCourseId(), trBasicInfo.getPaperNumber()); if (Objects.isNull(trBasicInfoDb)) { trBasicInfoDb = new TRBasicInfo(trBasicInfo, sysUser.getId()); TCPaperStruct tcPaperStruct = tcPaperStructService.queryPaperStruct(trBasicInfo.getCultureProgramId(), trBasicInfo.getCourseId(), trBasicInfo.getPaperNumber()); MarkPaper markPaper = printCommonService.getMarkPaper(trBasicInfo.getExamId(), trBasicInfo.getCourseCode(), Objects.nonNull(tcPaperStruct) ? tcPaperStruct.getPaperNumber() : trBasicInfo.getPaperNumber(), trBasicInfo.getCourseId()); ObeCourseOutline obeCourseOutline = obeCourseOutlineService.findByCultureProgramIdAndCourseId(trBasicInfo.getCultureProgramId(), trBasicInfo.getCourseId()); trBasicInfoDb = trBasicInfoService.getReportView(trBasicInfoDb, markPaper, sysUser.getId(), trBasicInfoService.findCourseWeightResultRmi(obeCourseOutline.getId()), trBasicInfo.getCultureProgramId(), trBasicInfo.getCourseId()); } 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 cultureProgramId, @ApiParam(value = "课程id", required = true) @RequestParam Long courseId, @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber) { File txtFileTemp = null, fileTemp = null; try { Long schoolId = Long.valueOf(ServletUtil.getRequestHeaderSchoolId().toString()); ObeCourseOutline obeCourseOutline = obeCourseOutlineService.findByCultureProgramIdAndCourseId(cultureProgramId, courseId); BasicSchool basicSchool = commonCacheService.schoolCache(schoolId); TRBasicInfo trBasicInfo = trBasicInfoService.queryBasicInfo(cultureProgramId, courseId, paperNumber); Objects.requireNonNull(trBasicInfo, "没有报告信息"); Objects.requireNonNull(trBasicInfo.getCourseEvaluationResult(), "没有课程目标信息"); Objects.requireNonNull(trBasicInfo.getCourseEvaluationResultDetail(), "没有课程考生信息"); ObeCourseWeightResult obeCourseWeightResult = trBasicInfoService.findCourseWeightResultRmi(obeCourseOutline.getId()); TCPaperStruct tcPaperStruct = tcPaperStructService.queryPaperStruct(cultureProgramId, courseId, paperNumber); if (Objects.nonNull(tcPaperStruct) && Objects.nonNull(tcPaperStruct.getPaperStructDimension())) { List paperStructDimensionResultList = GsonUtil.fromJson(tcPaperStruct.getPaperStructDimension(), new TypeToken>() { }.getType()); for (CourseWeightDto c : obeCourseWeightResult.getSubmitForm()) { Double score = paperStructDimensionResultList.stream().filter(s -> Objects.equals(s.getCourseTargetName(), c.getCourseTargetName())).mapToDouble(s -> s.getScore().doubleValue()).sum(); Objects.requireNonNull(c.getTotalWeight(), "[" + c.getCourseTargetName() + "]未设置权重"); List courseWeightDetailDtoList = c.getEvaluationList(); for (CourseWeightDetailDto courseWeightDetailDto : courseWeightDetailDtoList) { if (Objects.equals(courseWeightDetailDto.getEvaluationName(), SystemConstant.FINAL_SCORE_STR)) { courseWeightDetailDto.setTargetScore(new BigDecimal(score)); break; } } } } ReportCourseEvaluationResultDto reportCourseEvaluationResultDto = JSONObject.parseObject(trBasicInfo.getCourseEvaluationResult(), ReportCourseEvaluationResultDto.class); if (Objects.nonNull(reportCourseEvaluationResultDto.getWeightSettingSign()) && reportCourseEvaluationResultDto.getWeightSettingSign().longValue() != obeCourseWeightResult.getWeightSettingSign().longValue()) { trBasicInfoService.clearReportData(cultureProgramId, courseId, paperNumber, Objects.nonNull(tcPaperStruct) && Objects.nonNull(tcPaperStruct.getDimensionSign()) && tcPaperStruct.getDimensionSign().longValue() != obeCourseWeightResult.getDimensionSign().longValue()); this.reportView(cultureProgramId, courseId, paperNumber); this.reportExport(cultureProgramId, courseId, paperNumber); } else { //评价样本的基本信息 JSONObject jsonObject = JSONObject.parseObject(trBasicInfo.getCourseEvaluationResultDetail()); List 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, 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)); //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); } } 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 cultureProgramId, @ApiParam(value = "课程id", required = true) @RequestParam Long courseId, @ApiParam(value = "试卷编号") @RequestParam(required = false) String paperNumber, @ApiParam(value = "true:报告,false:成绩管理", required = true) @RequestParam boolean report) { ObeCourseOutline obeCourseOutline = obeCourseOutlineService.findByCultureProgramIdAndCourseId(cultureProgramId, courseId); ReportChangeResult reportChangeResult = new ReportChangeResult(); List tcUsualScoreList = tcUsualScoreService.queryUsualScore(cultureProgramId, courseId, paperNumber); if (CollectionUtils.isNotEmpty(tcUsualScoreList)) { Set usualScoreCourseSet = new LinkedHashSet<>(); TCUsualScore tcUsualScore = tcUsualScoreList.get(0); List tcUsualScoreDtoList = JSONArray.parseArray(tcUsualScore.getScore(), TCUsualScoreDto.class); List usualScoreList = tcUsualScoreDtoList.stream().map(s -> s.getName()).collect(Collectors.toList()); List courseWeightDtoList = trBasicInfoService.findCourseWeightDtoRmi(obeCourseOutline.getId()); List courseTargetList = new ArrayList<>(courseWeightDtoList.size()); if (CollectionUtils.isNotEmpty(courseWeightDtoList)) { courseWeightDtoList.stream().peek(e -> { courseTargetList.add(e.getCourseTargetName()); List 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 usualScoreCourseList = new ArrayList<>(usualScoreCourseSet); Collections.sort(usualScoreList); Collections.sort(usualScoreCourseList); if (!CollectionUtils.isEqualCollection(usualScoreList, usualScoreCourseList)) { reportChangeResult.setEvaluationChange(true); } } TRBasicInfo trBasicInfo = trBasicInfoService.queryBasicInfo(cultureProgramId, courseId, paperNumber); if (Objects.nonNull(trBasicInfo) && Objects.nonNull(trBasicInfo.getCourseEvaluationResultDetail())) { JSONObject jsonObject = JSONObject.parseObject(trBasicInfo.getCourseEvaluationResultDetail()); List courseTargetWordDtoList = JSONArray.parseArray(jsonObject.get("targetWordMap").toString(), CourseTargetWordDto.class); List courseTargetDbList = courseTargetWordDtoList.stream().map( CourseTargetWordDto::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(cultureProgramId, courseId, paperNumber); if (Objects.nonNull(tcPaperStruct) && Objects.nonNull(tcPaperStruct.getPaperStructDimension())) { List paperStructDimensionResultList = GsonUtil.fromJson(tcPaperStruct.getPaperStructDimension(), new TypeToken>() { }.getType()); StringJoiner stringJoiner = new StringJoiner(""); for (CourseWeightDto c : courseWeightDtoList) { if (Objects.isNull(c.getTotalWeight())) { reportChangeResult.setTargetScoreChange(true); stringJoiner.add("[").add(c.getCourseTargetName()).add("]").add("未设置权重").add("\r\n"); } } if (reportChangeResult.isTargetScoreChange()) { trBasicInfoService.clearReportData(cultureProgramId, courseId, paperNumber, false); reportChangeResult.setTargetScoreChangeStr(stringJoiner.toString()); } } } } return ResultUtil.ok(reportChangeResult); } }