package com.ruoyi.web.service; import com.alibaba.fastjson.JSONArray; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.ruoyi.common.core.content.VistorContextHolder; import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.enums.UserRegStatus; import com.ruoyi.common.exception.CustomException; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.http.HttpUtils; import com.ruoyi.dz.domain.DzCards; import com.ruoyi.dz.service.IDzCardsService; import com.ruoyi.enums.CardTimeStatus; import com.ruoyi.enums.UserTypeEnum; import com.ruoyi.learn.domain.LearnKnowledgeCourse; import com.ruoyi.learn.domain.LearnKnowledgeTree; import com.ruoyi.learn.domain.LearnPaper; import com.ruoyi.learn.domain.LearnQuestions; import com.ruoyi.learn.service.ILearnPaperService; import com.ruoyi.learn.service.ILearnQuestionsService; import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.utils.downloadpaper.DownloadPaperUtils; import org.apache.commons.io.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import javax.servlet.http.HttpServletResponse; import java.nio.charset.StandardCharsets; import java.time.LocalDate; import java.time.ZoneId; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @Service public class CommService { private final ISysConfigService configService; private final IDzCardsService cardsService; @Autowired ILearnPaperService paperService; @Autowired ILearnQuestionsService learnQuestionsService; public CommService(ISysConfigService configService, IDzCardsService cardsService) { this.configService = configService; this.cardsService = cardsService; } // 检查初始密码是否提醒修改 public boolean initPasswordIsModify(Date pwdUpdateDate) { Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify")); return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null; } // 检查密码是否过期 public boolean passwordIsExpiration(Date pwdUpdateDate) { Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays")); if (passwordValidateDays != null && passwordValidateDays > 0) { if (StringUtils.isNull(pwdUpdateDate)) { // 如果从未修改过初始密码,直接提醒过期 return true; } Date nowDate = DateUtils.getNowDate(); return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays; } return false; } public void requireVip() { SysUser user = SecurityUtils.getLoginUser().getUser(); if (!UserRegStatus.Student.equals(user.getRegStatus()) || null == user.getCardId()) { if (UserTypeEnum.isCard(user.getUserType())) { throw new CustomException("没有权限,请开通VIP", 405); } return; } DzCards card = cardsService.selectDzCardsByCardId(user.getCardId()); Date nowDate = Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant()); if (null == card || !CardTimeStatus.Valid.getVal().equals(card.getTimeStatus()) || (null != card.getOutDate() && card.getOutDate().getTime() < nowDate.getTime())) { throw new CustomException("没有权限,请开通VIP", 405); } } public List buildTree(List ktList, Set knowledgeIdSet, Map knowCountMap) { List treeNodeList = Lists.newArrayList(); Map teMap = Maps.newHashMap(); Integer[] counts; for(LearnKnowledgeTree kt : ktList) { LearnTeacherService.TreeNode tn; if(null != knowCountMap && null != (counts = knowCountMap.get(kt.getId()))) { tn = new LearnTeacherService.TreeNode(kt.getId(), kt.getName(),kt.getSubjectId(), counts); } else { tn = new LearnTeacherService.TreeNode(kt.getId(), kt.getName(),kt.getSubjectId(), null); } teMap.put(kt.getId(), tn); } for(LearnKnowledgeTree kt : ktList) { if(null == kt.getPid()) { treeNodeList.add(teMap.get(kt.getId())); continue; } LearnTeacherService.TreeNode parent = teMap.get(kt.getPid()); LearnTeacherService.TreeNode node = teMap.get(kt.getId()); if(null != node.getQuestionCount()) { if(null == parent) { continue; } parent.setQuestionCount(parent.getQuestionCount() + node.getQuestionCount()); parent.setFinishedCount(parent.getFinishedCount() + node.getFinishedCount()); parent.setRightCount(parent.getRightCount() + node.getRightCount()); parent.calcRatio(); } parent.getChildren().add(node); } if(!CollectionUtils.isEmpty(knowledgeIdSet)) { List childList; List rootList = Lists.newArrayList(); for(LearnTeacherService.TreeNode tn : treeNodeList) { if(knowledgeIdSet.contains(tn.getId())) { rootList.add(tn); } else if(!(childList = tn.getChildren().stream().filter(t -> knowledgeIdSet.contains(t.getId())).collect(Collectors.toList())).isEmpty()) { tn.setChildren(childList); rootList.add(tn); } } return rootList; } return treeNodeList; } public List buildCourseKnowledgeTree(List ktList, Map knowCountMap) { List treeNodeList = Lists.newArrayList(); Map teMap = Maps.newHashMap(); Integer[] counts; for(LearnKnowledgeCourse kt : ktList) { LearnTeacherService.TreeNode tn; if(null != knowCountMap && null != (counts = knowCountMap.get(kt.getId()))) { tn = new LearnTeacherService.TreeNode(kt.getId(), kt.getName(),null, counts); } else { tn = new LearnTeacherService.TreeNode(kt.getId(), kt.getName(),null, null); } teMap.put(kt.getId(), tn); } for(LearnKnowledgeCourse kt : ktList) { if(null == kt.getPid()) { treeNodeList.add(teMap.get(kt.getId())); continue; } LearnTeacherService.TreeNode parent = teMap.get(kt.getPid()); LearnTeacherService.TreeNode node = teMap.get(kt.getId()); if(null != node.getQuestionCount()) { parent.setQuestionCount(parent.getQuestionCount() + node.getQuestionCount()); parent.setFinishedCount(parent.getFinishedCount() + node.getFinishedCount()); parent.setRightCount(parent.getRightCount() + node.getRightCount()); parent.calcRatio(); } parent.getChildren().add(node); } return treeNodeList; } public String getLocation(){ return getLocation(null); } public String getLocation(String location){ if(org.apache.commons.lang3.StringUtils.isBlank(location)) { location = VistorContextHolder.getLocation(); } if (org.apache.commons.lang3.StringUtils.isBlank(location)) { location = "湖南"; } return location; } /** * 下载试卷 * @param response * @param paperId */ public void download(HttpServletResponse response, Long paperId){ try { LearnPaper papers = paperService.selectLearnPaperById(paperId); List questions = learnQuestionsService.selectQuestionByPaperId(paperId); byte[] data = DownloadPaperUtils.download(papers.getPaperName(), questions); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "No-cache"); response.setHeader("Expires", "0"); response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", new String((papers.getPaperName() + ".docx").getBytes("utf-8"), "ISO-8859-1"))); response.setHeader("Content-Type", "application/octet-stream"); IOUtils.write(data, response.getOutputStream()); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } public void downloadRemote(HttpServletResponse response, Long paperId,String url) { try { // 获取试卷信息 LearnPaper paper = paperService.selectLearnPaperById(paperId); if (paper == null) { throw new RuntimeException("试卷不存在"); } // 获取题目列表 List questions = learnQuestionsService.selectQuestionByPaperId(paperId); // 将题目列表转换为 JSON 字符串 String quesJson = JSONArray.toJSONString(questions); // 远程服务器地址 String remoteUrl = (StringUtils.isEmpty(url)?"https://www.dz1kt.com/prod-api":url)+"/learn/paper/downloadPaper"; // 构建请求参数 String params = "paperName=" + java.net.URLEncoder.encode(paper.getPaperName(), StandardCharsets.UTF_8.toString()) + "&ques=" + java.net.URLEncoder.encode(quesJson, StandardCharsets.UTF_8.toString()); // 设置响应头 response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "No-cache"); response.setHeader("Expires", "0"); response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", new String((paper.getPaperName() + ".docx").getBytes("utf-8"), "ISO-8859-1"))); response.setHeader("Content-Type", "application/octet-stream"); // 调用远程服务器并将响应流写入到本地响应 HttpUtils.sendGetStream(remoteUrl, params, response.getOutputStream()); } catch (Exception e) { throw new RuntimeException("下载失败: " + e.getMessage(), e); } } /** * 通用:下载试卷(外部传入数据),不依赖本地数据 * @param response * @param paperName * @param questions */ public void download(HttpServletResponse response, String paperName,List questions){ try { byte[] data = DownloadPaperUtils.download(paperName, questions); response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "No-cache"); response.setHeader("Expires", "0"); response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", new String((paperName + ".docx").getBytes("utf-8"), "ISO-8859-1"))); response.setHeader("Content-Type", "application/octet-stream"); IOUtils.write(data, response.getOutputStream()); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } }