派生自 projectDept/qhighschool

Administrator
2022-11-29 8c99e2d8b6c1e0d9cde6abbe80b4df75be19f6d1
课程与课件bug修复
30个文件已修改
3个文件已添加
4516 ■■■■■ 已修改文件
pom.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/admin/classes/service/impl/ClassLectureService.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/admin/classes/service/impl/ClsClassService.java 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/admin/progress/dao/ProgressDAO.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/admin/progress/model/SubjectLectureProgressDetail.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/admin/progress/service/IDetailProgressService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/admin/progress/service/IProgressService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/admin/progress/service/impl/ProgressService.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/admin/progress/service/impl/StudyProgressUtils.java 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/admin/progress/service/impl/item/ChapterProgressService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/admin/progress/service/impl/item/ClassProgressService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/admin/progress/service/impl/item/LectureProgressService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/admin/progress/service/impl/item/SubjectProgressService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/admin/progress/service/impl/lecture/LectureCommonProgressService.java 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/admin/progress/service/impl/lecture/LectureDocProgressService.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/admin/progress/service/impl/lecture/LectureVideoProgressService.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/base/service/impl/RedisCacheBean.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/base/util/ClientUtils.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/controller/CoursewareController.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/stucontroller/StuSubjectController.java 789 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/sys/utils/AudioUtil.java 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/sys/utils/VideoUtil.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/teach/res/service/impl/resitem/ResItemAudioService.java 33 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/teach/res/service/impl/resitem/ResItemVideoService.java 234 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/teach/subject/model/SubjectUtils.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/teach/subject/model/view/MyLectureV.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/teach/subject/model/view/MySubjectV.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/teach/subject/service/ILectureService.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/teach/subject/service/ISubjectService.java 121 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/teach/subject/service/impl/SubjectLectureService.java 62 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/qxueyou/scc/teach/subject/service/impl/SubjectService.java 2687 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
target/generated-sources/java/com/qxueyou/scc/teach/student/model/QStuStudent.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
target/generated-sources/java/com/qxueyou/scc/teach/subject/model/view/QMyLectureV.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -78,6 +78,19 @@
            <version>4.0.5.Final</version>
        </dependency>
        <!-- mp3文件支持(如语音时长)-->
        <dependency>
            <groupId>org</groupId>
            <artifactId>jaudiotagger</artifactId>
            <version>2.0.1</version>
        </dependency>
        <!-- mp4文件支持(如语音时长)-->
        <dependency>
            <groupId>com.googlecode.mp4parser</groupId>
            <artifactId>isoparser</artifactId>
            <version>1.1.22</version>
        </dependency>
        <!-- hibernate-core-4.3.7.Final.jar -->
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
src/main/java/com/qxueyou/scc/admin/classes/service/impl/ClassLectureService.java
@@ -270,6 +270,19 @@
        }
    }
    public Result updateLecturetime(String targetId) {
        ClsSubjectLecture lecture = read(ClsSubjectLecture.class, targetId);
        TraceUtils.setUpdateTrace(lecture);
        lecture.setUpdateTime(new Date());
        lecture.setUpdator(ClientUtils.getUserId());
        save(lecture);
        return new Result(true, "success");
    }
    @Override
    public Result updateLecture(String lectureId, String resId) {
@@ -567,7 +580,7 @@
    @Override
    public Result doStudy(String clsLectureId, Double from, Double to) {
        return progressService.addProgress(Progress.PROGRESS_TYPE_LECTURE, clsLectureId, from.doubleValue(), to.doubleValue(),
        return progressService.addProgress(Progress.PROGRESS_TYPE_LECTURE, clsLectureId, from.intValue(), to.intValue(),
                ClientUtils.getUserId());
    }
src/main/java/com/qxueyou/scc/admin/classes/service/impl/ClsClassService.java
@@ -1,12 +1,11 @@
package com.qxueyou.scc.admin.classes.service.impl;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
import com.qxueyou.scc.teach.subject.model.view.MyLectureV;
import com.qxueyou.scc.teach.subject.model.view.MySubjectV;
import com.qxueyou.scc.teach.subject.service.ILectureService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
@@ -53,6 +52,9 @@
    @Autowired
    ITeacherService teacherService;
    @Autowired
    ILectureService lectureService;
    /**
     * 添加班级
@@ -242,6 +244,27 @@
    @Override
    public List<Map<String, Object>> getSubjectLstByClsId(String classId) {
        String hql = "from MySubjectV where classId = ?";
        List<MySubjectV> mySubjectVList = find(hql,CollectionUtils.newList(classId),MySubjectV.class);
        List<Map<String,Object>> maps = new ArrayList<>();
        for(MySubjectV mySubjectV : mySubjectVList){
            List<MyLectureV> myLectureVList = lectureService.listLectureVBySubjectId(mySubjectV.getId().getUserId(),mySubjectV.getId().getSubjectId(), "", 1000, 1, null);
            Double percent = 0.0;
            Double progressValue = 0.0;
            Double percentAvg = 0.0;
            if(!myLectureVList.isEmpty()) {
                for (MyLectureV myLectureV : myLectureVList) {
                    if (myLectureV.getPercent() != null && myLectureV.getProgressValue() != null) {
                        percent += myLectureV.getPercent();
                        progressValue += myLectureV.getProgressValue().intValue();
                    }
                }
                percentAvg = percent / myLectureVList.size();
                if (percentAvg.isNaN()) {
                    percentAvg = 0.0;
                }
            }
        }
        return null;
    }
src/main/java/com/qxueyou/scc/admin/progress/dao/ProgressDAO.java
@@ -38,15 +38,15 @@
     * @return
     */
    @Cacheable(value = "progress", key = "#targetId+#learnerId")
    public Double[][] getProgress(String targetId, String learnerId) {
    public int[][] getProgress(String targetId, String learnerId) {
        List<SubjectLectureProgressDetail> lstDetail = this.find("from SubjectLectureProgressDetail where targetId = ? and learnerId = ? and deleteFlag is false", CollectionUtils.newList(targetId, learnerId), SubjectLectureProgressDetail.class);
        if(lstDetail == null || lstDetail.isEmpty()) {
            return new Double[][] {};
            return new int[][] {};
        }else {
            Double[][] progress = new  Double[lstDetail.size()][2];
            int[][] progress = new  int[lstDetail.size()][2];
             int i = 0;
             for(SubjectLectureProgressDetail objDetail : lstDetail) {
                 progress[i++] = new Double[] {objDetail.getStart(), objDetail.getEnd()};
                 progress[i++] = new int[] {objDetail.getStart(), objDetail.getEnd()};
             }
             return progress;
@@ -54,7 +54,7 @@
    }
    @CachePut(value = "progress", key = "#targetId+#learnerId")
    public Double[][] mergeProgress(String targetId, String learnerId, Double start, Double end, Double[][] origProgress) {
    public int[][] mergeProgress(String targetId, String learnerId, int start, int end, int[][] origProgress) {
        return StudyProgressUtils.merge(origProgress, start, end);
    }
src/main/java/com/qxueyou/scc/admin/progress/model/SubjectLectureProgressDetail.java
@@ -30,8 +30,8 @@
    private static final long serialVersionUID = -1565188126862586738L;
    private String detailId;
    private String progressId;
    private Double start;
    private Double end;
    private int start;
    private int end;
    private String learnerId;
    private String targetId;
    private Date createTime;
@@ -55,25 +55,25 @@
        this.progressId = progressId;
    }
    public Double getStart() {
    public int getStart() {
        return start;
    }
    public void setStart(Double start) {
    public void setStart(int start) {
        this.start = start;
    }
    public Double getEnd() {
    public int getEnd() {
        return end;
    }
    public void setEnd(Double end) {
    public void setEnd(int end) {
        this.end = end;
    }
src/main/java/com/qxueyou/scc/admin/progress/service/IDetailProgressService.java
@@ -13,7 +13,7 @@
     * @param end 学习结束位置
     * @return
     */
    Result addProgress(String targetId,String learnerId,Double start,Double end);
    Result addProgress(String targetId,String learnerId,int start,int end);
    /**
     * 返回进度类型
src/main/java/com/qxueyou/scc/admin/progress/service/IProgressService.java
@@ -48,7 +48,7 @@
     *            学习结束位置
     * @return
     */
    Result addProgress(String type, String targetId, Double start, Double end, String userId);
    Result addProgress(String type, String targetId, int start, int end, String userId);
    List<SubjectProgressTreeV> getSubjectChapterTreeVList(String parentId,String userId);
src/main/java/com/qxueyou/scc/admin/progress/service/impl/ProgressService.java
@@ -84,7 +84,7 @@
    }
    @Override
    public Result addProgress(String type, String targetId, Double start, Double end, String userId) {
    public Result addProgress(String type, String targetId, int start, int end, String userId) {
        String userId_ = StringUtils.isBlank(userId) ? ClientUtils.getUserId() : userId;
        return resItemServiceMap.get(type).addProgress(targetId, userId_, start, end);
    }
@@ -109,7 +109,7 @@
            BigDecimal progressValue = new BigDecimal(itemProgress.get("progressValue").toString());
            if (progress == null) {
                String nodeType = subjectProgressTreeV.getNodeType();
                this.addProgress(nodeType, nodeId, 0.0, 0.0, userId);
                this.addProgress(nodeType, nodeId, 0, 0, userId);
                cacheService.lstRightPush(SUBJECT_PROGRESS_STATISTIC, nodeIdOrUserId);
                return;
            }
src/main/java/com/qxueyou/scc/admin/progress/service/impl/StudyProgressUtils.java
@@ -41,10 +41,10 @@
     *            结束位置
     * @return
     */
    public static Double[][] merge(Double[][] orig, Double start, Double end) {
    public static int[][] merge(int[][] orig, int start, int end) {
        // 中间合并结果
        Double[][] result = new Double[orig.length + 1][2];
        int[][] result = new int[orig.length + 1][2];
        int j = 0;
        int i = 0;
@@ -57,13 +57,13 @@
            switch (action) {
            case ACTION_INSERT: {
                result[j++] = new Double[] { start, end };
                result[j++] = new int[] { start, end };
                result[j++] = orig[i];
                breakFlag = true;
                break;
            }
            case ACTION_MERGE_01: {
                result[j++] = new Double[] { start, orig[i][1] };
                result[j++] = new int[] { start, orig[i][1] };
                breakFlag = true;
                break;
            }
@@ -95,14 +95,12 @@
        }
        // 如果本次学习终止位置超出以往所有学习进度,则添加到最后
        if (orig.length == 0 ) {
            result[j++] = new Double[] { start, end };
        }else if(pos(end, orig[orig.length - 1]) == POS_AFTER){
            result[j++] = new Double[] { start, end };
        if (orig.length == 0 || pos(end, orig[orig.length - 1]) == POS_AFTER) {
            result[j++] = new int[] { start, end };
        }
        // 最终合并结果,去掉中间合并结果的多出为空的元素
        Double[][] finalResult = new Double[j][2];
        int[][] finalResult = new int[j][2];
        for (int k = 0; k < result.length; k++) {
            if (result[k][0] == 0 && result[k][1] == 0 && k>0) {
@@ -122,18 +120,18 @@
     *            全部学习进度
     * @return
     */
    public static Double sum(Double[][] orig) {
    public static int sum(int[][] orig) {
        Double sum = 0.0;
        int sum = 0;
        for (Double[] item : orig) {
        for (int[] item : orig) {
            sum += (item[1] - item[0] + 1);
        }
        return sum;
    }
    private static int action(Double[] segment, Double start, Double end) {
    private static int action(int[] segment, int start, int end) {
        int startPos = pos(start, segment);
        int endPos = pos(end, segment);
@@ -165,7 +163,7 @@
    }
    private static int pos(Double index, Double[] range) {
    private static int pos(int index, int[] range) {
        if (index < range[0]) {
            return POS_BEFORE;
        }
src/main/java/com/qxueyou/scc/admin/progress/service/impl/item/ChapterProgressService.java
@@ -1,6 +1,7 @@
package com.qxueyou.scc.admin.progress.service.impl.item;
import java.math.BigDecimal;
import java.util.Date;
import org.springframework.stereotype.Service;
@@ -15,7 +16,7 @@
public class ChapterProgressService extends CommonAppService implements IDetailProgressService {
    @Override
    public Result addProgress(String targetId, String learnerId, Double start, Double end) {
    public Result addProgress(String targetId, String learnerId, int start, int end) {
        Progress p = new Progress();
        TraceUtils.setCreateTrace(p);
        p.setLearnerId(learnerId);
@@ -25,6 +26,13 @@
        p.setTargetId(targetId);
        p.setType(Progress.PROGRESS_TYPE_CHAPTER);
        p.setProgressPercent(0d);
        p.setDeleteFlag(false);
        p.setCreator(ClientUtils.getUserName());
        p.setCreateId(ClientUtils.getUserId());
        p.setCreateTime(new Date());
        p.setUpdator(ClientUtils.getUserName());
        p.setUpdateId(ClientUtils.getUserId());
        p.setUpdateTime(new Date());
        save(p);
        return new Result(true);
    }
src/main/java/com/qxueyou/scc/admin/progress/service/impl/item/ClassProgressService.java
@@ -1,6 +1,7 @@
package com.qxueyou.scc.admin.progress.service.impl.item;
import java.math.BigDecimal;
import java.util.Date;
import org.springframework.stereotype.Service;
@@ -15,7 +16,7 @@
public class ClassProgressService extends CommonAppService implements IDetailProgressService {
    @Override
    public Result addProgress(String targetId, String learnerId, Double start, Double end) {
    public Result addProgress(String targetId, String learnerId, int start, int end) {
        Progress p = new Progress();
        TraceUtils.setCreateTrace(p);
        p.setLearnerId(learnerId);
@@ -25,6 +26,13 @@
        p.setTargetId(targetId);
        p.setType(Progress.PROGRESS_TYPE_CLASS);
        p.setProgressPercent(0d);
        p.setDeleteFlag(false);
        p.setCreator(ClientUtils.getUserName());
        p.setCreateId(ClientUtils.getUserId());
        p.setCreateTime(new Date());
        p.setUpdator(ClientUtils.getUserName());
        p.setUpdateId(ClientUtils.getUserId());
        p.setUpdateTime(new Date());
        save(p);
        return new Result(true);
    }
src/main/java/com/qxueyou/scc/admin/progress/service/impl/item/LectureProgressService.java
@@ -44,7 +44,7 @@
    @Override
    public Result addProgress(String targetId,String learnerId, Double start, Double end) {
    public Result addProgress(String targetId,String learnerId, int start, int end) {
        ClsSubjectLecture lecture = lectureService.readClsLecture(targetId);
        String lectureType = null;
src/main/java/com/qxueyou/scc/admin/progress/service/impl/item/SubjectProgressService.java
@@ -1,6 +1,7 @@
package com.qxueyou.scc.admin.progress.service.impl.item;
import java.math.BigDecimal;
import java.util.Date;
import org.springframework.stereotype.Service;
@@ -15,7 +16,7 @@
public class SubjectProgressService extends CommonAppService implements IDetailProgressService {
    @Override
    public Result addProgress(String targetId, String learnerId, Double start, Double end) {
    public Result addProgress(String targetId, String learnerId, int start, int end) {
        Progress p = new Progress();
        TraceUtils.setCreateTrace(p);
        p.setLearnerId(learnerId);
@@ -25,6 +26,13 @@
        p.setTargetId(targetId);
        p.setType(Progress.PROGRESS_TYPE_SUBJECT);
        p.setProgressPercent(0d);
        p.setDeleteFlag(false);
        p.setCreator(ClientUtils.getUserName());
        p.setCreateId(ClientUtils.getUserId());
        p.setCreateTime(new Date());
        p.setUpdator(ClientUtils.getUserName());
        p.setUpdateId(ClientUtils.getUserId());
        p.setUpdateTime(new Date());
        save(p);
        return new Result(true);
    }
src/main/java/com/qxueyou/scc/admin/progress/service/impl/lecture/LectureCommonProgressService.java
@@ -1,7 +1,10 @@
package com.qxueyou.scc.admin.progress.service.impl.lecture;
import java.math.BigDecimal;
import java.util.Date;
import com.qxueyou.scc.admin.classes.model.ClsSubjectLecture;
import com.qxueyou.scc.admin.classes.service.impl.ClassLectureService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -28,20 +31,23 @@
    @Autowired
    ProgressDAO dao;
    @Autowired
    ClassLectureService classLectureService;
    @Override
    public Result addProgress(String targetId, String learnerId, Double start, Double end) {
    public Result addProgress(String targetId, String learnerId, int start, int end) {
        if (start > end || start < 0 || end < 0) {
            return new Result(false, "invalid arguments");
        }
        Double[][] progress = dao.mergeProgress(targetId, learnerId, start, end , dao.getProgress(targetId, learnerId));
        int[][] progress = dao.mergeProgress(targetId, learnerId, start, end , dao.getProgress(targetId, learnerId));
        if (!checkLecture(targetId).isSuccess()) {
            return checkLecture(targetId);
        }
        Double sum = StudyProgressUtils.sum(progress);
        int sum = StudyProgressUtils.sum(progress);
        Progress p = dao.getProgress(Progress.PROGRESS_TYPE_LECTURE, targetId, learnerId);
@@ -53,6 +59,8 @@
        //保存学习记录明细
        this.saveProgressDetail(start, end, targetId, p.getProgressId(), learnerId);
        classLectureService.updateLecturetime(targetId);
        SubjectProgressTreeV subjectProgressTreeV = dao.getSubjectProgressTreeV(targetId, learnerId);
@@ -77,7 +85,7 @@
     * @param progressId
     * @param learnerId
     */
    private void saveProgressDetail(Double start, Double end, String targetId, String progressId, String learnerId) {
    private void saveProgressDetail(int start, int end, String targetId, String progressId, String learnerId) {
        SubjectLectureProgressDetail detail = new SubjectLectureProgressDetail();
        detail.setDeleteFlag(false);
        detail.setEnd(end);
@@ -85,10 +93,14 @@
        detail.setTargetId(targetId);
        detail.setProgressId(progressId);
        detail.setLearnerId(learnerId);
        detail.setCreator(ClientUtils.getUserName());
        detail.setCreateId(ClientUtils.getUserId());
        detail.setCreateTime(new Date());
        detail.setUpdateTime(new Date());
        TraceUtils.setCreateTrace(detail);
        this.save(detail);
        save(detail);
    }
    /**
@@ -98,7 +110,8 @@
     * @param sum
     * @return
     */
    protected double getProgressPercent(String targetId, Double sum) {
    protected double getProgressPercent(String targetId, int sum) {
        return 1.00d;
    }
@@ -107,17 +120,17 @@
        return Progress.PROGRESS_TYPE_LECTURE;
    }
    protected void updateProgress(String targetId, Progress p, Double sum) {
    protected void updateProgress(String targetId, Progress p, int sum) {
        TraceUtils.setUpdateTrace(p);
        p.setProgressValue(BigDecimal.valueOf(Double.valueOf(sum)));
        p.setProgressValue(BigDecimal.valueOf(Long.valueOf(sum)));
        p.setProgressPercent(1d);
        save(p);
    }
    protected Progress newProgress(String targetId, String learnerId, Double sum) {
    protected Progress newProgress(String targetId, String learnerId, int sum) {
        Progress p = new Progress();
        TraceUtils.setCreateTrace(p);
@@ -125,10 +138,17 @@
        p.setLearnerId(learnerId);
        p.setLearnerName(ClientUtils.getUserName());
        p.setProgressUnit("s");
        p.setProgressValue(BigDecimal.valueOf(Double.valueOf(sum)));
        p.setProgressValue(BigDecimal.valueOf(Long.valueOf(sum)));
        p.setTargetId(targetId);
        p.setType(Progress.PROGRESS_TYPE_LECTURE);
        p.setProgressPercent(1d);
        p.setDeleteFlag(false);
        p.setCreator(ClientUtils.getUserName());
        p.setCreateId(ClientUtils.getUserId());
        p.setCreateTime(new Date());
        p.setUpdator(ClientUtils.getUserName());
        p.setUpdateId(ClientUtils.getUserId());
        p.setUpdateTime(new Date());
        save(p);
        return p;
src/main/java/com/qxueyou/scc/admin/progress/service/impl/lecture/LectureDocProgressService.java
@@ -1,6 +1,7 @@
package com.qxueyou.scc.admin.progress.service.impl.lecture;
import java.math.BigDecimal;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -31,7 +32,7 @@
     * @return
     */
    @Override
    public double getProgressPercent(String targetId, Double sum) {
    public double getProgressPercent(String targetId, int sum) {
        LectureDocV LectureDoc = lectureService.readDocLecture(targetId);
@@ -39,7 +40,7 @@
    }
    @Override
    public Progress newProgress(String targetId, String learnerId, Double sum) {
    public Progress newProgress(String targetId, String learnerId, int sum) {
        Progress p = new Progress();
        TraceUtils.setCreateTrace(p);
@@ -47,10 +48,17 @@
        p.setLearnerId(learnerId);
        p.setLearnerName(ClientUtils.getUserName());
        p.setProgressUnit("s");
        p.setProgressValue(BigDecimal.valueOf(Double.valueOf(sum)));
        p.setProgressValue(BigDecimal.valueOf(Long.valueOf(sum)));
        p.setTargetId(targetId);
        p.setType(Progress.PROGRESS_TYPE_LECTURE);
        p.setProgressPercent(getProgressPercent(targetId, sum));
        p.setDeleteFlag(false);
        p.setCreator(ClientUtils.getUserName());
        p.setCreateId(ClientUtils.getUserId());
        p.setCreateTime(new Date());
        p.setUpdator(ClientUtils.getUserName());
        p.setUpdateId(ClientUtils.getUserId());
        p.setUpdateTime(new Date());
        save(p);
@@ -58,10 +66,10 @@
    }
    @Override
    public void updateProgress(String targetId, Progress p, Double sum) {
    public void updateProgress(String targetId, Progress p, int sum) {
        TraceUtils.setUpdateTrace(p);
        p.setProgressValue(BigDecimal.valueOf(Double.valueOf(sum)));
        p.setProgressValue(BigDecimal.valueOf(Long.valueOf(sum)));
        if(p.getProgressPercent() == null || getProgressPercent(targetId, sum)>p.getProgressPercent()) {
            p.setProgressPercent(getProgressPercent(targetId, sum));
        }
src/main/java/com/qxueyou/scc/admin/progress/service/impl/lecture/LectureVideoProgressService.java
@@ -1,6 +1,7 @@
package com.qxueyou.scc.admin.progress.service.impl.lecture;
import java.math.BigDecimal;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -38,7 +39,7 @@
    }
    @Override
    public Progress newProgress(String targetId, String learnerId, Double sum) {
    public Progress newProgress(String targetId, String learnerId, int sum) {
        Progress p = new Progress();
        TraceUtils.setCreateTrace(p);
@@ -46,10 +47,17 @@
        p.setLearnerId(learnerId);
        p.setLearnerName(ClientUtils.getUserName());
        p.setProgressUnit("s");
        p.setProgressValue(BigDecimal.valueOf(Double.valueOf(sum)));
        p.setProgressValue(BigDecimal.valueOf(Long.valueOf(sum)));
        p.setTargetId(targetId);
        p.setType(Progress.PROGRESS_TYPE_LECTURE);
        p.setProgressPercent(getProgressPercent(targetId, sum));
        p.setDeleteFlag(false);
        p.setCreator(ClientUtils.getUserName());
        p.setCreateId(ClientUtils.getUserId());
        p.setCreateTime(new Date());
        p.setUpdator(ClientUtils.getUserName());
        p.setUpdateId(ClientUtils.getUserId());
        p.setUpdateTime(new Date());
        save(p);
@@ -57,7 +65,7 @@
    }
    @Override
    public void updateProgress(String targetId, Progress p, Double sum) {
    public void updateProgress(String targetId, Progress p, int sum) {
        TraceUtils.setUpdateTrace(p);
        p.setProgressValue(BigDecimal.valueOf(Double.valueOf(sum)));
src/main/java/com/qxueyou/scc/base/service/impl/RedisCacheBean.java
@@ -19,9 +19,11 @@
import com.qxueyou.scc.base.service.ICacheService;
import com.qxueyou.scc.base.util.CollectionUtils;
import javax.annotation.Resource;
/**
 * 阿里云OCS缓存服务
 *
 *
 * @author 德虎
 *
 */
@@ -32,7 +34,7 @@
    private static final Logger log = LogManager.getLogger("RedisCacheService");
    @SuppressWarnings("rawtypes")
    @Autowired
    @Resource
    private RedisTemplate redisTemplate;
    @SuppressWarnings("unchecked")
@@ -78,7 +80,7 @@
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();
        ops.set(key, obj);
    }
    @SuppressWarnings("unchecked")
    @Override
    public boolean setIfAbsent(String key, Object obj) {
@@ -129,8 +131,8 @@
    public void lstRightPush(String key, Object value) {
        redisTemplate.opsForList().rightPush(key, value);
    }
    @SuppressWarnings("unchecked")
    @Override
    public void expire(String key,long timeout,TimeUnit unit) {
src/main/java/com/qxueyou/scc/base/util/ClientUtils.java
@@ -50,16 +50,16 @@
    public static UserInfoWrapper getUserInfo() {
//        UserInfoWrapper wrapper = threadLocalUserInfo.get();
//        if(wrapper == null) {
            wrapper = (UserInfoWrapper)redisTemplate.opsForValue().get(UserInfoWrapper.SESSION_USER_INFO_KEY);
            if (wrapper == null) {
                wrapper = new UserInfoWrapper();
                User user = new User();
                //默认值,上传可以作为默认上传者
                user.setUserId(Constants.VISITOR_USER_ID);
                user.setName(Constants.VISITOR_USER_ID);
                wrapper.setUser(user);
                setUserInfo(wrapper);
            }
        wrapper = (UserInfoWrapper)redisTemplate.opsForValue().get(UserInfoWrapper.SESSION_USER_INFO_KEY);
        if (wrapper == null) {
            wrapper = new UserInfoWrapper();
            User user = new User();
            //默认值,上传可以作为默认上传者
            user.setUserId(Constants.VISITOR_USER_ID);
            user.setName(Constants.VISITOR_USER_ID);
            wrapper.setUser(user);
            setUserInfo(wrapper);
        }
//        }
//        else{
//            redisTemplate.opsForValue().set(UserInfoWrapper.SESSION_USER_INFO_KEY,wrapper);
src/main/java/com/qxueyou/scc/controller/CoursewareController.java
@@ -4,7 +4,9 @@
import java.util.List;
import java.util.Map;
import com.qxueyou.scc.admin.classes.model.ClsClassReSubject;
import com.qxueyou.scc.admin.classes.service.IClassLectureService;
import com.qxueyou.scc.teach.subject.model.Subject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
@@ -133,7 +135,9 @@
    @GetMapping(value = "deleteCourseware")
    public Result deleteCourseware(String id) {
        return lectureService.deleteLecture(id.split(","));
        Result result = lectureService.deleteLecture(id.split(","));
        lectureService.deleteLectureLoad(id.split(","));
        return result;
    }
@@ -319,6 +323,7 @@
            result = lectureService.addLecture(sectionId, resId_);
            successCount = result.isSuccess() ? 1 : 0;
        }
        lectureService.addLectureLoad(sectionId);
        return new Result(true, null, successCount);
    }
src/main/java/com/qxueyou/scc/stucontroller/StuSubjectController.java
@@ -1,12 +1,21 @@
package com.qxueyou.scc.stucontroller;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.querydsl.jpa.hibernate.HibernateQueryFactory;
import com.qxueyou.scc.base.dao.BaseDAO;
import com.qxueyou.scc.base.model.UserInfoWrapper;
import com.qxueyou.scc.teach.subject.model.SubjectUtils;
import com.qxueyou.scc.user.model.User;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.orm.jpa.vendor.HibernateJpaSessionFactoryBean;
import org.springframework.web.bind.annotation.*;
import com.alibaba.druid.util.StringUtils;
@@ -34,6 +43,7 @@
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -41,429 +51,450 @@
 * 学习端 课程前端控制器
 *
 * @author chenjunliang
 *
 */
@Api(tags= "课程管理-学员端")
@Api(tags = "课程管理-学员端")
@RestController
@CrossOrigin(origins="*",maxAge=3600)
@CrossOrigin(origins = "*", maxAge = 3600)
@RequestMapping(value = "stu/subject")
public class StuSubjectController {
    @Autowired
    ISubjectService subjectService;
    @Autowired
    ISubjectService subjectService;
    @Autowired
    ILectureService lectureService;
    @Autowired
    ILectureService lectureService;
    @Autowired
    IClassLectureService clsLectureService;
    @Autowired
    IClassLectureService clsLectureService;
    @Autowired
    IResAudioService audioService;
    @Autowired
    IResAudioService audioService;
    @Autowired
    ProgressDAO progressDao;
    @Autowired
    ProgressDAO progressDao;
    @Autowired
    ITopicService topicService;
    @Autowired
    ITopicService topicService;
    @Autowired
    IEvaluateService evaluateService;
    @Autowired
    IEvaluateService evaluateService;
    //--------------------------------------------------------------app端接口---------------------------------------------------------------------------------------------------
    /**
     * 学习端获取 所有课件
     *
     * @param classId
     * @return 状态说明(0,视频。1,音频。2,文档。3,练习。)
     */
    @ApiOperation(value = "获取班级所有课件-学习端", notes = "状态说明(0,视频。1,音频。2,文档。3,练习。)")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "sort", value = "排序方式(desc从大到小,asc从小到大)", required = false, paramType="query", dataType = "String"),
    })
    @GetMapping(value = "/app/getCoursewareLstByClassId")
    public Result appCoursewareLst(String classId, @RequestParam(defaultValue="desc")String sort, Pager pager) {
        System.out.println(classId);
        return clsLectureService.listSubjectLecture(CommonUtils.getClassId(classId), sort, pager);
    }
    //--------------------------------------------------------------app端接口---------------------------------------------------------------------------------------------------
    /**
     *
     * 学习端获取课程列表
     *
     */
    @ApiOperation(value = "学习端获取课程学年列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType="query", dataType = "String"),
    })
    @GetMapping(value = "/app/termList")
    public Result termList(String classId) {
        classId = CommonUtils.getClassId(classId);
        if(StringUtils.isEmpty(classId)) {
            return new Result(false, "班级id不能为空");
        }
        //课程
        List<Map<String, Object>> lstSubject = subjectService.clsSubjectlist(classId, null, null);
        //组装的学期和课程
        List<Map<String, Object>> lstTerm = subjectService.termSubjectList(classId, lstSubject);
        return new Result(true, "success",CollectionUtils.newObjectMap("termList", lstTerm, "allSubject", lstSubject));
    }
    /**
     *
     * 学习端获取课程列表
     *
     */
    @ApiOperation(value = "我的课程按学期分类")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType="query", dataType = "String"),
    })
    @GetMapping(value = "/app/myTermSubjectList")
    public Result myTermSubjectList(String classId) {
        classId = CommonUtils.getClassId(classId);
        System.out.println("vvvvvvvvv"+classId);
        if(StringUtils.isEmpty(classId)) {
            return new Result(false, "班级id不能为空");
        }
        return new Result(true, "success",subjectService.myTermSubjectList(classId));
    }
    /**
     *
     * 学习端获取课程列表
     *
     */
    @ApiOperation(value = "我的课程按时间排序")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType="query", dataType = "String"),
    })
    @GetMapping(value = "/app/mySubjectList")
    public Result mySubjectList(String classId, Pager pager ) {
//        System.out.println("0.0.0.0"+classId);
        classId = CommonUtils.getClassId(classId);
        long count = subjectService.myClsSubjectCount(classId);
        return new Result(true, "success",
                CollectionUtils.newObjectMap("count", count, "listData", subjectService.mySubjectList(classId, pager)));
    }
    /**
     * 我的课程详情
     *
     * @param subjectId
     * @param classId
     * @return
     */
    @ApiOperation(value = "我的课程详情")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "subjectId", value = "课程id", required = true, paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType="query", dataType = "String"),
    })
    @GetMapping(value = "/app/mySubjectInfo")
    public Result mySubjectInfo(String subjectId, String classId) {
        classId = CommonUtils.getClassId(classId);
        if(StringUtils.isEmpty(classId)) {
            return new Result(false, "班级id不能为空");
        }
        if(StringUtils.isEmpty(subjectId)) {
            return new Result(false, "课程id不能为空");
        }
        return new Result(true, "success", subjectService.mySubjectInfo(subjectId, classId));
    }
    /**
     *
     * 学习端获取课程列表
     *
     */
    @ApiOperation(value = "我的班级信息")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType="query", dataType = "String"),
    })
    @GetMapping(value = "/app/myClassInfo")
    public Result myClassInfo(String classId) {
        classId = ClientUtils.getClassId();
        if(StringUtils.isEmpty(classId)) {
            return new Result(false, "班级id不能为空");
        }
        return new Result(true, "success",subjectService.myClassInfo(classId));
    }
    /**
     *
     * 学习端获取课程列表
     *
     */
    @ApiOperation(value = "学习端获取课程列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "schoolYear", value = "学年", required = true, paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "term", value = "学期", required = true, paramType="query", dataType = "String")
    })
    @GetMapping(value = "/app/subjectList")
    public Result subjectList(String classId, Integer schoolYear, Integer term) {
        return new Result(true, "success",subjectService.clsSubjectlist(CommonUtils.getClassId(classId), schoolYear, term));
    }
    /**
     *
     * 学习端获取课程列表
     *
     */
    @ApiOperation(value = "学习端获取课程下课件,按创建时间排序")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "subjectId", value = "课程id", required = true, paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "sort", value = "排序方式(desc从大到小,asc从小到大)", required = false, paramType="query", dataType = "String"),
    })
    @GetMapping(value = "/app/listLectureBySubject")
    public Result listLectureBySubject(String subjectId, String classId, @RequestParam(defaultValue="desc")String sort, Pager pager) {
        return new Result(true, "success",clsLectureService.listLectureBySubjectOrderCreateTime(subjectId, CommonUtils.getClassId(classId), sort, pager));
    }
    /**
     *
     * 学习端获取其他课件统计
     *
     */
    @ApiOperation(value = "学习端获取其他课件统计")
    @GetMapping(value = "/app/otherLectureCount")
    public Result otherLectureCount() {
        return new Result(true, "success", CollectionUtils.newObjectMap("topicCount",
                topicService.getClassTopicCount(ClientUtils.getClassId()), "evaluate", this.evaluateService.queryStuEvaluateCount()));
    }
    /**
     *
     * 学习端获取课程列表
     *
     */
    @ApiOperation(value = "学习端获取课程下课件,按目录分类", notes = "")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "subjectId", value = "课程id", required = true, paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "type", value = "课件类型", required = false, paramType="query", dataType = "String")
    })
    @GetMapping(value = "/app/coursewareList")
    public Result coursewareList(String classId,String subjectId, String type) {
        classId = CommonUtils.getClassId(classId);
        if(StringUtils.isEmpty(subjectId)) {
            return new Result(false, "课程id不能为空");
        }
        return this.clsLectureService.coursewareChapterList(classId, subjectId, type);
    }
     /**
     * 我的公开课列表
    /**
     * 学习端获取 所有课件
     *
    */
     * @param classId
     * @return 状态说明(0, 视频 。 1, 音频 。 2, 文档 。 3, 练习 。)
     */
    @ApiOperation(value = "获取班级所有课件-学习端", notes = "状态说明(0,视频。1,音频。2,文档。3,练习。)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "sort", value = "排序方式(desc从大到小,asc从小到大)", required = false, paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "/app/getCoursewareLstByClassId")
    public Result appCoursewareLst(String classId, @RequestParam(defaultValue = "desc") String sort, Pager pager) {
        System.out.println(classId);
        return clsLectureService.listSubjectLecture(CommonUtils.getClassId(classId), sort, pager);
    }
    /**
     * 学习端获取课程列表
     */
    @ApiOperation(value = "学习端获取课程学年列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "/app/termList")
    public Result termList(String classId) {
        classId = CommonUtils.getClassId(classId);
        if (StringUtils.isEmpty(classId)) {
            return new Result(false, "班级id不能为空");
        }
        //课程
        List<Map<String, Object>> lstSubject = subjectService.clsSubjectlist(classId, null, null);
        //组装的学期和课程
        List<Map<String, Object>> lstTerm = subjectService.termSubjectList(classId, lstSubject);
        return new Result(true, "success", CollectionUtils.newObjectMap("termList", lstTerm, "allSubject", lstSubject));
    }
    /**
     * 学习端获取课程列表
     */
    @ApiOperation(value = "我的课程按学期分类")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "/app/myTermSubjectList")
    public Result myTermSubjectList(String classId) {
        classId = CommonUtils.getClassId(classId);
        System.out.println("vvvvvvvvv" + classId);
        if (StringUtils.isEmpty(classId)) {
            return new Result(false, "班级id不能为空");
        }
        return new Result(true, "success", subjectService.myTermSubjectList(classId));
    }
    /**
     * 学习端获取课程列表
     */
    @ApiOperation(value = "我的课程按时间排序")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "/app/mySubjectList")
    public Result mySubjectList(String classId, Pager pager) {
//        System.out.println("0.0.0.0"+classId);
        classId = CommonUtils.getClassId(classId);
        long count = subjectService.myClsSubjectCount(classId);
        return new Result(true, "success",
                CollectionUtils.newObjectMap("count", count, "listData", subjectService.mySubjectList(classId, pager)));
    }
    /**
     * 我的课程详情
     *
     * @param subjectId
     * @param classId
     * @return
     */
    @ApiOperation(value = "我的课程详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "subjectId", value = "课程id", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "/app/mySubjectInfo")
    public Result mySubjectInfo(String subjectId, String classId) {
        classId = CommonUtils.getClassId(classId);
        if (StringUtils.isEmpty(classId)) {
            return new Result(false, "班级id不能为空");
        }
        if (StringUtils.isEmpty(subjectId)) {
            return new Result(false, "课程id不能为空");
        }
        return new Result(true, "success", subjectService.mySubjectInfo(subjectId, classId));
    }
    /**
     * 学习端获取课程列表
     */
    @ApiOperation(value = "我的班级信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "/app/myClassInfo")
    public Result myClassInfo(String classId) {
        classId = ClientUtils.getClassId();
        if (StringUtils.isEmpty(classId)) {
            return new Result(false, "班级id不能为空");
        }
        return new Result(true, "success", subjectService.myClassInfo(classId));
    }
    /**
     * 学习端获取课程列表
     */
    @ApiOperation(value = "学习端获取课程列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "schoolYear", value = "学年", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "term", value = "学期", required = true, paramType = "query", dataType = "String")
    })
    @GetMapping(value = "/app/subjectList")
    public Result subjectList(String classId, Integer schoolYear, Integer term) {
        return new Result(true, "success", subjectService.clsSubjectlist(CommonUtils.getClassId(classId), schoolYear, term));
    }
    /**
     * 学习端获取课程列表
     */
    @ApiOperation(value = "学习端获取课程下课件,按创建时间排序")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "subjectId", value = "课程id", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "sort", value = "排序方式(desc从大到小,asc从小到大)", required = false, paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "/app/listLectureBySubject")
    public Result listLectureBySubject(String subjectId, String classId, @RequestParam(defaultValue = "desc") String sort, Pager pager) {
        return new Result(true, "success", clsLectureService.listLectureBySubjectOrderCreateTime(subjectId, CommonUtils.getClassId(classId), sort, pager));
    }
    /**
     * 学习端获取其他课件统计
     */
    @ApiOperation(value = "学习端获取其他课件统计")
    @GetMapping(value = "/app/otherLectureCount")
    public Result otherLectureCount() {
        return new Result(true, "success", CollectionUtils.newObjectMap("topicCount",
                topicService.getClassTopicCount(ClientUtils.getClassId()), "evaluate", this.evaluateService.queryStuEvaluateCount()));
    }
    /**
     * 学习端获取课程列表
     */
    @ApiOperation(value = "学习端获取课程下课件,按目录分类", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "subjectId", value = "课程id", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "type", value = "课件类型", required = false, paramType = "query", dataType = "String")
    })
    @GetMapping(value = "/app/coursewareList")
    public Result coursewareList(String classId, String subjectId, String type) {
        classId = CommonUtils.getClassId(classId);
        if (StringUtils.isEmpty(subjectId)) {
            return new Result(false, "课程id不能为空");
        }
        return this.clsLectureService.coursewareChapterList(classId, subjectId, type);
    }
    /**
     * 我的公开课列表
     */
    @ApiOperation(value = "我的公开课列表", notes = "")
       @GetMapping(value = "/app/myOpenSubjectList")
       public Result myOpenSubjectList(Pager pager, @RequestParam(defaultValue = "")String keyword) {
           return new Result(true, "success", this.subjectService.myOpenSubjectList(pager.getOffset(), pager.getPageSize(), keyword));
       }
    @GetMapping(value = "/app/myOpenSubjectList")
    public Result myOpenSubjectList(Pager pager, @RequestParam(defaultValue = "") String keyword) {
        return new Result(true, "success", this.subjectService.myOpenSubjectList(pager.getOffset(), pager.getPageSize(), keyword));
    }
    /**
     * 公开课列表
     *
    */
     */
    @ApiOperation(value = "公开课列表", notes = "")
       @GetMapping(value = "/app/openSubjectList")
       public Result openSubjectList(Pager pager, @RequestParam(defaultValue = "")String keyword) {
           return new Result(true, "success", this.subjectService.openSubjectList(pager.getOffset(), pager.getPageSize(), keyword));
       }
    @GetMapping(value = "/app/openSubjectList")
    public Result openSubjectList(Pager pager, @RequestParam(defaultValue = "") String keyword) {
        return new Result(true, "success", this.subjectService.openSubjectList(pager.getOffset(), pager.getPageSize(), keyword));
    }
    /**
     * 公开课详情
     *
     */
    @ApiOperation(value = "公开课详情", notes = "")
       @GetMapping(value = "/app/openSubjectInfo")
       public Result openSubjectInfo(@RequestParam(defaultValue = "")String subjectId) {
           return new Result(true, "success", this.subjectService.openSubjectInfo(subjectId));
       }
    @GetMapping(value = "/app/openSubjectInfo")
    public Result openSubjectInfo(@RequestParam(defaultValue = "") String subjectId) {
        return new Result(true, "success", this.subjectService.openSubjectInfo(subjectId));
    }
    //--------------------------------------------------------后台端接口---------------------------------------------------------------------------------------------------
    //--------------------------------------------------------后台端接口---------------------------------------------------------------------------------------------------
    /**
     * 加载课件tree
     */
    @ApiOperation(value = "加载课件tree", notes = "")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "subjectId", value = "班级id", required = false, paramType="query", dataType = "String")
    })
    @GetMapping(value = "categoryTree")
    public Result categoryTree(String subjectId, String parentId) {
    /**
     * 加载课件tree
     */
    @ApiOperation(value = "加载课件tree", notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "subjectId", value = "班级id", required = false, paramType = "query", dataType = "String")
    })
    @GetMapping(value = "categoryTree")
    public Result categoryTree(String subjectId, String parentId) {
//        classId = StringUtils.isEmpty(classId)?ClientUtils.getClassId():classId;
        List<SubjectProgressTreeV> chapterLst = clsLectureService.getChapterTreeVList(subjectId, parentId);
        List<SubjectProgressTreeV> chapterLst = clsLectureService.getChapterTreeVList(subjectId, parentId);
        for (SubjectProgressTreeV v : chapterLst) {
            v.setNodeName(v.getNodeName() + "(" + String.format("%.2f", v.getPercent()*100) + "%)"); //保留两位小数
        }
        for (SubjectProgressTreeV v : chapterLst) {
            v.setNodeName(v.getNodeName() + "(" + String.format("%.2f", v.getPercent() * 100) + "%)"); //保留两位小数
        }
        return new Result(true, "success", QBeanUtils.listBean2ListMap(chapterLst, CollectionUtils
                .newStringMap("nodeName", "name", "id.nodeId", "id", "parentId", "parentId", "percent", "percent")));
    }
        return new Result(true, "success", QBeanUtils.listBean2ListMap(chapterLst, CollectionUtils
                .newStringMap("nodeName", "name", "id.nodeId", "id", "parentId", "parentId", "percent", "percent")));
    }
    /**
     * 学习端获取 所有课件
     *
     * @param classId
     * @return 状态说明(0,视频。1,音频。2,文档。3,练习。)
     */
    @ApiOperation(value = "学习端获取 所有课件", notes = "状态说明(0,视频。1,音频。2,文档。3,练习。)")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "subjectId", value = "班级id", required = false, paramType="query", dataType = "String")
    })
    @GetMapping(value = "getCoursewareLstByClassId")
    public Result getCoursewareLst(String subjectId) {
        List<ClsSubjectLecture> lectureLst = clsLectureService.listLecture(subjectId);
    /**
     * 学习端获取 所有课件
     *
     * @param classId
     * @return 状态说明(0, 视频 。 1, 音频 。 2, 文档 。 3, 练习 。)
     */
    @ApiOperation(value = "学习端获取 所有课件", notes = "状态说明(0,视频。1,音频。2,文档。3,练习。)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "subjectId", value = "班级id", required = false, paramType = "query", dataType = "String")
    })
    @GetMapping(value = "getCoursewareLstByClassId")
    public Result getCoursewareLst(String subjectId) {
        List<ClsSubjectLecture> lectureLst = clsLectureService.listLecture(subjectId);
        // id为小节id //返回的数据按照tree的小节排序
        return new Result(true, "success",
        // id为小节id //返回的数据按照tree的小节排序
        return new Result(true, "success",
                QBeanUtils.listBean2ListMap(lectureLst, CollectionUtils.newStringMap("name", "name", "lectureId", "id",
                        "lectureType", "type", "chapterId", "chapterId")));
    }
                QBeanUtils.listBean2ListMap(lectureLst, CollectionUtils.newStringMap("name", "name", "lectureId", "id",
                        "lectureType", "type", "chapterId", "chapterId")));
    }
    /**
     * 获取课件列表
     *
     * @param chapterId
     *            章节id
     * @param type
     *            课件类型
     * @param keyword
     *            搜索关键字
     * @param limit
     *            每页显示几条
     * @param pageNum
     *            页码
     * @return 状态说明(0,视频。1,音频。2,文档。3,练习。)
     */
    @ApiOperation(value = "根据章节获取课件列表", notes = "状态说明(0,视频。1,音频。2,文档。3,练习。)")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "chapterId", value = "章节id", required = true, paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "type", value = "课件类型", required = false, paramType="query", dataType = "String")
    })
    @GetMapping(value = "coursewareListByChapterId")
    public Result coursewareList(String chapterId, String type, String keyword, Integer limit, @RequestParam(defaultValue="1")Integer pageNum) {
    /**
     * 获取课件列表
     *
     * @param chapterId 章节id
     * @param type      课件类型
     * @param keyword   搜索关键字
     * @param limit     每页显示几条
     * @param pageNum   页码
     * @return 状态说明(0, 视频 。 1, 音频 。 2, 文档 。 3, 练习 。)
     */
    @ApiOperation(value = "根据章节获取课件列表", notes = "状态说明(0,视频。1,音频。2,文档。3,练习。)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "chapterId", value = "章节id", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "type", value = "课件类型", required = false, paramType = "query", dataType = "String")
    })
    @GetMapping(value = "coursewareListByChapterId")
    public Result coursewareList(String chapterId, String type, String keyword, Integer limit, @RequestParam(defaultValue = "1") Integer pageNum) {
        List<MyLectureV> lectures = clsLectureService.listLectureV(ClientUtils.getUserId(), chapterId, keyword, limit,
                pageNum, type);
        List<MyLectureV> lectures = clsLectureService.listLectureV(ClientUtils.getUserId(), chapterId, keyword, limit,
                pageNum, type);
        return new Result(true, "success",
                CollectionUtils.newObjectMap("coursewareLst",
                        QBeanUtils.listBean2ListMap(lectures,
                                CollectionUtils.newStringMap("lectureName", "name", "id.lectureId", "id", "lectureType",
                                        "type", "lectureUpdateTime", "endUpdateTime", "percent", "percent"))));
        return new Result(true, "success",
                CollectionUtils.newObjectMap("coursewareLst",
                        QBeanUtils.listBean2ListMap(lectures,
                                CollectionUtils.newStringMap("lectureName", "name", "id.lectureId", "id", "lectureType",
                                        "type", "lectureUpdateTime", "endUpdateTime", "percent", "percent"))));
    }
    }
    /**
     * 课件学习进度提交 stu/subject/study
     *
     * @param lectureId
     *            课件id
     * @param from
     *            开始学习位置 ,如视频,则为时分秒(00:10:12),如文档,则无需提交该参数
     * @param to
     *            结束学习位置,同to
     */
    @ApiOperation(value = "提交学习进度")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "lectureId", value = "课件id", required = true, paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "from", value = "开始学习位置 ,如视频,则为时分秒(00:10:12),如文档,则无需提交该参数", required = true, paramType="query", dataType = "Double"),
        @ApiImplicitParam(name = "to", value = "结束学习位置,同to", required = true, paramType="query", dataType = "Double"),
        @ApiImplicitParam(name = "subjectId", value = "课程id", required = true, paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "lectureParentId", value = "父课件id", required = false, paramType="query", dataType = "String"),
    })
    @GetMapping(value = "study")
    public Result study(String lectureId, @RequestParam(defaultValue = "1") Double from,
            @RequestParam(defaultValue = "0") Double to, String subjectId, String classId, String lectureParentId) {
        String userId = ClientUtils.getUserId();
        classId = CommonUtils.getClassId(classId);
        progressDao.putStudyById(userId, subjectId, lectureId, lectureParentId, classId);// 记录学员每个课程的学习位置;
        progressDao.putStudyByUserId(userId, subjectId, lectureId, lectureParentId, classId);// 记录学员上次学习的位置;
        return clsLectureService.doStudy(lectureId, from, to);
    }
    /**
     * 课件学习进度提交 stu/subject/study
     *
     * @param lectureId 课件id
     * @param from      开始学习位置 ,如视频,则为时分秒(00:10:12),如文档,则无需提交该参数
     * @param to        结束学习位置,同to
     */
    @ApiOperation(value = "提交学习进度")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "lectureId", value = "课件id", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "from", value = "开始学习位置 ,如视频,则为时分秒(00:10:12),如文档,则无需提交该参数", required = true, paramType = "query", dataType = "Double"),
            @ApiImplicitParam(name = "to", value = "结束学习位置,同to", required = true, paramType = "query", dataType = "Double"),
            @ApiImplicitParam(name = "subjectId", value = "课程id", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "lectureParentId", value = "父课件id", required = false, paramType = "query", dataType = "String"),
    })
    @GetMapping(value = "study")
    public Result study(String lectureId, @RequestParam(defaultValue = "1") Double from,
                        @RequestParam(defaultValue = "0") Double to, String subjectId, String classId, String lectureParentId) {
        String userId = ClientUtils.getUserId();
        classId = CommonUtils.getClassId(classId);
        progressDao.putStudyById(userId, subjectId, lectureId, lectureParentId, classId);// 记录学员每个课程的学习位置;
        progressDao.putStudyByUserId(userId, subjectId, lectureId, lectureParentId, classId);// 记录学员上次学习的位置;
        return clsLectureService.doStudy(lectureId, from, to);
    }
    /**
     * 音频时长提交 stu/subject/submitAudioDuration
     *
     * @param lectureId
     *            课件id
     * @param seconds
     *            时长
     */
    @ApiOperation(value = "音频时长提交")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "lectureId", value = "课件id", required = true, paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "seconds", value = "时长", required = true, paramType="query", dataType = "Double")
    })
    @CacheEvict(value = "LectureAudioV", key = "#lectureId")
    @GetMapping(value = "submitAudioDuration")
    public Result submitAudioDuration(String lectureId, double seconds) {
    /**
     * 音频时长提交 stu/subject/submitAudioDuration
     *
     * @param lectureId 课件id
     * @param seconds   时长
     */
    @ApiOperation(value = "音频时长提交")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "lectureId", value = "课件id", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "seconds", value = "时长", required = true, paramType = "query", dataType = "Double")
    })
    @CacheEvict(value = "LectureAudioV", key = "#lectureId")
    @GetMapping(value = "submitAudioDuration")
    public Result submitAudioDuration(String lectureId, double seconds) {
        LectureAudioV audio = lectureService.readAudioLecture(lectureId);
        LectureAudioV audio = lectureService.readAudioLecture(lectureId);
        return audioService.updateDuration(audio.getAudioId(), (int) seconds);
        return audioService.updateDuration(audio.getAudioId(), (int) seconds);
    }
    }
    /**
     * 课程列表
     *
     * @param clssId
     *            班级id
     * @param startTime
     *            开班时间
     */
    @ApiOperation(value = "课程列表")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType="query", dataType = "String"),
        @ApiImplicitParam(name = "startTime", value = "开班时间", required = false, paramType="query", dataType = "String")
    })
    @GetMapping(value = "getSubjectLst")
    public Result getList(String userId,String classId, String startTime, Integer limit, @RequestParam(defaultValue="1")Integer pageNum, HttpServletRequest request) {
        userId = StringUtils.isEmpty(userId)?ClientUtils.getUserId():userId;
        if(userId == null || userId == ""){
            userId = ClientUtils.getUserId();
        }
        classId = StringUtils.isEmpty(classId)?ClientUtils.getClassId():classId;
        List<MySubjectV> result = subjectService.listMySubjectV(classId,userId);
        return new Result(true, "success",
                QBeanUtils.listBean2ListMap(result,
                        CollectionUtils.newStringMap("id.subjectId", "subjectId", "id.classId", "classId",
                                "subjectName", "subjectName,coursewareName", "percent", "percent", "progressValue",
                                "studyTime", "coverPageUrl", "coverPageUrl")));
    }
    /**
     * 课程列表
     *
     * @param clssId    班级id
     * @param startTime 开班时间
     */
    @ApiOperation(value = "课程列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "classId", value = "班级id", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "startTime", value = "开班时间", required = false, paramType = "query", dataType = "String")
    })
    @GetMapping(value = "getSubjectLst")
    public Result getList(String userId, String classId, String startTime, Integer limit, @RequestParam(defaultValue = "1") Integer pageNum, HttpServletRequest request) {
        userId = StringUtils.isEmpty(userId) ? ClientUtils.getUserId() : userId;
        classId = StringUtils.isEmpty(classId) ? ClientUtils.getClassId() : classId;
        List<MySubjectV> resultMs = subjectService.listMySubjectV(classId, userId);
        List<MySubjectV> result = new ArrayList<>();
        List<Object> lecurelist = new ArrayList<>();
        int i = 0;
        for(MySubjectV ms : resultMs){
            SubjectUtils subjectUtils = new SubjectUtils();
            List<MyLectureV> myLectureVList = lectureService.listLectureVBySubjectId(userId, ms.getId().getSubjectId(), "", 1000, 1, null);
            Double percent = 0.0;
            Double progressValue = 0.0;
            Double percentAvg = 0.0;
            if(!myLectureVList.isEmpty()) {
                for (MyLectureV myLectureV : myLectureVList) {
                    if (myLectureV.getPercent() != null && myLectureV.getProgressValue() != null) {
                        percent += myLectureV.getPercent();
                        progressValue += myLectureV.getProgressValue().intValue();
                    }
                }
                percentAvg = percent / myLectureVList.size();
                if (percentAvg.isNaN()) {
                    percentAvg = 0.0;
                }
                subjectUtils.setCoursewareName(myLectureVList.get(0).getLectureName());
                subjectUtils.setSubjectId(myLectureVList.get(0).getSubjectId());
                subjectUtils.setPercent(new BigDecimal(percentAvg));
                subjectUtils.setStudyTime(new BigDecimal(progressValue));
            }else {
                subjectUtils.setCoursewareName(null);
                subjectUtils.setSubjectId(ms.getId().getSubjectId());
                subjectUtils.setPercent(new BigDecimal(percentAvg));
                subjectUtils.setStudyTime(new BigDecimal(progressValue));
            }
            result.add(ms);
            lecurelist.add(subjectUtils);
        }
        return new Result(true, "success",
                CollectionUtils.newObjectMap("subjectList",
                QBeanUtils.listBean2ListMap(result,
                        CollectionUtils.newStringMap("id.subjectId", "subjectId", "id.classId", "classId",
                                "subjectName", "subjectName", "percent", "percent", "progressValue",
                                "studyTime", "coverPageUrl", "coverPageUrl")),"lecurelist",lecurelist));
    }
    /**
     * 进入课程
     *
     * @param subjectId
     *            课程id
     */
    @ApiOperation(value = "课程详情")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "subjectId", value = "课程id", required = false, paramType="query", dataType = "String")
    })
    @GetMapping(value = "getSubjectDetail")
    public Result getSubjectDetail(String subjectId) {
        MySubjectV subject = subjectService.getMy1stSubjectVById(subjectId);
    /**
     * 进入课程
     *
     * @param subjectId 课程id
     */
    @ApiOperation(value = "课程详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "subjectId", value = "课程id", required = false, paramType = "query", dataType = "String")
    })
    @GetMapping(value = "getSubjectDetail")
    public Result getSubjectDetail(String subjectId) {
        MySubjectV subject = subjectService.getMy1stSubjectVById(subjectId);
        List<Map<String, Object>> progressLst = subjectService.listChapterStudyProgress(subjectId);
        List<Map<String, Object>> progressLst = subjectService.listChapterStudyProgress(subjectId);
        List<MyLectureV> myLectureVList = lectureService.listLectureVBySubjectId(ClientUtils.getUserId(), subjectId, "", 1000, 1, null);
        Double percent = 0.0;
        Double progressValue = 0.0;
        String coursewareName = null;
        if(!myLectureVList.isEmpty()) {
             for (MyLectureV myLectureV : myLectureVList) {
                if (myLectureV.getPercent() != null && myLectureV.getProgressValue() != null) {
                    percent += myLectureV.getPercent();
                    progressValue += myLectureV.getProgressValue().intValue();
                }
             }
            Double percentAvg = percent / myLectureVList.size();
            if (percentAvg.isNaN()) {
                percentAvg = 0.0;
        }
            subject.setPercent(percentAvg);
            subject.setProgressValue(new BigDecimal(progressValue));
            progressLst.get(0).put("percent", subject.getPercent());
            progressLst.get(0).put("studyTime", subject.getProgressValue());
            coursewareName = myLectureVList.get(0).getLectureName();
        }else {
        return new Result(true, "success",
                CollectionUtils.newObjectMap("subject", QBeanUtils.bean2Map(subject,
                        CollectionUtils.newStringMap("subjectName", "subjectName", "id.subjectId", "subjectId",
                                "progressValue", "studyTime", "percent", "percent", "coverPageUrl", "coverPageUrl")),
                        "chapterLst",progressLst));
    }
        }
        return new Result(true, "success",
                CollectionUtils.newObjectMap("subject", QBeanUtils.bean2Map(subject,
                        CollectionUtils.newStringMap("subjectName", "subjectName", "id.subjectId", "subjectId",
                                "progressValue", "studyTime", "percent", "percent", "coverPageUrl", "coverPageUrl")),
                        "chapterLst", progressLst,"coursewareName",coursewareName));
    }
}
src/main/java/com/qxueyou/scc/sys/utils/AudioUtil.java
New file
@@ -0,0 +1,103 @@
package com.qxueyou.scc.sys.utils;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.mp3.MP3AudioHeader;
import org.jaudiotagger.audio.mp3.MP3File;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import java.io.File;
public class AudioUtil {
    /**
     * 获取语音文件播放时长(秒) 支持wav 格式
     * @param filePath
     * @return
     */
    public static Float getDuration(String filePath){
        try{
            File destFile = new File(filePath);
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(destFile);
            AudioFormat format = audioInputStream.getFormat();
            long audioFileLength = destFile.length();
            int frameSize = format.getFrameSize();
            float frameRate = format.getFrameRate();
            float durationInSeconds = (audioFileLength / (frameSize * frameRate));
            return durationInSeconds;
        }catch (Exception e){
            e.printStackTrace();
            return 0f;
        }
    }
    /**
     * 获取mp3语音文件播放时长(秒) mp3
     * @param filePath
     * @return
     */
    public static Float getMp3Duration(String filePath){
        try {
            File mp3File = new File(filePath);
            MP3File f = (MP3File) AudioFileIO.read(mp3File);
            MP3AudioHeader audioHeader = (MP3AudioHeader)f.getAudioHeader();
            return Float.parseFloat(audioHeader.getTrackLength()+"");
        } catch(Exception e) {
            e.printStackTrace();
            return 0f;
        }
    }
    /**
     * 获取mp3语音文件播放时长(秒)
     * @param mp3File
     * @return
     */
    public static Float getMp3Duration(File mp3File){
        try {
            //File mp3File = new File(filePath);
            MP3File f = (MP3File) AudioFileIO.read(mp3File);
            MP3AudioHeader audioHeader = (MP3AudioHeader)f.getAudioHeader();
            return Float.parseFloat(audioHeader.getTrackLength()+"");
        } catch(Exception e) {
            e.printStackTrace();
            return 0f;
        }
    }
    /**
     * 得到pcm文件的毫秒数
     *
     * pcm文件音频时长计算
     * 同图像bmp文件一样,pcm文件保存的是未压缩的音频信息。 16bits 编码是指,每次采样的音频信息用2个字节保存。可以对比下bmp文件用分别用2个字节保存RGB颜色的信息。 16000采样率 是指 1秒钟采样 16000次。常见的音频是44100HZ,即一秒采样44100次。 单声道: 只有一个声道。
     *
     * 根据这些信息,我们可以计算: 1秒的16000采样率音频文件大小是 2*16000 = 32000字节 ,约为32K 1秒的8000采样率音频文件大小是 2*8000 = 16000字节 ,约为 16K
     *
     * 如果已知录音时长,可以根据文件的大小计算采样率是否正常。
     * @param filePath
     * @return
     */
    public static long getPCMDurationMilliSecond(String filePath) {
        File file = new File(filePath);
        //得到多少秒
        long second = file.length() / 32000 ;
        long milliSecond = Math.round((file.length() % 32000)   / 32000.0  * 1000 ) ;
        return second * 1000 + milliSecond;
    }
}
src/main/java/com/qxueyou/scc/sys/utils/VideoUtil.java
New file
@@ -0,0 +1,86 @@
package com.qxueyou.scc.sys.utils;
import com.coremedia.iso.IsoFile;
import java.io.IOException;
public class VideoUtil {
    /**
     * 获取视频文件的播放长度(mp4、mov格式)
     * @param videoPath
     * @return 单位为毫秒
     */
    public static long getMp4Duration(String videoPath) throws IOException {
        IsoFile isoFile = new IsoFile(videoPath);
        long lengthInSeconds =
                isoFile.getMovieBox().getMovieHeaderBox().getDuration() /
                        isoFile.getMovieBox().getMovieHeaderBox().getTimescale();
        return lengthInSeconds;
    }
    /**
     * 得到语音或视频文件时长,单位秒
     * @param filePath
     * @return
     * @throws IOException
     */
    public static long getDuration(String filePath) throws IOException {
        String format = getVideoFormat(filePath);
        long result = 0;
        if("wav".equals(format)){
            result = AudioUtil.getDuration(filePath).intValue();
        }else if("mp3".equals(format)){
            result = AudioUtil.getMp3Duration(filePath).intValue();
        }else if("m4a".equals(format)) {
            result = VideoUtil.getMp4Duration(filePath);
        }else if("mov".equals(format)){
            result = VideoUtil.getMp4Duration(filePath);
        }else if("mp4".equals(format)){
            result = VideoUtil.getMp4Duration(filePath);
        }
        return result;
    }
    /**
     * 得到语音或视频文件时长,单位秒
     * @param filePath
     * @return
     * @throws IOException
     */
    public static long getDuration(String filePath,String format) throws IOException {
        long result = 0;
        if("wav".equals(format)){
            result = AudioUtil.getDuration(filePath).intValue();
        }else if("mp3".equals(format)){
            result = AudioUtil.getMp3Duration(filePath).intValue();
        }else if("m4a".equals(format)) {
            result = VideoUtil.getMp4Duration(filePath);
        }else if("mov".equals(format)){
            result = VideoUtil.getMp4Duration(filePath);
        }else if("mp4".equals(format)){
            result = VideoUtil.getMp4Duration(filePath);
        }
        return result;
    }
    /**
     * 得到文件格式
     * @param path
     * @return
     */
    public static String getVideoFormat(String path){
        return  path.toLowerCase().substring(path.toLowerCase().lastIndexOf(".") + 1);
    }
}
src/main/java/com/qxueyou/scc/teach/res/service/impl/resitem/ResItemAudioService.java
@@ -2,9 +2,12 @@
import java.util.Date;
import com.qxueyou.scc.sys.utils.AudioUtil;
import com.qxueyou.scc.sys.utils.VideoUtil;
import com.qxueyou.scc.teach.res.model.ResItemVideo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.qxueyou.scc.base.model.Result;
@@ -28,16 +31,24 @@
    @Autowired
    ICacheService cacheService;
    @Value("${scc.resRootPath}")
    String resRootPath;
    @Override
    public String add(String fileId, String name) {
        ResFile file = fileService.read(fileId);
        String mediaVideoId = addVideoConverTask(file);
        ResItemAudio audio = new ResItemAudio();
        TraceUtils.setCreateTrace(audio);
        audio.setStatus(ResItemAudio.STATUS_LINEUP);
        audio.setFileId(fileId);
        audio.setName(name);
        audio.setMediaVideoId(mediaVideoId);
        try {
            audio.setStatus(ResItemAudio.STATUS_LINEUP);
            audio.setPlayTime(AudioUtil.getMp3Duration(resRootPath+"/"+file.getPath()).intValue());
            audio.setFileId(fileId);
            audio.setName(name);
            audio.setMediaVideoId(mediaVideoId);
        }catch (Exception e){
            e.printStackTrace();
        }
        // 将mediaVideoId放进缓存
        cacheService.lstRightPush(ResItemVideoService.RES_VIDEO_CONVER_LST, mediaVideoId);
        save(audio);
@@ -61,10 +72,16 @@
        TraceUtils.setCreateTrace(video);
        video.setDeleteFlag(false);
        video.setName(file.getFileName());
        video.setOrigUrl(file.getPath());
        video.setStatus(MediaVideo.STATUS_LINEUP);
        video.setType(MediaVideo.MEDIA_AUDIO);
        try {
            video.setDeleteFlag(false);
            video.setPlayTime((int) VideoUtil.getMp4Duration(resRootPath +"/"+ file.getPath()));
            video.setName(file.getFileName());
            video.setOrigUrl(file.getPath());
            video.setStatus(MediaVideo.STATUS_LINEUP);
            video.setType(MediaVideo.MEDIA_AUDIO);
        }catch (Exception e){
            e.printStackTrace();
        }
        save(video);
src/main/java/com/qxueyou/scc/teach/res/service/impl/resitem/ResItemVideoService.java
@@ -1,10 +1,14 @@
package com.qxueyou.scc.teach.res.service.impl.resitem;
import java.io.File;
import java.util.Date;
import com.qxueyou.scc.sys.utils.VideoUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@@ -27,159 +31,169 @@
@Service(value = "ResItemVideoService")
public class ResItemVideoService extends CommonAppService implements IResItemService {
    public static final String RES_VIDEO_CONVER_LST = "RES_VIDEO_CONVER_LST";
    public static final String RES_VIDEO_CONVER_LST = "RES_VIDEO_CONVER_LST";
    @Autowired
    IFileService fileService;
    @Autowired
    IFileService fileService;
    @Autowired
    ICacheService cacheService;
    @Autowired
    ICacheService cacheService;
    @Override
    public String add(String fileId, String name) {
    @Value("${scc.resRootPath}")
    String resRootPath;
        ResFile file = fileService.read(fileId);
        String mediaVideoId = addVideoConverTask(file);
    @Override
    public String add(String fileId, String name) {
            ResFile file = fileService.read(fileId);
            String mediaVideoId = addVideoConverTask(file);
        ResItemVideo resVideo = new ResItemVideo();
            ResItemVideo resVideo = new ResItemVideo();
        TraceUtils.setCreateTrace(resVideo);
            TraceUtils.setCreateTrace(resVideo);
        try {
            resVideo.setFileId(fileId);
            resVideo.setPlayTime((int) VideoUtil.getMp4Duration(resRootPath +"/"+ file.getPath()));
            resVideo.setName(name);
            resVideo.setMediaVideoId(mediaVideoId);
            resVideo.setStatus(ResItemVideo.STATUS_LINEUP);
            save(resVideo);
        resVideo.setFileId(fileId);
        resVideo.setName(name);
        resVideo.setMediaVideoId(mediaVideoId);
        resVideo.setStatus(ResItemVideo.STATUS_LINEUP);
        save(resVideo);
            // 将mediaVideoId放进缓存
            cacheService.lstRightPush(RES_VIDEO_CONVER_LST, mediaVideoId);
        }catch (Exception e){
            e.printStackTrace();
        }
        return resVideo.getVideoId();
    }
        // 将mediaVideoId放进缓存
        cacheService.lstRightPush(RES_VIDEO_CONVER_LST, mediaVideoId);
    private String addVideoConverTask(ResFile file) {
        return resVideo.getVideoId();
    }
        MediaVideo video = insertMediaVideo(file);
        insertMediaVideoConverTask(video);
    private String addVideoConverTask(ResFile file) {
        return video.getVideoId();
        MediaVideo video = insertMediaVideo(file);
        insertMediaVideoConverTask(video);
    }
        return video.getVideoId();
    private MediaVideo insertMediaVideo(ResFile file) {
    }
        MediaVideo video = new MediaVideo();
    private MediaVideo insertMediaVideo(ResFile file) {
        TraceUtils.setCreateTrace(video);
        MediaVideo video = new MediaVideo();
        try {
            video.setDeleteFlag(false);
            video.setPlayTime((int) VideoUtil.getMp4Duration(resRootPath +"/"+ file.getPath()));
            video.setName(file.getFileName());
            video.setOrigUrl(file.getPath());
            video.setStatus(MediaVideo.STATUS_LINEUP);
            video.setType(MediaVideo.MEDIA_VIDEO);
        }catch (Exception e){
            e.printStackTrace();
        }
        TraceUtils.setCreateTrace(video);
        save(video);
        video.setDeleteFlag(false);
        video.setName(file.getFileName());
        video.setOrigUrl(file.getPath());
        video.setStatus(MediaVideo.STATUS_LINEUP);
        video.setType(MediaVideo.MEDIA_VIDEO);
        return video;
    }
        save(video);
    private Result insertMediaVideoConverTask(MediaVideo resVideo) {
        return video;
    }
        VideoConverTask task = new VideoConverTask();
    private Result insertMediaVideoConverTask(MediaVideo resVideo) {
        task.setCreateTime(new Date());
        task.setDeleteFlag(false);
        task.setVideoId(resVideo.getVideoId());
        task.setVideoUrl(resVideo.getOrigUrl());
        task.setType(MediaVideo.MEDIA_VIDEO);
        task.setPriority(5);
        VideoConverTask task = new VideoConverTask();
        save(task);
        task.setCreateTime(new Date());
        task.setDeleteFlag(false);
        task.setVideoId(resVideo.getVideoId());
        task.setVideoUrl(resVideo.getOrigUrl());
        task.setType(MediaVideo.MEDIA_VIDEO);
        task.setPriority(5);
        return new Result(true);
    }
        save(task);
    @Override
    public Result update(String id, String name) {
        return new Result(true);
    }
        ResItemVideo video = read(ResItemVideo.class, id);
    @Override
    public Result update(String id, String name) {
        TraceUtils.setUpdateTrace(video);
        ResItemVideo video = read(ResItemVideo.class, id);
        video.setName(name);
        TraceUtils.setUpdateTrace(video);
        save(video);
        video.setName(name);
        return new Result(true, "success");
    }
        save(video);
    @Override
    public String readAccessPath(String resId, String attribute) {
        return new Result(true, "success");
    }
        ResItemVideo resItemVideo = read(ResItemVideo.class, resId);
    @Override
    public String readAccessPath(String resId, String attribute) {
        ResItemVideo resItemVideo = read(ResItemVideo.class, resId);
        if (resItemVideo != null && resItemVideo.getStatus() != ResItemVideo.STATUS_DRAFT) {
            ResFile resFile = read(ResFile.class,resItemVideo.getFileId());
            return resFile.getPath();
        if (resItemVideo != null && resItemVideo.getStatus() != ResItemVideo.STATUS_DRAFT) {
            ResFile resFile = read(ResFile.class, resItemVideo.getFileId());
            return resFile.getPath();
//            return null;
        }
        }
        MediaVideo video = read(MediaVideo.class, resItemVideo.getMediaVideoId());
        MediaVideo video = read(MediaVideo.class, resItemVideo.getMediaVideoId());
        if (video == null) {
            return null;
        }
        if (video == null) {
            return null;
        }
        return JSONObject.toJSONString(CollectionUtils.newObjectMap("hd",video.getAndroidHD(), "sd", video.getAndroidSD(), "ld", video.getAndroidLD(), "path",StringUtils.isNotEmpty(video.getAndroidHD()) ? video.getAndroidHD()
                : StringUtils.isNotEmpty(video.getAndroidSD()) ? video.getAndroidSD() : video.getAndroidLD()));
        return JSONObject.toJSONString(CollectionUtils.newObjectMap("hd", video.getAndroidHD(), "sd", video.getAndroidSD(), "ld", video.getAndroidLD(), "path", StringUtils.isNotEmpty(video.getAndroidHD()) ? video.getAndroidHD()
                : StringUtils.isNotEmpty(video.getAndroidSD()) ? video.getAndroidSD() : video.getAndroidLD()));
    }
    }
    @Override
    public String getResItemType() {
        return Res.FILE_TYPE_VIDEO;
    }
    @Override
    public String getResItemType() {
        return Res.FILE_TYPE_VIDEO;
    }
    /**
     * 定时器转码成功后 同步更新ResItemVideo的状态
     */
    @Scheduled(cron = "0/2 * * * * ?") // 每2秒执行一次
    public void doTimer() {
    /**
     * 定时器转码成功后 同步更新ResItemVideo的状态
     */
    @Scheduled(cron = "0/2 * * * * ?") // 每2秒执行一次
    public void doTimer() {
        String mediaVideoId = cacheService.lstLeftPop(RES_VIDEO_CONVER_LST);
        String mediaVideoId = cacheService.lstLeftPop(RES_VIDEO_CONVER_LST);
        if (StringUtils.isBlank(mediaVideoId)) {
            return;
        }
        if (StringUtils.isBlank(mediaVideoId)) {
            return;
        }
        MediaVideo mediaVideo = read(MediaVideo.class, mediaVideoId);
        if (mediaVideo.getStatus() == MediaVideo.STATUS_DRAFT) {
            if (mediaVideo.getType().equals("video")) {
                ResItemVideo resItemVideo = findUnique(
                        "from ResItemVideo where deleteFlag is false and mediaVideoId = ?",
                        CollectionUtils.newList(mediaVideoId), ResItemVideo.class);
                resItemVideo.setStatus(ResItemVideo.STATUS_DRAFT);
                TraceUtils.setUpdateTrace(resItemVideo);
                resItemVideo.setVideoSeconds(mediaVideo.getPlayTime());
                save(resItemVideo);
        MediaVideo mediaVideo = read(MediaVideo.class, mediaVideoId);
        if (mediaVideo.getStatus() == MediaVideo.STATUS_DRAFT) {
            if (mediaVideo.getType().equals("video")) {
                ResItemVideo resItemVideo = findUnique(
                        "from ResItemVideo where deleteFlag is false and mediaVideoId = ?",
                        CollectionUtils.newList(mediaVideoId), ResItemVideo.class);
                resItemVideo.setStatus(ResItemVideo.STATUS_DRAFT);
                TraceUtils.setUpdateTrace(resItemVideo);
                resItemVideo.setVideoSeconds(mediaVideo.getPlayTime());
                save(resItemVideo);
                cacheService.lstRightPush(ResService.RES_TOUPDATE_CONVER_STATUS_LST, resItemVideo.getVideoId());// 将转码完成后的文件id放入缓存。
                return;
            } else if (mediaVideo.getType().equals("audio")) {
                ResItemAudio resItemAudio = findUnique(
                        "from ResItemAudio where deleteFlag is false and mediaVideoId = ?",
                        CollectionUtils.newList(mediaVideoId), ResItemAudio.class);
                resItemAudio.setStatus(ResItemVideo.STATUS_DRAFT);
                TraceUtils.setUpdateTrace(resItemAudio);
                resItemAudio.setSeconds(mediaVideo.getPlayTime());
                save(resItemAudio);
                cacheService.lstRightPush(ResService.RES_TOUPDATE_CONVER_STATUS_LST, resItemVideo.getVideoId());// 将转码完成后的文件id放入缓存。
                return;
            } else if (mediaVideo.getType().equals("audio")) {
                ResItemAudio resItemAudio = findUnique(
                        "from ResItemAudio where deleteFlag is false and mediaVideoId = ?",
                        CollectionUtils.newList(mediaVideoId), ResItemAudio.class);
                resItemAudio.setStatus(ResItemVideo.STATUS_DRAFT);
                TraceUtils.setUpdateTrace(resItemAudio);
                resItemAudio.setSeconds(mediaVideo.getPlayTime());
                save(resItemAudio);
                cacheService.lstRightPush(ResService.RES_TOUPDATE_CONVER_STATUS_LST, resItemAudio.getAudioId());// 将转码完成后的文件id放入缓存。
                return;
            }
                cacheService.lstRightPush(ResService.RES_TOUPDATE_CONVER_STATUS_LST, resItemAudio.getAudioId());// 将转码完成后的文件id放入缓存。
                return;
            }
        }
        cacheService.lstRightPush(RES_VIDEO_CONVER_LST, mediaVideoId);
        }
        cacheService.lstRightPush(RES_VIDEO_CONVER_LST, mediaVideoId);
    }
    }
}
src/main/java/com/qxueyou/scc/teach/subject/model/SubjectUtils.java
New file
@@ -0,0 +1,46 @@
package com.qxueyou.scc.teach.subject.model;
import javax.persistence.Entity;
import java.math.BigDecimal;
/**
 * 工具类 用来缓存课程信息
 */
public class SubjectUtils implements java.io.Serializable {
    private String subjectId;
    private BigDecimal percent;
    private BigDecimal studyTime;
    private String coursewareName;
    public String getSubjectId() {
        return subjectId;
    }
    public void setSubjectId(String subjectId) {
        this.subjectId = subjectId;
    }
    public BigDecimal getPercent() {
        return percent;
    }
    public void setPercent(BigDecimal percent) {
        this.percent = percent;
    }
    public BigDecimal getStudyTime() {
        return studyTime;
    }
    public void setStudyTime(BigDecimal studyTime) {
        this.studyTime = studyTime;
    }
    public String getCoursewareName() {
        return coursewareName;
    }
    public void setCoursewareName(String coursewareName) {
        this.coursewareName = coursewareName;
    }
}
src/main/java/com/qxueyou/scc/teach/subject/model/view/MyLectureV.java
@@ -16,12 +16,14 @@
import org.springframework.format.annotation.DateTimeFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.transaction.annotation.Transactional;
/**
 * MySubjectV generated by hbm2java
 */
@Entity
@Table(name = "my_lecture_v")
@Transactional(readOnly = true)
public class MyLectureV implements java.io.Serializable {
    private static final long serialVersionUID = -332455459706490649L;
src/main/java/com/qxueyou/scc/teach/subject/model/view/MySubjectV.java
@@ -19,7 +19,7 @@
    private static final long serialVersionUID = -1272201343379309257L;
    private MySubjectVId id;
    private BigDecimal progressValue;
    private Double percent;
@@ -29,11 +29,11 @@
    private String className;
    private String origSubjectId;
    private String teacherId;
    private String subjectStatus;
    private Integer schoolYear;
    private Integer term;
    private Integer lectureCount;
@@ -67,7 +67,7 @@
    public void setId(MySubjectVId id) {
        this.id = id;
    }
    @Column(name="LECTURE_COUNT")
    public Integer getLectureCount() {
        return lectureCount;
@@ -103,7 +103,7 @@
    public void setProgressValue(BigDecimal progressValue) {
        this.progressValue = progressValue;
    }
    @Column(name = "PERCENT", nullable = false)
    public Double getPercent() {
        return this.percent;
@@ -112,7 +112,7 @@
    public void setPercent(Double percent) {
        this.percent = percent;
    }
    @Column(name = "COVER_PAGE_URL", length = 256)
    public String getCoverPageUrl() {
        return this.coverPageUrl;
@@ -130,7 +130,7 @@
    public void setUserName(String userName) {
        this.userName = userName;
    }
    @Column(name = "SUBJECT_NAME", length = 150)
    public String getSubjectName() {
        return this.subjectName;
@@ -139,7 +139,7 @@
    public void setSubjectName(String subjectName) {
        this.subjectName = subjectName;
    }
    @Column(name = "CLASS_NAME")
    public String getClassName() {
        return this.className;
@@ -163,9 +163,9 @@
        return subjectStatus;
    }
    public void setSubjectStatus(String subjectStatus) {
        this.subjectStatus = subjectStatus;
    }
}
src/main/java/com/qxueyou/scc/teach/subject/service/ILectureService.java
@@ -15,7 +15,7 @@
    /**
     * 新增章节文件夹
     *
     *
     * @param subjectId
     *            课程id
     * @param parentChapterId
@@ -28,7 +28,7 @@
    /**
     * 读取课件目录
     *
     *
     * @param chapterId
     * @return
     */
@@ -36,7 +36,7 @@
    /**
     * 修改章节文件夹
     *
     *
     * @param chapterId
     *            文件夹id
     * @param name
@@ -47,7 +47,7 @@
    /**
     * 删除章节文件夹
     *
     *
     * @param chapterIds
     *            章节文件夹id数组
     * @return 上传结果:{"success":true,msg:"success",attrs:{}}
@@ -56,7 +56,7 @@
    /**
     * 返回下级章节文件夹列表,如果
     *
     *
     * @param subjectId
     *            课程id
     * @param parentChapterId
@@ -67,7 +67,7 @@
    /**
     * 返回下级章节文件夹列表,如果
     *
     *
     * @param subjectId
     *            课程id
     * @param parentChapterId
@@ -78,7 +78,7 @@
    /**
     * 返回下级章节文件夹列表
     *
     *
     * @param subjectId
     *            课程id
     * @param parentChapterId
@@ -89,7 +89,7 @@
    /**
     * 返回所有章节列表,按createTime排序
     *
     *
     * @param subjectId
     *            课程id
     * @return 返回章节列表
@@ -98,7 +98,7 @@
    /**
     * 新增课件
     *
     *
     * @param chapterId
     *            章节id
     * @param resId
@@ -107,9 +107,14 @@
     */
    Result addLecture(String chapterId, String resId);
    /**
     * 新增后刷新课件
     */
    Result addLectureLoad(String sectionId);
    /**
     * 读取课件
     *
     *
     * @param lectureId
     *            课件id
     * @return SubjectLecture
@@ -118,7 +123,7 @@
    /**
     * 读取视频课件
     *
     *
     * @param lectureId
     *            课件id
     * @return SubjectLecture
@@ -127,7 +132,7 @@
    /**
     * 读取音频课件
     *
     *
     * @param lectureId
     *            课件id
     * @return LectureAudioV
@@ -136,7 +141,7 @@
    /**
     * 修改课件
     *
     *
     * @param lectureId
     *            课件id
     * @param resId
@@ -147,16 +152,18 @@
    /**
     * 删除课件
     *
     *
     * @param lectureIds
     *            课件id数组
     * @return 上传结果:{"success":true,msg:"success",attrs:{}}
     */
    Result deleteLecture(String[] lectureIds);
    Result deleteLectureLoad(String[] lectureIds);
    /**
     * 复制课件
     *
     *
     * @param lectureId
     *            课件id
     * @param destChapterId
@@ -169,7 +176,7 @@
    /**
     * 移动课件
     *
     *
     * @param lectureId
     *            课件id
     * @param destChapterId
@@ -182,7 +189,7 @@
    /**
     * 课件列表搜索
     *
     *
     * @param chapterId
     *            章节id
     * @param keyword
@@ -199,7 +206,7 @@
    /**
     * 课件列表大小
     *
     *
     * @param chapterId
     *            章节id
     * @param keyword
@@ -212,7 +219,7 @@
    /**
     * 课件列表搜索
     *
     *
     * @param chapterId
     *            章节id
     * @param keyword
@@ -230,14 +237,14 @@
    /**
     * 课件列表搜索
     *
     *
     * @return
     */
    List<SubjectLecture> listLectureBySubjectId(String subjectId);
    /**
     * 读取课件真实文件访问路径
     *
     *
     * @param lectureId
     *            课件id数组
     * @param attribute
@@ -252,4 +259,17 @@
     * 读取文档课件
     */
    LectureDocV readDocLecture(String handoutId);
    /**
     * 课件详情查询
     * @param learnerId
     * @param subjectId
     * @param keyword
     * @param pageSize
     * @param pageNum
     * @param type
     * @return
     */
    List<MyLectureV> listLectureVBySubjectId(String learnerId, String subjectId, String keyword, Integer pageSize,
                                                    Integer pageNum, String type);
}
src/main/java/com/qxueyou/scc/teach/subject/service/ISubjectService.java
@@ -8,12 +8,13 @@
import com.qxueyou.scc.base.model.Result;
import com.qxueyou.scc.teach.subject.model.Subject;
import com.qxueyou.scc.teach.subject.model.view.MySubjectV;
import org.springframework.transaction.annotation.Transactional;
public interface ISubjectService {
    /**
     * 新增课程
     *
     *
     * @param subjectName
     *            课程名称
     * @param coverPageFileId
@@ -26,7 +27,7 @@
    /**
     * 修改课程
     *
     *
     * @param subjectName
     *            课程名称
     * @param subjectId
@@ -41,7 +42,7 @@
    /**
     * 删除课程
     *
     *
     * @param subjectIds
     *            课程id数组
     * @return 上传结果:{"success":true,msg:"success",attrs:{}}
@@ -50,7 +51,7 @@
    /**
     * 发布课程
     *
     *
     * @param subjectIds
     *            课程id数组
     * @return 上传结果:{"success":true,msg:"success",attrs:{}}
@@ -59,7 +60,7 @@
    /**
     * 撤回课程
     *
     *
     * @param subjectIds
     *            课程id数组
     * @return 上传结果:{"success":true,msg:"success",attrs:{}}
@@ -68,7 +69,7 @@
    /**
     * 更新课件数量
     *
     *
     * @param subjectId
     * @param count
     * @return
@@ -77,7 +78,7 @@
    /**
     * 查询课程
     *
     *
     * @param text
     *            搜索文本
     * @param pageSize
@@ -90,7 +91,7 @@
    /**
     * 查询课程个数
     *
     *
     * @param text
     *            搜索文本
     * @return 返回课程总数
@@ -99,7 +100,7 @@
    /**
     * 读取课程
     *
     *
     * @param subjectId
     *            课程ID
     * @return 返回课程列表
@@ -108,7 +109,7 @@
    /**
     * 读取课程详情介绍
     *
     *
     * @param subjectId
     *            课程ID
     * @return 返回课程详情介绍
@@ -117,7 +118,7 @@
    /**
     * 查询我的课程
     *
     *
     * @param classId
     *            班级id
     * @return 返回课程列表
@@ -131,7 +132,7 @@
    /**
     * 查询我的课程
     *
     *
     * @param classId
     *            班级id
     * @return 返回课程列表
@@ -140,7 +141,7 @@
    /**
     * 查询个人课程章节的学习进度
     *
     *
     * @param classId
     *            班级id
     * @return 返回章节学习进度列表
@@ -154,7 +155,7 @@
    /**
     * 我的活动获取课程完成情况
     *
     *
     * @return
     */
    Result getPerformance4Subject();
@@ -166,7 +167,7 @@
    /**
     * 获取数据排行
     *
     *
     * @return
     */
    Result getDataDesc(String classId, String subjectId);
@@ -175,7 +176,7 @@
     * 获取上次学习的位置
     */
    Result lastStudied(String userId);
    /**
     * 添加班级课程
     * @param origSubjectId
@@ -183,12 +184,12 @@
     * @param schoolYear
     * @param term
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    Result addClsSubject(String classId,String origSubjectId, String teacherId, Integer schoolYear, Integer term) throws IllegalAccessException, InvocationTargetException;
    /**
     * 更新班级课程
     * @param subjectId
@@ -199,7 +200,7 @@
     * @return
     */
    Result updateClsSubject(String classId,String subjectId, String origSubjectId, String teacherId, Integer schoolYear, Integer term);
    /**
     * 删除班级课程
     * @param classId
@@ -207,147 +208,147 @@
     * @return
     */
    Result deleteClsSubject(String classId, String[] subjectIds);
    /**
     * 查询班级课程
     *
     *
     * @param classId
     * @param schoolYear
     * @param term
     * @return
     */
    public List<Map<String, Object>> clsSubjectlist(String classId, Integer schoolYear, Integer term);
    /**
     * 获取班级学期
     *
     *
     * @param classId
     * @return
     */
    public List<Map<String,Object>> termList(String classId);
    /**
     * 我的课程按学期分类
     *
     *
     * @param classId
     * @return
     */
    public List<Map<String,Object>> myTermSubjectList(String classId);
    /**
     * 我的课程,按时间排序
     *
     *
     * @param classId
     * @return
     */
    public List<Map<String,Object>> mySubjectList(String classId, Pager pager);
    /**
     * 查询老师或管理员可用的课程ID和课程名字列表
     * @param teacherId 根据教师ID过滤
     * @return
     */
    List<Map<String, Object>> queryAvailableSubjectIdAndName(String teacherId,Integer sbujectType);
    /**
     * 我的班级信息
     *
     *
     * @param classId
     * @return
     */
    public Map<String,Object> myClassInfo(String classId);
    /**
     * 获取我的课程数量
     *
     *
     * @param classId
     * @return
     */
    public long myClsSubjectCount(String classId);
    /**
     * 获取我的课程进度
     *
     *
     * @param classId
     * @param userId
     * @return
     */
    public List<Map<String,Object>> myClsSubjectlist(String classId, String userId, Pager pager);
    /**
     * 学员课程作业进度
     *
     *
     * @param classId
     * @param subjectId
     * @return
     */
    public Map<String, Object> studentSubjectHomeworkProgress(String classId, String subjectId, String userId);
    /**
     * 学员考试作业进度
     *
     *
     * @param classId
     * @param subjectId
     * @return
     */
    public Map<String, Object> studentSubjectExamProgress(String classId, String subjectId, String studentId);
    /**
     * 获取学员的课程进度
     *
     *
     * @param classId
     * @return
     */
    public List<Map<String,Object>> studentSubjectProgress(String classId, Pager pager);
    /**
     * 班级学员课件总体进度
     *
     *
     * @param subjectId
     * @param classId
     * @return
     */
    public List<Map<String, Object>> studentSubjectLectureProgress(String subjectId, String classId);
    /**
     * 我的公开课列表
     *
     *
     * @param pageNum
     * @param pageSize
     * @param keyword
     * @return
     */
    public Map<String,Object> myOpenSubjectList(Integer pageNum, Integer pageSize, String keyword);
    /**
     * 公开课列表
     *
     *
     * @param pageNum
     * @param pageSize
     * @param keyword
     * @return
     */
    public Map<String,Object> openSubjectList(Integer pageNum, Integer pageSize, String keyword);
    /**
     * 公开课详情
     *
     *
     * @param subjectId
     * @return
     */
    public Map<String,Object> openSubjectInfo(String subjectId);
    /**
     * 我的课程详情
     *
     *
     * @param classId
     * @return
     */
    public Map<String,Object> mySubjectInfo(String subjectId, String classId);
    /**
     * app教师端课程列表
     *
     *
     * @param text
     * @param status
     * @param type
@@ -356,26 +357,26 @@
     * @return
     */
    Result teacherSubjectList(Pager pager, String keyword, String status,Integer type);
    /**
     * 课程按学期分类
     *
     *
     * @param classId
     * @return
     */
    List<Map<String,Object>> termSubjectList(String classId, List<Map<String,Object>> clsSubjectlist);
    /**
     * 查询课程关联的班级信息
     * @param origSubjectId
     * @return
     */
    List<Map<String, Object>> querySubjectReClassInfos(String origSubjectId);
    /**
     * 获取课件数量
     *
     *
     * @param subjectId
     * @return
     */
src/main/java/com/qxueyou/scc/teach/subject/service/impl/SubjectLectureService.java
@@ -2,7 +2,9 @@
import java.util.List;
import com.qxueyou.scc.admin.classes.model.ClsClassReSubject;
import com.qxueyou.scc.admin.classes.service.IClassLectureService;
import com.qxueyou.scc.teach.subject.model.Subject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
@@ -30,6 +32,7 @@
import com.qxueyou.scc.teach.subject.model.view.MyLectureV;
import com.qxueyou.scc.teach.subject.service.ILectureService;
import com.qxueyou.scc.teach.subject.service.ISubjectService;
import org.springframework.transaction.annotation.Transactional;
@Service
public class SubjectLectureService extends CommonAppService implements ILectureService {
@@ -177,12 +180,26 @@
        lecture.setRemark(res.getRemark());
        lecture.setSubjectId(chapter.getSubjectId());
        lecture.setResItemId(res.getResId());
        save(lecture);
        subjectService.addLectureCount(lecture.getSubjectId(), 1);
        return new Result(true, "success");
    }
        subjectService.addLectureCount(chapter.getSubjectId(), 1);
    @Override
    public Result addLectureLoad(String sectionId){
        SubjectChapter chapter = read(SubjectChapter.class, sectionId);
        String hql = "from Subject where subjectId = ? and deleteFlag is false";
        String subjectId = chapter.getSubjectId();
        Subject subjectOne = findUnique(hql,CollectionUtils.newList(subjectId),Subject.class);
        String hqlOne = "from Subject where name = ? and deleteFlag is false";
        List<Subject> subjectTwo = find(hqlOne,CollectionUtils.newList(subjectOne.getName()),Subject.class);
        for (Subject s : subjectTwo){
            String hqlTwo = "from ClsClassReSubject where subjectId = ? and deleteFlag is false";
            ClsClassReSubject subject = findUnique(hqlTwo,CollectionUtils.newList(s.getSubjectId()),ClsClassReSubject.class);
            if(subject != null){
                subjectService.updateClsSubject(subject.getClassId(),s.getSubjectId(),s.getOrigSubjectId(),s.getTeacherId(),s.getSchoolYear(),s.getTerm());
            }
        }
        return new Result(true, "success");
    }
@@ -209,7 +226,23 @@
        for (String lectureId : lectureIds) {
            deleteLecture(lectureId);
        }
        return new Result(true, "success");
    }
    @Override
    public Result deleteLectureLoad(String[] lectureIds){
        SubjectLecture lecture = read(SubjectLecture.class, lectureIds[0]);
        String hql = "from Subject where subjectId = ? and deleteFlag is false";
        String subjectId = lecture.getSubjectId();
        Subject subjectOne = findUnique(hql,CollectionUtils.newList(subjectId),Subject.class);
        String hqlOne = "from Subject where name = ? and deleteFlag is false";
        List<Subject> subjectTwo = find(hqlOne,CollectionUtils.newList(subjectOne.getName()),Subject.class);
        for (Subject s : subjectTwo){
            String hqlTwo = "from ClsClassReSubject where subjectId = ? and deleteFlag is false";
            ClsClassReSubject subject = findUnique(hqlTwo,CollectionUtils.newList(s.getSubjectId()),ClsClassReSubject.class);
            if(subject != null){
                subjectService.updateClsSubject(subject.getClassId(),s.getSubjectId(),s.getOrigSubjectId(),s.getTeacherId(),s.getSchoolYear(),s.getTerm());
            }
        }
        return new Result(true, "success");
    }
@@ -225,7 +258,6 @@
        TraceUtils.setUpdateTrace(lecture);
        lecture.setDeleteFlag(true);
        save(lecture);
        subjectService.addLectureCount(lecture.getSubjectId(), -1);
@@ -268,6 +300,22 @@
            Integer pageNum, String type) {
        StringBuffer hql = new StringBuffer("from MyLectureV where chapterId=? and id.userId=?");
        List<Object> args = CollectionUtils.newList(chapterId, learnerId);
        if (StringUtils.isNotEmpty(type)) {
            hql.append(" and lectureType=?");
            args.add(type);
        }
        List<MyLectureV> result = findList(hql.toString(), new Pager(pageSize, pageNum), args, MyLectureV.class);
        return result;
    }
    @Override
    public List<MyLectureV> listLectureVBySubjectId(String learnerId, String subjectId, String keyword, Integer pageSize,
                                         Integer pageNum, String type) {
        StringBuffer hql = new StringBuffer("from MyLectureV where subjectId=? and id.userId=? order by lectureUpdateTime desc");
        List<Object> args = CollectionUtils.newList(subjectId, learnerId);
        if (StringUtils.isNotEmpty(type)) {
            hql.append(" and lectureType=?");
@@ -370,7 +418,7 @@
    @Override
    public Result doStudy(String lectureId, Double from, Double to) {
        String userId = null;
        return progressService.addProgress(Progress.PROGRESS_TYPE_LECTURE, lectureId, from.doubleValue(), to.doubleValue(),
        return progressService.addProgress(Progress.PROGRESS_TYPE_LECTURE, lectureId, from.intValue(), to.intValue(),
                userId);
    }
src/main/java/com/qxueyou/scc/teach/subject/service/impl/SubjectService.java
@@ -10,6 +10,7 @@
import com.qxueyou.scc.base.model.UserInfoWrapper;
import com.qxueyou.scc.sys.model.CacheParamters;
import com.qxueyou.scc.teach.subject.model.view.*;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
@@ -61,441 +62,433 @@
import com.qxueyou.scc.teach.subject.model.Subject;
import com.qxueyou.scc.teach.subject.model.SubjectChapter;
import com.qxueyou.scc.teach.subject.model.SubjectLecture;
import com.qxueyou.scc.teach.subject.model.view.MySubjectV;
import com.qxueyou.scc.teach.subject.model.view.OpenSubjectV;
import com.qxueyou.scc.teach.subject.model.view.QMyLectureV;
import com.qxueyou.scc.teach.subject.model.view.QMySubjectV;
import com.qxueyou.scc.teach.subject.model.view.QOpenSubjectV;
import com.qxueyou.scc.teach.subject.service.ILectureService;
import com.qxueyou.scc.teach.subject.service.ISubjectService;
import com.qxueyou.scc.user.model.QUser;
import com.qxueyou.scc.user.model.UserTeacher;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
@Service
public class SubjectService extends CommonAppService implements ISubjectService {
    private final Logger log = LogManager.getLogger(SubjectService.class);
    private final Logger log = LogManager.getLogger(SubjectService.class);
    @Autowired
    SubjectDAO subjectDAO;
    @Autowired
    SubjectDAO subjectDAO;
    @Autowired
    IFileService fileService;
    @Autowired
    IFileService fileService;
    @Autowired
    ILectureService lectureService;
    @Autowired
    ILectureService lectureService;
    @Autowired
    IClassLectureService clsLectureService;
    @Autowired
    IClassLectureService clsLectureService;
    @Autowired
    IProgressService progressService;
    @Autowired
    IProgressService progressService;
    @Autowired
    IExamService examService;
    @Autowired
    IExamService examService;
    @Autowired
    IExerciseInfoService exerciseInfoService;
    @Autowired
    IExerciseInfoService exerciseInfoService;
    @Autowired
    ProgressDAO progressDao;
    @Autowired
    ProgressDAO progressDao;
    @Autowired
    private ITeacherService teacherService;
    @Autowired
    private ITeacherService teacherService;
    @Autowired
    private IMediaLiveService mediaLiveService;
    @Autowired
    private IMediaLiveService mediaLiveService;
    @Override
    public Result add(String subjectName,String coverPageFileId, String contentFileId,int type) {
    @Override
    public Result add(String subjectName, String coverPageFileId, String contentFileId, int type) {
        Subject subject = new Subject();
        if (StringUtils.isNotEmpty(coverPageFileId)) {
            ResFile file = fileService.read(coverPageFileId);
            subject.setCoverPageFileId(coverPageFileId);
            subject.setCoverPageUrl(file.getPath());
        }
        Subject subject = new Subject();
        if (StringUtils.isNotEmpty(coverPageFileId)) {
            ResFile file = fileService.read(coverPageFileId);
            subject.setCoverPageFileId(coverPageFileId);
            subject.setCoverPageUrl(file.getPath());
        }
        TraceUtils.setCreateTrace(subject);
        subject.setContentFileId(contentFileId);
        subject.setName(subjectName);
        subject.setStatus(Subject.STATUS_DRAFT);
        subject.setLectureCount(0);
        subject.setType(type);
        subject.setOrgId(ClientUtils.getOrgId());
        TraceUtils.setCreateTrace(subject);
        subject.setContentFileId(contentFileId);
        subject.setName(subjectName);
        subject.setStatus(Subject.STATUS_DRAFT);
        subject.setLectureCount(0);
        subject.setType(type);
        subject.setOrgId(ClientUtils.getOrgId());
        save(subject);
        save(subject);
        //初始化创建 根节点
        SubjectChapter chapter = new SubjectChapter();
        TraceUtils.setCreateTrace(chapter);
        chapter.setName("根节点");
        chapter.setSubjectId(subject.getSubjectId());
        chapter.setParentChapterId(SubjectChapter.ROOT_CHAPTER_ID);
        save(chapter);
        //初始化创建 根节点
        SubjectChapter chapter = new SubjectChapter();
        TraceUtils.setCreateTrace(chapter);
        chapter.setName("根节点");
        chapter.setSubjectId(subject.getSubjectId());
        chapter.setParentChapterId(SubjectChapter.ROOT_CHAPTER_ID);
        save(chapter);
        return new Result(true,"success",CollectionUtils.newObjectMap("subjectId",subject.getSubjectId()));
    }
        return new Result(true, "success", CollectionUtils.newObjectMap("subjectId", subject.getSubjectId()));
    }
    @Override
    public Result update(String subjectId, String subjectName, String coverPageFileId, String contentFileId,int type) {
        Subject subject = read(Subject.class, subjectId);
        if (StringUtils.isNotEmpty(coverPageFileId)) {
            ResFile file = fileService.read(coverPageFileId);
            subject.setCoverPageUrl(file.getPath());
            subject.setCoverPageFileId(coverPageFileId);
        }else{
            subject.setCoverPageUrl(null);
            subject.setCoverPageFileId(null);
        }
    @Override
    public Result update(String subjectId, String subjectName, String coverPageFileId, String contentFileId, int type) {
        Subject subject = read(Subject.class, subjectId);
        if (StringUtils.isNotEmpty(coverPageFileId)) {
            ResFile file = fileService.read(coverPageFileId);
            subject.setCoverPageUrl(file.getPath());
            subject.setCoverPageFileId(coverPageFileId);
        } else {
            subject.setCoverPageUrl(null);
            subject.setCoverPageFileId(null);
        }
        TraceUtils.setUpdateTrace(subject);
        subject.setContentFileId(contentFileId);
        subject.setName(subjectName);
        subject.setType(type);
        TraceUtils.setUpdateTrace(subject);
        subject.setContentFileId(contentFileId);
        subject.setName(subjectName);
        subject.setType(type);
        save(subject);
        save(subject);
        //更新所有关联的课程
        if(subject.getType()==Subject.TYPE_ORG_SUBJECT){
            this.bulkUpdate("update Subject t set t.name=?,t.contentFileId=?,"
                    + "t.coverPageFileId=?,t.coverPageUrl=? where t.deleteFlag is false and t.origSubjectId=? ",new Object[]{subject.getName(),
                            subject.getContentFileId(),subject.getCoverPageFileId(),subject.getCoverPageUrl(),subject.getSubjectId()} );
        }
        //更新所有关联的课程
        if (subject.getType() == Subject.TYPE_ORG_SUBJECT) {
            this.bulkUpdate("update Subject t set t.name=?,t.contentFileId=?,"
                    + "t.coverPageFileId=?,t.coverPageUrl=? where t.deleteFlag is false and t.origSubjectId=? ", new Object[]{subject.getName(),
                    subject.getContentFileId(), subject.getCoverPageFileId(), subject.getCoverPageUrl(), subject.getSubjectId()});
        }
        return new Result(true, "success");
    }
        return new Result(true, "success");
    }
    @Override
    public Result delete(String[] subjectIds) {
        for (String subjectId : subjectIds) {
            deleteSubject(subjectId);
    @Override
    public Result delete(String[] subjectIds) {
        for (String subjectId : subjectIds) {
            deleteSubject(subjectId);
            //删除班级课程
            List<Map<String,Object>> result = this.findListWithMapByHql(
                    "select r.classId as classId,r.subjectId as subjectId from ClsClassReSubject r,Subject j  "
                    + "where r.subjectId = j.subjectId and j.origSubjectId=:origSubjectId and r.deleteFlag is false and j.deleteFlag is false",
                    CollectionUtils.newObjectMap("origSubjectId",subjectId));
            //删除班级课程
            List<Map<String, Object>> result = this.findListWithMapByHql(
                    "select r.classId as classId,r.subjectId as subjectId from ClsClassReSubject r,Subject j  "
                            + "where r.subjectId = j.subjectId and j.origSubjectId=:origSubjectId and r.deleteFlag is false and j.deleteFlag is false",
                    CollectionUtils.newObjectMap("origSubjectId", subjectId));
            if(result!=null && result.size()>0){
                for(Map<String,Object> map : result){
                    this.deleteClsSubject((String)map.get("classId"), new String []{(String)map.get("subjectId")});
                }
            }
        }
            if (result != null && result.size() > 0) {
                for (Map<String, Object> map : result) {
                    this.deleteClsSubject((String) map.get("classId"), new String[]{(String) map.get("subjectId")});
                }
            }
        }
        return new Result(true, "success");
    }
        return new Result(true, "success");
    }
    /**
     * 删除单个课程
     *
     * @param chapterId
     *            章节id
     * @return
     */
    private Result deleteSubject(String subjectId) {
    /**
     * 删除单个课程
     *
     * @param chapterId 章节id
     * @return
     */
    private Result deleteSubject(String subjectId) {
        Subject subject = read(Subject.class, subjectId);
        Subject subject = read(Subject.class, subjectId);
        TraceUtils.setUpdateTrace(subject);
        subject.setDeleteFlag(true);
        TraceUtils.setUpdateTrace(subject);
        subject.setDeleteFlag(true);
        save(subject);
        save(subject);
        return new Result(true, "success");
    }
        return new Result(true, "success");
    }
    @Override
    public List<Subject> list(String text, String teacherId, String status,Integer type, Integer pageSize, Integer pageNum) {
    @Override
    public List<Subject> list(String text, String teacherId, String status, Integer type, Integer pageSize, Integer pageNum) {
        StringBuffer hql = new StringBuffer("from Subject where name like ? and orgId=? and deleteFlag is false and origSubjectId is null ");
        StringBuffer hql = new StringBuffer("from Subject where name like ? and orgId=? and deleteFlag is false and origSubjectId is null ");
        List<Object> args = CollectionUtils.newList(text + "%",ClientUtils.getOrgId());
        List<Object> args = CollectionUtils.newList(text + "%", ClientUtils.getOrgId());
        if(type!=null){
            hql.append(" and type=?");
            args.add(type);
        }
        if (type != null) {
            hql.append(" and type=?");
            args.add(type);
        }
        if (!StringUtils.isEmpty(status)) {
            hql.append(" and status=?");
            args.add(status);
        }
        if (!StringUtils.isEmpty(status)) {
            hql.append(" and status=?");
            args.add(status);
        }
        if (!StringUtils.isEmpty(teacherId)) {
            hql.append(" and createId=?");
            args.add(teacherId);
        }
        hql.append(" order by createTime desc");
        List<Subject> result = findList(hql.toString(), new Pager(pageSize, pageNum), args, Subject.class);
        if (!StringUtils.isEmpty(teacherId)) {
            hql.append(" and createId=?");
            args.add(teacherId);
        }
        hql.append(" order by createTime desc");
        List<Subject> result = findList(hql.toString(), new Pager(pageSize, pageNum), args, Subject.class);
        return result;
    }
        return result;
    }
    /**
     * app教师端课程列表
     *
     * @param text
     * @param status
     * @param type
     * @param pageSize
     * @param pageNum
     * @return
     */
    @Override
    public Result teacherSubjectList(Pager pager, String keyword, String status,Integer type) {
        String teacherId = teacherService.getTeacherIdByUserId(ClientUtils.getUserId());
        if(StringUtils.isEmpty(teacherId)) {
            return new Result(false, "当前用户无老师角色");
        }
    /**
     * app教师端课程列表
     *
     * @param text
     * @param status
     * @param type
     * @param pageSize
     * @param pageNum
     * @return
     */
    @Override
    public Result teacherSubjectList(Pager pager, String keyword, String status, Integer type) {
        String teacherId = teacherService.getTeacherIdByUserId(ClientUtils.getUserId());
        if (StringUtils.isEmpty(teacherId)) {
            return new Result(false, "当前用户无老师角色");
        }
        QSubject qSubject = QSubject.subject;
        QSubjectLecture qSubjectLecture = QSubjectLecture.subjectLecture;
        QProgress qProgress = QProgress.progress;
        QClsClassReSubject qClsClassReSubject = QClsClassReSubject.clsClassReSubject;
        QSubject qSubject = QSubject.subject;
        QSubjectLecture qSubjectLecture = QSubjectLecture.subjectLecture;
        QProgress qProgress = QProgress.progress;
        QClsClassReSubject qClsClassReSubject = QClsClassReSubject.clsClassReSubject;
        JPAQuery<Tuple> query = this.getQueryFactory()
                .select(qSubject.subjectId, qSubject.name, qSubject.term,qSubject.coverPageUrl, qSubject.schoolYear, qSubject.createTime, qSubject.type)
                .from(qSubject)
                .where(qSubject.deleteFlag.isFalse()
                        .and(qSubject.status.eq(Subject.STATUS_ISSUED)).and(qSubject.type.eq(type))
                        .and(qSubject.createId.eq(ClientUtils.getUserId()))
                        .and(qSubject.name.like("%" + keyword + "%")));
        JPAQuery<Tuple> query = this.getQueryFactory()
                .select(qSubject.subjectId, qSubject.name, qSubject.term, qSubject.coverPageUrl, qSubject.schoolYear, qSubject.createTime, qSubject.type)
                .from(qSubject)
                .where(qSubject.deleteFlag.isFalse()
                        .and(qSubject.status.eq(Subject.STATUS_ISSUED)).and(qSubject.type.eq(type))
                        .and(qSubject.createId.eq(ClientUtils.getUserId()))
                        .and(qSubject.name.like("%" + keyword + "%")));
        long count = query.fetchCount();
        long count = query.fetchCount();
        List<Map<String, Object>> listData = query.orderBy(qSubject.createTime.desc()).limit(pager.getPageSize())
                .offset(pager.getOffset()).fetch().stream().map(tuple -> {
                    Map<String, Object> map = new HashMap<String, Object>(10);
                    String subjectId = tuple.get(qSubject.subjectId);
        List<Map<String, Object>> listData = query.orderBy(qSubject.createTime.desc()).limit(pager.getPageSize())
                .offset(pager.getOffset()).fetch().stream().map(tuple -> {
                    Map<String, Object> map = new HashMap<String, Object>(10);
                    String subjectId = tuple.get(qSubject.subjectId);
                    map.put("name", tuple.get(qSubject.name));
                    map.put("subjectId", subjectId);
                    map.put("schoolYear", tuple.get(qSubject.schoolYear));
                    map.put("term", tuple.get(qSubject.term));
                    map.put("coverPageUrl", tuple.get(qSubject.coverPageUrl));
                    map.put("createTime", tuple.get(qSubject.createTime));
                    map.put("type", tuple.get(qSubject.type));
                    map.put("classId", "");
                    map.put("studyCount", this.getQueryFactory().selectDistinct(qProgress.learnerId).from(qProgress, qSubjectLecture)
                            .where(qProgress.deleteFlag.isFalse().and(qSubjectLecture.subjectId.eq(subjectId)).and(qProgress.targetType.eq(Progress.PROGRESS_TYPE_LECTURE))
                                    .and(qProgress.targetId.eq(qSubjectLecture.lectureId)).and(qSubjectLecture.deleteFlag.isFalse())).fetchCount());
                    map.put("classCount",
                            this.getQueryFactory().selectDistinct(qClsClassReSubject.classId)
                                    .from(qClsClassReSubject, qSubject)
                                    .where(qSubject.deleteFlag.isFalse().and(qClsClassReSubject.deleteFlag.isFalse())
                                            .and(qClsClassReSubject.subjectId.eq(qSubject.subjectId)).and(qSubject.origSubjectId.eq(subjectId))).fetchCount());
                    return map;
                }).collect(Collectors.toList());
                    map.put("name", tuple.get(qSubject.name));
                    map.put("subjectId", subjectId);
                    map.put("schoolYear", tuple.get(qSubject.schoolYear));
                    map.put("term", tuple.get(qSubject.term));
                    map.put("coverPageUrl", tuple.get(qSubject.coverPageUrl));
                    map.put("createTime", tuple.get(qSubject.createTime));
                    map.put("type", tuple.get(qSubject.type));
                    map.put("classId", "");
                    map.put("studyCount", this.getQueryFactory().selectDistinct(qProgress.learnerId).from(qProgress, qSubjectLecture)
                            .where(qProgress.deleteFlag.isFalse().and(qSubjectLecture.subjectId.eq(subjectId)).and(qProgress.targetType.eq(Progress.PROGRESS_TYPE_LECTURE))
                                    .and(qProgress.targetId.eq(qSubjectLecture.lectureId)).and(qSubjectLecture.deleteFlag.isFalse())).fetchCount());
                    map.put("classCount",
                            this.getQueryFactory().selectDistinct(qClsClassReSubject.classId)
                                    .from(qClsClassReSubject, qSubject)
                                    .where(qSubject.deleteFlag.isFalse().and(qClsClassReSubject.deleteFlag.isFalse())
                                            .and(qClsClassReSubject.subjectId.eq(qSubject.subjectId)).and(qSubject.origSubjectId.eq(subjectId))).fetchCount());
        return new Result(true, "", CollectionUtils.newObjectMap("count", count, "listData", listData));
    }
                    return map;
                }).collect(Collectors.toList());
    @Override
    public int listCount(String text, String teacherId, String status,Integer type) {
        StringBuffer hql = new StringBuffer("from Subject where name like ? and orgId=? and deleteFlag is false and origSubjectId is null ");
        List<Object> args = CollectionUtils.newList(text + "%",ClientUtils.getOrgId());
        return new Result(true, "", CollectionUtils.newObjectMap("count", count, "listData", listData));
    }
        if(type!=null){
            hql.append(" and type=?");
            args.add(type);
        }
    @Override
    public int listCount(String text, String teacherId, String status, Integer type) {
        StringBuffer hql = new StringBuffer("from Subject where name like ? and orgId=? and deleteFlag is false and origSubjectId is null ");
        List<Object> args = CollectionUtils.newList(text + "%", ClientUtils.getOrgId());
        if (StringUtils.isNotBlank(status)) {
            hql = hql.append(" and status = ?");
            args.add(status);
        }
        if (type != null) {
            hql.append(" and type=?");
            args.add(type);
        }
        if (!StringUtils.isEmpty(teacherId)) {
            hql.append(" and createId=?");
            args.add(teacherId);
        }
        if (StringUtils.isNotBlank(status)) {
            hql = hql.append(" and status = ?");
            args.add(status);
        }
        return findCount(hql.toString(), args);
        if (!StringUtils.isEmpty(teacherId)) {
            hql.append(" and createId=?");
            args.add(teacherId);
        }
    }
        return findCount(hql.toString(), args);
    @Override
    public Subject read(String subjectId) {
        return read(Subject.class, subjectId);
    }
    }
    @Override
    public String readSubjectContent(String subjectId) {
    @Override
    public Subject read(String subjectId) {
        return read(Subject.class, subjectId);
    }
        Subject sub = read(subjectId);
    @Override
    public String readSubjectContent(String subjectId) {
        //读取原课程
        if(StringUtils.isNotBlank(sub.getOrigSubjectId())) {
            sub = read(sub.getOrigSubjectId());
        }
        Subject sub = read(subjectId);
        try {
            if(!StringUtils.isEmpty(sub.getContentFileId())){
                return IOUtils.toString(fileService.readStreamById(sub.getContentFileId()));
            }
        } catch (Exception e) {
            log.error(e, e);
        }
        return null;
        //读取原课程
        if (StringUtils.isNotBlank(sub.getOrigSubjectId())) {
            sub = read(sub.getOrigSubjectId());
        }
    }
        try {
            if (!StringUtils.isEmpty(sub.getContentFileId())) {
                return IOUtils.toString(fileService.readStreamById(sub.getContentFileId()));
            }
        } catch (Exception e) {
            log.error(e, e);
        }
        return null;
    @Override
    public Result doRelease(String[] subjectIds) {
        for (String subjectId : subjectIds) {
            releaseSubject(subjectId);
        }
    }
        return new Result(true, "success");
    }
    @Override
    public Result doRelease(String[] subjectIds) {
        for (String subjectId : subjectIds) {
            releaseSubject(subjectId);
        }
    @Override
    public Result doCancel(String[] subjectIds) {
        for (String subjectId : subjectIds) {
            cancelSubject(subjectId);
        }
        return new Result(true, "success");
    }
        return new Result(true, "success");
    }
    @Override
    public Result doCancel(String[] subjectIds) {
        for (String subjectId : subjectIds) {
            cancelSubject(subjectId);
        }
    /**
     * 发布单个课程
     *
     * @param chapterId
     *            章节id
     * @return
     */
    private Result releaseSubject(String subjectId) {
        return new Result(true, "success");
    }
        Subject subject = read(Subject.class, subjectId);
    /**
     * 发布单个课程
     *
     * @param chapterId 章节id
     * @return
     */
    private Result releaseSubject(String subjectId) {
        TraceUtils.setUpdateTrace(subject);
        subject.setStatus(Subject.STATUS_ISSUED);
        Subject subject = read(Subject.class, subjectId);
        save(subject);
        TraceUtils.setUpdateTrace(subject);
        subject.setStatus(Subject.STATUS_ISSUED);
        //更新所有关联的课程
        this.bulkUpdate("update Subject set status='" + Subject.STATUS_ISSUED + "' where origSubjectId=? and deleteFlag is false ",new Object[]{subjectId});
        save(subject);
        return new Result(true, "success");
    }
        //更新所有关联的课程
        this.bulkUpdate("update Subject set status='" + Subject.STATUS_ISSUED + "' where origSubjectId=? and deleteFlag is false ", new Object[]{subjectId});
    /**
     * 发布单个课程
     *
     * @param chapterId
     *            章节id
     * @return
     */
    private Result cancelSubject(String subjectId) {
        return new Result(true, "success");
    }
        Subject subject = read(Subject.class, subjectId);
    /**
     * 发布单个课程
     *
     * @param chapterId 章节id
     * @return
     */
    private Result cancelSubject(String subjectId) {
        TraceUtils.setUpdateTrace(subject);
        subject.setStatus(Subject.STATUS_OFFLINE);
        Subject subject = read(Subject.class, subjectId);
        save(subject);
        TraceUtils.setUpdateTrace(subject);
        subject.setStatus(Subject.STATUS_OFFLINE);
        //更新所有关联的课程
        this.bulkUpdate("update Subject set status='" + Subject.STATUS_OFFLINE + "' where origSubjectId=? and deleteFlag is false ",new Object[]{subjectId});
        save(subject);
        return new Result(true, "success");
    }
        //更新所有关联的课程
        this.bulkUpdate("update Subject set status='" + Subject.STATUS_OFFLINE + "' where origSubjectId=? and deleteFlag is false ", new Object[]{subjectId});
    @Override
    public List<MySubjectV> listMySubjectV(String classId,String userId) {
        StringBuffer hql = new StringBuffer("from MySubjectV p where p.id.userId=? and p.subjectStatus=?");
        List<Object> args = CollectionUtils.newList(userId,Subject.STATUS_ISSUED);
        return new Result(true, "success");
    }
        if (!StringUtils.isEmpty(classId)) {
            hql.append(" and p.id.classId = ?");
            args.add(classId);
    @Override
    public List<MySubjectV> listMySubjectV(String classId, String userId) {
        StringBuffer hql = new StringBuffer("from MySubjectV p where p.id.userId=? and p.subjectStatus=?");
        List<Object> args = CollectionUtils.newList(userId, Subject.STATUS_ISSUED);
        }
        List<MySubjectV> result = find(hql.toString(), args, MySubjectV.class);
        if (!StringUtils.isEmpty(classId)) {
            hql.append(" and p.id.classId = ?");
            args.add(classId);
        return result;
    }
        }
        List<MySubjectV> result = find(hql.toString(), args, MySubjectV.class);
    @Override
    public List<Map<String, Object>> listChapterStudyProgress(String subjectId) {
        return result;
    }
        QSubjectProgressTreeV qSubjectProgressTreeV = QSubjectProgressTreeV.subjectProgressTreeV;
        List<Map<String, Object>> lstResult = this.getQueryFactory().selectFrom(qSubjectProgressTreeV).
                where(qSubjectProgressTreeV.id.nodeId.eq(subjectId).and(qSubjectProgressTreeV.id.userId.eq(ClientUtils.getUserId())))
                .fetch().stream().map(objSubjectProgressTreeV ->{
                    Map<String, Object> map = new HashMap<>();
                    map.put("chapterName", objSubjectProgressTreeV.getNodeName());
                    map.put("chapterId", objSubjectProgressTreeV.getId().getNodeId());
                    map.put("percent", objSubjectProgressTreeV.getPercent());
                    map.put("studyTime", objSubjectProgressTreeV.getProgressValue());
    @Override
    public List<Map<String, Object>> listChapterStudyProgress(String subjectId) {
                    return map;
                }).collect(Collectors.toList());
        QSubjectProgressTreeV qSubjectProgressTreeV = QSubjectProgressTreeV.subjectProgressTreeV;
        List<Map<String, Object>> lstResult = this.getQueryFactory().selectFrom(qSubjectProgressTreeV).
                where(qSubjectProgressTreeV.id.nodeId.eq(subjectId).and(qSubjectProgressTreeV.id.userId.eq(ClientUtils.getUserId())))
                .fetch().stream().map(objSubjectProgressTreeV -> {
                    Map<String, Object> map = new HashMap<>();
                    map.put("chapterName", objSubjectProgressTreeV.getNodeName());
                    map.put("chapterId", objSubjectProgressTreeV.getId().getNodeId());
                    map.put("percent", objSubjectProgressTreeV.getPercent());
                    map.put("studyTime", objSubjectProgressTreeV.getProgressValue());
        return lstResult;
    }
                    return map;
                }).collect(Collectors.toList());
    @Override
    public MySubjectV getMy1stSubjectVById(String subjectId) {
        String hql = "from MySubjectV p where p.id.userId=? and p.id.subjectId=?";
        String UserId = ClientUtils.getUserId();
        MySubjectV result = findUnique(hql, CollectionUtils.newList(UserId, subjectId),
                MySubjectV.class);
        return lstResult;
    }
        return result;
    }
    @Override
    public MySubjectV getMy1stSubjectVById(String subjectId) {
        String hql = "from MySubjectV p where p.id.userId=? and p.id.subjectId=?";
        String UserId = ClientUtils.getUserId();
        MySubjectV result = findUnique(hql, CollectionUtils.newList(UserId, subjectId),
                MySubjectV.class);
        return result;
    }
    @Override
    public Result addLectureCount(String subjectId, int count) {
    @Override
    public Result addLectureCount(String subjectId, int count) {
        subjectDAO.addLectureCount(subjectId, count);
        subjectDAO.addLectureCount(subjectId, count);
        return new Result(true);
    }
        return new Result(true);
    }
    @Override
    public Subject readSubject(String subjectId) {
    @Override
    public Subject readSubject(String subjectId) {
        return read(Subject.class, subjectId);
    }
        return read(Subject.class, subjectId);
    }
    @Override
    public Result addClsSubject(String classId,String origSubjectId, String teacherId, Integer schoolYear,Integer term) throws IllegalAccessException, InvocationTargetException {
        //新增老师课程
        Subject newSubject = new Subject();
        Subject origSubject = this.read(origSubjectId);
        UserTeacher teacher = this.read(UserTeacher.class, teacherId);
        BeanUtils.copyProperties(newSubject,origSubject);
    @Override
    public Result addClsSubject(String classId, String origSubjectId, String teacherId, Integer schoolYear, Integer term) throws IllegalAccessException, InvocationTargetException {
        //新增老师课程
        Subject newSubject = new Subject();
        Subject origSubject = this.read(origSubjectId);
        UserTeacher teacher = this.read(UserTeacher.class, teacherId);
        BeanUtils.copyProperties(newSubject, origSubject);
        TraceUtils.setCreateTrace(newSubject);
        newSubject.setSubjectId(null);
        newSubject.setTeacherId(teacherId);
        newSubject.setSchoolYear(schoolYear);
        newSubject.setTerm(term);
        newSubject.setStatus(origSubject.getStatus());
        newSubject.setOrigSubjectId(origSubjectId);
        newSubject.setOrigCopySubjectId(origSubjectId);
        newSubject.setType(Subject.TYPE_CLS_SUBJECT);
        newSubject.setTeacherName(teacher.getName());
        newSubject.setOrgId(ClientUtils.getOrgId());
        save(newSubject);
        TraceUtils.setCreateTrace(newSubject);
        newSubject.setSubjectId(null);
        newSubject.setTeacherId(teacherId);
        newSubject.setSchoolYear(schoolYear);
        newSubject.setTerm(term);
        newSubject.setStatus(origSubject.getStatus());
        newSubject.setOrigSubjectId(origSubjectId);
        newSubject.setOrigCopySubjectId(origSubjectId);
        newSubject.setType(Subject.TYPE_CLS_SUBJECT);
        newSubject.setTeacherName(teacher.getName());
        newSubject.setOrgId(ClientUtils.getOrgId());
        save(newSubject);
        //添加班级课程关系
        addClassReSubject(newSubject.getSubjectId(),classId);
        //添加班级课程关系
        addClassReSubject(newSubject.getSubjectId(), classId);
        //复制课件
        clsLectureService.doCopyLecturesToClass(origSubjectId,newSubject.getSubjectId(),classId);
        //复制课件
        clsLectureService.doCopyLecturesToClass(origSubjectId, newSubject.getSubjectId(), classId);
        return new Result(true, "success",CollectionUtils.newStringMap("subjectId",newSubject.getSubjectId()));
    }
        return new Result(true, "success", CollectionUtils.newStringMap("subjectId", newSubject.getSubjectId()));
    }
    private void addClassReSubject(String subjectId, String classId) {
        ClsClassReSubject re = new ClsClassReSubject();
@@ -505,1043 +498,1061 @@
        save(re);
    }
    @Override
    public Result updateClsSubject(String classId,String subjectId,String origSubjectId, String teacherId, Integer schoolYear,Integer term) {
        Subject origSubject = this.read(origSubjectId);
        Subject subject = this.read(subjectId);
        UserTeacher teacher = this.read(UserTeacher.class, teacherId);
    @Override
    public Result updateClsSubject(String classId, String subjectId, String origSubjectId, String teacherId, Integer schoolYear, Integer term) {
        Subject origSubject = this.read(origSubjectId);
        Subject subject = this.read(subjectId);
        UserTeacher teacher = this.read(UserTeacher.class, teacherId);
        //如果原课程做出了修改
        if(!origSubjectId.equals(subject.getOrigSubjectId())){
            subject.setContentFileId(origSubject.getCoverPageFileId());
            subject.setCoverPageUrl(origSubject.getCoverPageUrl());
            subject.setContentFileId(origSubject.getContentFileId());
            subject.setName(origSubject.getName());
            subject.setOrigSubjectId(origSubjectId);
            subject.setOrigCopySubjectId(origSubjectId);
        //如果原课程做出了修改
        if (!origSubjectId.equals(subject.getOrigSubjectId())) {
            subject.setContentFileId(origSubject.getCoverPageFileId());
            subject.setCoverPageUrl(origSubject.getCoverPageUrl());
            subject.setContentFileId(origSubject.getContentFileId());
            subject.setName(origSubject.getName());
            subject.setOrigSubjectId(origSubjectId);
            subject.setOrigCopySubjectId(origSubjectId);
            //清理并复制原课程
            clsLectureService.doClearLecturesToClass(classId,subjectId);
            clsLectureService.doCopyLecturesToClass(origSubjectId, subjectId, classId);
        }else {
            clsLectureService.doClearLecturesToClass(classId,subjectId);
            clsLectureService.doCopyLecturesToClass(origSubjectId, subjectId, classId);
        }
        TraceUtils.setUpdateTrace(subject);
        subject.setTeacherId(teacherId);
        subject.setTeacherName(teacher.getName());
        subject.setSchoolYear(schoolYear);
        subject.setTerm(term);
            //清理并复制原课程
            clsLectureService.doClearLecturesToClass(classId, subjectId);
            clsLectureService.doCopyLecturesToClass(origSubjectId, subjectId, classId);
        } else {
            clsLectureService.doClearLecturesToClass(classId, subjectId);
            clsLectureService.doCopyLecturesToClass(origSubjectId, subjectId, classId);
        }
        TraceUtils.setUpdateTrace(subject);
        subject.setTeacherId(teacherId);
        subject.setTeacherName(teacher.getName());
        subject.setSchoolYear(schoolYear);
        subject.setTerm(term);
        save(subject);
        return new Result(true, "success");
    }
    @Override
    public Result deleteClsSubject(String classId,String[] subjectIds) {
        Map<String,Object> paramMap = new HashMap<String,Object>();
        paramMap.put("classId", classId);
        paramMap.put("subjectIds", subjectIds);
        List<String>  reIdLst =  this.findByComplexHql("select r.clsReSubjectId from ClsClassReSubject r where r.deleteFlag is false and r.classId=:classId and r.subjectId in (:subjectIds) ",
                    paramMap, String.class);
        //删除关联关系
        if(reIdLst!=null && reIdLst.size()>0){
            this.bulkUpdateInLoop("update ClsClassReSubject set deleteFlag = true where clsReSubjectId=?", reIdLst.toArray());
        }
        this.delete(subjectIds);
        return new Result(true, "success");
    }
    @Override
    public Result getPerformance4Subject() {
        String findCompleteCountByHql = "from MySubjectV where id.userId = ? and percent = 1 ";
        String findUndoneByHql = "from MySubjectV where id.userId = ? and (percent != 1 or percent is null)";
        String userId = ClientUtils.getUserId();
        int CompleteCount = findCount(findCompleteCountByHql, CollectionUtils.newList(userId));
        int UndoneCount = findCount(findUndoneByHql, CollectionUtils.newList(userId));
        return new Result(true, "success",
                CollectionUtils.newObjectMap("CompleteCount", CompleteCount, "UndoneCount", UndoneCount));
    }
    @Override
    public Result lstSubjectDetail() {
        String userId = ClientUtils.getUserId();
        StringBuffer hql = new StringBuffer(
                "select percent as percent,className as className ,id.classId as classId ,id.subjectId as subjectId ,"
                        + "subjectName as subjectName ,coverPageUrl as coverPageUrl , progressValue as progressValue from"
                        + " MySubjectV p where p.id.userId =:userId and p.subjectStatus=:subjectStatus ");
        Map<String, Object> args = CollectionUtils.newObjectMap("userId", userId,"subjectStatus",Subject.STATUS_ISSUED);
        List<Map<String, Object>> subjectLstMap = findListWithMapByHql(hql.toString(), args);
        for (Map<String, Object> subject : subjectLstMap) {
            String classId = (String) subject.get("classId");
            String subjectId = (String) subject.get("subjectId");
            Map<String, Object> map = progressDao.getStudyById(userId, subjectId, classId);
            subject.put("lectureParentId", map.get("lectureParentId"));
            subject.put("lectureId", map.get("lectureId"));
            subject.put("unCommitExerciseCount", exerciseInfoService.getUnCommitExerciseCount(classId, userId));
            subject.put("toBeCommitExerciseCount", exerciseInfoService.getToBeCommitExerciseCount(classId, userId));
            subject.put("CommitExerciseCount", exerciseInfoService.getCommitExerciseCount(classId, userId));
            subject.put("exerciseCount", exerciseInfoService.getExerciseCount(classId, userId));
            subject.put("examCount", examService.getExamCount(classId, userId));
            subject.put("unCommitExamCount", examService.getUnCommitExamCount(classId, userId));
            subject.put("commitExamCount", examService.getCommitExamCount(classId, userId));
            subject.put("toBeCommitExamCount", examService.getToBeCommitExamCount(classId, userId));
        }
        return new Result(true, "success", subjectLstMap);
    }
    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public Result getDataDesc(String classId, String subjectId) {
        if(StringUtils.isEmpty(classId)) {
            return new Result(false, "班级id参数错误");
        }
        QSubjectProgressTreeV qSubjectProgressTreeV = QSubjectProgressTreeV.subjectProgressTreeV;
        List<Map<String, Object>> percentDesc = this.percentDesc(classId, subjectId, new OrderSpecifier(Order.DESC, qSubjectProgressTreeV.percent));
        List<Map<String, Object>> studyTimeDesc = this.percentDesc(classId, subjectId, new OrderSpecifier(Order.DESC, qSubjectProgressTreeV.progressValue));
        List<Map<String, Object>> exerciseInfoDesc = this.exerciseInfoDesc(classId, subjectId);
        List<Map<String, Object>> examInfoDesc = this.examInfoDesc(classId, subjectId);
        return new Result(true, "success", CollectionUtils.newObjectMap("percentDesc", percentDesc, "studyTimeDesc",
                studyTimeDesc, "exerciseInfoDesc", exerciseInfoDesc, "examInfoDesc", examInfoDesc));
    }
    /**
     * 获取班级对应的学员 按进度进行排序
     */
    private List<Map<String, Object>> percentDesc(String classId, String subjectId, @SuppressWarnings("rawtypes") OrderSpecifier order) {
        QSubjectProgressTreeV qSubjectProgressTreeV = QSubjectProgressTreeV.subjectProgressTreeV;
        QUser qUser = QUser.user;
        String nodeId = StringUtils.isNotEmpty(subjectId)?subjectId:classId;
        String nodeType = StringUtils.isNotEmpty(subjectId)?Progress.PROGRESS_TYPE_SUBJECT:Progress.PROGRESS_TYPE_CLASS;
        List<Map<String, Object>> lstMap = this.getQueryFactory().select(qSubjectProgressTreeV.progressValue,
                qSubjectProgressTreeV.percent, qUser.name, qUser.userId,qSubjectProgressTreeV.id.nodeId).from(qSubjectProgressTreeV, qUser).
                where(qSubjectProgressTreeV.id.userId.eq(qUser.userId).and(qSubjectProgressTreeV.nodeType.eq(nodeType))
                        .and(qSubjectProgressTreeV.id.nodeId.eq(nodeId))).orderBy(order).fetch().stream().map(tuple -> {
                            Map<String, Object> map = new HashMap<>();
                            map.put("userName", tuple.get(qUser.name));
                            map.put("userId", tuple.get(qUser.userId));
                            map.put("classId", tuple.get(qSubjectProgressTreeV.id.nodeId));
                            map.put("percent", tuple.get(qSubjectProgressTreeV.percent));
                            map.put("progressValue", tuple.get(qSubjectProgressTreeV.progressValue));
                            return map;
                        }).collect(Collectors.toList());
        return lstMap;
    }
    /**
     * 通过作业完成个数排序
     *
     */
    private List<Map<String, Object>> exerciseInfoDesc(String classId, String subjectId) {
        QExerciseResultV qExerciseResultV = QExerciseResultV.exerciseResultV;
        //查询条件
        Predicate predicate = StringUtils.isEmpty(subjectId)?qExerciseResultV.id.classId.eq(classId):
            qExerciseResultV.id.classId.eq(classId).and(qExerciseResultV.subjectId.eq(subjectId));
        //case数量判断
        NumberExpression<BigDecimal> caseCount = new CaseBuilder()
        .when(qExerciseResultV.completeStatus.eq(ExerciseCompleteInfo.STATUS_CHECKED)
                .or(qExerciseResultV.completeStatus.eq(ExerciseCompleteInfo.STATUS_COMMIT)))
        .then(BigDecimal.ONE).otherwise(BigDecimal.ZERO).sum();
        //case分数
        NumberExpression<BigDecimal> caseScoreSum = new CaseBuilder()
                .when(qExerciseResultV.completeStatus.eq(ExerciseCompleteInfo.STATUS_CHECKED)
                        .or(qExerciseResultV.completeStatus.eq(ExerciseCompleteInfo.STATUS_COMMIT)))
                .then(qExerciseResultV.score).otherwise(BigDecimal.ZERO).sum();
        List<Map<String, Object>> lstMap = this.getQueryFactory().select(qExerciseResultV.userId,qExerciseResultV.studentName,
                caseScoreSum.divide(caseCount), qExerciseResultV.count(), caseCount).from(qExerciseResultV).where(predicate).
                groupBy(qExerciseResultV.userId).
                orderBy(caseScoreSum.divide(caseCount).desc()).fetch().stream().map(tuple ->{
                    Map<String, Object> map = new HashMap<>();
                    map.put("userId", tuple.get(qExerciseResultV.userId));
                    map.put("userName", tuple.get(qExerciseResultV.studentName));
                    map.put("avgScore", tuple.get(2, BigDecimal.class));
                    map.put("exerciseCount",tuple.get(3, BigDecimal.class));
                    map.put("commitExerciseCount", tuple.get(4, BigDecimal.class));
                    return map;
                }).collect(Collectors.toList());
        return lstMap;
    }
    /**
     *
     */
    private List<Map<String, Object>> examInfoDesc(String classId, String subjectId) {
        QExamResultV qExamResultV = QExamResultV.examResultV;
        //查询条件
        Predicate predicate = StringUtils.isEmpty(subjectId)?qExamResultV.id.classId.eq(classId):
            qExamResultV.id.classId.eq(classId).and(qExamResultV.subjectId.eq(subjectId));
        //case判断
        NumberExpression<BigDecimal> caseCount = new CaseBuilder()
                .when(qExamResultV.status.eq("0")).then(BigDecimal.ZERO).otherwise(BigDecimal.ONE).sum();
        //case分数
        NumberExpression<BigDecimal> caseScoreSum = new CaseBuilder()
                .when(qExamResultV.status.eq("0")).then(BigDecimal.ZERO).otherwise(qExamResultV.score).sum();
        List<Map<String, Object>> lstMap = this.getQueryFactory().select(qExamResultV.userId,qExamResultV.studentName,
                caseScoreSum.divide(caseCount), qExamResultV.count(), caseCount).from(qExamResultV).where(predicate).
                groupBy(qExamResultV.userId).
                orderBy(caseScoreSum.divide(caseCount).desc()).fetch().stream().map(tuple ->{
                    Map<String, Object> map = new HashMap<>();
                    map.put("userId", tuple.get(qExamResultV.userId));
                    map.put("userName", tuple.get(qExamResultV.studentName));
                    map.put("avgScore", tuple.get(2, BigDecimal.class));
                    map.put("examCount",tuple.get(3, BigDecimal.class));
                    map.put("commitExamCount", tuple.get(4, BigDecimal.class));
                    return map;
                }).collect(Collectors.toList());
        return lstMap;
    }
    @Override
    public Result lastStudied(String userId) {
        Map<String, Object> map = progressDao.getStudyByUserId(userId);
        String subjectId = (String) map.get("subjectId");
        Subject subject = read(Subject.class, subjectId);
        if (subject != null) {
            map.put("subjectName", subject.getName());
        }
        return new Result(true, "success", map);
    }
    @Override
    public List<Map<String,Object>> queryAvailableSubjectIdAndName(String teacherId,Integer subjectType){
        List<Map<String,Object>> result = null;
        if(subjectType==Subject.TYPE_PUBLIC_SUBJECT){
            result =  this.findListWithMapByHql(
                    "select subjectId as subjectId ,name as subjectName from Subject where deleteFlag is false and type=" + Subject.TYPE_PUBLIC_SUBJECT + " and orgId='" + ClientUtils.getOrgId() + "'" , null);
        }else{
            if(StringUtils.isNotEmpty(teacherId)){
                 result =  this.findListWithMapByHql(
                            "select distinct origSubjectId as subjectId ,name as subjectName from Subject where deleteFlag is false and type=" + Subject.TYPE_CLS_SUBJECT + " and teacherId='" + teacherId + "'", null);
            }else{
                 result =  this.findListWithMapByHql(
                            "select subjectId as subjectId ,name as subjectName from Subject where deleteFlag is false and type=" + Subject.TYPE_ORG_SUBJECT + " and orgId='" + ClientUtils.getOrgId() + "'", null);
            }
        }
        return result;
    }
    @Override
    public List<Map<String, Object>> getMySubjectList() {
        String sql = "SELECT o.CLASS_ID, a.`NAME` AS subjectName, a.SUBJECT_ID, o.`NAME` AS className FROM ( ( SELECT "
                + "c.CLASS_ID, c.`NAME` FROM stu_student s, cls_class c WHERE s.CLASS_ID = c.CLASS_ID AND s.USER_ID =:userId"
                + " ) o LEFT JOIN ( SELECT r.class_id,s.SUBJECT_ID, s.`NAME` FROM `subject` s, cls_class_re_subject r WHERE "
                + "s.SUBJECT_ID = r.subject_id ) a ON o.CLASS_ID = a.class_id ) ";
        List<Object[]> list = findByComplexSql(sql, CollectionUtils.newObjectMap("userId", ClientUtils.getUserId()),
                Object[].class);
        List<Map<String, Object>> lstMap = new ArrayList<Map<String, Object>>(list.size());
        Map<String, Object> map = null;
        for (Object[] objects : list) {
            map = new HashMap<String, Object>(objects.length);
            map.put("classId", objects[0]);
            map.put("subjectName", objects[1]);
            map.put("subjectId", objects[2]);
            map.put("className", objects[3]);
            lstMap.add(map);
        }
        return lstMap;
    }
    @Override
    public List<Map<String,Object>> clsSubjectlist(String classId, Integer schoolYear, Integer term) {
        QSubject qSubject = QSubject.subject;
        QClsClassReSubject qClsClassReSubject = QClsClassReSubject.clsClassReSubject;
        QueryDslOptionBuilder builder = new QueryDslOptionBuilder().
                and(qSubject.deleteFlag::eq, false)
                .and(qClsClassReSubject.classId::eq, classId)
                .and(qClsClassReSubject.subjectId::eq, qSubject.subjectId)
                .and(qClsClassReSubject.deleteFlag::eq, false).and(qSubject.status::eq, Subject.STATUS_ISSUED);
        if(schoolYear != null && schoolYear != 0){//学年
            builder = builder.and(qSubject.schoolYear::eq, schoolYear);
        }
        if(term != null && term != 0){//学期
            builder = builder.and(qSubject.term::eq, term);
        }
        return this.getQueryFactory().select(qSubject.name,qSubject.origSubjectId,qSubject.subjectId,qSubject.schoolYear, qSubject.term).distinct()
                .from(qSubject, qClsClassReSubject)
                .where(builder.build())
                .orderBy(qSubject.createTime.desc())
                .fetch().stream()
                .map(tuple -> {
                    Map<String,Object> map = new HashMap<String,Object>(2);
                    map.put("name", tuple.get(qSubject.name));
                    map.put("subjectId",  tuple.get(qSubject.subjectId));
                    map.put("schoolYear",  tuple.get(qSubject.schoolYear));
                    map.put("term",  tuple.get(qSubject.term));
                    map.put("origSubjectId",  tuple.get(qSubject.origSubjectId));
                    return map;
                }).collect(Collectors.toList());
    }
    @Override
    public List<Map<String,Object>> termList(String classId) {
        QSubject qSubject = QSubject.subject;
        QClsClassReSubject qClsClassReSubject = QClsClassReSubject.clsClassReSubject;
        QueryDslOptionBuilder builder = new QueryDslOptionBuilder().
                and(qSubject.deleteFlag::eq, false)
                .and(qClsClassReSubject.classId::eq, classId)
                .and(qClsClassReSubject.subjectId::eq, qSubject.subjectId)
                .and(qClsClassReSubject.deleteFlag::eq, false).and(qSubject.status::eq, Subject.STATUS_ISSUED);
        return this.getQueryFactory().select(qSubject.schoolYear.as("schoolYear"),qSubject.term.as("term"))
                .from(qSubject, qClsClassReSubject)
                .where(builder.build().and(qSubject.schoolYear.isNotNull())
                        .and(qSubject.term.isNotNull())).groupBy(qSubject.schoolYear, qSubject.term)
                .orderBy(qSubject.schoolYear.desc(), qSubject.term.desc())
                .fetch().stream()
                .map(tuple -> {
                    Map<String,Object> map = new HashMap<String,Object>(2);
                    map.put("schoolYear", tuple.get(0, Integer.class));
                    map.put("term",  tuple.get(1, Integer.class));
                    return map;
                }).collect(Collectors.toList());
    }
    /**
     * 我的班级信息
     *
     * @param classId
     * @return
     */
    public Map<String,Object> myClassInfo(String classId){
        ClsClass objClsClass = this.read(ClsClass.class, classId);
        QSubjectProgressTreeV qSubjectProgressTreeV = QSubjectProgressTreeV.subjectProgressTreeV;
        List<Subject> lstSubject = objClsClass.getSubjects();
        //过滤掉状态为草稿的
        List<String> teachers = lstSubject.stream().filter(u->u.getStatus().equals(Subject.STATUS_ISSUED)).map(tuple -> {
            return tuple.getTeacherName();
        }).collect(Collectors.toList());
        SubjectProgressTreeV objSubjectProgressTreeV = this.getQueryFactory().selectFrom(qSubjectProgressTreeV)
                .where(qSubjectProgressTreeV.id.nodeId.eq(classId).and(qSubjectProgressTreeV.id.userId.eq(ClientUtils.getUserId())).and(qSubjectProgressTreeV.nodeType.eq("class"))).fetchOne();
        if(objSubjectProgressTreeV != null) {
            long allCount = this.getQueryFactory().selectFrom(qSubjectProgressTreeV)
                    .where(qSubjectProgressTreeV.id.nodeId.eq(classId)).fetchCount();
            long lgCount = this.getQueryFactory().selectFrom(qSubjectProgressTreeV)
                    .where(qSubjectProgressTreeV.id.nodeId.eq(classId).and(qSubjectProgressTreeV.percent.gt(objSubjectProgressTreeV.getPercent()))).fetchCount();
            //排行
            float rank = (allCount-lgCount)/allCount;
            return CollectionUtils.newObjectMap("className", objClsClass.getName(), "progressPercent",
                    objSubjectProgressTreeV.getPercent(), "progressValue", objSubjectProgressTreeV.getProgressValue(), "rank", rank, "teacherName", teachers);
        }else {
            return CollectionUtils.newObjectMap("className", objClsClass.getName(), "percent",
                    0, "progressValue", 0, "rank", 0, teachers);
        }
    }
    /**
     * 获取我的课程进度
     *
     * @param classId
     * @return
     */
    public List<Map<String,Object>> myClsSubjectlist(String classId, String userId,  Pager pager){
        String teacherId = this.teacherService.getTeacherIdByUserId(ClientUtils.getUserId());
        QMySubjectV qMySubjectV = QMySubjectV.mySubjectV;
        Predicate predicate = null;
        if(StringUtils.isNotEmpty(teacherId)) {
            predicate = qMySubjectV.id.classId.eq(classId).and(qMySubjectV.id.userId.eq(userId)).and(qMySubjectV.teacherId.eq(teacherId).and(qMySubjectV.subjectStatus.eq(Subject.STATUS_ISSUED)));
        }else {
            predicate = qMySubjectV.id.classId.eq(classId).and(qMySubjectV.id.userId.eq(userId).and(qMySubjectV.subjectStatus.eq(Subject.STATUS_ISSUED)));
        }
        return this.getQueryFactory().select(qMySubjectV.id.subjectId,
                qMySubjectV.subjectName,qMySubjectV.term,
                qMySubjectV.schoolYear,qMySubjectV.percent, qMySubjectV.coverPageUrl,qMySubjectV.origSubjectId)
                .from(qMySubjectV)
                .where(predicate)
                .orderBy(qMySubjectV.schoolYear.desc(),qMySubjectV.term.desc())
                .limit(pager.getPageSize()).offset(pager.getOffset())
                .fetch().stream()
                .map(tuple -> {
                    Map<String,Object> map = new HashMap<String,Object>(5);
                    map.put("name", tuple.get(qMySubjectV.subjectName));
                    map.put("origSubjectId",  tuple.get(qMySubjectV.origSubjectId));
                    map.put("subjectId",  tuple.get(qMySubjectV.id.subjectId));
                    map.put("progressPercent",  tuple.get(qMySubjectV.percent));
                    map.put("schoolYear",  tuple.get(qMySubjectV.schoolYear));
                    map.put("term",  tuple.get(qMySubjectV.term));
                    map.put("coverPageUrl",  tuple.get(qMySubjectV.coverPageUrl));
                    return map;
                }).collect(Collectors.toList());
    }
    /**
     * 获取我的课程数量
     *
     * @param classId
     * @return
     */
    public long myClsSubjectCount(String classId){
        QMySubjectV qMySubjectV = QMySubjectV.mySubjectV;
        return this.getQueryFactory().select(qMySubjectV.id.subjectId,
                qMySubjectV.subjectName,qMySubjectV.term,
                qMySubjectV.schoolYear,qMySubjectV.percent)
                .from(qMySubjectV)
                .where(qMySubjectV.id.classId.eq(classId).and(qMySubjectV.id.userId.eq(ClientUtils.getUserId())).and(qMySubjectV.subjectStatus.eq(Subject.STATUS_ISSUED)))
                .fetchCount();
    }
    /**
     * 获取学员的课程进度
     *
     * @param classId
     * @return
     */
    public List<Map<String,Object>> studentSubjectProgress(String classId, Pager pager){
        String teacherId = this.teacherService.getTeacherIdByUserId(ClientUtils.getUserId());
        QSubjectProgressTreeV qSubjectProgressTreeV = QSubjectProgressTreeV.subjectProgressTreeV;
        QMySubjectV qMySubjectV = QMySubjectV.mySubjectV;
        return this.getQueryFactory().select(qMySubjectV.id.subjectId,
                qMySubjectV.subjectName,qMySubjectV.term,qMySubjectV.coverPageUrl,
                qMySubjectV.schoolYear,qMySubjectV.lectureCount, qMySubjectV.percent.avg().as(qMySubjectV.percent))
                .from(qMySubjectV)
                .where(qMySubjectV.id.classId.eq(classId).and(qMySubjectV.teacherId.eq(teacherId)))
                .groupBy(qMySubjectV.id.subjectId)
                .orderBy(qMySubjectV.schoolYear.desc(),qMySubjectV.term.desc())
                .limit(pager.getPageSize()).offset(pager.getOffset())
                .fetch().stream()
                .map(tuple -> {
                    Map<String,Object> map = new HashMap<String,Object>(5);
                    map.put("name", tuple.get(qMySubjectV.subjectName));
                    map.put("subjectId",  tuple.get(qMySubjectV.id.subjectId));
                    map.put("schoolYear",  tuple.get(qMySubjectV.schoolYear));
                    map.put("term",  tuple.get(qMySubjectV.term));
                    map.put("progressPercent",
                            this.getQueryFactory().select(qSubjectProgressTreeV.percent.avg())
                                    .from(qSubjectProgressTreeV)
                                    .where(qSubjectProgressTreeV.id.nodeId.eq(tuple.get(qMySubjectV.id.subjectId))
                                            .and(qSubjectProgressTreeV.nodeType.eq(Progress.PROGRESS_TYPE_SUBJECT)))
                                    .groupBy(qSubjectProgressTreeV.id.nodeId).fetchOne());
                    map.put("coverPageUrl",  tuple.get(qMySubjectV.coverPageUrl));
                    map.put("lectureCount",  this.getLectureCount(tuple.get(qMySubjectV.id.subjectId)));
                    return map;
                }).collect(Collectors.toList());
    }
    /**
     * 获取课件数量
     *
     * @param subjectId
     * @return
     */
    public long getLectureCount(String subjectId) {
        Subject subject = this.read(subjectId);
        if(subject == null) {
            return 0l;
        }
        if(subject.getType() == Subject.TYPE_CLS_SUBJECT) {//班级课程
            QClsSubjectLecture qSubjectLecture = QClsSubjectLecture.clsSubjectLecture;
            return this.getQueryFactory().selectFrom(qSubjectLecture).where(qSubjectLecture.deleteFlag.isFalse()
                    .and(qSubjectLecture.subjectId.eq(subjectId)).and(qSubjectLecture.status.eq(SubjectLecture.STATUS_DRAFT))).fetchCount();
        }else {
            QSubjectLecture qSubjectLecture = QSubjectLecture.subjectLecture;
            return this.getQueryFactory().selectFrom(qSubjectLecture).where(qSubjectLecture.deleteFlag.isFalse()
                    .and(qSubjectLecture.subjectId.eq(subjectId)).and(qSubjectLecture.status.eq(SubjectLecture.STATUS_DRAFT))).fetchCount();
        }
    }
    /**
     * 我的公开课列表
     *
     * @param pageNum
     * @param pageSize
     * @param keyword
     * @return
     */
    public Map<String,Object> myOpenSubjectList(Integer pageNum, Integer pageSize, String keyword){
        QSubject qSubject = QSubject.subject;
        QProgress qProgress = QProgress.progress;
        QSubjectLecture qSubjectLecture = QSubjectLecture.subjectLecture;
        JPAQuery<Tuple> query = this.getQueryFactory()
                .select(qSubject.subjectId, qSubject.name, qSubject.term,qSubject.coverPageUrl, qSubject.schoolYear,
                        qProgress.progressPercent.avg().as(qProgress.progressPercent), qProgress.progressValue.sum().as(qProgress.progressValue))
                .from(qSubject, qProgress, qSubjectLecture )
                .where(qSubject.deleteFlag.isFalse().and(qSubjectLecture.subjectId.eq(qSubject.subjectId))
                        .and(qSubjectLecture.deleteFlag.isFalse()).and(qSubjectLecture.lectureId.eq(qProgress.targetId))
                        .and(qProgress.learnerId.eq(ClientUtils.getUserId()))
                        .and(qSubject.name.like("%" + keyword + "%").and(qProgress.deleteFlag.isFalse()))
                        .and(qProgress.type.eq(Progress.PROGRESS_TYPE_LECTURE)).and(qSubject.status.eq(Subject.STATUS_ISSUED))).groupBy(qSubject.subjectId);
        long count = query.fetchCount();
        List<Map<String, Object>> listData = query.orderBy(qProgress.createTime.desc()).limit(pageSize).offset(pageNum).fetch().stream().map(tuple -> {
                    Map<String, Object> map = new HashMap<String, Object>(7);
                    String subjectId = tuple.get(qSubject.subjectId);
                    map.put("name", tuple.get(qSubject.name));
                    map.put("subjectId", subjectId);
                    map.put("schoolYear", tuple.get(qSubject.schoolYear));
                    map.put("term", tuple.get(qSubject.term));
                    map.put("coverPageUrl", tuple.get(qSubject.coverPageUrl));
                    map.put("progressPercent", tuple.get(qProgress.progressPercent));
                    map.put("progressValue", tuple.get(qProgress.progressValue));
                    Map<String,Object> openSubjectDetail = this.openSubjectDetail(subjectId);
                    // 直播数量
                    map.put("mediaVideoLiveCount",openSubjectDetail.get("mediaVideoLiveCount"));
                    // 课件数量
                    map.put("subjectLectureCount",openSubjectDetail.get("subjectLectureCount"));
                    //学习人次
                    map.put("studyCount",openSubjectDetail.get("studyCount"));
                    map.put("content",openSubjectDetail.get("content"));
                    // 已观看完成课件数量
                    map.put("subjectLectureDoCount",openSubjectDetail.get("subjectLectureDoCount"));
                    return map;
                }).collect(Collectors.toList());
        return CollectionUtils.newObjectMap("count", count, "listData", listData);
    }
    /**
     * 课程统计详情
     *
     * @param subjectId
     * @return
     */
    public Map<String,Object> openSubjectDetail(String subjectId){
        Map<String, Object> map = new HashMap<String, Object>();
        QMediaVideoLive qMediaVideoLive = QMediaVideoLive.mediaVideoLive;
        QSubjectLecture qSubjectLecture = QSubjectLecture.subjectLecture;
        QProgress qProgress = QProgress.progress;
        // 直播数量
        map.put("mediaVideoLiveCount",
                this.getQueryFactory().select(qMediaVideoLive).from(qMediaVideoLive)
                        .where(qMediaVideoLive.deleteFlag.isFalse()
                                .and(qMediaVideoLive.status.gt(0))
                                .and(qMediaVideoLive.subjectId.eq(subjectId)))
                        .fetchCount());
        // 课件数量
        map.put("subjectLectureCount",
                this.getQueryFactory().select(qSubjectLecture).from(qSubjectLecture)
                        .where(qSubjectLecture.deleteFlag.isFalse()
                                .and(qSubjectLecture.subjectId.eq(subjectId)).and(qSubjectLecture.status.eq(SubjectLecture.STATUS_DRAFT)))
                        .fetchCount());
        //学习人次
        map.put("studyCount",
                this.getQueryFactory().selectDistinct(qProgress.learnerId).from(qProgress, qSubjectLecture)
                        .where(qProgress.deleteFlag.isFalse().and(qSubjectLecture.deleteFlag.isFalse()).and(qSubjectLecture.subjectId.eq(subjectId)).and(qProgress.type.eq(Progress.PROGRESS_TYPE_LECTURE))
                                .and(qProgress.targetId.eq(qSubjectLecture.lectureId)))
                        .fetchCount());
        map.put("content", this.readSubjectContent(subjectId));
        // 已观看完成课件数量
        map.put("subjectLectureDoCount",
                this.getQueryFactory().select(qSubjectLecture).from(qSubjectLecture, qProgress)
                        .where(qSubjectLecture.deleteFlag.isFalse().and(qProgress.deleteFlag.isFalse())
                                .and(qProgress.learnerId.eq(ClientUtils.getUserId())).and(qProgress.type.eq(Progress.PROGRESS_TYPE_LECTURE))
                                .and(qProgress.progressPercent.gt(0.95)).and(qProgress.targetId.eq(qSubjectLecture.lectureId))
                                .and(qSubjectLecture.subjectId.eq(subjectId)))
                        .fetchCount());
        return map;
    }
    /**
     * 公开课详情
     *
     * @param subjectId
     * @return
     */
    public Map<String,Object> openSubjectInfo(String subjectId){
        QProgress qProgress = QProgress.progress;
        QSubjectLecture qSubjectLecture = QSubjectLecture.subjectLecture;
        Subject objSubject = this.read(subjectId);
        Tuple progress = this.getQueryFactory()
                .select(qProgress.progressPercent.sum().as(qProgress.progressPercent), qProgress.progressValue.sum().as(qProgress.progressValue)).from(qProgress,qSubjectLecture).where(qProgress.learnerId.eq(ClientUtils.getUserId())
                                .and(qProgress.targetId.eq(qSubjectLecture.lectureId))
                        .and(qProgress.deleteFlag.isFalse()).and(qSubjectLecture.deleteFlag.isFalse()).and(qSubjectLecture.subjectId.eq(subjectId))
                        .and(qProgress.type.eq(Progress.PROGRESS_TYPE_LECTURE))).fetchOne();
        Map<String, Object> subjectInfo = new HashMap<String, Object>(7);
        subjectInfo.put("name", objSubject.getName());
        subjectInfo.put("subjectId", subjectId);
        subjectInfo.put("schoolYear", objSubject.getSchoolYear());
        subjectInfo.put("term", objSubject.getTerm());
        subjectInfo.put("coverPageUrl", objSubject.getCoverPageUrl());
        subjectInfo.put("teacherName", objSubject.getTeacherName());
        Map<String,Object> openSubjectDetail = this.openSubjectDetail(subjectId);
        Map<String, Object> map = new HashMap<String, Object>(7);
        // 直播数量
        map.put("mediaVideoLiveCount",openSubjectDetail.get("mediaVideoLiveCount"));
        // 课件数量
        map.put("subjectLectureCount",openSubjectDetail.get("subjectLectureCount"));
        //学习人次
        map.put("studyCount",openSubjectDetail.get("studyCount"));
        subjectInfo.put("content",openSubjectDetail.get("content"));
        // 已观看完成课件数量
        map.put("subjectLectureDoCount",openSubjectDetail.get("subjectLectureDoCount"));
        map.put("subjectInfo", subjectInfo);
        if(openSubjectDetail.get("subjectLectureCount") == null || progress == null || progress.get(qProgress.progressPercent) == null) {
            subjectInfo.put("progressPercent", 0);
        }else {
            subjectInfo.put("progressPercent", progress.get(qProgress.progressPercent).floatValue()/(Long)openSubjectDetail.get("subjectLectureCount"));
        }
        subjectInfo.put("progressValue", progress == null?0:progress.get(qProgress.progressValue));
        return map;
    }
    @Override
    public Map<String, Object> mySubjectInfo(String subjectId, String classId) {
        QMySubjectV qMySubjectV = QMySubjectV.mySubjectV;
        QMyLectureV qMyLectureV = QMyLectureV.myLectureV;
        // 课程
        Tuple tuple = this.getQueryFactory()
                .select(qMySubjectV.id.subjectId, qMySubjectV.subjectName, qMySubjectV.term, qMySubjectV.schoolYear,qMySubjectV.origSubjectId,
                        qMySubjectV.percent,qMySubjectV.coverPageUrl, qMySubjectV.progressValue)
                .from(qMySubjectV)
                .where(qMySubjectV.id.classId.eq(classId).and(qMySubjectV.id.userId.eq(ClientUtils.getUserId()))
                        .and(qMySubjectV.id.subjectId.eq(subjectId)))
                .fetchOne();
        Subject objSubject = this.read(subjectId);
        Map<String, Object> subject = new HashMap<String, Object>(5);
        subject.put("name", objSubject.getName());
        subject.put("subjectId", subjectId);
        subject.put("origSubjectId", objSubject.getOrigSubjectId());
        subject.put("schoolYear", objSubject.getSchoolYear());
        subject.put("term", objSubject.getTerm());
        subject.put("coverPageUrl", objSubject.getCoverPageUrl());
        subject.put("content", this.readSubjectContent(subjectId));
        subject.put("teacherName", objSubject.getTeacherName());
        if(tuple == null) {
            subject.put("progressPercent", 0);
            subject.put("progressValue", 0);
        }else {
            subject.put("progressPercent", tuple.get(qMySubjectV.percent));
            subject.put("progressValue", tuple.get(qMySubjectV.progressValue));
        }
        String origSubjectId = objSubject.getOrigSubjectId();
        // 考试统计
        long examsCount = this.examService.listStudentExamCount("", new String[] {classId}, origSubjectId, null);
        // 作业统计
        long homeworksCount = exerciseInfoService.queryStuExerciseListCount("", null, ClientUtils.getUserId(), origSubjectId, null);
        // 课件统计
        Tuple tupleLecture = this.getQueryFactory().select(qMyLectureV.count(),
                new CaseBuilder().when(qMyLectureV.percent.gt(0.95)).then(1).otherwise(0).sum()).// 大于95%算完成
                from(qMyLectureV)
                .where(qMyLectureV.classId.eq(classId).and(qMyLectureV.id.userId.eq(ClientUtils.getUserId()))
                        .and(qMyLectureV.subjectId.eq(subjectId)))
                .groupBy(qMyLectureV.subjectId).fetchOne();
        long mediaVideoLivesCount = this.mediaLiveService.listCount("", new String[] {classId}, origSubjectId, null);
        return CollectionUtils.newObjectMap("mediaVideoLivesCount", mediaVideoLivesCount, "examsCount", examsCount,
                "homeworksCount", homeworksCount, "subjectInfo", subject, "lectureCount",
                tupleLecture == null?0:tupleLecture.get(0, Long.class),
                "completeLectureCount", tupleLecture == null?0:tupleLecture.get(1,Integer.class));
    }
    /**
     * 公开课列表
     *
     * @param pageNum
     * @param pageSize
     * @param keyword
     * @return
     */
    public Map<String,Object> openSubjectList(Integer pageNum, Integer pageSize, String keyword){
        QOpenSubjectV qOpenSubjectV = QOpenSubjectV.openSubjectV;
        JPAQuery<OpenSubjectV> query = this.getQueryFactory().selectFrom(qOpenSubjectV).where(qOpenSubjectV.subjectName.like("%" + keyword + "%"));
        long count = query.fetchCount();
        List<Map<String, Object>> listData = query.orderBy(qOpenSubjectV.mediaVideoCount.desc(),
                qOpenSubjectV.learnerCount.desc(), qOpenSubjectV.createTime.desc()).limit(pageSize).offset(pageNum)
                .fetch().stream().map(tuple -> {
                    Map<String, Object> map = new HashMap<String, Object>(8);
                    map.put("name", tuple.getSubjectName());
                    map.put("subjectId", tuple.getSubjectId());
                    map.put("schoolYear", tuple.getSchoolYear());
                    map.put("term", tuple.getTerm());
                    map.put("coverPageUrl", tuple.getCoverPageUrl());
                    map.put("mediaVideoCount", tuple.getMediaVideoCount());
                    map.put("learnerCount", tuple.getLearnerCount());
                    map.put("createTime", tuple.getCreateTime());
                    return map;
                }).collect(Collectors.toList());
        return CollectionUtils.newObjectMap("count", count, "listData", listData);
    }
    /**
     * 班级学员课件总体进度
     *
     * @param subjectId
     * @param classId
     * @return
     */
    @Override
    public List<Map<String, Object>> studentSubjectLectureProgress(String subjectId, String classId) {
        QMyLectureV qMyLectureV = QMyLectureV.myLectureV;
        return this.getQueryFactory()
                .select(qMyLectureV.lectureName, qMyLectureV.id.lectureId, qMyLectureV.lectureType,
                        qMyLectureV.chapterId, qMyLectureV.subjectId, qMyLectureV.lectureCreateTime,
                        qMyLectureV.percent.avg().as(qMyLectureV.percent))
                .from(qMyLectureV).where(qMyLectureV.classId.eq(classId).and(qMyLectureV.subjectId.eq(subjectId)))
                .groupBy(qMyLectureV.id.lectureId).orderBy(qMyLectureV.lectureCreateTime.desc()).fetch().stream()
                .map(tuple -> {
                    Map<String, Object> map = new HashMap<String, Object>(6);
                    map.put("lectureName", tuple.get(qMyLectureV.lectureName));
                    map.put("lectureId", tuple.get(qMyLectureV.id.lectureId));
                    map.put("lectureType", tuple.get(qMyLectureV.lectureType));
                    map.put("chapterId", tuple.get(qMyLectureV.chapterId));
                    map.put("subjectId", tuple.get(qMyLectureV.subjectId));
                    map.put("progressPercent", tuple.get(qMyLectureV.percent));
                    map.put("createTime", tuple.get(qMyLectureV.lectureCreateTime));
                    return map;
                }).collect(Collectors.toList());
        save(subject);
        return new Result(true, "success");
    }
    /**
     * 学员课程作业进度
     *
     * @param classId
     * @param subjectId
     * @return
     */
    public Map<String, Object> studentSubjectHomeworkProgress(String classId, String subjectId, String studentId){
        QExerciseResultV qHomeworkScoreV = QExerciseResultV.exerciseResultV;
    @Override
    public Result deleteClsSubject(String classId, String[] subjectIds) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("classId", classId);
        paramMap.put("subjectIds", subjectIds);
        StuStudent student = read(StuStudent.class, studentId);
        Subject subject = read(Subject.class, subjectId);
        List<String> reIdLst = this.findByComplexHql("select r.clsReSubjectId from ClsClassReSubject r where r.deleteFlag is false and r.classId=:classId and r.subjectId in (:subjectIds) ",
                paramMap, String.class);
        Tuple tuple = this.getQueryFactory()
                .select(qHomeworkScoreV.subjectId, qHomeworkScoreV.count(),
                        new CaseBuilder()
                                .when(qHomeworkScoreV.completeStatus.eq(ExerciseCompleteInfo.STATUS_CHECKED)
                                        .or(qHomeworkScoreV.completeStatus.eq(ExerciseCompleteInfo.STATUS_COMMIT)))
                                .then(qHomeworkScoreV.studentScore).otherwise(BigDecimal.ZERO).sum(),
                        new CaseBuilder()
                                .when(qHomeworkScoreV.completeStatus.eq(ExerciseCompleteInfo.STATUS_CHECKED)
                                        .or(qHomeworkScoreV.completeStatus.eq(ExerciseCompleteInfo.STATUS_COMMIT)))
                                .then(1).otherwise(0).sum())
                .from(qHomeworkScoreV)
                .where(qHomeworkScoreV.subjectId.eq(subject.getOrigSubjectId())
                        .and(qHomeworkScoreV.userId.eq(student.getUserId()))
                        .and(qHomeworkScoreV.exerciseStatus.eq(ExerciseInfo.EXERCISE_STATUS_PUBLISHED)))
                .groupBy(qHomeworkScoreV.userId).fetchOne();
        //删除关联关系
        if (reIdLst != null && reIdLst.size() > 0) {
            this.bulkUpdateInLoop("update ClsClassReSubject set deleteFlag = true where clsReSubjectId=?", reIdLst.toArray());
        }
        Map<String,Object> map = new HashMap<String,Object>(4);
        if(tuple == null) {
            map.put("subjectId", subjectId);
            map.put("homeworkCount",  0);
            map.put("avgScore",  "0");
            map.put("commitHomeworkCount",  0);
        }else {
            int commitHomeworkCount = tuple.get(3, Integer.class) == null?0:tuple.get(3, Integer.class);
            map.put("subjectId", subjectId);
            map.put("homeworkCount",  tuple.get(1, Integer.class) == null?0:tuple.get(1, Integer.class));
            map.put("avgScore",  String.valueOf(commitHomeworkCount == 0 || tuple.get(2, BigDecimal.class) == null?BigDecimal.ZERO:tuple.get(2, BigDecimal.class).divide(BigDecimal.valueOf(commitHomeworkCount), 2, BigDecimal.ROUND_HALF_UP)));
            map.put("commitHomeworkCount", commitHomeworkCount);
        }
        this.delete(subjectIds);
        return new Result(true, "success");
    }
        return map;
    }
    @Override
    public Result getPerformance4Subject() {
        String findCompleteCountByHql = "from MySubjectV where id.userId = ? and percent = 1 ";
        String findUndoneByHql = "from MySubjectV where id.userId = ? and (percent != 1 or percent is null)";
        String userId = ClientUtils.getUserId();
        int CompleteCount = findCount(findCompleteCountByHql, CollectionUtils.newList(userId));
        int UndoneCount = findCount(findUndoneByHql, CollectionUtils.newList(userId));
        return new Result(true, "success",
                CollectionUtils.newObjectMap("CompleteCount", CompleteCount, "UndoneCount", UndoneCount));
    }
    /**
     * 学员考试作业进度
     *
     * @param classId
     * @param subjectId
     * @return
     */
    public Map<String, Object> studentSubjectExamProgress(String classId, String subjectId, String studentId){
        QExamResultV qExamScoreV = QExamResultV.examResultV;
    @Override
    public Result lstSubjectDetail() {
        String userId = ClientUtils.getUserId();
        StringBuffer hql = new StringBuffer(
                "select percent as percent,className as className ,id.classId as classId ,id.subjectId as subjectId ,"
                        + "subjectName as subjectName ,coverPageUrl as coverPageUrl , progressValue as progressValue from"
                        + " MySubjectV p where p.id.userId =:userId and p.subjectStatus=:subjectStatus ");
        StuStudent student = read(StuStudent.class, studentId);
        Subject subject = read(Subject.class, subjectId);
        Map<String, Object> args = CollectionUtils.newObjectMap("userId", userId, "subjectStatus", Subject.STATUS_ISSUED);
        Tuple tuple = this.getQueryFactory().select(qExamScoreV.subjectId, qExamScoreV.count(), new CaseBuilder()
                .when(qExamScoreV.status.eq("0")).then(BigDecimal.ZERO).otherwise(qExamScoreV.score).sum(), new CaseBuilder()
                .when(qExamScoreV.status.eq("0")).then(0).otherwise(1).sum()).
                from(qExamScoreV).
                where(qExamScoreV.subjectId.eq(subject.getOrigSubjectId()).and(qExamScoreV.userId.eq(student.getUserId())).and(qExamScoreV.examStatus.eq(ExerciseInfo.EXERCISE_STATUS_PUBLISHED))).
                groupBy(qExamScoreV.userId).fetchOne();
        Map<String,Object> map = new HashMap<String,Object>(4);
        map.put("subjectId", subjectId);
        if(tuple == null) {
            map.put("examCount",  0);
            map.put("avgScore",  "0");
            map.put("commitExamCount",  0);
        }else {
            int commitExamCount = tuple.get(3, Integer.class) == null?0:tuple.get(3, Integer.class);
        List<Map<String, Object>> subjectLstMap = findListWithMapByHql(hql.toString(), args);
            map.put("examCount",  tuple.get(1, Integer.class) == null?0:tuple.get(1, Integer.class));
            map.put("avgScore",  String.valueOf(commitExamCount == 0 || tuple.get(2, BigDecimal.class) == null?BigDecimal.ZERO:tuple.get(2, BigDecimal.class).divide(new BigDecimal(commitExamCount), 2, BigDecimal.ROUND_HALF_UP)));
            map.put("commitExamCount",  tuple.get(3, Integer.class) == null?0:tuple.get(3, Integer.class));
        }
        for (Map<String, Object> subject : subjectLstMap) {
        return map;
    }
            String classId = (String) subject.get("classId");
            String subjectId = (String) subject.get("subjectId");
            Map<String, Object> map = progressDao.getStudyById(userId, subjectId, classId);
            List<MyLectureV> myLectureVList = lectureService.listLectureVBySubjectId(userId, subjectId, "", 1000, 1, null);
            Double percent = 0.0;
            Double progressValue = 0.0;
            Double percentAvg = 0.0;
            if (!myLectureVList.isEmpty()) {
                for (MyLectureV myLectureV : myLectureVList) {
                    if (myLectureV.getPercent() != null && myLectureV.getProgressValue() != null) {
                        percent += myLectureV.getPercent();
                        progressValue += myLectureV.getProgressValue().intValue();
                    }
                }
                percentAvg = percent / myLectureVList.size();
                if (percentAvg.isNaN()) {
                    percentAvg = 0.0;
                }
            }
            subject.put("percent", new BigDecimal(percentAvg));
            subject.put("progressValue", new BigDecimal(progressValue));
    /**
     * 我的课件情况
     *
     * @param classId
     * @return
     */
    private List<Map<String, Object>> myLectureList(String classId){
        QMyLectureV qMyLectureV = QMyLectureV.myLectureV;
            subject.put("lectureParentId", map.get("lectureParentId"));
            subject.put("lectureId", map.get("lectureId"));
            subject.put("unCommitExerciseCount", exerciseInfoService.getUnCommitExerciseCount(classId, userId));
            subject.put("toBeCommitExerciseCount", exerciseInfoService.getToBeCommitExerciseCount(classId, userId));
            subject.put("CommitExerciseCount", exerciseInfoService.getCommitExerciseCount(classId, userId));
            subject.put("exerciseCount", exerciseInfoService.getExerciseCount(classId, userId));
            subject.put("examCount", examService.getExamCount(classId, userId));
            subject.put("unCommitExamCount", examService.getUnCommitExamCount(classId, userId));
            subject.put("commitExamCount", examService.getCommitExamCount(classId, userId));
            subject.put("toBeCommitExamCount", examService.getToBeCommitExamCount(classId, userId));
        return this.getQueryFactory().select(qMyLectureV.subjectId,
                qMyLectureV.count(),
                new CaseBuilder()
                .when(qMyLectureV.percent.gt(0.95)).then(1).otherwise(0).sum()).//大于95%算完成
                from(qMyLectureV).
                where(qMyLectureV.classId.eq(classId).and(qMyLectureV.id.userId.eq(ClientUtils.getUserId()))).
                groupBy(qMyLectureV.subjectId).fetch().stream()
                .map(tuple -> {
                    Map<String,Object> map = new HashMap<String,Object>(3);
                    map.put("subjectId", tuple.get(0, String.class));
                    map.put("lectureCount",  tuple.get(1, Integer.class));
                    map.put("completeLectureCount", tuple.get(2, String.class));
                    return map;
                }).collect(Collectors.toList());
    }
        }
        return new Result(true, "success", subjectLstMap);
    }
    /**
     * 我的课程,按时间排序
     *
     * @param classId
     * @return
     */
    public List<Map<String,Object>> mySubjectList(String classId, Pager pager) {
        //课程
        List<Map<String,Object>> clsSubjectlist = this.myClsSubjectlist(classId, ClientUtils.getUserId(), pager);
        //课件统计
        List<Map<String,Object>> lectures = this.myLectureList(classId);
        for(Map<String,Object> clsSubject : clsSubjectlist) {
            String origSubjectId = (String)clsSubject.get("origSubjectId");
            clsSubject.put("exam", CollectionUtils.newObjectMap("examCount", this.examService.listStudentExamCount("", new String[] {classId}, origSubjectId, null)));
            clsSubject.put("homework", CollectionUtils.newObjectMap("homeworkCount", exerciseInfoService.queryStuExerciseListCount("", null, ClientUtils.getUserId(), origSubjectId, null)));
            clsSubject.put("lecture", CollectionUtils.newObjectMap("lectureCount", 0, "completeLectureCount", 0));
            clsSubject.put("mediaVideoLive", CollectionUtils.newObjectMap("mediaVideoLiveCount", this.mediaLiveService.listCount("", new String[] {classId}, origSubjectId, null)));
    @SuppressWarnings({"unchecked", "rawtypes"})
    @Override
    public Result getDataDesc(String classId, String subjectId) {
        if (StringUtils.isEmpty(classId)) {
            return new Result(false, "班级id参数错误");
        }
        QSubjectProgressTreeV qSubjectProgressTreeV = QSubjectProgressTreeV.subjectProgressTreeV;
            this.setSubjectStatistics("lecture", clsSubject, lectures);
        }
        List<Map<String, Object>> percentDesc = this.percentDesc(classId, subjectId, new OrderSpecifier(Order.DESC, qSubjectProgressTreeV.percent));
        return clsSubjectlist;
    }
        List<Map<String, Object>> studyTimeDesc = this.percentDesc(classId, subjectId, new OrderSpecifier(Order.DESC, qSubjectProgressTreeV.progressValue));
    /**
     * 统计课程的数据
     *
     * @param type 类型
     * @param clsSubject 课程
     * @param lstStatistics 统计信息
     */
    private void setSubjectStatistics(String type, Map<String,Object> clsSubject,  List<Map<String,Object>> lstStatistics) {
        if(lstStatistics != null && !lstStatistics.isEmpty()) {
            for(Map<String,Object> statistics : lstStatistics) {
                if(clsSubject.get("origSubjectId").equals(statistics.get("subjectId")) || clsSubject.get("subjectId").equals(statistics.get("subjectId"))) {
                    clsSubject.put(type, statistics);
                }
            }
        }
        List<Map<String, Object>> exerciseInfoDesc = this.exerciseInfoDesc(classId, subjectId);
    }
        List<Map<String, Object>> examInfoDesc = this.examInfoDesc(classId, subjectId);
    /**
     * 我的课程详情
     *
     * @param classId
     * @return
     */
    public Map<String,Object> mySubjectInfo(String subjectId, String classId,HttpServletRequest request) {
        return new Result(true, "success", CollectionUtils.newObjectMap("percentDesc", percentDesc, "studyTimeDesc",
                studyTimeDesc, "exerciseInfoDesc", exerciseInfoDesc, "examInfoDesc", examInfoDesc));
    }
        QMySubjectV qMySubjectV = QMySubjectV.mySubjectV;
        QMyLectureV qMyLectureV = QMyLectureV.myLectureV;
        Object userId = request.getSession().getAttribute("userId");
        // 课程
        Tuple tuple = this.getQueryFactory()
                .select(qMySubjectV.id.subjectId, qMySubjectV.subjectName, qMySubjectV.term, qMySubjectV.schoolYear,qMySubjectV.origSubjectId,
                        qMySubjectV.percent,qMySubjectV.coverPageUrl, qMySubjectV.progressValue)
                .from(qMySubjectV)
                .where(qMySubjectV.id.classId.eq(classId).and(qMySubjectV.id.userId.eq(ClientUtils.getUserId()))
                        .and(qMySubjectV.id.subjectId.eq(subjectId)))
                .fetchOne();
        Subject objSubject = this.read(subjectId);
        Map<String, Object> subject = new HashMap<String, Object>(5);
        subject.put("name", objSubject.getName());
        subject.put("subjectId", subjectId);
        subject.put("origSubjectId", objSubject.getOrigSubjectId());
        subject.put("schoolYear", objSubject.getSchoolYear());
        subject.put("term", objSubject.getTerm());
        subject.put("coverPageUrl", objSubject.getCoverPageUrl());
        subject.put("content", this.readSubjectContent(subjectId));
        subject.put("teacherName", objSubject.getTeacherName());
        if(tuple == null) {
            subject.put("progressPercent", 0);
            subject.put("progressValue", 0);
        }else {
            subject.put("progressPercent", tuple.get(qMySubjectV.percent));
            subject.put("progressValue", tuple.get(qMySubjectV.progressValue));
        }
        String origSubjectId = objSubject.getOrigSubjectId();
        // 考试统计
        long examsCount = this.examService.listStudentExamCount("", new String[] {classId}, origSubjectId, null);
        // 作业统计
        long homeworksCount = exerciseInfoService.queryStuExerciseListCount("", null, ClientUtils.getUserId(), origSubjectId, null);
        // 课件统计
        Tuple tupleLecture = this.getQueryFactory().select(qMyLectureV.count(),
                new CaseBuilder().when(qMyLectureV.percent.gt(0.95)).then(1).otherwise(0).sum()).// 大于95%算完成
                from(qMyLectureV)
                .where(qMyLectureV.classId.eq(classId).and(qMyLectureV.id.userId.eq(ClientUtils.getUserId()))
                        .and(qMyLectureV.subjectId.eq(subjectId)))
                .groupBy(qMyLectureV.subjectId).fetchOne();
        long mediaVideoLivesCount = this.mediaLiveService.listCount("", new String[] {classId}, origSubjectId, null);
        return CollectionUtils.newObjectMap("mediaVideoLivesCount", mediaVideoLivesCount, "examsCount", examsCount,
                "homeworksCount", homeworksCount, "subjectInfo", subject, "lectureCount",
                tupleLecture == null?0:tupleLecture.get(0, Long.class),
                        "completeLectureCount", tupleLecture == null?0:tupleLecture.get(1,Integer.class));
    }
    /**
     * 我的课程按学期分类
     *
     * @param classId
     * @return
     */
    @Override
    public List<Map<String,Object>> myTermSubjectList(String classId) {
        //课程
        List<Map<String,Object>> clsSubjectlist = this.mySubjectList(classId, new Pager());
        System.out.println("clsSubjectlistaaaaaa"+clsSubjectlist);
        return this.termSubjectList(classId, clsSubjectlist);
    }
    /**
     * 获取班级对应的学员 按进度进行排序
     */
    private List<Map<String, Object>> percentDesc(String classId, String subjectId, @SuppressWarnings("rawtypes") OrderSpecifier order) {
        QSubjectProgressTreeV qSubjectProgressTreeV = QSubjectProgressTreeV.subjectProgressTreeV;
        QUser qUser = QUser.user;
        String nodeId = StringUtils.isNotEmpty(subjectId) ? subjectId : classId;
        String nodeType = StringUtils.isNotEmpty(subjectId) ? Progress.PROGRESS_TYPE_SUBJECT : Progress.PROGRESS_TYPE_CLASS;
        List<Map<String, Object>> lstMap = this.getQueryFactory().select(qSubjectProgressTreeV.progressValue,
                qSubjectProgressTreeV.percent, qUser.name, qUser.userId, qSubjectProgressTreeV.id.nodeId).from(qSubjectProgressTreeV, qUser).
                where(qSubjectProgressTreeV.id.userId.eq(qUser.userId).and(qSubjectProgressTreeV.nodeType.eq(nodeType))
                        .and(qSubjectProgressTreeV.id.nodeId.eq(nodeId))).orderBy(order).fetch().stream().map(tuple -> {
            Map<String, Object> map = new HashMap<>();
            map.put("userName", tuple.get(qUser.name));
            map.put("userId", tuple.get(qUser.userId));
            map.put("classId", tuple.get(qSubjectProgressTreeV.id.nodeId));
            map.put("percent", tuple.get(qSubjectProgressTreeV.percent));
            map.put("progressValue", tuple.get(qSubjectProgressTreeV.progressValue));
            return map;
        }).collect(Collectors.toList());
        return lstMap;
    }
    /**
     * 通过作业完成个数排序
     */
    private List<Map<String, Object>> exerciseInfoDesc(String classId, String subjectId) {
        QExerciseResultV qExerciseResultV = QExerciseResultV.exerciseResultV;
        //查询条件
        Predicate predicate = StringUtils.isEmpty(subjectId) ? qExerciseResultV.id.classId.eq(classId) :
                qExerciseResultV.id.classId.eq(classId).and(qExerciseResultV.subjectId.eq(subjectId));
        //case数量判断
        NumberExpression<BigDecimal> caseCount = new CaseBuilder()
                .when(qExerciseResultV.completeStatus.eq(ExerciseCompleteInfo.STATUS_CHECKED)
                        .or(qExerciseResultV.completeStatus.eq(ExerciseCompleteInfo.STATUS_COMMIT)))
                .then(BigDecimal.ONE).otherwise(BigDecimal.ZERO).sum();
        //case分数
        NumberExpression<BigDecimal> caseScoreSum = new CaseBuilder()
                .when(qExerciseResultV.completeStatus.eq(ExerciseCompleteInfo.STATUS_CHECKED)
                        .or(qExerciseResultV.completeStatus.eq(ExerciseCompleteInfo.STATUS_COMMIT)))
                .then(qExerciseResultV.score).otherwise(BigDecimal.ZERO).sum();
        List<Map<String, Object>> lstMap = this.getQueryFactory().select(qExerciseResultV.userId, qExerciseResultV.studentName,
                caseScoreSum.divide(caseCount), qExerciseResultV.count(), caseCount).from(qExerciseResultV).where(predicate).
                groupBy(qExerciseResultV.userId).
                orderBy(caseScoreSum.divide(caseCount).desc()).fetch().stream().map(tuple -> {
            Map<String, Object> map = new HashMap<>();
            map.put("userId", tuple.get(qExerciseResultV.userId));
            map.put("userName", tuple.get(qExerciseResultV.studentName));
            map.put("avgScore", tuple.get(2, BigDecimal.class));
            map.put("exerciseCount", tuple.get(3, BigDecimal.class));
            map.put("commitExerciseCount", tuple.get(4, BigDecimal.class));
            return map;
        }).collect(Collectors.toList());
        return lstMap;
    }
    /**
     *
     */
    private List<Map<String, Object>> examInfoDesc(String classId, String subjectId) {
        QExamResultV qExamResultV = QExamResultV.examResultV;
        //查询条件
        Predicate predicate = StringUtils.isEmpty(subjectId) ? qExamResultV.id.classId.eq(classId) :
                qExamResultV.id.classId.eq(classId).and(qExamResultV.subjectId.eq(subjectId));
        //case判断
        NumberExpression<BigDecimal> caseCount = new CaseBuilder()
                .when(qExamResultV.status.eq("0")).then(BigDecimal.ZERO).otherwise(BigDecimal.ONE).sum();
        //case分数
        NumberExpression<BigDecimal> caseScoreSum = new CaseBuilder()
                .when(qExamResultV.status.eq("0")).then(BigDecimal.ZERO).otherwise(qExamResultV.score).sum();
        List<Map<String, Object>> lstMap = this.getQueryFactory().select(qExamResultV.userId, qExamResultV.studentName,
                caseScoreSum.divide(caseCount), qExamResultV.count(), caseCount).from(qExamResultV).where(predicate).
                groupBy(qExamResultV.userId).
                orderBy(caseScoreSum.divide(caseCount).desc()).fetch().stream().map(tuple -> {
            Map<String, Object> map = new HashMap<>();
            map.put("userId", tuple.get(qExamResultV.userId));
            map.put("userName", tuple.get(qExamResultV.studentName));
            map.put("avgScore", tuple.get(2, BigDecimal.class));
            map.put("examCount", tuple.get(3, BigDecimal.class));
            map.put("commitExamCount", tuple.get(4, BigDecimal.class));
            return map;
        }).collect(Collectors.toList());
        return lstMap;
    }
    @Override
    public Result lastStudied(String userId) {
        Map<String, Object> map = progressDao.getStudyByUserId(userId);
        String subjectId = (String) map.get("subjectId");
        Subject subject = read(Subject.class, subjectId);
        if (subject != null) {
            map.put("subjectName", subject.getName());
        }
        return new Result(true, "success", map);
    }
    @Override
    public List<Map<String, Object>> queryAvailableSubjectIdAndName(String teacherId, Integer subjectType) {
        List<Map<String, Object>> result = null;
        if (subjectType == Subject.TYPE_PUBLIC_SUBJECT) {
            result = this.findListWithMapByHql(
                    "select subjectId as subjectId ,name as subjectName from Subject where deleteFlag is false and type=" + Subject.TYPE_PUBLIC_SUBJECT + " and orgId='" + ClientUtils.getOrgId() + "'", null);
        } else {
            if (StringUtils.isNotEmpty(teacherId)) {
                result = this.findListWithMapByHql(
                        "select distinct origSubjectId as subjectId ,name as subjectName from Subject where deleteFlag is false and type=" + Subject.TYPE_CLS_SUBJECT + " and teacherId='" + teacherId + "'", null);
            } else {
                result = this.findListWithMapByHql(
                        "select subjectId as subjectId ,name as subjectName from Subject where deleteFlag is false and type=" + Subject.TYPE_ORG_SUBJECT + " and orgId='" + ClientUtils.getOrgId() + "'", null);
            }
        }
        return result;
    }
    @Override
    public List<Map<String, Object>> getMySubjectList() {
        String sql = "SELECT o.CLASS_ID, a.`NAME` AS subjectName, a.SUBJECT_ID, o.`NAME` AS className FROM ( ( SELECT "
                + "c.CLASS_ID, c.`NAME` FROM stu_student s, cls_class c WHERE s.CLASS_ID = c.CLASS_ID AND s.USER_ID =:userId"
                + " ) o LEFT JOIN ( SELECT r.class_id,s.SUBJECT_ID, s.`NAME` FROM `subject` s, cls_class_re_subject r WHERE "
                + "s.SUBJECT_ID = r.subject_id ) a ON o.CLASS_ID = a.class_id ) ";
        List<Object[]> list = findByComplexSql(sql, CollectionUtils.newObjectMap("userId", ClientUtils.getUserId()),
                Object[].class);
        List<Map<String, Object>> lstMap = new ArrayList<Map<String, Object>>(list.size());
        Map<String, Object> map = null;
        for (Object[] objects : list) {
            map = new HashMap<String, Object>(objects.length);
            map.put("classId", objects[0]);
            map.put("subjectName", objects[1]);
            map.put("subjectId", objects[2]);
            map.put("className", objects[3]);
            lstMap.add(map);
        }
        return lstMap;
    }
    /**
     * 课程按学期分类
     *
     * @param classId
     * @return
     */
    @Override
    public List<Map<String,Object>> termSubjectList(String classId, List<Map<String,Object>> clsSubjectlist) {
        //学期
        List<Map<String,Object>> termList = this.termList(classId);
    @Override
    public List<Map<String, Object>> clsSubjectlist(String classId, Integer schoolYear, Integer term) {
        QSubject qSubject = QSubject.subject;
        QClsClassReSubject qClsClassReSubject = QClsClassReSubject.clsClassReSubject;
        if(termList != null && !termList.isEmpty()) {
            for(Map<String,Object> term : termList) {
                if(termList != null && !termList.isEmpty()) {
                    List<Map<String,Object>> subjectList = new ArrayList<>();
                    for(Map<String,Object> clsSubject : clsSubjectlist) {
                        if(term.get("schoolYear").equals(clsSubject.get("schoolYear")) &&
                                term.get("term").equals(clsSubject.get("term"))) {
                            subjectList.add(clsSubject);
                        }
                        term.put("subjectList", subjectList);
                    }
                }
            }
        }
        return termList;
    }
        QueryDslOptionBuilder builder = new QueryDslOptionBuilder().
                and(qSubject.deleteFlag::eq, false)
                .and(qClsClassReSubject.classId::eq, classId)
                .and(qClsClassReSubject.subjectId::eq, qSubject.subjectId)
                .and(qClsClassReSubject.deleteFlag::eq, false).and(qSubject.status::eq, Subject.STATUS_ISSUED);
        if (schoolYear != null && schoolYear != 0) {//学年
            builder = builder.and(qSubject.schoolYear::eq, schoolYear);
        }
        if (term != null && term != 0) {//学期
            builder = builder.and(qSubject.term::eq, term);
        }
        return this.getQueryFactory().select(qSubject.name, qSubject.origSubjectId, qSubject.subjectId, qSubject.schoolYear, qSubject.term).distinct()
                .from(qSubject, qClsClassReSubject)
                .where(builder.build())
                .orderBy(qSubject.createTime.desc())
                .fetch().stream()
                .map(tuple -> {
                    Map<String, Object> map = new HashMap<String, Object>(2);
                    map.put("name", tuple.get(qSubject.name));
                    map.put("subjectId", tuple.get(qSubject.subjectId));
                    map.put("schoolYear", tuple.get(qSubject.schoolYear));
                    map.put("term", tuple.get(qSubject.term));
                    map.put("origSubjectId", tuple.get(qSubject.origSubjectId));
                    return map;
                }).collect(Collectors.toList());
    }
    @Override
    public List<Map<String, Object>> termList(String classId) {
        QSubject qSubject = QSubject.subject;
        QClsClassReSubject qClsClassReSubject = QClsClassReSubject.clsClassReSubject;
        QueryDslOptionBuilder builder = new QueryDslOptionBuilder().
                and(qSubject.deleteFlag::eq, false)
                .and(qClsClassReSubject.classId::eq, classId)
                .and(qClsClassReSubject.subjectId::eq, qSubject.subjectId)
                .and(qClsClassReSubject.deleteFlag::eq, false).and(qSubject.status::eq, Subject.STATUS_ISSUED);
        return this.getQueryFactory().select(qSubject.schoolYear.as("schoolYear"), qSubject.term.as("term"))
                .from(qSubject, qClsClassReSubject)
                .where(builder.build().and(qSubject.schoolYear.isNotNull())
                        .and(qSubject.term.isNotNull())).groupBy(qSubject.schoolYear, qSubject.term)
                .orderBy(qSubject.schoolYear.desc(), qSubject.term.desc())
                .fetch().stream()
                .map(tuple -> {
                    Map<String, Object> map = new HashMap<String, Object>(2);
                    map.put("schoolYear", tuple.get(0, Integer.class));
                    map.put("term", tuple.get(1, Integer.class));
                    return map;
                }).collect(Collectors.toList());
    }
    /**
     * 我的班级信息
     *
     * @param classId
     * @return
     */
    public Map<String, Object> myClassInfo(String classId) {
        ClsClass objClsClass = this.read(ClsClass.class, classId);
        QSubjectProgressTreeV qSubjectProgressTreeV = QSubjectProgressTreeV.subjectProgressTreeV;
        List<Subject> lstSubject = objClsClass.getSubjects();
        //过滤掉状态为草稿的
        List<String> teachers = lstSubject.stream().filter(u -> u.getStatus().equals(Subject.STATUS_ISSUED)).map(tuple -> {
            return tuple.getTeacherName();
        }).collect(Collectors.toList());
        SubjectProgressTreeV objSubjectProgressTreeV = this.getQueryFactory().selectFrom(qSubjectProgressTreeV)
                .where(qSubjectProgressTreeV.id.nodeId.eq(classId).and(qSubjectProgressTreeV.id.userId.eq(ClientUtils.getUserId())).and(qSubjectProgressTreeV.nodeType.eq("class"))).fetchOne();
        if (objSubjectProgressTreeV != null) {
            long allCount = this.getQueryFactory().selectFrom(qSubjectProgressTreeV)
                    .where(qSubjectProgressTreeV.id.nodeId.eq(classId)).fetchCount();
            long lgCount = this.getQueryFactory().selectFrom(qSubjectProgressTreeV)
                    .where(qSubjectProgressTreeV.id.nodeId.eq(classId).and(qSubjectProgressTreeV.percent.gt(objSubjectProgressTreeV.getPercent()))).fetchCount();
            //排行
            float rank = (allCount - lgCount) / allCount;
            return CollectionUtils.newObjectMap("className", objClsClass.getName(), "progressPercent",
                    objSubjectProgressTreeV.getPercent(), "progressValue", objSubjectProgressTreeV.getProgressValue(), "rank", rank, "teacherName", teachers);
        } else {
            return CollectionUtils.newObjectMap("className", objClsClass.getName(), "percent",
                    0, "progressValue", 0, "rank", 0, teachers);
        }
    }
    /**
     * 获取我的课程进度
     *
     * @param classId
     * @return
     */
    public List<Map<String, Object>> myClsSubjectlist(String classId, String userId, Pager pager) {
        String teacherId = this.teacherService.getTeacherIdByUserId(ClientUtils.getUserId());
        QMySubjectV qMySubjectV = QMySubjectV.mySubjectV;
        Predicate predicate = null;
        if (StringUtils.isNotEmpty(teacherId)) {
            predicate = qMySubjectV.id.classId.eq(classId).and(qMySubjectV.id.userId.eq(userId)).and(qMySubjectV.teacherId.eq(teacherId).and(qMySubjectV.subjectStatus.eq(Subject.STATUS_ISSUED)));
        } else {
            predicate = qMySubjectV.id.classId.eq(classId).and(qMySubjectV.id.userId.eq(userId).and(qMySubjectV.subjectStatus.eq(Subject.STATUS_ISSUED)));
        }
        return this.getQueryFactory().select(qMySubjectV.id.subjectId,
                qMySubjectV.subjectName, qMySubjectV.term,
                qMySubjectV.schoolYear, qMySubjectV.percent, qMySubjectV.coverPageUrl, qMySubjectV.origSubjectId)
                .from(qMySubjectV)
                .where(predicate)
                .orderBy(qMySubjectV.schoolYear.desc(), qMySubjectV.term.desc())
                .limit(pager.getPageSize()).offset(pager.getOffset())
                .fetch().stream()
                .map(tuple -> {
                    Map<String, Object> map = new HashMap<String, Object>(5);
                    map.put("name", tuple.get(qMySubjectV.subjectName));
                    map.put("origSubjectId", tuple.get(qMySubjectV.origSubjectId));
                    map.put("subjectId", tuple.get(qMySubjectV.id.subjectId));
                    map.put("progressPercent", tuple.get(qMySubjectV.percent));
                    map.put("schoolYear", tuple.get(qMySubjectV.schoolYear));
                    map.put("term", tuple.get(qMySubjectV.term));
                    map.put("coverPageUrl", tuple.get(qMySubjectV.coverPageUrl));
                    return map;
                }).collect(Collectors.toList());
    }
    /**
     * 获取我的课程数量
     *
     * @param classId
     * @return
     */
    public long myClsSubjectCount(String classId) {
        QMySubjectV qMySubjectV = QMySubjectV.mySubjectV;
        return this.getQueryFactory().select(qMySubjectV.id.subjectId,
                qMySubjectV.subjectName, qMySubjectV.term,
                qMySubjectV.schoolYear, qMySubjectV.percent)
                .from(qMySubjectV)
                .where(qMySubjectV.id.classId.eq(classId).and(qMySubjectV.id.userId.eq(ClientUtils.getUserId())).and(qMySubjectV.subjectStatus.eq(Subject.STATUS_ISSUED)))
                .fetchCount();
    }
    /**
     * 获取学员的课程进度
     *
     * @param classId
     * @return
     */
    public List<Map<String, Object>> studentSubjectProgress(String classId, Pager pager) {
        String teacherId = this.teacherService.getTeacherIdByUserId(ClientUtils.getUserId());
        QSubjectProgressTreeV qSubjectProgressTreeV = QSubjectProgressTreeV.subjectProgressTreeV;
        QMySubjectV qMySubjectV = QMySubjectV.mySubjectV;
        return this.getQueryFactory().select(qMySubjectV.id.subjectId,
                qMySubjectV.subjectName, qMySubjectV.term, qMySubjectV.coverPageUrl,
                qMySubjectV.schoolYear, qMySubjectV.lectureCount, qMySubjectV.percent.avg().as(qMySubjectV.percent))
                .from(qMySubjectV)
                .where(qMySubjectV.id.classId.eq(classId).and(qMySubjectV.teacherId.eq(teacherId)))
                .groupBy(qMySubjectV.id.subjectId)
                .orderBy(qMySubjectV.schoolYear.desc(), qMySubjectV.term.desc())
                .limit(pager.getPageSize()).offset(pager.getOffset())
                .fetch().stream()
                .map(tuple -> {
                    Map<String, Object> map = new HashMap<String, Object>(5);
                    map.put("name", tuple.get(qMySubjectV.subjectName));
                    map.put("subjectId", tuple.get(qMySubjectV.id.subjectId));
                    map.put("schoolYear", tuple.get(qMySubjectV.schoolYear));
                    map.put("term", tuple.get(qMySubjectV.term));
                    map.put("progressPercent",
                            this.getQueryFactory().select(qSubjectProgressTreeV.percent.avg())
                                    .from(qSubjectProgressTreeV)
                                    .where(qSubjectProgressTreeV.id.nodeId.eq(tuple.get(qMySubjectV.id.subjectId))
                                            .and(qSubjectProgressTreeV.nodeType.eq(Progress.PROGRESS_TYPE_SUBJECT)))
                                    .groupBy(qSubjectProgressTreeV.id.nodeId).fetchOne());
                    map.put("coverPageUrl", tuple.get(qMySubjectV.coverPageUrl));
                    map.put("lectureCount", this.getLectureCount(tuple.get(qMySubjectV.id.subjectId)));
                    return map;
                }).collect(Collectors.toList());
    }
    /**
     * 获取课件数量
     *
     * @param subjectId
     * @return
     */
    public long getLectureCount(String subjectId) {
        Subject subject = this.read(subjectId);
        if (subject == null) {
            return 0l;
        }
        if (subject.getType() == Subject.TYPE_CLS_SUBJECT) {//班级课程
            QClsSubjectLecture qSubjectLecture = QClsSubjectLecture.clsSubjectLecture;
            return this.getQueryFactory().selectFrom(qSubjectLecture).where(qSubjectLecture.deleteFlag.isFalse()
                    .and(qSubjectLecture.subjectId.eq(subjectId)).and(qSubjectLecture.status.eq(SubjectLecture.STATUS_DRAFT))).fetchCount();
        } else {
            QSubjectLecture qSubjectLecture = QSubjectLecture.subjectLecture;
            return this.getQueryFactory().selectFrom(qSubjectLecture).where(qSubjectLecture.deleteFlag.isFalse()
                    .and(qSubjectLecture.subjectId.eq(subjectId)).and(qSubjectLecture.status.eq(SubjectLecture.STATUS_DRAFT))).fetchCount();
        }
    }
    /**
     * 查询课程关联的班级课程信息
     *
     * @param classId
     * @return
     */
    @Override
    public List<Map<String,Object>> querySubjectReClassInfos(String origSubjectId) {
        String hql = "select s.subjectId as subjectId ,s.teacherId as teacherId,s.teacherName as teacherName,"
                  + " s.schoolYear as schoolYear,s.term as term,c.classId as classId,c.name as className"
                  + " from Subject s ,ClsClassReSubject r ,ClsClass c where s.subjectId = r.subjectId "
                  + " and r.classId = c.classId and s.origSubjectId =:origSubjectId and s.deleteFlag is false";
    /**
     * 我的公开课列表
     *
     * @param pageNum
     * @param pageSize
     * @param keyword
     * @return
     */
    public Map<String, Object> myOpenSubjectList(Integer pageNum, Integer pageSize, String keyword) {
        QSubject qSubject = QSubject.subject;
        QProgress qProgress = QProgress.progress;
        QSubjectLecture qSubjectLecture = QSubjectLecture.subjectLecture;
        return this.findListWithMapByHql(hql,CollectionUtils.newObjectMap("origSubjectId",origSubjectId));
    }
        JPAQuery<Tuple> query = this.getQueryFactory()
                .select(qSubject.subjectId, qSubject.name, qSubject.term, qSubject.coverPageUrl, qSubject.schoolYear,
                        qProgress.progressPercent.avg().as(qProgress.progressPercent), qProgress.progressValue.sum().as(qProgress.progressValue))
                .from(qSubject, qProgress, qSubjectLecture)
                .where(qSubject.deleteFlag.isFalse().and(qSubjectLecture.subjectId.eq(qSubject.subjectId))
                        .and(qSubjectLecture.deleteFlag.isFalse()).and(qSubjectLecture.lectureId.eq(qProgress.targetId))
                        .and(qProgress.learnerId.eq(ClientUtils.getUserId()))
                        .and(qSubject.name.like("%" + keyword + "%").and(qProgress.deleteFlag.isFalse()))
                        .and(qProgress.type.eq(Progress.PROGRESS_TYPE_LECTURE)).and(qSubject.status.eq(Subject.STATUS_ISSUED))).groupBy(qSubject.subjectId);
        long count = query.fetchCount();
        List<Map<String, Object>> listData = query.orderBy(qProgress.createTime.desc()).limit(pageSize).offset(pageNum).fetch().stream().map(tuple -> {
            Map<String, Object> map = new HashMap<String, Object>(7);
            String subjectId = tuple.get(qSubject.subjectId);
            map.put("name", tuple.get(qSubject.name));
            map.put("subjectId", subjectId);
            map.put("schoolYear", tuple.get(qSubject.schoolYear));
            map.put("term", tuple.get(qSubject.term));
            map.put("coverPageUrl", tuple.get(qSubject.coverPageUrl));
            map.put("progressPercent", tuple.get(qProgress.progressPercent));
            map.put("progressValue", tuple.get(qProgress.progressValue));
            Map<String, Object> openSubjectDetail = this.openSubjectDetail(subjectId);
            // 直播数量
            map.put("mediaVideoLiveCount", openSubjectDetail.get("mediaVideoLiveCount"));
            // 课件数量
            map.put("subjectLectureCount", openSubjectDetail.get("subjectLectureCount"));
            //学习人次
            map.put("studyCount", openSubjectDetail.get("studyCount"));
            map.put("content", openSubjectDetail.get("content"));
            // 已观看完成课件数量
            map.put("subjectLectureDoCount", openSubjectDetail.get("subjectLectureDoCount"));
            return map;
        }).collect(Collectors.toList());
        return CollectionUtils.newObjectMap("count", count, "listData", listData);
    }
    /**
     * 课程统计详情
     *
     * @param subjectId
     * @return
     */
    public Map<String, Object> openSubjectDetail(String subjectId) {
        Map<String, Object> map = new HashMap<String, Object>();
        QMediaVideoLive qMediaVideoLive = QMediaVideoLive.mediaVideoLive;
        QSubjectLecture qSubjectLecture = QSubjectLecture.subjectLecture;
        QProgress qProgress = QProgress.progress;
        // 直播数量
        map.put("mediaVideoLiveCount",
                this.getQueryFactory().select(qMediaVideoLive).from(qMediaVideoLive)
                        .where(qMediaVideoLive.deleteFlag.isFalse()
                                .and(qMediaVideoLive.status.gt(0))
                                .and(qMediaVideoLive.subjectId.eq(subjectId)))
                        .fetchCount());
        // 课件数量
        map.put("subjectLectureCount",
                this.getQueryFactory().select(qSubjectLecture).from(qSubjectLecture)
                        .where(qSubjectLecture.deleteFlag.isFalse()
                                .and(qSubjectLecture.subjectId.eq(subjectId)).and(qSubjectLecture.status.eq(SubjectLecture.STATUS_DRAFT)))
                        .fetchCount());
        //学习人次
        map.put("studyCount",
                this.getQueryFactory().selectDistinct(qProgress.learnerId).from(qProgress, qSubjectLecture)
                        .where(qProgress.deleteFlag.isFalse().and(qSubjectLecture.deleteFlag.isFalse()).and(qSubjectLecture.subjectId.eq(subjectId)).and(qProgress.type.eq(Progress.PROGRESS_TYPE_LECTURE))
                                .and(qProgress.targetId.eq(qSubjectLecture.lectureId)))
                        .fetchCount());
        map.put("content", this.readSubjectContent(subjectId));
        // 已观看完成课件数量
        map.put("subjectLectureDoCount",
                this.getQueryFactory().select(qSubjectLecture).from(qSubjectLecture, qProgress)
                        .where(qSubjectLecture.deleteFlag.isFalse().and(qProgress.deleteFlag.isFalse())
                                .and(qProgress.learnerId.eq(ClientUtils.getUserId())).and(qProgress.type.eq(Progress.PROGRESS_TYPE_LECTURE))
                                .and(qProgress.progressPercent.gt(0.95)).and(qProgress.targetId.eq(qSubjectLecture.lectureId))
                                .and(qSubjectLecture.subjectId.eq(subjectId)))
                        .fetchCount());
        return map;
    }
    /**
     * 公开课详情
     *
     * @param subjectId
     * @return
     */
    public Map<String, Object> openSubjectInfo(String subjectId) {
        QProgress qProgress = QProgress.progress;
        QSubjectLecture qSubjectLecture = QSubjectLecture.subjectLecture;
        Subject objSubject = this.read(subjectId);
        Tuple progress = this.getQueryFactory()
                .select(qProgress.progressPercent.sum().as(qProgress.progressPercent), qProgress.progressValue.sum().as(qProgress.progressValue)).from(qProgress, qSubjectLecture).where(qProgress.learnerId.eq(ClientUtils.getUserId())
                        .and(qProgress.targetId.eq(qSubjectLecture.lectureId))
                        .and(qProgress.deleteFlag.isFalse()).and(qSubjectLecture.deleteFlag.isFalse()).and(qSubjectLecture.subjectId.eq(subjectId))
                        .and(qProgress.type.eq(Progress.PROGRESS_TYPE_LECTURE))).fetchOne();
        Map<String, Object> subjectInfo = new HashMap<String, Object>(7);
        subjectInfo.put("name", objSubject.getName());
        subjectInfo.put("subjectId", subjectId);
        subjectInfo.put("schoolYear", objSubject.getSchoolYear());
        subjectInfo.put("term", objSubject.getTerm());
        subjectInfo.put("coverPageUrl", objSubject.getCoverPageUrl());
        subjectInfo.put("teacherName", objSubject.getTeacherName());
        Map<String, Object> openSubjectDetail = this.openSubjectDetail(subjectId);
        Map<String, Object> map = new HashMap<String, Object>(7);
        // 直播数量
        map.put("mediaVideoLiveCount", openSubjectDetail.get("mediaVideoLiveCount"));
        // 课件数量
        map.put("subjectLectureCount", openSubjectDetail.get("subjectLectureCount"));
        //学习人次
        map.put("studyCount", openSubjectDetail.get("studyCount"));
        subjectInfo.put("content", openSubjectDetail.get("content"));
        // 已观看完成课件数量
        map.put("subjectLectureDoCount", openSubjectDetail.get("subjectLectureDoCount"));
        map.put("subjectInfo", subjectInfo);
        if (openSubjectDetail.get("subjectLectureCount") == null || progress == null || progress.get(qProgress.progressPercent) == null) {
            subjectInfo.put("progressPercent", 0);
        } else {
            subjectInfo.put("progressPercent", progress.get(qProgress.progressPercent).floatValue() / (Long) openSubjectDetail.get("subjectLectureCount"));
        }
        subjectInfo.put("progressValue", progress == null ? 0 : progress.get(qProgress.progressValue));
        return map;
    }
    @Override
    public Map<String, Object> mySubjectInfo(String subjectId, String classId) {
        QMySubjectV qMySubjectV = QMySubjectV.mySubjectV;
        QMyLectureV qMyLectureV = QMyLectureV.myLectureV;
        // 课程
        Tuple tuple = this.getQueryFactory()
                .select(qMySubjectV.id.subjectId, qMySubjectV.subjectName, qMySubjectV.term, qMySubjectV.schoolYear, qMySubjectV.origSubjectId,
                        qMySubjectV.percent, qMySubjectV.coverPageUrl, qMySubjectV.progressValue)
                .from(qMySubjectV)
                .where(qMySubjectV.id.classId.eq(classId).and(qMySubjectV.id.userId.eq(ClientUtils.getUserId()))
                        .and(qMySubjectV.id.subjectId.eq(subjectId)))
                .fetchOne();
        Subject objSubject = this.read(subjectId);
        Map<String, Object> subject = new HashMap<String, Object>(5);
        subject.put("name", objSubject.getName());
        subject.put("subjectId", subjectId);
        subject.put("origSubjectId", objSubject.getOrigSubjectId());
        subject.put("schoolYear", objSubject.getSchoolYear());
        subject.put("term", objSubject.getTerm());
        subject.put("coverPageUrl", objSubject.getCoverPageUrl());
        subject.put("content", this.readSubjectContent(subjectId));
        subject.put("teacherName", objSubject.getTeacherName());
        if (tuple == null) {
            subject.put("progressPercent", 0);
            subject.put("progressValue", 0);
        } else {
            subject.put("progressPercent", tuple.get(qMySubjectV.percent));
            subject.put("progressValue", tuple.get(qMySubjectV.progressValue));
        }
        String origSubjectId = objSubject.getOrigSubjectId();
        // 考试统计
        long examsCount = this.examService.listStudentExamCount("", new String[]{classId}, origSubjectId, null);
        // 作业统计
        long homeworksCount = exerciseInfoService.queryStuExerciseListCount("", null, ClientUtils.getUserId(), origSubjectId, null);
        // 课件统计
        Tuple tupleLecture = this.getQueryFactory().select(qMyLectureV.count(),
                new CaseBuilder().when(qMyLectureV.percent.gt(0.95)).then(1).otherwise(0).sum()).// 大于95%算完成
                from(qMyLectureV)
                .where(qMyLectureV.classId.eq(classId).and(qMyLectureV.id.userId.eq(ClientUtils.getUserId()))
                        .and(qMyLectureV.subjectId.eq(subjectId)))
                .groupBy(qMyLectureV.subjectId).fetchOne();
        long mediaVideoLivesCount = this.mediaLiveService.listCount("", new String[]{classId}, origSubjectId, null);
        return CollectionUtils.newObjectMap("mediaVideoLivesCount", mediaVideoLivesCount, "examsCount", examsCount,
                "homeworksCount", homeworksCount, "subjectInfo", subject, "lectureCount",
                tupleLecture == null ? 0 : tupleLecture.get(0, Long.class),
                "completeLectureCount", tupleLecture == null ? 0 : tupleLecture.get(1, Integer.class));
    }
    /**
     * 公开课列表
     *
     * @param pageNum
     * @param pageSize
     * @param keyword
     * @return
     */
    public Map<String, Object> openSubjectList(Integer pageNum, Integer pageSize, String keyword) {
        QOpenSubjectV qOpenSubjectV = QOpenSubjectV.openSubjectV;
        JPAQuery<OpenSubjectV> query = this.getQueryFactory().selectFrom(qOpenSubjectV).where(qOpenSubjectV.subjectName.like("%" + keyword + "%"));
        long count = query.fetchCount();
        List<Map<String, Object>> listData = query.orderBy(qOpenSubjectV.mediaVideoCount.desc(),
                qOpenSubjectV.learnerCount.desc(), qOpenSubjectV.createTime.desc()).limit(pageSize).offset(pageNum)
                .fetch().stream().map(tuple -> {
                    Map<String, Object> map = new HashMap<String, Object>(8);
                    map.put("name", tuple.getSubjectName());
                    map.put("subjectId", tuple.getSubjectId());
                    map.put("schoolYear", tuple.getSchoolYear());
                    map.put("term", tuple.getTerm());
                    map.put("coverPageUrl", tuple.getCoverPageUrl());
                    map.put("mediaVideoCount", tuple.getMediaVideoCount());
                    map.put("learnerCount", tuple.getLearnerCount());
                    map.put("createTime", tuple.getCreateTime());
                    return map;
                }).collect(Collectors.toList());
        return CollectionUtils.newObjectMap("count", count, "listData", listData);
    }
    /**
     * 班级学员课件总体进度
     *
     * @param subjectId
     * @param classId
     * @return
     */
    @Override
    public List<Map<String, Object>> studentSubjectLectureProgress(String subjectId, String classId) {
        QMyLectureV qMyLectureV = QMyLectureV.myLectureV;
        return this.getQueryFactory()
                .select(qMyLectureV.lectureName, qMyLectureV.id.lectureId, qMyLectureV.lectureType,
                        qMyLectureV.chapterId, qMyLectureV.subjectId, qMyLectureV.lectureCreateTime,
                        qMyLectureV.percent.avg().as(qMyLectureV.percent))
                .from(qMyLectureV).where(qMyLectureV.classId.eq(classId).and(qMyLectureV.subjectId.eq(subjectId)))
                .groupBy(qMyLectureV.id.lectureId).orderBy(qMyLectureV.lectureCreateTime.desc()).fetch().stream()
                .map(tuple -> {
                    Map<String, Object> map = new HashMap<String, Object>(6);
                    map.put("lectureName", tuple.get(qMyLectureV.lectureName));
                    map.put("lectureId", tuple.get(qMyLectureV.id.lectureId));
                    map.put("lectureType", tuple.get(qMyLectureV.lectureType));
                    map.put("chapterId", tuple.get(qMyLectureV.chapterId));
                    map.put("subjectId", tuple.get(qMyLectureV.subjectId));
                    map.put("progressPercent", tuple.get(qMyLectureV.percent));
                    map.put("createTime", tuple.get(qMyLectureV.lectureCreateTime));
                    return map;
                }).collect(Collectors.toList());
    }
    /**
     * 学员课程作业进度
     *
     * @param classId
     * @param subjectId
     * @return
     */
    public Map<String, Object> studentSubjectHomeworkProgress(String classId, String subjectId, String studentId) {
        QExerciseResultV qHomeworkScoreV = QExerciseResultV.exerciseResultV;
        StuStudent student = read(StuStudent.class, studentId);
        Subject subject = read(Subject.class, subjectId);
        Tuple tuple = this.getQueryFactory()
                .select(qHomeworkScoreV.subjectId, qHomeworkScoreV.count(),
                        new CaseBuilder()
                                .when(qHomeworkScoreV.completeStatus.eq(ExerciseCompleteInfo.STATUS_CHECKED)
                                        .or(qHomeworkScoreV.completeStatus.eq(ExerciseCompleteInfo.STATUS_COMMIT)))
                                .then(qHomeworkScoreV.studentScore).otherwise(BigDecimal.ZERO).sum(),
                        new CaseBuilder()
                                .when(qHomeworkScoreV.completeStatus.eq(ExerciseCompleteInfo.STATUS_CHECKED)
                                        .or(qHomeworkScoreV.completeStatus.eq(ExerciseCompleteInfo.STATUS_COMMIT)))
                                .then(1).otherwise(0).sum())
                .from(qHomeworkScoreV)
                .where(qHomeworkScoreV.subjectId.eq(subject.getOrigSubjectId())
                        .and(qHomeworkScoreV.userId.eq(student.getUserId()))
                        .and(qHomeworkScoreV.exerciseStatus.eq(ExerciseInfo.EXERCISE_STATUS_PUBLISHED)))
                .groupBy(qHomeworkScoreV.userId).fetchOne();
        Map<String, Object> map = new HashMap<String, Object>(4);
        if (tuple == null) {
            map.put("subjectId", subjectId);
            map.put("homeworkCount", 0);
            map.put("avgScore", "0");
            map.put("commitHomeworkCount", 0);
        } else {
            int commitHomeworkCount = tuple.get(3, Integer.class) == null ? 0 : tuple.get(3, Integer.class);
            map.put("subjectId", subjectId);
            map.put("homeworkCount", tuple.get(1, Integer.class) == null ? 0 : tuple.get(1, Integer.class));
            map.put("avgScore", String.valueOf(commitHomeworkCount == 0 || tuple.get(2, BigDecimal.class) == null ? BigDecimal.ZERO : tuple.get(2, BigDecimal.class).divide(BigDecimal.valueOf(commitHomeworkCount), 2, BigDecimal.ROUND_HALF_UP)));
            map.put("commitHomeworkCount", commitHomeworkCount);
        }
        return map;
    }
    /**
     * 学员考试作业进度
     *
     * @param classId
     * @param subjectId
     * @return
     */
    public Map<String, Object> studentSubjectExamProgress(String classId, String subjectId, String studentId) {
        QExamResultV qExamScoreV = QExamResultV.examResultV;
        StuStudent student = read(StuStudent.class, studentId);
        Subject subject = read(Subject.class, subjectId);
        Tuple tuple = this.getQueryFactory().select(qExamScoreV.subjectId, qExamScoreV.count(), new CaseBuilder()
                .when(qExamScoreV.status.eq("0")).then(BigDecimal.ZERO).otherwise(qExamScoreV.score).sum(), new CaseBuilder()
                .when(qExamScoreV.status.eq("0")).then(0).otherwise(1).sum()).
                from(qExamScoreV).
                where(qExamScoreV.subjectId.eq(subject.getOrigSubjectId()).and(qExamScoreV.userId.eq(student.getUserId())).and(qExamScoreV.examStatus.eq(ExerciseInfo.EXERCISE_STATUS_PUBLISHED))).
                groupBy(qExamScoreV.userId).fetchOne();
        Map<String, Object> map = new HashMap<String, Object>(4);
        map.put("subjectId", subjectId);
        if (tuple == null) {
            map.put("examCount", 0);
            map.put("avgScore", "0");
            map.put("commitExamCount", 0);
        } else {
            int commitExamCount = tuple.get(3, Integer.class) == null ? 0 : tuple.get(3, Integer.class);
            map.put("examCount", tuple.get(1, Integer.class) == null ? 0 : tuple.get(1, Integer.class));
            map.put("avgScore", String.valueOf(commitExamCount == 0 || tuple.get(2, BigDecimal.class) == null ? BigDecimal.ZERO : tuple.get(2, BigDecimal.class).divide(new BigDecimal(commitExamCount), 2, BigDecimal.ROUND_HALF_UP)));
            map.put("commitExamCount", tuple.get(3, Integer.class) == null ? 0 : tuple.get(3, Integer.class));
        }
        return map;
    }
    /**
     * 我的课件情况
     *
     * @param classId
     * @return
     */
    private List<Map<String, Object>> myLectureList(String classId) {
        QMyLectureV qMyLectureV = QMyLectureV.myLectureV;
        return this.getQueryFactory().select(qMyLectureV.subjectId,
                qMyLectureV.count(),
                new CaseBuilder()
                        .when(qMyLectureV.percent.gt(0.95)).then(1).otherwise(0).sum()).//大于95%算完成
                from(qMyLectureV).
                where(qMyLectureV.classId.eq(classId).and(qMyLectureV.id.userId.eq(ClientUtils.getUserId()))).
                groupBy(qMyLectureV.subjectId).fetch().stream()
                .map(tuple -> {
                    Map<String, Object> map = new HashMap<String, Object>(3);
                    map.put("subjectId", tuple.get(0, String.class));
                    map.put("lectureCount", tuple.get(1, Integer.class));
                    map.put("completeLectureCount", tuple.get(2, String.class));
                    return map;
                }).collect(Collectors.toList());
    }
    /**
     * 我的课程,按时间排序
     *
     * @param classId
     * @return
     */
    public List<Map<String, Object>> mySubjectList(String classId, Pager pager) {
        //课程
        List<Map<String, Object>> clsSubjectlist = this.myClsSubjectlist(classId, ClientUtils.getUserId(), pager);
        //课件统计
        List<Map<String, Object>> lectures = this.myLectureList(classId);
        for (Map<String, Object> clsSubject : clsSubjectlist) {
            String origSubjectId = (String) clsSubject.get("origSubjectId");
            clsSubject.put("exam", CollectionUtils.newObjectMap("examCount", this.examService.listStudentExamCount("", new String[]{classId}, origSubjectId, null)));
            clsSubject.put("homework", CollectionUtils.newObjectMap("homeworkCount", exerciseInfoService.queryStuExerciseListCount("", null, ClientUtils.getUserId(), origSubjectId, null)));
            clsSubject.put("lecture", CollectionUtils.newObjectMap("lectureCount", 0, "completeLectureCount", 0));
            clsSubject.put("mediaVideoLive", CollectionUtils.newObjectMap("mediaVideoLiveCount", this.mediaLiveService.listCount("", new String[]{classId}, origSubjectId, null)));
            this.setSubjectStatistics("lecture", clsSubject, lectures);
        }
        return clsSubjectlist;
    }
    /**
     * 统计课程的数据
     *
     * @param type          类型
     * @param clsSubject    课程
     * @param lstStatistics 统计信息
     */
    private void setSubjectStatistics(String type, Map<String, Object> clsSubject, List<Map<String, Object>> lstStatistics) {
        if (lstStatistics != null && !lstStatistics.isEmpty()) {
            for (Map<String, Object> statistics : lstStatistics) {
                if (clsSubject.get("origSubjectId").equals(statistics.get("subjectId")) || clsSubject.get("subjectId").equals(statistics.get("subjectId"))) {
                    clsSubject.put(type, statistics);
                }
            }
        }
    }
    /**
     * 我的课程详情
     *
     * @param classId
     * @return
     */
    public Map<String, Object> mySubjectInfo(String subjectId, String classId, HttpServletRequest request) {
        QMySubjectV qMySubjectV = QMySubjectV.mySubjectV;
        QMyLectureV qMyLectureV = QMyLectureV.myLectureV;
        Object userId = request.getSession().getAttribute("userId");
        // 课程
        Tuple tuple = this.getQueryFactory()
                .select(qMySubjectV.id.subjectId, qMySubjectV.subjectName, qMySubjectV.term, qMySubjectV.schoolYear, qMySubjectV.origSubjectId,
                        qMySubjectV.percent, qMySubjectV.coverPageUrl, qMySubjectV.progressValue)
                .from(qMySubjectV)
                .where(qMySubjectV.id.classId.eq(classId).and(qMySubjectV.id.userId.eq(ClientUtils.getUserId()))
                        .and(qMySubjectV.id.subjectId.eq(subjectId)))
                .fetchOne();
        Subject objSubject = this.read(subjectId);
        Map<String, Object> subject = new HashMap<String, Object>(5);
        subject.put("name", objSubject.getName());
        subject.put("subjectId", subjectId);
        subject.put("origSubjectId", objSubject.getOrigSubjectId());
        subject.put("schoolYear", objSubject.getSchoolYear());
        subject.put("term", objSubject.getTerm());
        subject.put("coverPageUrl", objSubject.getCoverPageUrl());
        subject.put("content", this.readSubjectContent(subjectId));
        subject.put("teacherName", objSubject.getTeacherName());
        if (tuple == null) {
            subject.put("progressPercent", 0);
            subject.put("progressValue", 0);
        } else {
            subject.put("progressPercent", tuple.get(qMySubjectV.percent));
            subject.put("progressValue", tuple.get(qMySubjectV.progressValue));
        }
        String origSubjectId = objSubject.getOrigSubjectId();
        // 考试统计
        long examsCount = this.examService.listStudentExamCount("", new String[]{classId}, origSubjectId, null);
        // 作业统计
        long homeworksCount = exerciseInfoService.queryStuExerciseListCount("", null, ClientUtils.getUserId(), origSubjectId, null);
        // 课件统计
        Tuple tupleLecture = this.getQueryFactory().select(qMyLectureV.count(),
                new CaseBuilder().when(qMyLectureV.percent.gt(0.95)).then(1).otherwise(0).sum()).// 大于95%算完成
                from(qMyLectureV)
                .where(qMyLectureV.classId.eq(classId).and(qMyLectureV.id.userId.eq(ClientUtils.getUserId()))
                        .and(qMyLectureV.subjectId.eq(subjectId)))
                .groupBy(qMyLectureV.subjectId).fetchOne();
        long mediaVideoLivesCount = this.mediaLiveService.listCount("", new String[]{classId}, origSubjectId, null);
        return CollectionUtils.newObjectMap("mediaVideoLivesCount", mediaVideoLivesCount, "examsCount", examsCount,
                "homeworksCount", homeworksCount, "subjectInfo", subject, "lectureCount",
                tupleLecture == null ? 0 : tupleLecture.get(0, Long.class),
                "completeLectureCount", tupleLecture == null ? 0 : tupleLecture.get(1, Integer.class));
    }
    /**
     * 我的课程按学期分类
     *
     * @param classId
     * @return
     */
    @Override
    public List<Map<String, Object>> myTermSubjectList(String classId) {
        //课程
        List<Map<String, Object>> clsSubjectlist = this.mySubjectList(classId, new Pager());
        System.out.println("clsSubjectlistaaaaaa" + clsSubjectlist);
        return this.termSubjectList(classId, clsSubjectlist);
    }
    /**
     * 课程按学期分类
     *
     * @param classId
     * @return
     */
    @Override
    public List<Map<String, Object>> termSubjectList(String classId, List<Map<String, Object>> clsSubjectlist) {
        //学期
        List<Map<String, Object>> termList = this.termList(classId);
        if (termList != null && !termList.isEmpty()) {
            for (Map<String, Object> term : termList) {
                if (termList != null && !termList.isEmpty()) {
                    List<Map<String, Object>> subjectList = new ArrayList<>();
                    for (Map<String, Object> clsSubject : clsSubjectlist) {
                        if (term.get("schoolYear").equals(clsSubject.get("schoolYear")) &&
                                term.get("term").equals(clsSubject.get("term"))) {
                            subjectList.add(clsSubject);
                        }
                        term.put("subjectList", subjectList);
                    }
                }
            }
        }
        return termList;
    }
    /**
     * 查询课程关联的班级课程信息
     *
     * @param classId
     * @return
     */
    @Override
    public List<Map<String, Object>> querySubjectReClassInfos(String origSubjectId) {
        String hql = "select s.subjectId as subjectId ,s.teacherId as teacherId,s.teacherName as teacherName,"
                + " s.schoolYear as schoolYear,s.term as term,c.classId as classId,c.name as className"
                + " from Subject s ,ClsClassReSubject r ,ClsClass c where s.subjectId = r.subjectId "
                + " and r.classId = c.classId and s.origSubjectId =:origSubjectId and s.deleteFlag is false";
        return this.findListWithMapByHql(hql, CollectionUtils.newObjectMap("origSubjectId", origSubjectId));
    }
};
target/generated-sources/java/com/qxueyou/scc/teach/student/model/QStuStudent.java
@@ -19,6 +19,8 @@
    public static final QStuStudent stuStudent = new QStuStudent("stuStudent");
    public final StringPath attendanceStatus = createString("attendanceStatus");
    public final StringPath classId = createString("classId");
    public final StringPath createId = createString("createId");
@@ -43,6 +45,8 @@
    public final StringPath studentNo = createString("studentNo");
    public final StringPath studentNumber = createString("studentNumber");
    public final NumberPath<java.math.BigDecimal> studyDuration = createNumber("studyDuration", java.math.BigDecimal.class);
    public final StringPath subjectId = createString("subjectId");
target/generated-sources/java/com/qxueyou/scc/teach/subject/model/view/QMyLectureV.java
@@ -40,14 +40,15 @@
    public final NumberPath<java.math.BigDecimal> progressValue = createNumber("progressValue", java.math.BigDecimal.class);
    public final StringPath status = createString("status");
    public final StringPath subjectId = createString("subjectId");
    public final StringPath subjectName = createString("subjectName");
    public final StringPath userName = createString("userName");
    public final StringPath deleteFlag = createString("deleteFlag");
    public QMyLectureV(String variable) {
        this(MyLectureV.class, forVariable(variable), INITS);
    }