package com.qxueyou.scc.school.service.impl; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.imageio.ImageIO; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.poi.util.IOUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.stereotype.Service; import com.alibaba.fastjson.JSON; import com.qxueyou.scc.base.model.Pager; import com.qxueyou.scc.base.model.Result; 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.TraceUtils; import com.qxueyou.scc.base.util.UUIDUtils; import com.qxueyou.scc.config.AliOssConfig; import com.qxueyou.scc.school.model.SchStudyReport; import com.qxueyou.scc.school.service.IStudyReportService; import com.qxueyou.scc.school.util.StudyReportUtils; //import com.qxueyou.scc.sys.service.IOssService; import com.qxueyou.scc.user.model.User; import com.qxueyou.scc.user.model.UserRegistration; /** * 学习报告查询及生成接口,如果存在,则直接查询,否则根据各类数据生成 * @author xiadehu * */ @Service("StudyReportService") @EnableConfigurationProperties(AliOssConfig.class) public class StudyReportService extends CommonAppService implements IStudyReportService { // @Autowired // ICacheService cache; // // @Autowired // IOssService oss; @Autowired AliOssConfig aliOssConfig; private static final Logger log = LogManager.getLogger("StudyReportService"); @Override public Result doGetOrCreateStudyReport() { String hql = "from SchStudyReport where userId=? and deleteFlag is false"; SchStudyReport report = findUnique(hql, CollectionUtils.newList(ClientUtils.getUserId()), SchStudyReport.class); if (report == null) { report = createReport(); } return new Result(true, null, toMapByReport(report)); } /** * 创建新的学习报告 * 汇聚各类数据 * * @return */ private SchStudyReport createReport() { SchStudyReport report = new SchStudyReport(); TraceUtils.setCreateTrace(report); User user = read(User.class, ClientUtils.getUserId()); report.setUserId(user.getUserId()); report.setName(user.getName()); report.setStudentOrder(getStudyOrder(user.getCreateTime())); report.setStudyPeriod(getStudyPeriod(user.getCreateTime())); report.setCourseCount(getCourseCount(user.getUserId())); setFirstCourseAndClass(report); report.setStudyHandoutCount(getStudyHandoutCount(user.getUserId())); report.setStudyVideoCount(getStudyVideoCount(user.getUserId())); report.setViewLiveCount(getViewLiveCount(user.getUserId())); setExerciseData(report); setAtsData(report); setOrgs(report); setRecCourses(report); setStudyTime(report); save(report); return report; } private int getStudyPeriod(Date createTime) { Calendar cal = Calendar.getInstance(); cal.setTime(createTime); long time1 = cal.getTimeInMillis(); long between_days=(System.currentTimeMillis()-time1)/(1000*3600*24); return Integer.parseInt(String.valueOf(between_days)); } /** * 统计出用户集中学习的时间段,选取排名靠前的三个时间段(每个时间段1小时)进行显示 * @param report */ private void setStudyTime(SchStudyReport report) { List> result = queryStudyTime(); //从0点到23点,统计每个时间段学习的次数 int[] hours = new int[24]; int h=0; int num = 0; int count = 0; for(Map item:result){ h = (Integer)item.get("h"); num = ((Long)item.get("num")).intValue(); hours[h]=hours[h]+num; count = count + num; } //计算出前三 int[][] most3 = new int[][]{{0,0},{0,0},{0,0}}; for(int i=0;i<24;i++){ for(int j=0;j<3;j++){ if(hours[i]>most3[j][0]){ most3[j][0]=hours[i]; most3[j][1]=i; break; } } } List> data = new ArrayList>(); //返回前三(非零)的数据 for(int j=0;j<3;j++){ if(most3[j][0]>0){ data.add(CollectionUtils.newObjectMap( "name",getTimeAlias(most3[j][1]), "timeFrom",most3[j][1], "timeTo",most3[j][1]+1, "percent",String.format("%.1f%%",(double)most3[j][0]/count*100))); } } report.setStudyTime(JSON.toJSONString(data)); report.setStudyTimeImg(createImg(data)); } private String createImg(List> data) { ByteArrayOutputStream os=null; InputStream is=null; try { BufferedImage img = StudyReportUtils.drawPng(180, 180, data); os = new ByteArrayOutputStream(); ImageIO.write(img, "png", os); is = new ByteArrayInputStream(os.toByteArray()); String destPath = "/web/res/img/studyreport/"+ClientUtils.getUserId()+"/"+UUIDUtils.generateUUID()+".png"; // oss.uplpadImage(is, "PNG", destPath); return destPath; } catch (IOException e) { log.error(e,e); } finally{ IOUtils.closeQuietly(is); IOUtils.closeQuietly(os); } return null; } /** * 查询练习、讲义、视频学习的时间统计数据 * @return */ private List> queryStudyTime() { String hql1 = " select hour(createTime) as h,count(1) as num from ExerciseItemAnalisiU where userId=:userId group by hour(createTime) "; String hql2 = " select hour(createTime) as h,count(1) as num from MediaVideoLiveRecord where userId=:userId group by hour(createTime) "; String hql3 = " select hour(createTime) as h,count(1) as num from MediaVideoRecord where userId=:userId group by hour(createTime) "; List> r1 = findListWithMapByHql(hql1, CollectionUtils.newObjectMap("userId",ClientUtils.getUserId())); List> r2 = findListWithMapByHql(hql2, CollectionUtils.newObjectMap("userId",ClientUtils.getUserId())); List> r3 = findListWithMapByHql(hql3, CollectionUtils.newObjectMap("userId",ClientUtils.getUserId())); r1.addAll(r2); r1.addAll(r3); return r1; } private String getTimeAlias(int hour){ if(hour<3){ return "深夜"; } if(hour<6){ return "凌晨"; } if(hour<12){ return "早上"; } if(hour<14){ return "中午"; } if(hour<18){ return "下午"; } if(hour<24){ return "晚上"; } return null; } private void setRecCourses(SchStudyReport report) { String hql = " select cls.orgId from UserRegistration reg,ClsClass cls where reg.userId=? and reg.status=? and reg.deleteFlag is false " + " and reg.classId=cls.classId order by reg.activationTime desc"; String orgId = findUnique(hql, CollectionUtils.newList( ClientUtils.getUserId(),UserRegistration.STATUS_ACTIVE), String.class); hql = " select code from Organization where organizationId=?"; String code = findUnique(hql, CollectionUtils.newList( orgId), String.class); hql = "select org.logoPath as imgPath,cls.name as name, org.name as orgName,concat('/transact/class/view/',cls.classId) as clickUrl from ClsClass cls,Organization org "+ "where cls.deleteFlag is false and cls.recommend is true and cls.orgId=:orgId and org.organizationId=cls.orgId " + "order by cls.studentCount desc,cls.clickNum desc"; List> data = findListWithMapByHql(hql, CollectionUtils.newObjectMap( "orgId",orgId),new Pager(3,1)); report.setRecCourses(JSON.toJSONString(data)); report.setMoreRecUrl("/weixin/qxueyou/redirect?orgCode="+code+"&routerUrl=/course/market"); } private void setOrgs(SchStudyReport report) { String hql = " select distinct org.name as name,org.logoPath as logoUrl from UserRegistration reg,ClsClass cls,Organization org " + "where reg.classId=cls.classId and cls.orgId=org.organizationId " + "and reg.userId=:userId and reg.deleteFlag is false and reg.status=:status"; List> data = findListWithMapByHql(hql, CollectionUtils.newObjectMap( "userId",ClientUtils.getUserId(), "status",UserRegistration.STATUS_ACTIVE),new Pager(10,1)); report.setOrgs(JSON.toJSONString(data)); } /** * 设置传播大使数据 * @param report */ @SuppressWarnings("unchecked") private void setAtsData(SchStudyReport report) { String hql = "select className from AtsShare where userId=? and deleteFlag is false order by shareTime"; String className = findUnique(hql, CollectionUtils.newList( ClientUtils.getUserId()), String.class); report.setFirstShareCourse(className); hql = "select sum(viewCount) as c from AtsShare where userId=? and deleteFlag is false"; BigDecimal count= findUnique(hql, CollectionUtils.newList(ClientUtils.getUserId()), BigDecimal.class); report.setViewCountOfShare(count==null?0:count.intValue()); hql = "select allBalance from TransAccount where userId=? and deleteFlag is false and accountTypeId=4"; BigDecimal allBalance= findUnique(hql, CollectionUtils.newList(ClientUtils.getUserId()), BigDecimal.class); report.setAwardAmountOfShare(allBalance); hql = "select count(1) from TransAccount where deleteFlag is false and accountTypeId=3"; int accountTotal= ((Number) findUnique(hql, Collections.EMPTY_LIST, Number.class)).intValue(); hql = "select his.rank from SchRankHis his,SchRankVer ver where his.versionId=ver.versionId and ver.rankType='ATS_SCORE' and his.userId=?"; Number rankN = findUnique(hql, CollectionUtils.newList(ClientUtils.getUserId()), Number.class); int rank= rankN==null?0:rankN.intValue(); report.setAtsOrder(BigDecimal.valueOf((double)(accountTotal-rank)/accountTotal)); } private void setExerciseData(SchStudyReport report) { String hql = "select count(distinct exerciseItemId) as c,coalesce(avg(accuracy),0) as accuracy from ExerciseItemAnalisiU where userId=:userId and deleteFlag is false"; List> data = findListWithMapByHql(hql, CollectionUtils.newObjectMap("userId",ClientUtils.getUserId())); if(data.isEmpty()){ report.setDoExerciseCount(0); report.setExerciseAccuracy(BigDecimal.ZERO); report.setAccuracyOrder(BigDecimal.valueOf(800000+(int)Math.random()*400000)); return; } report.setDoExerciseCount(((Long)(data.get(0).get("c"))).intValue()); report.setExerciseAccuracy(BigDecimal.valueOf((Double)data.get(0).get("accuracy"))); hql = "select count(1) from SchStudyReport where exerciseAccuracy>? and deleteFlag is false"; int order= findUnique(hql, CollectionUtils.newList(report.getExerciseAccuracy()), Number.class).intValue(); report.setAccuracyOrder(BigDecimal.valueOf(order)); } private int getViewLiveCount(String userId) { String hql = "select count(liveId) from MediaVideoLiveRecord where userId=? and deleteFlag is false"; return findUnique(hql, CollectionUtils.newList(userId), Number.class).intValue(); } private int getStudyVideoCount(String userId) { String hql = "select count(videoId) from MediaVideoRecord where userId=? and deleteFlag is false"; return findUnique(hql, CollectionUtils.newList(userId), Number.class).intValue(); } private int getStudyHandoutCount(String userId) { String hql = "select count(handoutId) from SchHandoutRecord where userId=? and deleteFlag is false"; return findUnique(hql, CollectionUtils.newList(userId), Number.class).intValue(); } private int getCourseCount(String userId) { String hql = "select count(classId) from UserRegistration where userId=? and deleteFlag is false and status=?"; return findUnique( hql, CollectionUtils.newList(userId, UserRegistration.STATUS_ACTIVE), Number.class).intValue(); } private void setFirstCourseAndClass(SchStudyReport report) { String hql = "select classId from UserRegistration where userId=? and deleteFlag is false and status=? order by activationTime"; String classId = findUnique(hql, CollectionUtils.newList( ClientUtils.getUserId(), UserRegistration.STATUS_ACTIVE), String.class); hql = "select coalesce(cls.name,'') as className,coalesce(cls.collegeCourseName,'') as courseName from ClsClass cls " + "where cls.classId=:classId and cls.deleteFlag is false"; List> cou = findListWithMapByHql(hql, CollectionUtils.newObjectMap("classId",classId)); if(cou==null||cou.isEmpty()){ return; } report.setFirstClass((String)cou.get(0).get("className")); report.setFirstCourse((String)cou.get(0).get("courseName")); } private int getStudyOrder(Date createTime) { String hql = "select count(1) from User where createTime toMapByReport(SchStudyReport report) { String resDomain = aliOssConfig.getDomain(); Map result = new HashMap(); result.put("resDomain", resDomain); result.put("name", report.getName()); result.put("studentOrder", report.getStudentOrder()); result.put("studyPeriod", report.getStudyPeriod()); result.put("courseCount", report.getCourseCount()); result.put("firstCourse", report.getFirstCourse()); result.put("firstClass", report.getFirstClass()); result.put("studyHandoutCount", report.getStudyHandoutCount()); result.put("studyVideoCount", report.getStudyVideoCount()); result.put("viewLiveCount", report.getViewLiveCount()); result.put("doExerciseCount", report.getDoExerciseCount()); result.put("exerciseAccuracy", report.getExerciseAccuracy()); result.put("accuracyOrder", report.getAccuracyOrder()); result.put("firstShareCourse", report.getFirstShareCourse()); result.put("viewCountOfShare", report.getViewCountOfShare()); result.put("awardAmountOfShare", report.getAwardAmountOfShare()); result.put("atsOrder", report.getAtsOrder()); result.put("studyTime", JSON.parse(report.getStudyTime())); result.put("setStudyTimeImg",report.getStudyTimeImg()); result.put("orgs", JSON.parse(report.getOrgs())); result.put("recCourses", JSON.parse(report.getRecCourses())); result.put("moreRecUrl", report.getMoreRecUrl()); result.put("atsWithAwardCount", getatsWithAwardCount()); return result; } private Integer getatsWithAwardCount() { // Long atsWithAwardCount = cache.get("school/studyReport/atsWithAwardCount", Long.class); // if(atsWithAwardCount!=null){ // return atsWithAwardCount.intValue(); // } String hql = "select count(1) from TransAccount where userId=? and allBalance>0 and deleteFlag is false and accountTypeId=4"; Number c= findUnique(hql, CollectionUtils.newList(ClientUtils.getUserId()), BigDecimal.class); // cache.set("school/studyReport/atsWithAwardCount",3600*3, c); return c.intValue(); } }