diff --git a/src/main/java/cn/teammodel/service/impl/EvaluationServiceImpl.java b/src/main/java/cn/teammodel/service/impl/EvaluationServiceImpl.java index ffb3a0e..fc80c93 100644 --- a/src/main/java/cn/teammodel/service/impl/EvaluationServiceImpl.java +++ b/src/main/java/cn/teammodel/service/impl/EvaluationServiceImpl.java @@ -31,6 +31,7 @@ import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.jfree.chart.ChartUtils; import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PiePlot; import org.jfree.data.general.DefaultPieDataset; import org.springframework.core.io.ClassPathResource; import org.springframework.data.domain.Page; @@ -40,12 +41,14 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; +import java.awt.*; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.time.Instant; import java.time.LocalDate; import java.util.*; +import java.util.List; import java.util.stream.Collectors; /** @@ -55,8 +58,8 @@ import java.util.stream.Collectors; @Service public class EvaluationServiceImpl implements EvaluationService { /** - * 评价记录对象的类型 - */ + * 评价记录对象的类型 + */ private final static String TARGET_STUDENT = "student"; private final static String TARGET_CLASS = "class"; @Resource @@ -112,8 +115,8 @@ public class EvaluationServiceImpl implements EvaluationService { /** - * 将 appraise 进行替换(天才) - */ + * 将 appraise 进行替换(天才) + */ private void refreshAppraiseTree(Appraise appraise) { List nodes = appraise.getNodes(); List rules = appraise.getAchievementRules(); @@ -332,7 +335,7 @@ public class EvaluationServiceImpl implements EvaluationService { // 获取班级信息 ClassInfo classInfo = classRepository.findClassByIdAndCode(classId, String.format(PK.CLASS, schoolId)); className = classInfo.getName(); - } else if (targetType.equals(TARGET_CLASS)){ + } else if (targetType.equals(TARGET_CLASS)) { ClassInfo classInfo = classRepository.findClassByIdAndCode(targetId, String.format(PK.CLASS, schoolId)); if (classInfo == null) { throw new ServiceException(ErrorCode.PARAMS_ERROR.getCode(), "班级不存在"); @@ -365,7 +368,7 @@ public class EvaluationServiceImpl implements EvaluationService { targetId, classId, academicYearId, - String.format(PK.PK_APPRAISE_RECORD,schoolId) + String.format(PK.PK_APPRAISE_RECORD, schoolId) ); // 初始化新的评价节点 @@ -376,7 +379,7 @@ public class EvaluationServiceImpl implements EvaluationService { item.setCreatorId(loginUser.getId()); item.setCreateTime(Instant.now().toEpochMilli()); // 处理学校与学生的差异 - if (targetType.equals(TARGET_CLASS)){ + if (targetType.equals(TARGET_CLASS)) { item.setSpread(spread); } else { item.setPushParent(pushParent); @@ -463,12 +466,12 @@ public class EvaluationServiceImpl implements EvaluationService { .findFirst().orElseThrow(() -> new ServiceException("该记录节点不存在")); // 鉴权(不是创建老师不能撤回) if (!loginUser.getRoles().contains("admin") && !userId.equals(record.getCreatorId())) { - throw new ServiceException(ErrorCode.NO_AUTH_ERROR.getCode(), "您不是创建老师,不能撤回"); + throw new ServiceException(ErrorCode.NO_AUTH_ERROR.getCode(), "您不是创建老师,不能撤回"); } // 删除评价项并且恢复评分 appraiseRecord.getNodes().removeIf(item -> nodeId.equals(item.getId())); boolean praise = record.getAppraiseNode().isPraise(); - Integer newPraiseCount = appraiseRecord.getPraiseCount() + (praise ? -1 : 1); + Integer newPraiseCount = appraiseRecord.getPraiseCount() + (praise ? -1 : 1); appraiseRecord.setPraiseCount(newPraiseCount); int score = record.getAppraiseNode().getScore() == null ? 0 : record.getAppraiseNode().getScore(); Integer newScore = appraiseRecord.getScore() - score; @@ -522,7 +525,7 @@ public class EvaluationServiceImpl implements EvaluationService { // 计算当前学生排名在全班次位 int greaterCount = appraiseRecordRepository.findClassRecord(String.format(PK.PK_APPRAISE_RECORD, schoolId), academicYearId, classId, praiseCount); float beyondPercent; - long currentRank = stuInClassCount - greaterCount; + long currentRank = stuInClassCount - greaterCount; beyondPercent = (float) currentRank / stuInClassCount; // 根据全部数据计算结果 @@ -530,7 +533,7 @@ public class EvaluationServiceImpl implements EvaluationService { AppraiseTreeNode appraiseNode = record.getAppraiseNode(); String[] path = appraiseNode.getPath(); // 数据异常则跳过 - if (path == null || path.length == 0){ + if (path == null || path.length == 0) { continue; } String root = path[0]; @@ -620,7 +623,7 @@ public class EvaluationServiceImpl implements EvaluationService { } @Override - public void exportStuReportPdf(IdRequest idRequest, HttpServletResponse response) throws IOException, DocumentException{ + public void exportStuReportPdf(IdRequest idRequest, HttpServletResponse response) throws IOException, DocumentException { // 设置response参数 response.reset(); response.setContentType("application/pdf"); @@ -636,34 +639,43 @@ public class EvaluationServiceImpl implements EvaluationService { PdfReader pdfReader = new PdfReader(in); PdfStamper stamper = new PdfStamper(pdfReader, os); + int criticalCount = reportVo.getCriticalDistribution().values().stream().mapToInt(Integer::intValue).sum(); Map data = new HashMap<>(); data.put("name", reportVo.getName()); data.put("studentId", reportVo.getStudentId()); data.put("className", reportVo.getClassName()); + data.put("totalCount", String.valueOf(reportVo.getPraiseCount() + criticalCount)); data.put("praiseCount", String.valueOf(reportVo.getPraiseCount())); + data.put("criticalCount", String.valueOf(criticalCount)); data.put("beyondPercent", String.valueOf(reportVo.getBeyondPercent())); data.put("topPraiseTeacher", StringUtils.isBlank(reportVo.getTopPraiseTeacher().getName()) ? "暂无" : reportVo.getTopPraiseTeacher().getName()); data.put("topCriticalTeacher", StringUtils.isBlank(reportVo.getTopCriticalTeacher().getName()) ? "暂无" : reportVo.getTopCriticalTeacher().getName()); data.put("topPraiseNode", StringUtils.isBlank(reportVo.getTopPraiseNode()) ? "暂无" : reportVo.getTopPraiseNode()); data.put("topCriticalNode", StringUtils.isBlank(reportVo.getTopCriticalNode()) ? "暂无" : reportVo.getTopCriticalNode()); - DefaultPieDataset praiseDistributionDataset = new DefaultPieDataset( ); + DefaultPieDataset praiseDistributionDataset = new DefaultPieDataset(); praiseDistributionDataset.setValue(FiveEducations.VIRTUE.getName(), reportVo.getPraiseDistribution().get(FiveEducations.VIRTUE.getCode())); praiseDistributionDataset.setValue(FiveEducations.INTELLIGENCE.getName(), reportVo.getPraiseDistribution().get(FiveEducations.INTELLIGENCE.getCode())); praiseDistributionDataset.setValue(FiveEducations.SPORTS.getName(), reportVo.getPraiseDistribution().get(FiveEducations.SPORTS.getCode())); praiseDistributionDataset.setValue(FiveEducations.ART.getName(), reportVo.getPraiseDistribution().get(FiveEducations.ART.getCode())); praiseDistributionDataset.setValue(FiveEducations.LABOUR.getName(), reportVo.getPraiseDistribution().get(FiveEducations.LABOUR.getCode())); JFreeChart praisePieChart = ChartUtil.pieChart("五育表扬指标分布", praiseDistributionDataset); + ByteArrayOutputStream praiseBos = new ByteArrayOutputStream(); ChartUtils.writeChartAsJPEG(praiseBos, praisePieChart, 340, 330); - DefaultPieDataset criticalDistributionDataset = new DefaultPieDataset( ); + // 如果分布为空,则填充默认值 1 + DefaultPieDataset criticalDistributionDataset = new DefaultPieDataset(); criticalDistributionDataset.setValue(FiveEducations.VIRTUE.getName(), reportVo.getCriticalDistribution().get(FiveEducations.VIRTUE.getCode())); criticalDistributionDataset.setValue(FiveEducations.INTELLIGENCE.getName(), reportVo.getCriticalDistribution().get(FiveEducations.INTELLIGENCE.getCode())); criticalDistributionDataset.setValue(FiveEducations.SPORTS.getName(), reportVo.getCriticalDistribution().get(FiveEducations.SPORTS.getCode())); criticalDistributionDataset.setValue(FiveEducations.ART.getName(), reportVo.getCriticalDistribution().get(FiveEducations.ART.getCode())); criticalDistributionDataset.setValue(FiveEducations.LABOUR.getName(), reportVo.getCriticalDistribution().get(FiveEducations.LABOUR.getCode())); JFreeChart criticalPieChart = ChartUtil.pieChart("五育待改进指标分布", criticalDistributionDataset); + PiePlot plot = (PiePlot) criticalPieChart.getPlot(); + plot.setNoDataMessage("无数据"); + plot.setNoDataMessageFont(new Font("宋体", Font.PLAIN, 18)); + ByteArrayOutputStream criticalBos = new ByteArrayOutputStream(); ChartUtils.writeChartAsJPEG(criticalBos, criticalPieChart, 340, 330); @@ -675,12 +687,11 @@ public class EvaluationServiceImpl implements EvaluationService { // stamper.setFormFlattening(true); stamper.close(); os.close(); - } /** - * 递归收集 id 的节点及 id 节点的孩子节点 (迭代器删除居然也报错) - */ + * 递归收集 id 的节点及 id 节点的孩子节点 (迭代器删除居然也报错) + */ private void collectNodesToDelete(String id, List nodes, List nodesToDelete) { for (AppraiseTreeNode node : nodes) { if (id.equals(node.getPid())) { @@ -712,8 +723,8 @@ public class EvaluationServiceImpl implements EvaluationService { /** - * 获取节点的孩子节点列表 - */ + * 获取节点的孩子节点列表 + */ private List getChildren(AppraiseTreeNode parent, List nodes) { List children = new ArrayList<>(); for (AppraiseTreeNode node : nodes) { @@ -723,4 +734,24 @@ public class EvaluationServiceImpl implements EvaluationService { } return children; } + + /** + * 保证饼图分布:distribution 全部为 0,则初始化为 1 + */ + private void checkIfDistributionNull(Map distribution) { + boolean flag = false; + for (Map.Entry entry : distribution.entrySet()) { + if (entry.getValue() != 0) { + flag = true; + break; + } + } + + if(flag) { + return; + } + // distribution 全部为 0,则初始化为 1 + distribution.forEach((k, v) -> distribution.put(k, 1)); + } } + diff --git a/src/main/resources/templates/pdf_templates/student_report.pdf b/src/main/resources/templates/pdf_templates/student_report.pdf index eb0fd54..ebd9bd9 100644 Binary files a/src/main/resources/templates/pdf_templates/student_report.pdf and b/src/main/resources/templates/pdf_templates/student_report.pdf differ