浏览代码

增加质量监控列表页面与重新计算逻辑

luoshi 6 年之前
父节点
当前提交
b63e0bce5d

+ 6 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/dao/MarkerDao.java

@@ -46,6 +46,12 @@ public interface MarkerDao extends PagingAndSortingRepository<Marker, Integer>,
             + "where m.id=?1")
     public void resetById(Integer id);
 
+    @Modifying
+    @Query("update Marker m set m.finishCount=?2, m.validCount=?3, m.avgSpeed=?4, m.avgScore=?5, m.stdevScore=?6 "
+            + "where m.id=?1")
+    public void updateQualityById(Integer id, int finishCount, int validCount, double avgSpeed, double avgScore,
+            double stdevScore);
+
     @Modifying
     @Query("update Marker m set m.finishCount=null, m.validCount=null, m.avgSpeed=null, m.avgScore=null, m.stdevScore=null "
             + "where m.examId=?1 and m.subjectCode=?2 and m.groupNumber=?3")

+ 22 - 32
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/query/MarkerSearchQuery.java

@@ -8,19 +8,17 @@ import cn.com.qmth.stmms.biz.exam.model.Marker;
 
 public class MarkerSearchQuery extends BaseQuery<Marker> {
 
-    private int id;
+    private Integer id;
 
-    private int examId;
+    private Integer examId;
 
     private String subjectCode;
 
     private String loginName;
 
-    private int groupNumber;
-    
-    private String name;
+    private Integer groupNumber;
 
-    private String topCount;
+    private String name;
 
     public void orderByLoginName() {
         setSort(new Sort(Direction.ASC, "loginName"));
@@ -30,11 +28,19 @@ public class MarkerSearchQuery extends BaseQuery<Marker> {
         setSort(new Sort(Direction.ASC, "id"));
     }
 
-    public int getExamId() {
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getExamId() {
         return examId;
     }
 
-    public void setExamId(int examId) {
+    public void setExamId(Integer examId) {
         this.examId = examId;
     }
 
@@ -54,36 +60,20 @@ public class MarkerSearchQuery extends BaseQuery<Marker> {
         this.loginName = loginName;
     }
 
-    public int getGroupNumber() {
+    public Integer getGroupNumber() {
         return groupNumber;
     }
 
-    public void setGroupNumber(int groupNumber) {
+    public void setGroupNumber(Integer groupNumber) {
         this.groupNumber = groupNumber;
     }
 
-	public int getId() {
-		return id;
-	}
-
-	public void setId(int id) {
-		this.id = id;
-	}
-
-	public String getTopCount() {
-		return topCount;
-	}
-
-	public void setTopCount(String topCount) {
-		this.topCount = topCount;
-	}
-
-	public String getName() {
-		return name;
-	}
+    public String getName() {
+        return name;
+    }
 
-	public void setName(String name) {
-		this.name = name;
-	}
+    public void setName(String name) {
+        this.name = name;
+    }
 
 }

+ 9 - 8
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/impl/MarkerServiceImpl.java

@@ -1,6 +1,5 @@
 package cn.com.qmth.stmms.biz.exam.service.impl;
 
-import java.util.Date;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Random;
@@ -148,7 +147,7 @@ public class MarkerServiceImpl extends BaseQueryService<Marker> implements Marke
     @Override
     public List<Marker> getMarkCount(int examId) {
         List<Marker> list = new LinkedList<Marker>();
-        List<Object[]> result = libraryDao.countByMarkerAndStatus(examId, LibraryStatus.MARKED);
+        List<Object[]> result = libraryDao.countMarkerAndStatus(examId, LibraryStatus.MARKED);
         if (result != null) {
             for (Object[] array : result) {
                 try {
@@ -165,7 +164,7 @@ public class MarkerServiceImpl extends BaseQueryService<Marker> implements Marke
     @Override
     public List<Marker> getMarkCount(int examId, String subjectCode) {
         List<Marker> list = new LinkedList<Marker>();
-        List<Object[]> result = libraryDao.countByMarkerAndStatus(examId, subjectCode, LibraryStatus.MARKED);
+        List<Object[]> result = libraryDao.countMarkerAndStatus(examId, subjectCode, LibraryStatus.MARKED);
         if (result != null) {
             for (Object[] array : result) {
                 try {
@@ -193,22 +192,24 @@ public class MarkerServiceImpl extends BaseQueryService<Marker> implements Marke
             @Override
             public Predicate toPredicate(Root<Marker> root, CriteriaQuery<?> cQuery, CriteriaBuilder cb) {
                 List<Predicate> predicates = new LinkedList<Predicate>();
-                if (query.getExamId() > 0) {
+                if (query.getId() != null) {
+                    predicates.add(cb.equal(root.get("id"), query.getId()));
+                }
+                if (query.getExamId() != null) {
                     predicates.add(cb.equal(root.get("examId"), query.getExamId()));
                 }
                 if (StringUtils.isNotBlank(query.getSubjectCode())) {
                     predicates.add(cb.equal(root.get("subjectCode"), query.getSubjectCode()));
                 }
+                if (query.getGroupNumber() != null) {
+                    predicates.add(cb.equal(root.get("groupNumber"), query.getGroupNumber()));
+                }
                 if (StringUtils.isNotBlank(query.getLoginName())) {
                     predicates.add(cb.equal(root.get("loginName"), query.getLoginName()));
                 }
-                if (query.getGroupNumber() > 0) {
-                    predicates.add(cb.equal(root.get("groupNumber"), query.getGroupNumber()));
-                }
                 if (StringUtils.isNotBlank(query.getName())) {
                     predicates.add(cb.equal(root.get("name"), query.getName()));
                 }
-                cQuery.orderBy(cb.desc(root.get("lastLoginTime").as(Date.class)));
                 return predicates.isEmpty() ? cb.conjunction()
                         : cb.and(predicates.toArray(new Predicate[predicates.size()]));
             }

+ 4 - 2
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/dao/MarkLibraryDao.java

@@ -28,6 +28,8 @@ public interface MarkLibraryDao extends JpaRepository<MarkLibrary, Integer>, Jpa
     List<MarkLibrary> findUnMarked(Integer examId, String subjectCode, Integer groupNumber, Integer markerId,
             Set<LibraryStatus> statusSet, Pageable page);
 
+    List<MarkLibrary> findByMarkerId(Integer markerId);
+
     @Query("select l from MarkLibrary l where l.studentId=?1 order by l.groupNumber ")
     List<MarkLibrary> findByStudentId(Integer studentId);
 
@@ -76,10 +78,10 @@ public interface MarkLibraryDao extends JpaRepository<MarkLibrary, Integer>, Jpa
     int resetById(Integer id, LibraryStatus newStatus, LibraryStatus previousStatus);
 
     @Query("select f.markerId, count(*) as markerCount from MarkLibrary f where f.examId=?1 and f.status=?2 group by f.markerId")
-    List<Object[]> countByMarkerAndStatus(Integer examId, LibraryStatus status);
+    List<Object[]> countMarkerAndStatus(Integer examId, LibraryStatus status);
 
     @Query("select f.markerId, count(*) as markerCount from MarkLibrary f where f.examId=?1 and f.subjectCode=?2 and f.status=?3 group by f.markerId")
-    List<Object[]> countByMarkerAndStatus(Integer examId, String subjectCode, LibraryStatus status);
+    List<Object[]> countMarkerAndStatus(Integer examId, String subjectCode, LibraryStatus status);
 
     @Query("select count(*) from MarkLibrary f where f.markerId=?1 and f.status in (?2)")
     long countByMarkerAndStatus(Integer markerId, LibraryStatus... status);

+ 28 - 1
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/MarkServiceImpl.java

@@ -36,6 +36,7 @@ import cn.com.qmth.stmms.biz.mark.model.MarkResult;
 import cn.com.qmth.stmms.biz.mark.model.TrialHistory;
 import cn.com.qmth.stmms.biz.mark.model.TrialLibrary;
 import cn.com.qmth.stmms.biz.mark.service.MarkService;
+import cn.com.qmth.stmms.biz.mark.thread.MarkQualityThread;
 import cn.com.qmth.stmms.biz.utils.FormalTaskUtil;
 import cn.com.qmth.stmms.biz.utils.ScoreItem;
 import cn.com.qmth.stmms.biz.utils.TrialTaskUtil;
@@ -582,6 +583,7 @@ public class MarkServiceImpl implements MarkService {
             libraryDao.updateByStudentIdAndGroupNumber(library.getStudentId(), library.getGroupNumber(),
                     LibraryStatus.WAIT_ARBITRATE);
         }
+        taskExecutor.submit(new MarkQualityThread(marker, this, null));
         return true;
     }
 
@@ -919,7 +921,32 @@ public class MarkServiceImpl implements MarkService {
     @Override
     @Transactional
     public void updateQuality(Marker marker) {
-        // TODO
+        List<MarkLibrary> list = libraryDao.findByMarkerId(marker.getId());
+        int finishCount = 0;
+        int validCount = 0;
+        double sumScore = 0;
+        double tempScore = 0;
+        double avgScore = 0;
+        double stdevScore = 0;
+        int sumSpent = 0;
+        double avgSpent = 0;
+        for (MarkLibrary library : list) {
+            finishCount++;
+            if (library.getStatus() == LibraryStatus.MARKED) {
+                validCount++;
+            }
+            double score = library.getMarkerScore() != null ? library.getMarkerScore() : 0;
+            int spent = library.getMarkerSpent() != null ? library.getMarkerSpent() : 0;
+
+            sumScore += score;
+            sumSpent += spent;
+            avgScore = sumScore / finishCount;
+            avgSpent = sumSpent / finishCount;
+            // 递归法计算标准差
+            tempScore = tempScore + 1.0 * (finishCount - 1) / finishCount * (score - avgScore) * (score - avgScore);
+            stdevScore = Math.sqrt(tempScore / (finishCount - 1));
+        }
+        markerDao.updateQualityById(marker.getId(), finishCount, validCount, avgSpent / 1000, avgScore, stdevScore);
     }
 
     private double sumTotalScore(Integer examId, String subjectCode) {

+ 59 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/thread/MarkQualityThread.java

@@ -0,0 +1,59 @@
+package cn.com.qmth.stmms.biz.mark.thread;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import cn.com.qmth.stmms.biz.exam.model.Marker;
+import cn.com.qmth.stmms.biz.mark.service.MarkService;
+import cn.com.qmth.stmms.common.utils.Callback;
+
+/**
+ * 评卷员计算评卷质量指标工作包装线程
+ * 
+ * @author luoshi
+ *
+ */
+public class MarkQualityThread implements Runnable {
+
+    protected static final Logger log = LoggerFactory.getLogger(MarkQualityThread.class);
+
+    private List<Marker> markers;
+
+    private MarkService markService;
+
+    private Callback callback;
+
+    public MarkQualityThread(Marker marker, MarkService markService, Callback callback) {
+        this.markers = new LinkedList<>();
+        this.markers.add(marker);
+        this.markService = markService;
+        this.callback = callback;
+    }
+
+    public MarkQualityThread(List<Marker> markers, MarkService markService, Callback callback) {
+        this.markers = markers;
+        this.markService = markService;
+        this.callback = callback;
+    }
+
+    @Override
+    public void run() {
+        if (markers != null) {
+            for (Marker marker : markers) {
+                log.info("start update quality for marker: " + marker.getId());
+                try {
+                    markService.updateQuality(marker);
+                    log.info("finish update quality for marker: " + marker.getId());
+                } catch (Exception e) {
+                    log.error("marker quality thread error", e);
+                }
+            }
+        }
+        if (callback != null) {
+            callback.invoke();
+        }
+    }
+}

+ 0 - 38
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/thread/MarkerQualityThread.java

@@ -1,38 +0,0 @@
-package cn.com.qmth.stmms.biz.mark.thread;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import cn.com.qmth.stmms.biz.exam.model.Marker;
-import cn.com.qmth.stmms.biz.mark.service.MarkService;
-
-/**
- * 评卷员计算评卷质量指标工作线程
- * 
- * @author luoshi
- *
- */
-public class MarkerQualityThread implements Runnable {
-
-    protected static final Logger log = LoggerFactory.getLogger(MarkerQualityThread.class);
-
-    private Marker marker;
-
-    private MarkService markService;
-
-    public MarkerQualityThread(Marker marker, MarkService markService) {
-        this.marker = marker;
-        this.markService = markService;
-    }
-
-    @Override
-    public void run() {
-        log.info("start marker quality thread for id=" + marker.getId());
-        try {
-            markService.updateQuality(marker);
-            log.info("finish marker quality thread for id=" + marker.getId());
-        } catch (Exception e) {
-            log.error("marker quality thread error", e);
-        }
-    }
-}

+ 6 - 0
stmms-common/src/main/java/cn/com/qmth/stmms/common/utils/Callback.java

@@ -0,0 +1,6 @@
+package cn.com.qmth.stmms.common.utils;
+
+public interface Callback {
+
+    public void invoke();
+}

+ 108 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/MarkQualityController.java

@@ -0,0 +1,108 @@
+package cn.com.qmth.stmms.admin.exam;
+
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.task.AsyncTaskExecutor;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import cn.com.qmth.stmms.biz.exam.model.ExamSubject;
+import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
+import cn.com.qmth.stmms.biz.exam.query.MarkerSearchQuery;
+import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
+import cn.com.qmth.stmms.biz.exam.service.MarkerService;
+import cn.com.qmth.stmms.biz.lock.LockService;
+import cn.com.qmth.stmms.biz.mark.service.MarkService;
+import cn.com.qmth.stmms.biz.mark.thread.MarkQualityThread;
+import cn.com.qmth.stmms.common.domain.WebUser;
+import cn.com.qmth.stmms.common.enums.LockType;
+import cn.com.qmth.stmms.common.utils.Callback;
+import cn.com.qmth.stmms.common.utils.RequestUtils;
+
+@Controller("markQualityController")
+@RequestMapping("/admin/exam/quality")
+public class MarkQualityController extends BaseExamController {
+
+    protected static Logger log = LoggerFactory.getLogger(MarkQualityController.class);
+
+    @Autowired
+    private MarkGroupService groupService;
+
+    @Autowired
+    private MarkerService markerService;
+
+    @Autowired
+    private MarkService markService;
+
+    @Autowired
+    private LockService lockService;
+
+    @Autowired
+    private AsyncTaskExecutor taskExecutor;
+
+    @RequestMapping
+    public String list(Model model, HttpServletRequest request, MarkerSearchQuery query) {
+        int examId = getSessionExamId(request);
+        WebUser wu = RequestUtils.getWebUser(request);
+        List<ExamSubject> subjectList = getExamSubject(examId, wu);
+        if (subjectList.isEmpty()) {
+            return "redirect:/admin/exam/mark";
+        }
+        query.setExamId(examId);
+        query.orderById();
+        if (query.getSubjectCode() == null && !subjectList.isEmpty()) {
+            query.setSubjectCode(subjectList.get(0).getCode());
+        }
+        subjectFilter(query, wu);
+        List<MarkGroup> groupList = groupService.findByExamAndSubject(examId, query.getSubjectCode());
+        if (query.getGroupNumber() == null && groupList.size() > 0) {
+            query.setGroupNumber(groupList.get(0).getNumber());
+        }
+        if (query.getSubjectCode() != null && query.getGroupNumber() != null) {
+            query = markerService.findByQuery(query);
+            model.addAttribute("running", lockService.isLocked(LockType.GROUP,
+                    getLockKey(examId, query.getSubjectCode(), query.getGroupNumber())));
+        }
+        model.addAttribute("query", query);
+        model.addAttribute("subjectList", subjectList);
+        model.addAttribute("groupList", groupList);
+        return "modules/exam/qualityList";
+    }
+
+    @RequestMapping("/update")
+    public String update(HttpServletRequest request, RedirectAttributes redirectAttributes,
+            @RequestParam String subjectCode, @RequestParam Integer groupNumber) {
+        int examId = getSessionExamId(request);
+        MarkGroup group = groupService.findOne(examId, subjectCode, groupNumber);
+        if (group != null) {
+            final String lockKey = getLockKey(examId, subjectCode, groupNumber);
+            if (lockService.trylock(LockType.GROUP, lockKey)) {
+                taskExecutor.submit(new MarkQualityThread(
+                        markerService.findByExamAndSubjectAndGroup(examId, subjectCode, groupNumber), markService,
+                        new Callback() {
+
+                            @Override
+                            public void invoke() {
+                                lockService.unlock(LockType.GROUP, lockKey);
+                            }
+                        }));
+            }
+            redirectAttributes.addAttribute("groupNumber", groupNumber);
+        }
+        redirectAttributes.addAttribute("subjectCode", subjectCode);
+        return "redirect:/admin/exam/quality";
+    }
+
+    private String getLockKey(Integer examId, String subjectCode, Integer groupNumber) {
+        return examId + "_" + subjectCode + "_" + groupNumber;
+    }
+
+}

+ 2 - 1
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/arbitrateList.jsp

@@ -12,8 +12,9 @@
         <li><a href="${ctx}/admin/exam/group?subjectCode=${query.subjectCode}">大题管理</a></li>
         <li><a href="${ctx}/admin/exam/marker?subjectCode=${query.subjectCode}">评卷员管理</a></li>
         <li><a href="${ctx}/admin/exam/trial?subjectCode=${query.subjectCode}">试评管理</a></li>
-        <li><a href="${ctx}/admin/exam/library?subjectCode=${query.subjectCode}">正评管理</a></li>
+        <li><a href="${ctx}/admin/exam/library?subjectCode=${query.subjectCode}">任务管理</a></li>
         <li class="active"><a href="##">仲裁管理</a></li>
+        <li><a href="${ctx}/admin/exam/quality?subjectCode=${query.subjectCode}">质量监控</a></li>
     </ul>
 	<form id="searchForm" action="${ctx}/admin/exam/arbitrate" method="post" class="breadcrumb form-search">
 	    <input type="hidden" id="pageNumber" name="pageNumber" value="${query.pageNumber }"/>

+ 2 - 1
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/groupList.jsp

@@ -12,8 +12,9 @@
         <li class="active"><a href="##">大题管理</a></li>
         <li><a href="${ctx}/admin/exam/marker?subjectCode=${subject.code}">评卷员管理</a></li>
         <li><a href="${ctx}/admin/exam/trial?subjectCode=${subject.code}">试评管理</a></li>
-        <li><a href="${ctx}/admin/exam/library?subjectCode=${subject.code}">正评管理</a></li>
+        <li><a href="${ctx}/admin/exam/library?subjectCode=${subject.code}">任务管理</a></li>
         <li><a href="${ctx}/admin/exam/arbitrate?subjectCode=${subject.code}">仲裁管理</a></li>
+        <li><a href="${ctx}/admin/exam/quality?subjectCode=${subject.code}">质量监控</a></li>
     </ul>
 	<form id="searchForm" action="${ctx}/admin/exam/group" method="post" class="breadcrumb form-search">
 		<div>

+ 2 - 1
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/libraryList.jsp

@@ -12,8 +12,9 @@
         <li><a href="${ctx}/admin/exam/group?subjectCode=${query.subjectCode}">大题管理</a></li>
         <li><a href="${ctx}/admin/exam/marker?subjectCode=${query.subjectCode}">评卷员管理</a></li>
         <li><a href="${ctx}/admin/exam/trial?subjectCode=${query.subjectCode}">试评管理</a></li>
-        <li class="active"><a href="##">正评管理</a></li>
+        <li class="active"><a href="##">任务管理</a></li>
         <li><a href="${ctx}/admin/exam/arbitrate?subjectCode=${query.subjectCode}">仲裁管理</a></li>
+        <li><a href="${ctx}/admin/exam/quality?subjectCode=${query.subjectCode}">质量监控</a></li>
     </ul>
 	<form id="searchForm" action="${ctx}/admin/exam/library" method="post" class="breadcrumb form-search">
 	    <input type="hidden" id="pageNumber" name="pageNumber" value="${query.pageNumber }"/>

+ 2 - 1
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/markerList.jsp

@@ -81,8 +81,9 @@
         <li><a href="${ctx}/admin/exam/group?subjectCode=${query.subjectCode}">大题管理</a></li>
         <li class="active"><a href="##">评卷员管理</a></li>
         <li><a href="${ctx}/admin/exam/trial?subjectCode=${query.subjectCode}">试评管理</a></li>
-        <li><a href="${ctx}/admin/exam/library?subjectCode=${query.subjectCode}">正评管理</a></li>
+        <li><a href="${ctx}/admin/exam/library?subjectCode=${query.subjectCode}">任务管理</a></li>
         <li><a href="${ctx}/admin/exam/arbitrate?subjectCode=${query.subjectCode}">仲裁管理</a></li>
+        <li><a href="${ctx}/admin/exam/quality?subjectCode=${query.subjectCode}">质量监控</a></li>
     </ul>
     <div id="importBox" class="hide">
         <form id="importForm" action="${ctx}/admin/exam/marker/import" method="post" enctype="multipart/form-data"

+ 130 - 0
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/qualityList.jsp

@@ -0,0 +1,130 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
+<html>
+<head>
+	<title>评卷质量监控</title>
+	<meta name="decorator" content="default"/>
+	<%@include file="/WEB-INF/views/include/head.jsp" %>
+	<style type="text/css">.sort{color:#0663A2;cursor:pointer;}</style>
+</head>
+<body>
+    <ul class="nav nav-tabs">
+        <li><a href="${ctx}/admin/exam/group?subjectCode=${query.subjectCode}">大题管理</a></li>
+        <li><a href="${ctx}/admin/exam/marker?subjectCode=${query.subjectCode}">评卷员管理</a></li>
+        <li><a href="${ctx}/admin/exam/trial?subjectCode=${query.subjectCode}">试评管理</a></li>
+        <li><a href="${ctx}/admin/exam/library?subjectCode=${query.subjectCode}">任务管理</a></li>
+        <li><a href="${ctx}/admin/exam/arbitrate?subjectCode=${query.subjectCode}">仲裁管理</a></li>
+        <li class="active"><a href="##">质量监控</a></li>
+    </ul>
+    
+	<form id="searchForm"  action="${ctx}/admin/exam/quality" method="post" class="breadcrumb form-search">
+		<input type="hidden" id="pageNumber" name="pageNumber" value="${query.pageNumber}"/>
+		<input type="hidden" id="pageSize" name="pageSize" value="${query.pageSize}"/>
+		<div>
+			<label>科目</label>
+			<select class="input-large" id="subject-select" name="subjectCode">
+				<c:forEach items="${subjectList}" var="subject">
+				<option value="${subject.code}" <c:if test="${subject.code==query.subjectCode}">selected</c:if>>${subject.code}-${subject.name}</option>
+				</c:forEach>
+			</select>
+			<label>大题</label>
+            <select class="input-medium" id="group-select" name="groupNumber">
+            </select>
+			&nbsp;
+			<input id="btnSubmit" class="btn btn-primary" type="button" value="查询" onclick="goSearch()"/>
+			<c:if test="${web_user.schoolAdmin==true && running!=null}">
+            &nbsp;
+            <c:if test="${running==true}">
+            <a href="##" class="btn disabled">正在计算</a>
+            </c:if>
+            <c:if test="${running==false}">
+            <a href="##" class="btn" id="update-button">重新计算</a>
+            </c:if>
+            </c:if>
+		</div>
+	</form>
+	<tags:message content="${message}"/>
+	<table id="contentTable" class="table table-striped table-bordered table-condensed">
+		<thead>
+			<tr>
+				<th>评卷员</th>
+				<th>姓名</th>
+				<th>完成任务数</th>
+				<th>有效评卷数</th>
+				<th>评卷采用率</th>
+				<th>评卷速度</th>
+				<th>平均分</th>
+				<th>标准差</th>
+			</tr>
+		</thead>
+		<tbody>
+		<c:forEach items="${query.result}" var="marker">
+			<tr>
+				<td>${marker.loginName}</td>
+				<td>${marker.name}</td>
+				<td>${marker.finishCount}</td>
+				<td>${marker.validCount}</td>
+				<td>
+				<c:choose>
+		        <c:when test="${marker.finishCount!=null && marker.validCount!=null && marker.finishCount>0}">
+		        <fmt:formatNumber type="percent" maxIntegerDigits="3" value="${marker.validCount/marker.finishCount}" />
+		        </c:when>
+		        <c:otherwise>0%</c:otherwise>
+		        </c:choose>
+				</td>
+				<td><fmt:formatNumber pattern="###.##" value="${marker.avgSpeed}"/></td>
+				<td><fmt:formatNumber pattern="###.##" value="${marker.avgScore}"/></td>
+				<td><fmt:formatNumber pattern="###.##" value="${marker.stdevScore}"/></td>
+			</tr>
+		</c:forEach>
+		</tbody>
+	</table>
+	<div class="pagination">${query}</div>
+<script type="text/javascript">
+var searchSubjectCode = '${query.subjectCode}';
+var searchGroupNumber = '${query.groupNumber}';
+$('#subject-select').change(function(){
+    var code = $(this).val();
+    $('#group-select').empty();
+    $.post('${ctx}/admin/exam/group/query', {subjectCode: code}, function(result){
+        var parent = $('#group-select');
+        for(var i=0;i<result.length;i++){
+            var group = result[i];
+            var dom = $('<option value="'+group.number+'">'+group.number+'-'+group.title+'</option>').appendTo(parent);
+        }
+        if(searchSubjectCode==code) {
+            parent.val(searchGroupNumber);
+            parent.trigger('change');
+        }
+    });
+});
+$('#update-button').click(function(){
+    var subjectCode = $('#subject-select').val();
+    var groupNumber = $('#group-select').val();
+    if(subjectCode=='') {
+        alert('请选择科目');
+        return false;
+    }
+    if(groupNumber=='') {
+        alert('请选择大题');
+        return false;
+    }
+    $(this).attr('href','${ctx}/admin/exam/quality/update?subjectCode='+subjectCode+'&groupNumber='+groupNumber);
+    return true;
+});
+function page(n,s){
+	$("#pageNumber").val(n);
+	$("#pageSize").val(s);
+	$("#searchForm").submit();
+	return false;
+}
+function goSearch(){
+	$("#pageNumber").val(1);
+	$("#pageSize").val('${query.pageSize}');
+	$("#searchForm").submit();
+	return false;
+}    
+$('#subject-select').trigger('change');
+</script>	
+</body>
+</html>

+ 2 - 1
stmms-web/src/main/webapp/WEB-INF/views/modules/exam/trialList.jsp

@@ -12,8 +12,9 @@
         <li><a href="${ctx}/admin/exam/group?subjectCode=${query.subjectCode}">大题管理</a></li>
         <li><a href="${ctx}/admin/exam/marker?subjectCode=${query.subjectCode}">评卷员管理</a></li>
         <li class="active"><a href="##">试评管理</a></li>
-        <li><a href="${ctx}/admin/exam/library?subjectCode=${query.subjectCode}">正评管理</a></li>
+        <li><a href="${ctx}/admin/exam/library?subjectCode=${query.subjectCode}">任务管理</a></li>
         <li><a href="${ctx}/admin/exam/arbitrate?subjectCode=${query.subjectCode}">仲裁管理</a></li>
+        <li><a href="${ctx}/admin/exam/quality?subjectCode=${query.subjectCode}">质量监控</a></li>
     </ul>
 	<form id="searchForm" action="${ctx}/admin/exam/trial" method="post" class="breadcrumb form-search">
 	    <input type="hidden" id="pageNumber" name="pageNumber" value="${query.pageNumber }"/>