package com.qxueyou.scc.school.service.impl; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Transparency; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.math.BigDecimal; import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.imageio.ImageIO; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.poi.hslf.HSLFSlideShow; import org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException; import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; import org.apache.poi.poifs.crypt.Decryptor; import org.apache.poi.poifs.crypt.EncryptionInfo; import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; import org.apache.poi.poifs.filesystem.POIFSFileSystem; //import org.jpedal.examples.images.ConvertPagesToImages; //import org.jpedal.exception.PdfException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.stereotype.Service; import com.qxueyou.scc.admin.classes.model.ClsClass; import com.qxueyou.scc.base.dao.CommonDAO; import com.qxueyou.scc.base.model.Pager; import com.qxueyou.scc.base.model.Result; import com.qxueyou.scc.base.model.UserInfoWrapper; import com.qxueyou.scc.base.service.IFileUploadService; import com.qxueyou.scc.base.service.impl.CommonAppService; import com.qxueyou.scc.base.util.ClientUtils; import com.qxueyou.scc.base.util.CollectionUtils; import com.qxueyou.scc.base.util.JacobUtil; import com.qxueyou.scc.base.util.TraceUtils; import com.qxueyou.scc.base.util.UUIDUtils; import com.qxueyou.scc.config.AliOnsConfig; import com.qxueyou.scc.config.SccConfig; import com.qxueyou.scc.org.model.OrgText; import com.qxueyou.scc.org.service.IOrgTextService; import com.qxueyou.scc.school.dao.HandoutDAO; import com.qxueyou.scc.school.model.SchClassSubject; import com.qxueyou.scc.school.model.SchCourseware; import com.qxueyou.scc.school.model.SchHandout; import com.qxueyou.scc.school.model.SchHandoutPage; import com.qxueyou.scc.school.model.SchHandoutPageFavor; import com.qxueyou.scc.school.model.SchHandoutReCourse; import com.qxueyou.scc.school.model.SchHandoutRecord; import com.qxueyou.scc.school.model.SchHandoutRecordDetail; import com.qxueyou.scc.school.model.SchHandoutStatistic; import com.qxueyou.scc.school.service.ICourseWareService; import com.qxueyou.scc.school.service.IDocdealMsgSenderService; import com.qxueyou.scc.school.service.IHandoutService; import com.qxueyou.scc.sys.model.SysFileUploadTrace; import com.qxueyou.scc.sys.service.IOssService; import com.qxueyou.scc.teach.subject.model.SubjectChapter; import com.qxueyou.scc.user.model.User; import com.qxueyou.scc.user.service.IUserService; import com.jacob.activeX.ActiveXComponent; import com.jacob.com.ComFailException; import com.jacob.com.ComThread; import com.jacob.com.Dispatch; import com.jacob.com.Variant; /** * 讲义管理服务 * * @author 德虎 2015-1-4 * */ @Service @EnableConfigurationProperties({ SccConfig.class, AliOnsConfig.class }) public class HandoutService extends CommonAppService implements IHandoutService { private final Logger log = LogManager.getLogger(HandoutService.class); private static final String HANDOUT_ID = "handoutId"; // @Autowired // CommonONSProducer onsProducer; // @Autowired AliOnsConfig aliOnsConfig; @Autowired SccConfig sccConfig; // @Autowired IOssService ossService; @Autowired IFileUploadService fileUploadService; @Autowired IUserService userService; @Autowired IOrgTextService orgTextService; // /** 极光推送替换信鸽 */ // @Autowired // IJPushService jpushService; @Autowired IDocdealMsgSenderService docdealMsgSenderService; private HandoutDAO handoutDAO; // // @Autowired // private ICacheService cacheService; @Autowired private ICourseWareService courseWareService; /** * 依赖注入 * * @param handoutDAO */ @Autowired(required = false) public void setHandoutDAO(@Qualifier("handoutDAO") HandoutDAO handoutDAO) { this.handoutDAO = handoutDAO; } /** * PPT\PPTX (office文件不直接处理,发送消息,使用特定的文档处理服务器处理) PDF直接处理 * * */ @Override public Result insertHandout(String fullPath, String module, SchHandout handout) { File file = null; try { // 取得当前上传文件类型:office(ppt、pptx)或者pdf,直接用后缀名来判断格式(office还是pdf) String filePart[] = fullPath.split("\\."); String fileType = filePart[filePart.length - 1]; // 1.下载到应用服务器本地 String uuid = UUIDUtils.generateUUID(); String filePath = HandoutService.class.getClassLoader().getResource("../uploads").getPath() .concat("handout/" + uuid + "/" + uuid + "." + fileType); file = fileUploadService.doGetOssFile(fullPath, filePath, module, ClientUtils.getUserId()); // 是否是office boolean pptFlag = false; if ("PPT".equals(fileType.toUpperCase()) || "PPTX".equals(fileType.toUpperCase())) { // 如果有密码,返回前台提示 07+ 无打开密码有权限密码无法检测出来 if (getDecryptFlag(file, fileType.toUpperCase())) { return new Result(false, "导入失败:您提交的文件有密码,请上传没有密码的文件!"); } pptFlag = true; } TraceUtils.setCreateTrace(handout); handout.setHandoutId(null); handout.setStatus(SchHandout.STATUS_PROCESSING); handout.setClassId(ClientUtils.getClassId()); handout.setPlayCount(0); handout.setFullPath(fullPath); handout.setOrigPath(fullPath); handout.setFullLength((int) (file.length() > 0 ? file.length() / 1024 : 0)); handout.setOrgId(ClientUtils.getOrgId()); this.saveHandout(handout); handout.setOriginHandoutId(handout.getHandoutId()); // 保存OrgText —— 讲义详情 orgTextService.doSaveOrgText(handout.getHandoutId(), OrgText.TABLE_NAME_HANDOUT, handout.getRemark()); // 更新上传文件使用轨迹 fileUploadService.updateUploadTrace(fullPath, module, SysFileUploadTrace.FILE_USE, handout.getHandoutId()); // 序号 String hql = "select MAX(c.orderNum) from SchHandout c where c.deleteFlag is false and c.classId = ? "; Integer iMax = this.findUnique(hql, CollectionUtils.newList(ClientUtils.getClassId()), Integer.class); if (iMax == null || iMax == 0) { iMax = 1; } else { iMax = iMax + 1; } handout.setOrderNum(iMax); this.saveHandout(handout); // 标记班级有讲义 ClsClass cls = read(ClsClass.class, ClientUtils.getClassId()); if (cls != null && cls.getHaveHandout() == ClsClass.NOT_HAVE_HANDOUT) { cls.setHaveHandout(ClsClass.HAVE_HANDOUT); save(cls); } Result result = new Result(true); result.addData("pptFlag", pptFlag); return result; } catch (Exception e) { this.log.error("讲义转码失败" + fullPath, e); } finally { if (file != null) { // 删除下载到应用服务器的文档 fileUploadService.doDeleteTempOssFile(file.getParentFile(), module, ClientUtils.getUserId()); } } return new Result(false); } /** * 转码PDF发送消息 * * @param handoutId * @param fullPath * @param module * @param userId * @return */ public Result sendMsgConvertPDF(String handoutId, String fullPath, String module, String userId) { // ONSMsg msg = new ONSMsg(onsProducer.getTopic()); // // msg.put("msgType", "CONVERT_PDF"); // msg.put(HANDOUT_ID, handoutId); // msg.put("fullPath", fullPath); // msg.put("module", module); // msg.put("userId", userId); // // try { // // onsProducer.sendMsg(msg); // return new Result(true); // // } catch (Exception e) { // log.error("call handoutService fail.handoutId: " + handoutId, e); // } return new Result(false); } @SuppressWarnings("unused") @Override public void doConvertPDF(String handoutId, String fullPath, String module, String userId) { try { insertHandoutPages(fullPath, handoutId, module, userId, "PDF"); } catch (Exception e) { String businessId = aliOnsConfig.getCommonTopic() + "-" + UUIDUtils.generateUUID(); String desp = "handoutId:" + handoutId + ";fullPath:" + fullPath + ";module:" + module; log.error(businessId + " :转码PDF讲义失败:" + e, e); } } @SuppressWarnings("unused") @Override public void doConvertDOC(String docPath, String handoutId, String uploadModule, String userId) { try { insertHandoutPages(docPath, handoutId, uploadModule, userId, "PPT"); } catch (Exception e) { String desp = "handoutId:" + handoutId + ";docPath:" + docPath + ";uploadModule:" + uploadModule; log.error(handoutId + " :上传讲义ppt消息发送失败:" + e, e); } } /** * docdeal 消息队列调用,将office文件从oss下载到web server上,解析成图片,将解析后的图片传到oss上 * 20150915:正式环境出现同一个ppt解析了两份,(消息队列处理前删除前面内容,用最新内容,这样操作,收藏的讲义可能会出现问题),已处理过不处理 * 修改bug:ppt和jpg当前不在同一个目录下面,修改到同一个目录下面 * * @param docPath * @param handoutId * @return */ @SuppressWarnings({ "unchecked", "unused" }) @Override public Result insertHandoutPages(String docPath, String handoutId, String uploadModule, String userId, String type) { log.debug("start...docDealMsgReceiveService call insertHandoutPages success: docPath: " + docPath + " ;handoutId: " + handoutId); File objOfficeFile = null; try { // 0. judge String hql = "from SchHandoutPage s where s.handoutId = ? and s.deleteFlag is false "; int iCount = this.findCount(hql, CollectionUtils.newList(handoutId)); if (iCount > 0) { log.debug("end0...docDealMsgReceiveService call insertHandoutPages already: docPath: " + docPath + " ;handoutId: " + handoutId); return new Result(true); } // 1.download File to local web server String uuid = UUIDUtils.generateUUID(); String filePart[] = docPath.split("\\."); String fileType = filePart[filePart.length - 1]; // String directory = // HandoutService.class.getClassLoader().getResource("../uploads").getPath().concat("/handout/" // + uuid + "/" + "downLoadOfficeFile" + // docPath.substring(docPath.lastIndexOf('.'))); // File file = new // File(HandoutService.class.getClassLoader().getResource("../uploads").getPath().concat("/handout/" // + uuid)); // objOfficeFile = fileUploadService.doGetOssFile(docPath, "/temp/uploads/handout/" + UUIDUtils.generateUUID() + "/" + fileType + "." + fileType, uploadModule, ClientUtils.getUserId()); // // file.mkdirs(); // objOfficeFile = fileUploadService.doGetOssFile(docPath, directory, // uploadModule, userId); // 2.deal doc // 使用新方式解析讲义,有个缺陷:上传img及数据库中handoutpage默认排序(15页ppt为例):1,10,11,12,13,14,15,2,3,4,5,6,7,8,9 List lstPages = Collections.EMPTY_LIST; if ("PPT".equals(type)) { lstPages = this.convertPPTToJPG(objOfficeFile, docPath, handoutId); } if ("PDF".equals(type)) { lstPages = this.convertPDFToPNG(objOfficeFile, docPath, handoutId); } // 3.insert pages if (lstPages.isEmpty()) { log.error("转换ppt为空:" + handoutId + "-" + docPath + "-" + userId + "-" + uploadModule); // 4.modify handout status and pageCount SchHandout objHandout = this.read(SchHandout.class, handoutId); // jgw ,直接修改为发布 objHandout.setStatus(SchHandout.STATUS_FAILURE); this.saveHandout(objHandout); return new Result(false, "office讲义转换失败"); } for (SchHandoutPage page : lstPages) { page.setHandoutId(handoutId); } saveOrUpdateAll(lstPages); // 4.modify handout status and pageCount SchHandout objHandout = this.read(SchHandout.class, handoutId); objHandout.setPageCount(lstPages.size()); // jgw ,直接修改为发布 objHandout.setStatus(SchHandout.STATUS_ISSUED); // 如果首页图片为null 并且 lstPages不为空 if (StringUtils.isBlank(objHandout.getCoverPageUrl())) { objHandout.setCoverPageUrl(lstPages.get(0).getImgPath()); } this.saveHandout(objHandout); // 如果是管理员上传,处理指定到别处的数据 doInitClassHandout(objHandout, lstPages); log.debug("end1...docDealMsgReceiveService call insertHandoutPages success: docPath: " + docPath + " ;handoutId: " + handoutId); } catch (Exception e) { log.error("调用docdeal服务器解析ppt失败,失败原因:" + handoutId, e); SchHandout objHandout = this.read(SchHandout.class, handoutId); if (null != objHandout) { objHandout.setStatus(SchHandout.STATUS_FAILURE); this.saveHandout(objHandout); } // throw e; } finally { if (null != objOfficeFile) { fileUploadService.doDeleteTempOssFile(objOfficeFile.getParentFile(), uploadModule, userId); } } return new Result(true); } /** * PPT\PPTX (office文件不直接处理,发送消息,使用特定的文档处理服务器处理) PDF直接处理 * * */ @SuppressWarnings("unused") @Override public Result insertOrgHandout(String fullPath, String module, SchHandout handout, String collegeCourseId) { File file = null; try { // 取得当前上传文件类型:office(ppt、pptx)或者pdf,直接用后缀名来判断格式(office还是pdf) String filePart[] = fullPath.split("\\."); String fileType = filePart[filePart.length - 1]; String rootPath = sccConfig.getResRootPath(); String outputPath = rootPath.concat(filePart[0].substring(1, filePart[0].length())); // 1.下载到应用服务器本地 file = fileUploadService.doGetOssFile(fullPath, "/temp/uploads/handout/" + UUIDUtils.generateUUID() + "/" + fileType + "." + fileType, module, ClientUtils.getUserId()); // 是否是office boolean pptFlag = false; if ("PPT".equals(fileType.toUpperCase()) || "PPTX".equals(fileType.toUpperCase())) { // 如果有密码,返回前台提示 07+ 无打开密码有权限密码无法检测出来 if (getDecryptFlag(file, fileType.toUpperCase())) { return new Result(false, "导入失败:您提交的文件有密码,请上传没有密码的文件!"); } pptFlag = true; } if (!"PDF".equals(fileType.toUpperCase())) { /* * docConverterUtil dcu=new docConverterUtil(file.getPath()); * dcu.setOutputPath(outputPath); dcu.conver(); fullPath=filePart[0]+".pdf"; */ JacobUtil.formatConvert(fileType, rootPath.concat(fullPath.substring(1, fullPath.length()))); fullPath = filePart[0] + ".pdf"; } TraceUtils.setCreateTrace(handout); handout.setPlayCount(0); handout.setStatus(SchHandout.STATUS_PROCESSING); handout.setClassId(ClientUtils.getClassId()); handout.setFullPath(fullPath); handout.setFullLength((int) (file.length() > 0 ? file.length() / 1024 : 0)); handout.setOrgId(ClientUtils.getOrgId()); this.saveHandout(handout); handout.setOriginHandoutId(handout.getHandoutId()); this.saveHandout(handout); // 保存OrgText —— 讲义详情 orgTextService.doSaveOrgText(handout.getHandoutId(), OrgText.TABLE_NAME_HANDOUT, handout.getRemark()); // 更新上传文件使用轨迹 fileUploadService.updateUploadTrace(fullPath, module, SysFileUploadTrace.FILE_USE, handout.getHandoutId()); // 讲义和科目关联 this.insertReCourse(collegeCourseId, handout.getHandoutId()); // 删除pdf ppt原文件,已上传至阿里与服务器 // FileUtils.deleteQuietly(file); // insertAppointSelfOrg(handout.getHandoutId(),ClientUtils.getOrgId(),collegeCourseId); Result result = new Result(true); result.addData("pptFlag", pptFlag); return result; } catch (Exception e) { this.log.error("讲义转码失败" + fullPath, e); } finally { if (file != null) { // 删除下载到应用服务器的文档 fileUploadService.doDeleteTempOssFile(file.getParentFile(), module, ClientUtils.getUserId()); } } return new Result(false); } /** * 编辑讲义 */ public Result doEditHandout(SchHandout newhandout, String type) { SchHandout handout = read(SchHandout.class, newhandout.getHandoutId()); handout.setName(newhandout.getName()); // handout.setSubjectId(newhandout.getSubjectId()); // handout.setSubjectName(newhandout.getSubjectName()); handout.setRemark(newhandout.getRemark()); if (StringUtils.isNotBlank(newhandout.getCoverPageUrl())) { handout.setCoverPageUrl(newhandout.getCoverPageUrl()); } TraceUtils.setUpdateTrace(handout); this.saveHandout(handout); // 保存OrgText —— 讲义详情 orgTextService.doSaveOrgText(handout.getHandoutId(), OrgText.TABLE_NAME_HANDOUT, newhandout.getRemark()); // 更新统计表讲义名字 updateHandoutStatisticName(handout.getHandoutId(), handout.getName()); /* * if ("class".equals(type)) { return new Result(true); } String hql = * " from SchHandout where handoutId != ? and originHandoutId = ?"; * List lstHandout = find(hql, * CollectionUtils.newList(handout.getHandoutId(), handout.getHandoutId()), * SchHandout.class); List classIds = new ArrayList(); * List origSubjectIds = new ArrayList(); List * handoutIds = new ArrayList(); for (SchHandout schHandout : * lstHandout) { classIds.add(schHandout.getClassId()); * origSubjectIds.add(schHandout.getSubjectId()); * handoutIds.add(schHandout.getHandoutId()); } */ /* * if (classIds.isEmpty() || origSubjectIds.isEmpty()) { return new * Result(true); } hql = * " from SchClassSubject where deleteFlag is false and classId in (:classIds) and origSubjectId in (:origSubjectIds)" * ; Map args = new HashMap(); * args.put("classIds", classIds.toArray()); args.put("origSubjectIds", * origSubjectIds.toArray()); List lstSubject = * findByComplexHql(hql, args, SchClassSubject.class); Map map = new HashMap(); for * (SchClassSubject schClassSubject : lstSubject) { * map.put(schClassSubject.getClassId() + schClassSubject.getOrigSubjectId(), * schClassSubject); } for (SchHandout schHandout : lstHandout) { * * SchClassSubject scs = map.get(schHandout.getClassId() + * schHandout.getSubjectId()); if (scs == null) { continue; } * TraceUtils.setUpdateTrace(schHandout); schHandout.setName(handout.getName()); * schHandout.setSubjectId(scs.getClassSubjectId()); * schHandout.setSubjectName(scs.getName()); this.saveHandout(schHandout); } * * // 保存OrgText —— 讲义详情 orgTextService.doSaveOrgTexts(handoutIds, * OrgText.TABLE_NAME_HANDOUT, newhandout.getRemark()); */ return new Result(true); } /** * 更新统计表讲义名字 * * @param handoutId * @param handoutName */ private void updateHandoutStatisticName(String handoutId, String handoutName) { String hql = " from SchHandoutStatistic where handoutId = ? and deleteFlag is false"; List handoutStatistics = find(hql, CollectionUtils.newList(handoutId), SchHandoutStatistic.class); for (SchHandoutStatistic schHandoutStatistic : handoutStatistics) { schHandoutStatistic.setHandoutName(handoutName); TraceUtils.setUpdateTrace(schHandoutStatistic); save(schHandoutStatistic); } } /** * 得到office 文档是否有密码 * * @param file * @param fileType * @return */ private boolean getDecryptFlag(File file, String fileType) { if ("PPT".equals(fileType.toUpperCase())) { return getPPTDecryptFlag(file); } else if ("PPTX".equals(fileType.toUpperCase())) { return getPPTXDecryptFlag(file); } return false; } /** * ppt 检测是否包含密码 * * @param file * @return */ @SuppressWarnings("unused") private boolean getPPTDecryptFlag(File file) { boolean flag = false; Biff8EncryptionKey.setCurrentUserPassword(null); NPOIFSFileSystem fs = null; try { fs = new NPOIFSFileSystem(file, true); HSLFSlideShow hss = new HSLFSlideShow(fs); IOUtils.closeQuietly(fs); } catch (IOException e) { log.error("PPT: getPPTDecryptFlag IOException :" + e); } catch (EncryptedPowerPointFileException e) { if ("The CurrentUserAtom specifies that the document is encrypted".equals(e.getMessage()) || "Encrypted PowerPoint files are not supported".equals(e.getMessage())) { flag = true; } } catch (Exception e) { log.error("PPT: getPPTDecryptFlag Exception :" + e); } return flag; } /** * pptx 检测是否有密码,07+ 无打开文件密码,有编辑密码,暂时判断不出来 * * @param file * @return */ private boolean getPPTXDecryptFlag(File file) { boolean flag = false; InputStream in = null; POIFSFileSystem fs = null; EncryptionInfo encInfo = null; try { in = new FileInputStream(file); fs = new POIFSFileSystem(in); encInfo = new EncryptionInfo(fs); if (null != encInfo) { Decryptor dec = Decryptor.getInstance(encInfo); if (!dec.verifyPassword(null)) { flag = true; } } } catch (FileNotFoundException e) { log.error("getPPTXDecryptFlag()_获取InputStream 异常:" + e); } catch (IOException e) { log.error("getPPTXDecryptFlag()_获取POIFSFileSystem 异常:" + e); } catch (NullPointerException e) { log.error("getPPTXDecryptFlag()_获取EncryptionInfo,07+ 异常:" + e); } catch (GeneralSecurityException e) { log.error("getPPTXDecryptFlag()_获取verifyPassword 异常:" + e); } catch (Exception e) { log.error("PPTX: getPPTXDecryptFlag Exception :" + e); } return flag; } /** * 使用jacob另存为图片,需要测试多个请求同时调用情况 1.office2013报错,但是用office2013另存為效果最好 * 2.office2007解析不完美,字体偏粗,边上有较明显锯齿,可以用jacob調用 * 3.office2010解析基本正常,但是较于office2013,大字体和边框会有非常少量锯齿(推荐使用) * * info:服务器推荐使用office2010,jacob.jar包更新后如果支持office2013,测试哪个版本会效果更好,可以替换服务器office版本 * * @param file * ppt文件 * @param docPath * oss 存放office文件的路径 * @return */ @Override public List convertPPTToJPG(File file, String docPath, String handoutId) { ActiveXComponent application = null; Dispatch ppt = null; List results = new ArrayList(30); try { if (!file.exists()) { throw new Exception("文件不存在!"); } // 获取另存为图片时的文件 File imgFile = getHandoutImgPath(file.getParentFile().getPath()); log.debug("消息调用JACOB解析ppt成功,进入解析方法,开始初始化JACOB组件!"); ComThread.InitSTA(); log.debug("开始初始化JACOB组件,ComThread.InitSTA()调用成功!"); application = new ActiveXComponent("PowerPoint.Application"); // 默认不可见,但是大文件另存为时,会出现“ESC可取消保存”的进度框,暂时不知道如何不显示进度条 // Dispatch.put(application, "Visible", new Variant(true)); // 打开一个现有的 Presentation 对象 Dispatch ppts = application.getProperty("Presentations").toDispatch(); ppt = Dispatch.call(ppts, "Open", file.getPath(), true, // ReadOnly false, // Untitled指定文件是否有标题 false// WithWindow指定文件是否可见 ).toDispatch(); // 另存为图片 (17):图片类型 // 将web服务器中的ppt另存为图片,调用ppt的另存为方法,图片格式为(幻灯片1.JPG,幻灯片2.JPG...) Dispatch.call(ppt, "SaveAs", imgFile.getPath(), new Variant(17)); // 上传图片到oss服务器并准备需要保存到数据库的handoutpage数据 results = uploadImgPrepareData(imgFile, docPath, handoutId); } catch (ComFailException e) { log.error("ComFailException解析保存ppt异常:" + e, e); } catch (Exception e) { log.error("Exception解析保存ppt异常:" + e, e); } finally { if (ppt != null) { Dispatch.call(ppt, "Close"); } if (application != null) { application.invoke("Quit"); } ComThread.Release(); ComThread.quitMainSTA(); } return results; } /** * 创建另存为图片文件路径,ppt解析的图片存在ppt同级目录image文件夹下,默认命名方式为:幻灯片1.JPG * * @param path * ppt上传到web服务器的路径 * @return */ private File getHandoutImgPath(String path) { File f = new File(path + "/image"); f.mkdirs(); return f; } /** * 将解析后的图片上传到oss,并且返回需要存储到数据库的handoutpage信息 * @param imgFileDir * @param docPath * @param handoutId * @return * @throws IOException */ @SuppressWarnings({ "unchecked", "unused" }) private List uploadImgPrepareData(File imgFileDir, String docPath, String handoutId) throws IOException { List results = Collections.EMPTY_LIST; try { if (imgFileDir != null && imgFileDir.exists()) { String[] filelist = imgFileDir.list(); // 判断是否有另存为的图片 if (null != filelist && filelist.length > 0) { results = new ArrayList(filelist.length); File imgFile; String startPath = ""; int iPosition = docPath.lastIndexOf('/'); if (iPosition != -1) { startPath = docPath.substring(0, iPosition); } int i = 1; for (String strFile : filelist) { // cacheService.set("handout_upload_schedule_"+handoutId, 60, // i*100f/filelist.length); // 直接使用strPath构造imgFile,会导致获取输入流时,报错,file只给文件名,默认为工程目录,和src同级,用全路径构造 imgFile = new File(imgFileDir.getPath() + "/" + strFile); if (imgFile.getName().indexOf(".") != -1) { // 图片文件名 String imgFileName = imgFile.getName().split("\\.")[0]; // 图片文件类型 String imgFileType = imgFile.getName().split("\\.")[1]; if (StringUtils.isNotBlank(imgFileName) && imgFileName.length() > 3) { // prepare image data String ossFileName = imgFileName.substring(3, imgFileName.length()); String destPath = startPath + "/" + ossFileName + "." + imgFileType; // upload data ossService.uplpadImage(imgFile, destPath); // prepare DB data results.add(newHandoutPage(destPath, Integer.parseInt(ossFileName))); } } } } else { log.error("jacob解析失败,无另存为的图片,image文件夹为空:" + imgFileDir.getPath()); return Collections.EMPTY_LIST; } } else { log.error("jacob解析失败,未生成imgFileDir文件夹"); return Collections.EMPTY_LIST; } } finally { FileUtils.deleteDirectory(imgFileDir); } return results; } /** * 使用jpedal转换pdf为图片,默认格式为1.PNG、2.PNG、3.PNG * * @param * * @return */ @SuppressWarnings("unchecked") private List convertPDFToPNG(File file, String module, String handoutId) { // List results = new ArrayList(30); // // 得到转换对象 // ConvertPagesToImages objConvert = new ConvertPagesToImages(file.getPath()); // try { // if (objConvert.openPDFFile()) { // int pageCount = objConvert.getPageCount(); // String webPath = HandoutService.class.getClassLoader().getResource("../../web").getPath(); // // for (int iPage = 1; iPage <= pageCount; iPage++) { // // cacheService.set("handout_upload_schedule_"+handoutId, 60, // // iPage*100f/pageCount); // // 得到解析的每一页图片 // BufferedImage img = objConvert.getPageAsImage(iPage, true); // // // 判断图片是否高大于宽 // int width = img.getWidth(); // int height = img.getHeight(); // BufferedImage handlerImg = null; // if (width < height) { // handlerImg = rotatePdfImg(img, 270, null); // } // // // 上传 // String destPath = "/web/res/img/school/handout/" + file.getParentFile().getName() + "/" + iPage // + ".PNG"; // String directory = webPath + "res/img/school/handout/" + file.getParentFile().getName(); // String path = directory + "/" + iPage + ".PNG"; // // ByteArrayOutputStream baos = new ByteArrayOutputStream(); // ImageIO.write(handlerImg == null ? img : handlerImg, "png", baos); // InputStream is = new ByteArrayInputStream(baos.toByteArray()); // // ossService.uplpadImage(is, "PNG", destPath); // // IOUtils.closeQuietly(baos); // // results.add(newHandoutPage(path, iPage)); // } // } // objConvert.closePDFfile(); // } catch (PdfException e) { // log.error("jpedal解析pdf为图片失败:", e); // return Collections.EMPTY_LIST; // } catch (IOException e) { // log.error("pdf解析为图片失败:", e); // return Collections.EMPTY_LIST; // } finally { // // 删除下载到应用服务器的文档 // fileUploadService.doDeleteTempOssFile(file.getParentFile(), module, ClientUtils.getUserId()); // } return null; } private BufferedImage rotatePdfImg(BufferedImage image, int degree, Color bgcolor) { int degree0 = degree; // 原始图象的宽高 int iwidth = image.getWidth(); int iheight = image.getHeight(); // 处理的宽高 int width = 0; int height = 0; int positionX = 0; int positionY = 0; degree0 = degree0 % 360; if (degree0 < 0) { degree0 = 360 + degree0; } // 将角度转为弧度 double ang = Math.toRadians(degree0); // 确定旋转后的图象的高度和宽度 if (degree0 == 180 || degree0 == 0 || degree0 == 360) { width = iwidth; height = iheight; } else if (degree0 == 90 || degree0 == 270) { width = iheight; height = iwidth; } else { double cosVal = Math.abs(Math.cos(ang)); double sinVal = Math.abs(Math.sin(ang)); width = (int) (sinVal * iheight) + (int) (cosVal * iwidth); height = (int) (sinVal * iwidth) + (int) (cosVal * iheight); } // 确定原点坐标 positionX = (width - iwidth) / 2; positionY = (height - iheight) / 2; BufferedImage rotatedImage = new BufferedImage(width, height, image.getType()); Graphics2D gs = (Graphics2D) rotatedImage.getGraphics(); if (bgcolor == null) { rotatedImage = gs.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT); } else { gs.setColor(bgcolor); gs.fillRect(0, 0, width, height); } AffineTransform at = new AffineTransform(); // 旋转图象 at.rotate(ang, width / 2, height / 2); at.translate(positionX, positionY); AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_BICUBIC); op.filter(image, rotatedImage); return rotatedImage; } /** * 新增HandoutPage对象 * @param path * @param i * @return */ private SchHandoutPage newHandoutPage(String path, int i) { String path0 = path; SchHandoutPage page = new SchHandoutPage(); path0 = path0.replace('\\', '/'); int startIdx = path0.indexOf("/web/"); path0 = path0.substring(startIdx); page.setImgPath(path0); // 旧版本convertPPTToPNG 这里为(i + 1) convertPPTToJPG 为i page.setPageOrder(i); TraceUtils.setCreateTrace(page); return page; } /* * (non-Javadoc) * * @see com.qxueyou.scc.school.service.IHandoutService#deleteHandouts(java.lang. * String[]) */ @Override public Result deleteHandouts(String[] handoutIds) { if (handoutIds.length == 0) { return new Result(false, "参数错误"); } for (String handoutId : handoutIds) { SchHandout interact = read(SchHandout.class, handoutId); interact.setDeleteFlag(true); TraceUtils.setUpdateTrace(interact); this.saveHandout(interact); } return new Result(true); } @Override public Result deleteOrgHandouts(String[] handoutIds, Integer delAll, String orgIds[], String classIds[]) { for (String handoutId : handoutIds) { if ((orgIds != null && orgIds.length != 0) || (classIds != null && classIds.length != 0)) { // 删除需要回撤的讲义 deleteAppoint(handoutId, orgIds, classIds); } else { // 删除讲义 String hql = " from SchHandoutReCourse where handoutId = ? and deleteFlag is false and orgId = ?"; SchHandoutReCourse shr = findUnique(hql, CollectionUtils.newList(handoutId, ClientUtils.getOrgId()), SchHandoutReCourse.class); if (shr != null) { TraceUtils.setUpdateTrace(shr); shr.setDeleteFlag(true); save(shr); this.courseWareService.deleteOrgCourseware(shr.getHandoutId(), shr.getOrgId()); } /* * SchHandout handout = this.read(SchHandout.class, handoutId); if(handout != * null){ TraceUtils.setUpdateTrace(handout); handout.setDeleteFlag(true); * this.saveHandout(handout); } */ // 用户选择同时删除下级讲义 if (delAll == 1) { deleteSub(handoutId, ClientUtils.getOrgId()); } } } return new Result(true); } @SuppressWarnings("unchecked") private void deleteSub(String handoutId, String currOrgId) { // 机构层级视频是没有重新new ,查询出机构下级ID再删关联表 String sql = " select oa.organization_id from organization as oa,organization ob " + " where " + " ob.ORGANIZATION_ID = ? " + " and " + " oa.org_code like CONCAT(ob.org_code,'%' ) " + " and oa.delete_flag is false and ob.delete_flag is false " + " order by oa.level,oa.org_code asc "; List orgIds = this.findBySql(sql, CollectionUtils.newList(currOrgId)); String hql = " from SchHandoutReCourse where handoutId = :handoutId and deleteFlag is false and orgId in (:orgIds)"; Map map = new HashMap(); map.put(HANDOUT_ID, handoutId); map.put("orgIds", orgIds.toArray()); List handoutCourses = findByComplexHql(hql, map, SchHandoutReCourse.class); for (SchHandoutReCourse schHandoutReCourse : handoutCourses) { schHandoutReCourse.setDeleteFlag(true); TraceUtils.setUpdateTrace(schHandoutReCourse); save(schHandoutReCourse); } // 班主任层面视频指定过后都是new 出来的,通过originVideoId 可以查出所有指定过去的视频 hql = "select classId from ClsClass where orgId in (:orgIds) and deleteFlag is false"; map = new HashMap(); map.put("orgIds", orgIds.toArray()); List clsIds = findByComplexHql(hql, map, String.class); if (!clsIds.isEmpty()) { hql = " from SchHandout where originHandoutId = :handoutId and deleteFlag is false and handoutId!=originHandoutId and classId in (:classIds)"; map = new HashMap(); map.put(HANDOUT_ID, handoutId); map.put("classIds", clsIds.toArray()); List lstHandout = findByComplexHql(hql, map, SchHandout.class); for (SchHandout schHandout : lstHandout) { schHandout.setDeleteFlag(true); TraceUtils.setUpdateTrace(schHandout); this.saveHandout(schHandout); } } } private Result deleteAppoint(String handoutId, String orgIds[], String classIds[]) { Map args = new HashMap(); // 删除需要回撤的机构讲义 if (orgIds.length != 0) { String hql = " from SchHandoutReCourse where handoutId = :handoutId and deleteFlag is false and orgId in (:orgIds) and orgId != :currOrgId"; args = new HashMap(); args.put(HANDOUT_ID, handoutId); args.put("orgIds", orgIds); args.put("currOrgId", ClientUtils.getOrgId()); List courses = findByComplexHql(hql, args, SchHandoutReCourse.class); for (SchHandoutReCourse course : courses) { TraceUtils.setUpdateTrace(course); course.setDeleteFlag(true); save(course); this.courseWareService.deleteOrgCourseware(course.getHandoutId(), course.getOrgId()); } } // 删除需要回撤的班主任讲义 if (classIds.length != 0) { args = new HashMap(); args.put(HANDOUT_ID, handoutId); args.put("classIds", classIds); String hql = " from SchHandout where originHandoutId = :handoutId and deleteFlag is false and classId in (:classIds)"; List handouts = findByComplexHql(hql, args, SchHandout.class); for (SchHandout handout : handouts) { TraceUtils.setUpdateTrace(handout); handout.setDeleteFlag(true); this.saveHandout(handout); } } return new Result(true); } /** * 获取讲义列表数据 * * @return */ @Override public List> handoutLst(String tid) { User user = read(User.class, ClientUtils.getUserId()); List handoutLst = null; String hql = ""; List agrs = new ArrayList(); agrs.add(ClientUtils.getClassId()); // 1班主任:获取该班级(class_id)下面的讲师负责课程下的讲义; // 2讲师:获取该讲师(teacher_id)负责课程下的讲义 if (user != null && UserInfoWrapper.ROLE_CHARGER.equals(ClientUtils.getCurrentRole())) { hql = "select h.handoutId,h.name,h.pageCount,h.status,h.subjectId,h.subjectName, h.orderNum, h.remark " + " from SchHandout h " + " where h.deleteFlag is false " + " and h.classId = ?"; } else if (user != null && UserInfoWrapper.ROLE_TEACHER.equals(ClientUtils.getCurrentRole())) { hql = "select h.handoutId,h.name,h.pageCount,h.status,h.subjectId,h.subjectName,h.orderNum, h.remark " + " from SchHandout h " + " where h.deleteFlag is false " + " and h.classId = ?"; } if (StringUtils.isNotBlank(tid)) { // 其他 if ("-1".equals(tid)) { hql = hql.concat( " and not EXISTS (select 1 from SchClassSubject t where t.deleteFlag is false and t.classSubjectId = h.subjectId) "); } else { hql = hql.concat(" and h.subjectId = ?"); agrs.add(tid); } } hql = hql.concat(" ORDER BY h.orderNum ASC"); handoutLst = findwithRawResult(hql, agrs); List> lstMap = new ArrayList>(handoutLst.size()); Map map = null; for (Object[] obj : handoutLst) { map = new HashMap(6); map.put(HANDOUT_ID, obj[0]); map.put("name", obj[1]); map.put("pageCount", obj[2]); map.put("status", obj[3]); map.put("subjectId", obj[4]); map.put("subjectName", obj[5]); map.put("orderNum", obj[6]); map.put("remark", obj[7]); lstMap.add(map); } return lstMap; } /** * 获取机构讲义列表数据 * * @return */ @Override public List> handoutOrgLst(String collegeCourseId, String subjectId) { List handoutLst = null; List args = new ArrayList(); String hql = ""; // 其他 if (("-" + collegeCourseId).equals(subjectId)) { hql = "select v.handoutId,v.name,v.pageCount,v.status,'','','',0,v.subjectId from SchHandout v,SchHandoutReCourse r where v.collegeCourseId = ? and v.deleteFlag is false and r.deleteFlag is false and r.handoutId = v.handoutId and r.orgId = ? and" + " not EXISTS (select 1 from SchSubject t where t.deleteFlag is false and t.subjectId = v.subjectId)"; args.add(collegeCourseId); args.add(ClientUtils.getOrgId()); } else { hql = "select h.handoutId,h.name,h.pageCount,h.status,o.courseCategoryName,o.name,h.subjectName,s.orderNum,h.subjectId " + " from SchHandoutReCourse s , SchHandout h,OrgCollegeCourse o" + " where s.deleteFlag is false and h.deleteFlag is false " + " and o.collegeCourseId = s.collegeCourseId" + " and s.orgId = ?" + " and s.handoutId = h.handoutId "; args.add(ClientUtils.getOrgId()); if (StringUtils.isNotBlank(subjectId)) { hql = hql.concat(" and h.subjectId = ?"); args.add(subjectId); } hql = hql.concat(" and s.collegeCourseId = ? ORDER BY s.orderNum ASC"); args.add(collegeCourseId); } handoutLst = find(hql, args, Object[].class); List> lstMap = new ArrayList>(handoutLst.size()); Map map = null; for (Object[] obj : handoutLst) { map = new HashMap(); map.put(HANDOUT_ID, obj[0]); map.put("name", obj[1]); map.put("pageCount", obj[2]); map.put("status", obj[3]); map.put("courseCategoryName", obj[4]); map.put("courseName", obj[5]); map.put("subjectName", obj[6]); map.put("orderNum", obj[7]); map.put("subjectId", obj[8]); // findAlreadyOrg(map,obj); lstMap.add(map); } return lstMap; } /** * 指定机构讲义 * * @return */ @Override public Result insertAppointHandout(String handoutIds[], String orgIds[], String classIds[], String collegeCourseId) { if (null == handoutIds || handoutIds.length == 0) { return new Result(false, "参数错误"); } // 一次性查询classId对应的orgId Map argsMap = new HashMap(); Map classMap = new HashMap(); if (classIds.length > 0) { String hql = " from ClsClass where classId in (:classIds) and deleteFlag is false"; argsMap = new HashMap(); argsMap.put("classIds", classIds); List classList = findByComplexHql(hql, argsMap, ClsClass.class); // 放入map中 KEY:classId VALUE:orgId for (ClsClass orgClass : classList) { classMap.put(orgClass.getClassId(), orgClass.getOrgId()); } } // 一次性查出handoutId对应的handoutOrder Map orderMap = new HashMap(); String hql = " from SchHandoutReCourse where handoutId in (:handoutIds) and deleteFlag is false and orgId = :currOrgId"; argsMap = new HashMap(); argsMap.put("handoutIds", handoutIds); argsMap.put("currOrgId", ClientUtils.getOrgId()); List handoutCourse = findByComplexHql(hql, argsMap, SchHandoutReCourse.class); for (SchHandoutReCourse schHandoutReCourse : handoutCourse) { orderMap.put(schHandoutReCourse.getHandoutId(), schHandoutReCourse.getOrderNum()); } for (String handoutId : handoutIds) { if (orgIds.length > 0) { // 指定给机构 insertAppointOrg(orgIds, handoutId, collegeCourseId, orderMap); } if (classIds.length > 0) { // 指定给班级 insertAppointClass(classIds, handoutId, classMap, collegeCourseId, orderMap); } } return new Result(true); } /** * 指定给机构 * * @param orgIds * @param handoutId * @param collegeCourseId */ private void insertAppointOrg(String orgIds[], String handoutId, String collegeCourseId, Map orderMap) { String hql = "select orgId from SchHandoutReCourse where handoutId = :handoutId and deleteFlag is false and orgId in (:orgIds)"; Map args = new HashMap(); args.put(HANDOUT_ID, handoutId); args.put("orgIds", orgIds); List strings = findByComplexHql(hql, args, String.class); List orgList = new ArrayList(); for (String orgId : orgIds) { orgList.add(orgId); } // 剔除掉不符合条件的orgId orgList.removeAll(strings); if (orgList.isEmpty()) { return; } for (String orgId : orgList) { SchHandoutReCourse shrc = new SchHandoutReCourse(); shrc.setCollegeCourseId(collegeCourseId); shrc.setDeleteFlag(false); shrc.setHandoutId(handoutId); shrc.setOrderNum(orderMap.get(handoutId)); shrc.setOrgId(orgId); TraceUtils.setCreateTrace(shrc); save(shrc); this.courseWareService.insertOrgCourseware(handoutId, ClientUtils.getOrgId(), orgId, collegeCourseId); } } /** * 指定给班级 * * @param classIds * @param handoutId * @param classMap */ private void insertAppointClass(String classIds[], String handoutId, Map classMap, String collegeCourseId, Map orderMap) { // 章节id Map origChapterMap = new HashMap(); SchHandout handout = read(SchHandout.class, handoutId); String hql = "select classId from SchHandout where deleteFlag is false and originHandoutId = :handoutId and classId in (:classIds)"; Map args = new HashMap(); args.put("classIds", classIds); args.put(HANDOUT_ID, handoutId); List strings = findByComplexHql(hql, args, String.class); List classList = new ArrayList(); for (String classId : classIds) { classList.add(classId); } classList.removeAll(strings); if (classList.isEmpty()) { return; } // 一次性查询班级ID对应的classSubjectId hql = " from SchClassSubject where classId in(:classIds) and origSubjectId = :subjectId and deleteFlag is false"; args = new HashMap(); args.put("classIds", classList.toArray()); args.put("subjectId", handout.getSubjectId()); List lstClassSubject = findByComplexHql(hql, args, SchClassSubject.class); Map subjectMap = new HashMap(); for (SchClassSubject schClassSubject : lstClassSubject) { subjectMap.put(schClassSubject.getClassId(), schClassSubject.getClassSubjectId()); } OrgText oldOrgText = orgTextService.getOrgText(handoutId, OrgText.TABLE_NAME_HANDOUT); for (String classId : classList) { SchHandout sh = new SchHandout(); sh.setDeleteFlag(false); sh.setName(handout.getName()); sh.setPageCount(handout.getPageCount()); sh.setStatus(handout.getStatus()); sh.setTotalCount(handout.getTotalCount()); sh.setPlayCount(0); sh.setClassId(classId); sh.setOriginHandoutId(handoutId); sh.setOrgId(classMap.get(classId)); sh.setFullPath(handout.getFullPath()); sh.setFullLength(handout.getFullLength()); sh.setSubjectId(subjectMap.get(classId)); sh.setSubjectName(handout.getSubjectName()); sh.setCollegeCourseId(collegeCourseId); sh.setOrderNum(1000); sh.setCoverPageUrl(handout.getCoverPageUrl()); sh.setRemark(handout.getRemark()); if (null != origChapterMap.get(classId)) { sh.setChapterId(origChapterMap.get(classId).getChapterId()); } else { sh.setChapterId(null); } TraceUtils.setCreateTrace(sh); this.saveHandout(sh); // 插入OrgText orgTextService.doInsertOrgText(sh.getHandoutId(), OrgText.TABLE_NAME_HANDOUT, oldOrgText == null ? sh.getRemark() : oldOrgText.getContent()); hql = " from SchHandoutPage where handoutId = ? and deleteFlag is false "; List pages = find(hql, CollectionUtils.newList(handoutId), SchHandoutPage.class); for (SchHandoutPage schHandoutPage : pages) { SchHandoutPage page = new SchHandoutPage(); page.setDeleteFlag(false); page.setHandoutId(sh.getHandoutId()); page.setImgPath(schHandoutPage.getImgPath()); page.setPageOrder(schHandoutPage.getPageOrder()); TraceUtils.setCreateTrace(page); save(page); } // 标记班级有讲义 ClsClass cls = read(ClsClass.class, classId); if (cls != null && cls.getHaveHandout() == ClsClass.NOT_HAVE_HANDOUT) { cls.setHaveHandout(ClsClass.HAVE_HANDOUT); save(cls); } } } /* * (non-Javadoc) * * @see * com.qxueyou.scc.school.service.IHandoutService#doStartHandouts(java.lang. * String[]) */ @SuppressWarnings("unused") @Override public Result doStartHandouts(String handoutIds) { if (StringUtils.isEmpty(handoutIds)) { return new Result(false, "参数错误"); } String[] handoutIdArray = handoutIds.split(","); // 发送讲义系统通知 sendSysMsg(handoutIds); for (String handoutId : handoutIdArray) { SchHandout handout = read(SchHandout.class, handoutId); handout.setStatus(SchHandout.STATUS_ISSUED); TraceUtils.setUpdateTrace(handout); this.saveHandout(handout); // 推送消息给学员 Map extras = new HashMap(1); extras.put("senderId", "sys_msg"); extras.put("type", "SYS_MSG"); List> lstUserIdList = this.queryPushUserIds(handout.getClassScheduleId()); if (lstUserIdList.isEmpty()) { return new Result(true); } for (List userIds : lstUserIdList) { // jpushService.doJpushByUserIds(userIds, extras, "有新讲义", "发布了讲义:" + // handout.getName(), "发布了讲义:" + handout.getName()); } } return new Result(true); } /** * 拆分成200人一组 * @param classId * @return */ @SuppressWarnings("null") private List> queryPushUserIds(String classId) { List> result = new ArrayList>(1); // List lstUserIds = userService.getUserLstByClassId(classId); List lstUserIds = null; // 小于200 直接返回 if (lstUserIds.size() < 200) { result.add(lstUserIds); return result; } // 大于200,分批处理 int iSize = lstUserIds.size() / 200; int iLeft = lstUserIds.size() % 200; iSize = iLeft == 0 ? iSize : iSize + 1; List lstSplitUserIds; for (int i = 0; i < iSize; i++) { lstSplitUserIds = new ArrayList(200); // 200 个 if (i < (iSize - 1)) { lstSplitUserIds.addAll(lstUserIds.subList(i * 200, (i + 1) * 200)); } else { // 最后剩下的,可能小于200个 lstSplitUserIds.addAll(lstUserIds.subList(i * 200, lstUserIds.size())); } result.add(lstSplitUserIds); } return result; } /** * 发送讲义系统消息 * @param handoutIds * @return */ private Result sendSysMsg(String handoutIds) { // boolean allSuccess = true; // // ONSMsg msg = new ONSMsg(onsProducer.getTopic()); // // msg.put("msgType", "SYS_HANDOUT_SAVE"); // msg.put("classId", ClientUtils.getClassId()); // msg.put("handoutIds", handoutIds); // try { // onsProducer.sendMsg(msg); // // 消费类:com.qxueyou.scc.school.service.impl.HandoutSysMsgDealService // // } catch (Exception e) { // log.error("call DocdealMsgSendService fail.userId: " + // ClientUtils.getClassId(), e); // allSuccess = false; // } return new Result(false); } /* * (non-Javadoc) * * @see com.qxueyou.scc.school.service.IHandoutService#doStopHandouts(java.lang. * String[]) */ @Override public Result doStopHandouts(String[] handoutIds) { if (handoutIds.length == 0) { return new Result(false, "参数错误"); } for (String handoutId : handoutIds) { SchHandout interact = read(SchHandout.class, handoutId); interact.setStatus(SchHandout.STATUS_DISCARD); TraceUtils.setUpdateTrace(interact); this.saveHandout(interact); } return new Result(true); } /** * 插入历史讲义 * * @param handout * @param oldHandoutId * @return */ @Override public Result insertChooseHandout(SchHandout handout, String oldHandoutId) { SchHandout oldSchHandout = read(SchHandout.class, oldHandoutId); List handoutPages = oldSchHandout.getHandoutPages(); TraceUtils.setCreateTrace(handout); handout.setPageCount(oldSchHandout.getPageCount()); handout.setName(oldSchHandout.getName()); handout.setStatus(SchHandout.STATUS_DRAFT); handout.setClassId(ClientUtils.getClassId()); handout.setOrgId(oldSchHandout.getOrgId()); handout.setOrderNum(oldSchHandout.getOrderNum()); handout.setCoverPageUrl(oldSchHandout.getCoverPageUrl()); handout.setFullPath(oldSchHandout.getFullPath()); handout.setFullLength(oldSchHandout.getFullLength()); handout.setPlayCount(0); handout.setCollegeCourseId(ClientUtils.getCourseId()); this.saveHandout(handout); List newHandoutPages = new ArrayList(); for (SchHandoutPage page : handoutPages) { SchHandoutPage newPage = new SchHandoutPage(); TraceUtils.setCreateTrace(newPage); newPage.setHandoutId(handout.getHandoutId()); newPage.setImgPath(page.getImgPath()); newPage.setPageOrder(page.getPageOrder()); newHandoutPages.add(newPage); } saveOrUpdateAll(newHandoutPages); return new Result(true); } /** * 拷贝讲义 * @param oldHandoutId * @param subjectId * @param collegeCourseId * @param chapterId * @param subjectName * @return * @throws IllegalAccessException * @throws InstantiationException * @throws InvocationTargetException * @throws NoSuchMethodException */ @Override public Result doCopyHandout(String oldHandoutId, String subjectId, String collegeCourseId, String chapterId, String subjectName) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException { SchHandout oldSchHandout = read(SchHandout.class, oldHandoutId); List handoutPages = oldSchHandout.getHandoutPages(); oldSchHandout.setHandoutPages(null); SchHandout newHandout = (SchHandout) BeanUtils.cloneBean(oldSchHandout); newHandout.setHandoutId(null); TraceUtils.setCreateTrace(newHandout); newHandout.setChapterId(chapterId); newHandout.setSubjectId(subjectId); newHandout.setSubjectName(subjectName); newHandout.setOrderNum(1000); newHandout.setCollegeCourseId(collegeCourseId); newHandout.setStatus(SchHandout.STATUS_DRAFT); newHandout.setPlayCount(0); this.saveHandout(newHandout); List newHandoutPages = new ArrayList(); if (!handoutPages.isEmpty()) { for (SchHandoutPage page : handoutPages) { SchHandoutPage newPage = (SchHandoutPage) BeanUtils.cloneBean(page); TraceUtils.setCreateTrace(newPage); newPage.setHandoutId(newHandout.getHandoutId()); newPage.setHandoutPageId(null); newHandoutPages.add(newPage); } saveOrUpdateAll(newHandoutPages); } // 非班级拷贝需要关联表新增记录 if (StringUtils.isEmpty(ClientUtils.getClassId())) { this.insertReCourse(collegeCourseId, newHandout.getHandoutId()); } return new Result(true); } /** * 插入讲义和科目关联 * * @param collegeCourseId * @param handoutId */ private void insertReCourse(String collegeCourseId, String handoutId) { // 序号 String hql = "select MAX(c.orderNum) from SchHandoutReCourse c where c.deleteFlag is false and c.collegeCourseId = ? and orgId = ? "; Integer iMax = this.findUnique(hql, CollectionUtils.newList(collegeCourseId, ClientUtils.getOrgId()), Integer.class); if (iMax == null || iMax == 0) { iMax = 1; } else { iMax = iMax + 1; } SchHandoutReCourse course = new SchHandoutReCourse(); course.setCollegeCourseId(collegeCourseId); course.setDeleteFlag(false); course.setHandoutId(handoutId); course.setOrderNum(iMax); course.setOrgId(ClientUtils.getOrgId()); TraceUtils.setCreateTrace(course); save(course); } /** * 查询讲义列表 * * @param hql * @param args * @return */ @Override public List schHandoutList(int type, String hql, Pager page, List args) { return handoutDAO.schHandoutList(type, hql, page, args); } /** * 批量操作讲义收藏记录 * * @param lstFavor * @return */ @Override public Result doOperHandoutFavorDataBatch(List lstFavor) { // 批量增加或者更新 this.saveOrUpdateAll(lstFavor); return new Result(true); } /** * 后台获取列表数据 * * @param sql * @param args * @return */ @Override public List queryDataList(String sql, List args) { return handoutDAO.queryDataList(sql, args); } /** * 查询选择班级下历史讲义 * @param sql * @param args * @return */ @Override public List queryChooseHandoutList(String sql, List args) { return null; // handoutDAO.queryChooseList(sql, args); } private Result doInitClassHandout(SchHandout handout, List lstPages) { String hql = " from SchHandout s where s.originHandoutId = ? and s.originHandoutId <> s.handoutId and deleteFlag is false "; List handouts = this.find(hql, CollectionUtils.newList(handout.getHandoutId()), SchHandout.class); if (null == handouts || handouts.isEmpty()) { return new Result(true, "无关联讲义"); } List allPages = new ArrayList(); // 循环处理 for (SchHandout ho : handouts) { TraceUtils.setUpdateTrace(ho); ho.setStatus(handout.getStatus()); ho.setPageCount(handout.getPageCount()); allPages.addAll(this.initCurrPages(lstPages, ho.getHandoutId())); this.saveHandout(ho); } // 明细 this.saveOrUpdateAll(allPages); return new Result(true); } /** * 赋值所有讲义明细 * * @param lstPages * @param handoutId * @return */ private List initCurrPages(List lstPages, String handoutId) { List currPages = new ArrayList(lstPages.size()); SchHandoutPage page = null; for (SchHandoutPage currPage : lstPages) { page = new SchHandoutPage(); page.setDeleteFlag(false); page.setHandoutId(handoutId); page.setImgPath(currPage.getImgPath()); page.setPageOrder(currPage.getPageOrder()); TraceUtils.setCreateTrace(page); currPages.add(page); } return currPages; } /** * 旋转讲义图片 * * @param angle * @param handoutPageId * @return */ @Override public Result doRotatePic(String angle, String handoutPageId) { SchHandoutPage page = this.read(SchHandoutPage.class, handoutPageId); if (null == page) { return new Result(false, "page为空"); } String imgPath = page.getImgPath(); int iIndex = imgPath.indexOf('@'); if (iIndex != -1) { imgPath = imgPath.substring(0, iIndex); } if (StringUtils.isBlank(imgPath)) { return new Result(false, "path解析出错"); } imgPath = imgPath.concat("@").concat(angle).concat("r"); page.setImgPath(imgPath); save(page); return new Result(true); } /** * 查询讲义,模糊课程名或者讲义名 * * @param keyWord * 查询关键字 * @return */ @Override public List queryHandoutByKeyWord(String keyWord) { String keyWord0 = keyWord; String sql = "select h.* from sch_handout h,sch_class_schedule l where " + "l.class_schedule_id = h.class_schedule_id and l.delete_flag = 0 and h.delete_flag = 0 " + "and h.class_id = ? " + "and ( h.lesson like ? or h.name like ? ) "; keyWord0 = "%".concat(keyWord0).concat("%"); return handoutDAO.queryDataList(sql, CollectionUtils.newList(ClientUtils.getClassId(), keyWord0, keyWord0)); } /** * 更新讲义观看量 */ public Result updatePlayCount(String handoutId) { SchHandout sh = read(SchHandout.class, handoutId); if (null == sh) { return new Result(true); } if (sh.getPlayCount() == null) { bulkUpdateInLoop("update SchHandout set playCount = 1 where handoutId = ?", new String[] { handoutId }); } else { bulkUpdateInLoop("update SchHandout set playCount = (playCount + 1) where handoutId = ?", new String[] { handoutId }); } return new Result(true); } @Override public Result insertplayRecordNew(SchHandoutRecord record, String pageNums) { SchHandout sh = read(SchHandout.class, record.getHandoutId()); if (null == sh) { return new Result(true); } record.setOrgId(ClientUtils.getOrgId()); record.setClassId(ClientUtils.getClassId()); record.setUserId(ClientUtils.getUserId()); String[] nums = pageNums.split(","); record.setPlayCount(nums.length); record.setPageCount(sh.getPageCount()); record.setDeleteFlag(false); TraceUtils.setCreateTrace(record); save(record); List numList = new ArrayList(); for (String num : nums) { numList.add(Integer.parseInt(num)); } String hql = " from SchHandoutPage where pageOrder in (:nums) and handoutId = :handoutId"; Map args = new HashMap(); args.put("nums", numList.toArray()); args.put(HANDOUT_ID, sh.getHandoutId()); List lstPages = findByComplexHql(hql, args, SchHandoutPage.class); Map map = new HashMap(); for (SchHandoutPage schHandoutPage : lstPages) { map.put(schHandoutPage.getPageOrder() + schHandoutPage.getHandoutId(), schHandoutPage); } for (String string : nums) { SchHandoutRecordDetail shrd = new SchHandoutRecordDetail(); shrd.setDeleteFlag(false); shrd.setHandoutRecordId(record.getHandoutRecordId()); shrd.setPageNum(Integer.parseInt(string)); if (null != record.getType()) { shrd.setCollection(record.getType()); } SchHandoutPage shp = map.get(string + sh.getHandoutId()); shrd.setPageId(shp.getHandoutPageId()); TraceUtils.setCreateTrace(shrd); save(shrd); } // 统计表增加数据 hql = " from SchHandoutStatistic where userId=? and classId=? and handoutId=?"; SchHandoutStatistic shs = findUnique(hql, CollectionUtils.newList(ClientUtils.getUserId(), ClientUtils.getClassId(), sh.getHandoutId()), SchHandoutStatistic.class); if (shs == null) { shs = new SchHandoutStatistic(); shs.setClassId(ClientUtils.getClassId()); shs.setCompDegree(new BigDecimal(record.getPlayCount()).divide(new BigDecimal(record.getPageCount()), 2, BigDecimal.ROUND_HALF_UP)); shs.setDeleteFlag(false); shs.setHandoutId(record.getHandoutId()); shs.setHandoutName(sh.getName()); shs.setUserId(ClientUtils.getUserId()); shs.setUserName(ClientUtils.getUserName()); TraceUtils.setCreateTrace(shs); save(shs); } else { hql = "select DISTINCT d.PAGE_NUM from sch_handout_record_detail d where d.HANDOUT_RECORD_ID in " + "( select r.HANDOUT_RECORD_ID from sch_handout_record r where USER_ID=? and CLASS_ID=? and HANDOUT_ID=?)"; List pageLst = handoutDAO.schHandoutPageNum(hql, CollectionUtils.newList(ClientUtils.getUserId(), ClientUtils.getClassId(), record.getHandoutId())); Set set = new HashSet(); // 本次观看 for (String string2 : nums) { set.add(string2); } // 数据库观看记录 set.addAll(pageLst); shs.setCompDegree(new BigDecimal(set.size()).divide(new BigDecimal(record.getPageCount()), 2, BigDecimal.ROUND_HALF_UP)); TraceUtils.setUpdateTrace(shs); save(shs); } return new Result(true); } @Override public Result insertplayRecord(SchHandoutRecord record, String pageNums) { return this.insertplayRecordNew(record, pageNums); } /** * 讲义上传重复数据处理 * * @param handoutId * @return */ @Override public Result doInitHandoutRepeatData(String handoutId) { String hql = "select max(p.handoutPageId) from SchHandoutPage p where p.deleteFlag is false and p.handoutId = ? group by p.handoutId, p.pageOrder having count(1) > 1 "; List pageIds = this.find(hql, CollectionUtils.newList(handoutId), String.class); if (null == pageIds || pageIds.isEmpty()) { return new Result(true); } List pages = new ArrayList(pageIds.size()); SchHandoutPage page; for (String pageId : pageIds) { page = this.read(SchHandoutPage.class, pageId); page.setDeleteFlag(true); pages.add(page); } this.saveOrUpdateAll(pages); return new Result(true); } /** * 排序 * * @param ids * 排序id * @param index * 序号 * @return */ public Result doOrder(List ids, List index) { // 循环修改order CommonDAO commonDAO = this.getCommonDAO(); for (int i = 0; i < ids.size(); i++) { String handoutId = ids.get(i); if (UserInfoWrapper.ROLE_TEACHER.equals(ClientUtils.getCurrentRole()) || UserInfoWrapper.ROLE_CHARGER.equals(ClientUtils.getCurrentRole())) { commonDAO.bulkUpdate("update SchHandout set orderNum = " + index.get(i) + " where handoutId = ?", new Object[] { handoutId }); } else { commonDAO.bulkUpdate( "update SchHandoutReCourse set orderNum = " + index.get(i) + " where handoutId = ?", new Object[] { handoutId }); } commonDAO.bulkUpdate("update SchCourseware set orderNum = " + index.get(i) + " where id = ?", new Object[] { handoutId }); } return new Result(true); } /** * 保存讲义接口 * * @param handout * @return */ public Result saveHandout(SchHandout handout) { Result result = new Result(false); result = this.save(handout); String parentChapterId = null; if (StringUtils.isNotEmpty(handout.getChapterId())) { SubjectChapter chapter = this.read(SubjectChapter.class, handout.getChapterId()); parentChapterId = chapter == null ? null : chapter.getParentChapterId(); } boolean isClass = StringUtils.isNotEmpty(ClientUtils.getClassId()) || StringUtils.isNotEmpty(handout.getClassId()); SchCourseware courseware = null; if (isClass) { courseware = this.findUnique("from SchCourseware where id = ? and classId = ? and deleteFlag is false", CollectionUtils.newList(handout.getHandoutId(), handout.getClassId()), SchCourseware.class); } else { courseware = this.findUnique( "from SchCourseware where id = ? and orgId = ? and classId is null and deleteFlag is false", CollectionUtils.newList(handout.getHandoutId(), handout.getOrgId()), SchCourseware.class); this.bulkUpdate("update SchCourseware set name = ? where id = ?", new Object[] { handout.getName(), handout.getHandoutId() }); } if (courseware == null) { courseware = new SchCourseware(); courseware.setChapterId(handout.getChapterId()); courseware.setId(handout.getHandoutId()); courseware.setCollegeCourseId(handout.getCollegeCourseId()); courseware.setcType(-1); courseware.setType(SchCourseware.COURSEWARE_TYPE_HANDOUT); courseware.setName(handout.getName()); courseware.setRemark(String.valueOf(handout.getPageCount())); courseware.setDeleteFlag(handout.getDeleteFlag()); courseware.setOrderNum(1000); courseware.setSubjectId(handout.getSubjectId()); courseware.setStatus(handout.getStatus()); courseware.setOrgId(handout.getOrgId()); courseware.setClassId(handout.getClassId()); courseware.setParentChapterId(parentChapterId); TraceUtils.setCreateTrace(courseware); } else { courseware.setChapterId(handout.getChapterId()); // courseware.setCollegeCourseId(handout.getCollegeCourseId()); courseware.setcType(-1); courseware.setName(handout.getName()); courseware.setRemark(String.valueOf(handout.getPageCount())); courseware.setDeleteFlag(handout.getDeleteFlag()); courseware.setOrderNum(handout.getOrderNum() == null ? 1000 : handout.getOrderNum()); courseware.setSubjectId(handout.getSubjectId()); courseware.setStatus(handout.getStatus()); courseware.setParentChapterId(parentChapterId); TraceUtils.setUpdateTrace(courseware); } this.save(courseware); return result; } }