• 课时统计


    项目是是应用springmvc 框架

    java,类。控制层

    package com.school.web.controller.nini;
    
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.List;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.ServletRequestUtils;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;
    
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.school.business.StatisticsDurationCuManager;
    import com.school.domain.StatisticsDurationCourse;
    import com.school.util.PageRequest;
    import com.school.util.Pageable;
    import com.school.util.Paginator;
    
    @Controller
    @RequestMapping("/secure/course/statistics")
    public class StatisticsDurationCuController extends AbstractSecureController {
    
        @Autowired
        private StatisticsDurationCuManager statisticsDurationCuManager;
    
        /**
         * 依据一门课程学员分组去统计时长。

    */ @RequestMapping("/{courseId}/duration") public ModelAndView getStuOneCourseDur(@PathVariable String courseId, HttpServletRequest request) { String schoolId = this.getSchoolId(request); // 网校ID int page = ServletRequestUtils.getIntParameter(request, "page", 1); // 第几页 // 分页查询该课程的全部学员 Pageable pageable = new PageRequest(page, PAGE_SIZE); Paginator<StatisticsDurationCourse> paginator = statisticsDurationCuManager.getDurationByCourse(schoolId, courseId, pageable); // 模版视图 ModelAndView mav = this.createCourseModelAndView(courseId, request); mav.setViewName(getSecureViewDir(request) + "/courseStatistics/students"); String queryString = null; mav.addObject("paginator", paginator); mav.addObject("paginationHtml", paginator.toPaginationHtml(queryString)); return mav; } /** * 依据一门课程学员分组去统计时长的详情。

    (分页) */ @RequestMapping("/{courseId}/duration/{userId}/detailed") public ModelAndView getStuOneCourseDurDetail(@PathVariable String courseId, @PathVariable String userId, HttpServletRequest request) { String schoolId = this.getSchoolId(request); // 网校ID String nickname = ServletRequestUtils.getStringParameter(request, "nickname", ""); String duration = ServletRequestUtils.getStringParameter(request, "duration", ""); String count = ServletRequestUtils.getStringParameter(request, "count", ""); int page = ServletRequestUtils.getIntParameter(request, "page", 1); // 第几页 // 分页查询 Pageable pageable = new PageRequest(page, PAGE_SIZE); Paginator<StatisticsDurationCourse> paginator = statisticsDurationCuManager.getDurByCourseDetailPage(schoolId, courseId, userId, pageable); // 模版视图 ModelAndView mav = this.createCourseModelAndView(courseId, request); mav.setViewName(getSecureViewDir(request) + "/courseStatistics/detailed"); String url = "/secure/course/statistics/" + courseId + "/duration/" + userId + "/detailed"; String queryString = null; mav.addObject("paginator", paginator); mav.addObject("paginationHtml", paginator.toPaginationHtml(url, queryString)); mav.addObject("nickname", nickname); mav.addObject("courseId", courseId); mav.addObject("userId", courseId); mav.addObject("duration", duration); mav.addObject("count", count); return mav; } /** * 依据一门课程学员分组去统计时长的详情。

    (不分页) */ @RequestMapping("/{courseId}/duration/{userId}/detailed/list") public ModelAndView getStuOneCoDurDetailList(@PathVariable String courseId, @PathVariable String userId, HttpServletRequest request) { String schoolId = this.getSchoolId(request); // 网校ID String nickname = ServletRequestUtils.getStringParameter(request, "nickname", ""); List<StatisticsDurationCourse> durationList = statisticsDurationCuManager.getDurByCourseDetailed(schoolId, courseId, userId); // 模版视图 ModelAndView mav = this.createCourseModelAndView(courseId, request); mav.setViewName(getSecureViewDir(request) + "/courseStatistics/detailed"); mav.addObject("durationList", durationList); mav.addObject("nickname", nickname); return mav; } /** * 一门课程近期30天的时长统计 * @throws IOException * @throws ParseException */ @RequestMapping("/{courseId}/duration/day") public ModelAndView getCourseDurationDay(@PathVariable String courseId, HttpServletRequest request) throws IOException, ParseException { String schoolId = this.getSchoolId(request); // 网校ID String type = ServletRequestUtils.getStringParameter(request, "type", ""); String startDate = ServletRequestUtils.getStringParameter(request, "startDate", ""); String endDate = ServletRequestUtils.getStringParameter(request, "endDate", ""); ModelAndView mav = this.createCourseModelAndView(courseId, request); boolean selectmark = false;// 页面传过来的不合法的自己定义的查询条件 if (StringUtils.isNotBlank(type)) { if ("week".equals(type.trim())) { // 依照时间的顺序,近期7天 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String currentTime = sdf.format(new Date()); String sevenDay = getPassDate(currentTime, 7); List<StatisticsDurationCourse> durationList = statisticsDurationCuManager.getDurationByTime( schoolId, courseId, sevenDay, currentTime); //补数据。没有记录的数据,一天没有产生数据。补一条0的数据 List<StatisticsDurationCourse> durationListData = addNullDayData(durationList,7); mav.addObject("durationList", durationListData); // 报表所须要的折线图 List<String> dayList = new ArrayList<String>(); List<Integer> numberList = new ArrayList<Integer>(); List<Float> totalTimes = new ArrayList<Float>(); if (durationListData.size() > 0) { for (int i = durationListData.size(); i >0; i--) { StatisticsDurationCourse sdc = new StatisticsDurationCourse(); sdc = durationListData.get(i-1); String dateString=sdf.format(sdc.getDate()); Calendar cal = Calendar.getInstance(); cal.setTime(sdf.parse(dateString)); int month = cal.get(Calendar.MONTH) + 1; int day = cal.get(Calendar.DAY_OF_MONTH); String dayX = month + "月" + day + "日"; numberList.add(sdc.getNumber()); totalTimes.add(sdc.getTotalDuration()*60); dayList.add(dayX); } } // 转为json数组 String numberListStr = writeListToJsonArray(numberList); String dayListStr = writeListToJsonArray(dayList); String totalTimesStr = writeListToJsonArray(totalTimes); mav.addObject("numberList", numberListStr);// 次数 mav.addObject("totalTimes", totalTimesStr);// 时长 mav.addObject("dayList", dayListStr);// 时间 mav.addObject("timeMark", "week");// 查询条件说明 } else if ("month".equals(type.trim())) { // 近期30天 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String currentTime = sdf.format(new Date()); String thirtyDay = getPassDate(currentTime, 30); List<StatisticsDurationCourse> durationList = statisticsDurationCuManager.getDurationByTime( schoolId, courseId, thirtyDay, currentTime); //补数据,没有记录的数据。一天没有产生数据。补一条0的数据 List<StatisticsDurationCourse> durationListData = addNullDayData(durationList,30); mav.addObject("durationList", durationListData); // 报表所须要的折线图 List<String> dayList = new ArrayList<String>(); List<Integer> numberList = new ArrayList<Integer>(); List<Float> totalTimes = new ArrayList<Float>(); if (durationListData.size() > 0) { for (int i = durationListData.size(); i >0; i--) { StatisticsDurationCourse sdc = new StatisticsDurationCourse(); sdc = durationListData.get(i-1); Calendar cal = Calendar.getInstance(); cal.setTime(sdc.getDate()); int month = cal.get(Calendar.MONTH) + 1; int day = cal.get(Calendar.DAY_OF_MONTH); String dayX = month + "月" + day + "日"; numberList.add(sdc.getNumber()); totalTimes.add(sdc.getTotalDuration() * 60); dayList.add(dayX); } } // 转为json数组 String numberListStr = writeListToJsonArray(numberList); String dayListStr = writeListToJsonArray(dayList); String totalTimesStr = writeListToJsonArray(totalTimes); mav.addObject("numberList", numberListStr);// 次数 mav.addObject("totalTimes", totalTimesStr);// 时长 mav.addObject("dayList", dayListStr);// 时间 mav.addObject("timeMark", "month");// 查询条件说明 } else if ("time".equals(type.trim())) { // 自由选择时间 // 时间段小于30天 // 结束时间超过当前时间 if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); Date d1 = sdf.parse(startDate); Date d2 = sdf.parse(endDate); Date now = new Date(); long daysNows = (d2.getTime() - now.getTime() + 1000000) / (3600 * 24 * 1000); if (daysNows > 0) { // 结束时间超过当前时间,吧当前时间的值给结束时间 endDate = sdf.format(now); } long daysBetween = (d2.getTime() - d1.getTime() + 1000000) / (3600 * 24 * 1000); //System.out.println("1987-01-01 与 2010-01-01 相隔 "+daysBetween+" 天"); // 两个自己定义时间之间必须小于31天 if ((daysBetween + 1) <= 31 && (daysBetween + 1) >= 1) { List<StatisticsDurationCourse> durationList = statisticsDurationCuManager.getDurationByTime( schoolId, courseId, startDate, endDate); //补数据,没有记录的数据。一天没有产生数据,补一条0的数据 int intervalDay=(int) daysBetween+1; List<StatisticsDurationCourse> durationListData = addNullDayData(durationList,intervalDay); mav.addObject("durationList", durationListData); // 报表所须要的折线图 List<String> dayList = new ArrayList<String>(); List<Integer> numberList = new ArrayList<Integer>(); List<Float> totalTimes = new ArrayList<Float>(); if (durationListData.size() > 0) { for (int i = durationListData.size(); i >0; i--) { StatisticsDurationCourse sdc = new StatisticsDurationCourse(); sdc = durationListData.get(i-1); Calendar cal = Calendar.getInstance(); cal.setTime(sdc.getDate()); int month = cal.get(Calendar.MONTH) + 1; int day = cal.get(Calendar.DAY_OF_MONTH); String dayX = month + "月" + day + "日"; numberList.add(sdc.getNumber()); totalTimes.add(sdc.getTotalDuration()*60); dayList.add(dayX); } } // 转为json数组 String numberListStr = writeListToJsonArray(numberList); String dayListStr = writeListToJsonArray(dayList); String totalTimesStr = writeListToJsonArray(totalTimes); mav.addObject("numberList", numberListStr);// 次数 mav.addObject("totalTimes", totalTimesStr);// 时长 mav.addObject("dayList", dayListStr);// 时间 mav.addObject("timeMark", "time");// 查询条件说明 mav.addObject("startDate", startDate);// 開始时间 mav.addObject("endDate", endDate);// 结束时间 } else { //超过31天,依照7天来搜索 selectmark=true; } }else { //查询时间条件为空 selectmark = true; } }//if time }//type是否为空 if(selectmark){ // 两个时间之间超过31天 ,依照7天来统计 // 依照时间的顺序,近期7天 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String currentTime = sdf.format(new Date()); String sevenDay = getPassDate(currentTime, 7); List<StatisticsDurationCourse> durationList = statisticsDurationCuManager.getDurationByTime( schoolId, courseId, sevenDay, currentTime); //补数据。没有记录的数据,一天没有产生数据,补一条0的数据 List<StatisticsDurationCourse> durationListData = addNullDayData(durationList,7); mav.addObject("durationList", durationListData); // 报表所须要的折线图 List<String> dayList = new ArrayList<String>(); List<Integer> numberList = new ArrayList<Integer>(); List<Float> totalTimes = new ArrayList<Float>(); if (durationListData.size() > 0) { for (int i = durationListData.size(); i >0; i--) { StatisticsDurationCourse sdc = new StatisticsDurationCourse(); sdc = durationListData.get(i-1); String dateString=sdf.format(sdc.getDate()); Calendar cal = Calendar.getInstance(); cal.setTime(sdf.parse(dateString)); int month = cal.get(Calendar.MONTH) + 1; int day = cal.get(Calendar.DAY_OF_MONTH); String dayX = month + "月" + day + "日"; numberList.add(sdc.getNumber()); totalTimes.add(sdc.getTotalDuration()*60); dayList.add(dayX); } } // 转为json数组 String numberListStr = writeListToJsonArray(numberList); String dayListStr = writeListToJsonArray(dayList); String totalTimesStr = writeListToJsonArray(totalTimes); mav.addObject("numberList", numberListStr);// 次数 mav.addObject("totalTimes", totalTimesStr);// 时长 mav.addObject("dayList", dayListStr);// 时间 mav.addObject("timeMark", "week");// 查询条件说明 } mav.setViewName(getSecureViewDir(request) + "/courseStatistics/count"); return mav; } /** * 一门课程一个月的每一天的时长统计 */ @RequestMapping("/{courseId}/duration/month") public ModelAndView getCourseDurationMonth(@PathVariable String courseId, HttpServletRequest request) { String schoolId = this.getSchoolId(request); // 网校ID String time = ServletRequestUtils.getStringParameter(request, "time", "");// ModelAndView mav = this.createCourseModelAndView(courseId, request); if (StringUtils.isBlank(time)) { // 统计当前月份的 Calendar cal = Calendar.getInstance(); int month = cal.get(Calendar.MONTH) + 1; int year = cal.get(Calendar.YEAR); // int day = cal.get(Calendar.DAY_OF_MONTH); List<StatisticsDurationCourse> durationList = statisticsDurationCuManager.getDurationMonth(schoolId, courseId, year, month); mav.addObject("durationList", durationList); } else { // 统计上一个月的 Calendar cal = Calendar.getInstance(); int month = cal.get(Calendar.MONTH); int year = cal.get(Calendar.YEAR); // int day = cal.get(Calendar.DAY_OF_MONTH); List<StatisticsDurationCourse> durationList = statisticsDurationCuManager.getDurationMonth(schoolId, courseId, year, month); mav.addObject("durationList", durationList); } mav.setViewName(getSecureViewDir(request) + "/courseStatistics/durationByDay"); return mav; } // list转为json数组 public String writeListToJsonArray(List list) throws IOException { OutputStream out = new ByteArrayOutputStream(); ObjectMapper mapper = new ObjectMapper(); mapper.writeValue(out, list); byte[] data = ((ByteArrayOutputStream) out).toByteArray(); // System.out.println(new String(data)); String result = new String(data, "UTF-8"); return result; } /** * 依据输入的日期字符串 和 提前天数 , * 获得 指定日期提前几天的日期对象 * @param dateString 日期对象 ,格式如 1-31-1900 * @param lazyDays 倒推的天数 * @return 指定日期倒推指定天数后的日期对象 * @throws ParseException */ public String getPassDate(String dateString, int beforeDays) throws ParseException { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); Date inputDate = dateFormat.parse(dateString); Calendar cal = Calendar.getInstance(); cal.setTime(inputDate); int inputDayOfYear = cal.get(Calendar.DAY_OF_YEAR); cal.set(Calendar.DAY_OF_YEAR, inputDayOfYear - beforeDays); String dateTime = dateFormat.format(cal.getTime()); return dateTime; } //补数据,没有记录的数据,一天没有产生数据,补一条0的数据 public List<StatisticsDurationCourse> addNullDayData(List<StatisticsDurationCourse> durationList,int len) throws ParseException { List<StatisticsDurationCourse> durationListSort = new ArrayList<StatisticsDurationCourse>(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); if(durationList.size()>0){ for(int j=0;j<len;j++){ //找出空的时间,补数据 String currentTime2 = sdf.format(new Date()); String recentlyDay = getPassDate(currentTime2, j);//近期7天的时间 boolean addmark=true; for (int i = 0; i < durationList.size(); i++) { StatisticsDurationCourse sdc = new StatisticsDurationCourse(); sdc = durationList.get(i); String dateString=sdf.format(sdc.getDate()); if(recentlyDay.equals(dateString)){ //记录里有近期7天当中一天的数据 durationListSort.add(sdc); addmark=false; break; } } if(addmark){ //记录里没有近期7天中不论什么一天的数据 StatisticsDurationCourse sdcNo = new StatisticsDurationCourse(); sdcNo.setDate(sdf.parse(recentlyDay)); sdcNo.setNumber(0); sdcNo.setTotalDuration(0); durationListSort.add(sdcNo); } } } return durationListSort; } }


    页面是使用freemarker

    <#-- 页头 -->
    <#assign pageTitle="课程统计">
    <#include "/default/commons/header.ftl">
      <style>
         .searchDate{
            margin:10px auto -10px;
         }
         .inputLabel{
            line-height:30px;
         }
         .form-radio{
            margin-top:-2px;
         }
         .name-font{
            font-size:18px;
            text-indent:2em;
            margin-top:20px;
         }
         .terminal{
            margin-top:10px;
         }
         #draw{
            95%;
            height:400px;
            margin:0 auto;
         }
         .table-th{
            background-color: #4B4B4B;
            color:#e2e2e2;
         }
         .warnning{
            padding:5px 15px;
         }
      </style>
      <div id="content-container" class="container">
      
        <#-- 课程管理相关页面的顶部模版 -->
        <#include "../course/manage/topSection.ftl">  
        
         <div class="row">
         
    	  <div class="col-md-3">
    	    <#-- 左側导航 -->
    	    <#assign sidebarNav="duration">
    	    <#include "../course/manage/sidebar.ftl">
    	  </div>
    	  
    	<div class="col-md-9">
    	   <div class="panel panel-default panel-col">
    	   <!--右側内容-->
             
               <div class="well well-sm" style="90%; margin-top:20px;margin-left:auto;margin-right:auto;text-align:center;">
    			    <form id="statistics-search" class="form-inline" action="/secure/course/statistics/${course.courseId}/duration/day" method="get"> 
    				      <div class="form-group">
    				        <input class="form-control" type="text" id="startDate" name="startDate" value="" placeholder="起始时间">
    				      </div>
    				
    				      <span>--</span>
    				      
    				      <div class="form-group">
    				        <input class="form-control" type="text" id="endDate" name="endDate" value="" placeholder="结束时间">
    				      </div>
    				      <span>--</span>
    				
    				      <div class="form-group">
    				          <select class="form-control" name="type" id="markType">
    					         <option value="week">近期7天</option>
    					         <option value="month">近期30天</option>
    					         <option value="time">自己定义时间</option>
    					      </select>
    				      </div>
    				
    				      <button class="btn btn-primary">统计</button>
    			    </form>
      		  </div>
             
               <!--统计日期选择-->
               <div class="name-font">
                  « <span id="courseName">${(course.title)!''}</span>» 统计   
                  <span id="markText" style="float:right;margin-right:40px;"></span>
               </div>
               <div id="draw">
               </div>
               <!--折线图-->
          
               <div class="table-view" style="90%;margin:auto;">
                   <table class="table table-hover" id="tongji" style="text-align:center;">
                      <thead class="table-th">
                         <th style="text-align:center;">日期</th>
                         <th style="text-align:center;">观看次数(次)</th>
                         <th style="text-align:center;">观看时长(分钟)</th>
                      </thead>
                      <tbody>
                        <#if durationList?has_content>
                          	<#list durationList as item>
    		                    <tr>
    		                       <td>${(item.date)?string("yyyy-MM-dd")}</td>
    		                       <td>${(item.number)!''}</td>
    		                       <td>${((item.totalDuration)*60)?string("0.##")}</td>
    		                    </tr>
    	                     </#list>
    	                <#else>
    	                   <span> 临时还没数据! </span>    
                        </#if>
                      </tbody>
                   </table>
               </div>
               <!--数据列表-->
               <input type="hidden" id="timeMark" value="${(timeMark)!''}" />
           </div>
       </div>
       </div>
    
    
     
     <#--页脚開始 -->
    <#include "/default/commons/footerBegin.ftl">
    <script type="text/javascript" src="/resources/echart/esl.js"></script> 
    <script type="text/javascript" src="/resources/datetimepicker/js/bootstrap-datetimepicker.min.js"></script> 
    
    
      <script type="text/javascript">  
                // 路径配置  
                require.config({  
                    paths:{   
                        'echarts' : '/resources/echart/echarts',  
                        'echarts/chart/bar' : '/resources/echart/echarts'  
                    }  
                });  
                  
                // 使用  
                require(  
                    [  
                        'echarts',  
                        'echarts/chart/bar' // 使用柱状图就载入bar模块。按需载入  
                    ],  
                    function (ec) {  
                        // 基于准备好的dom。初始化echarts图表  
                        var myChart = ec.init(document.getElementById('draw'));   
                          
                         var jsonNum=${numberList};
    					  var jsonTime=${totalTimes};
    					  var jsonDay=${dayList};
                          
                       option = {
    					    tooltip : {
    					        trigger: 'axis'
    					    },
    					    legend: {
    					        data:['观看次数','观看时长']
    					    },
    					    toolbox: {
    					        show : true,
    					        feature : {
    					            magicType : {show: false, type: ['line']}
    					           
    					            
    					        }
    					    },
    					    calculable : true,
    					    xAxis : [
    					        {
    					            type : 'category',
    					            boundaryGap : true,
    					            name: '月份',
    					            data : jsonDay
    					        }
    					    ],
    					    yAxis : [
    					        {
    					            type : 'value',
    					            name: '分钟/次数'
    					        }
    					    ],
    					    series : [
    					        {
    					            name:'观看次数',
    					            type:'line',
    					            stack: '次',
    					            data:jsonNum
    					        },
    					        {
    					            name:'观看时长',
    					            type:'line',
    					            stack: '分钟',
    					            data:jsonTime
    					        }
    					    ]
    					}; 
                  
                        // 为echarts对象载入数据   
                        myChart.setOption(option);   
                    }  
                );  
      </script> 
      
      
      <script>
      
          $(document).ready(function(){
              var timeMark="${timeMark}";
               $("#markType").val(timeMark);
               
               if("time"==timeMark){
                  var startDate="${startDate}";
                  var endDate="${endDate}";
                  var textStr=startDate+"----"+endDate+"的观看情况";
                  $("#markText").text(textStr);
               }
          });
      
           $("#startDate").datetimepicker({
    		    weekStart: 1,
    	        todayBtn:  1,
    			autoclose: 1,
    			todayHighlight: 1,
    			startView: 2,
    			minView: 2,
    			forceParse: 0,
         	  format:"yyyy-mm-dd"
           });
                	   
    	   $("#endDate").datetimepicker({
    	        weekStart: 1,
                todayBtn:  1,
    		    autoclose: 1,
    		    todayHighlight: 1,
    		    startView: 2,
    		    minView: 2,
    		    forceParse: 0,
     	        format:"yyyy-mm-dd"
           });
      </script>
    
    
      
    <#--页脚页脚页脚-->
    <#include "/default/commons/footerEnd.ftl">
    

    执行效果图:






  • 相关阅读:
    自定义属性的操作 element.属性 以及 element.getAttribute('属性') 获取、自定义方法以及修改值
    鼠标点击、经过,离开案例
    水平垂直居中方法 flex和table-cell区别 父盒子使用定位 水平方向、垂直方向上是否受到影响?
    关于margin 和 margin auto
    python基础
    实验二流程图
    关于实验二的补充(面向对象的程序设计)
    树的重心 POJ_1655
    KMP板子题
    Educational Codeforces Round 62 (Rated for Div. 2) 2019年3月23日
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6963004.html
Copyright © 2020-2023  润新知