1
0
Эх сурвалжийг харах

轨迹阅卷模式新增“特殊标识”样式

nikang 6 жил өмнө
parent
commit
5ba79c98d9

+ 27 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/dao/MarkSpecialTagDao.java

@@ -0,0 +1,27 @@
+package cn.com.qmth.stmms.biz.mark.dao;
+
+import cn.com.qmth.stmms.biz.mark.model.MarkSpecialTag;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+import java.util.List;
+
+/**
+ * @ClassName MarkSpecialTagDao
+ * @Description TODO
+ * @Author nikang
+ * @Date 2018/9/4 20:51
+ * @Version 1.0
+ */
+public interface MarkSpecialTagDao extends PagingAndSortingRepository<MarkSpecialTag, Integer>,
+        JpaSpecificationExecutor<MarkSpecialTag> {
+
+    @Modifying
+    @Query("delete from MarkSpecialTag s where s.libraryId = ?1")
+    public void deleteByLibraryId(Integer libraryId);
+
+    public List<MarkSpecialTag> findByLibraryIdOrderByIdAsc(Integer libraryId);
+
+}

+ 69 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/MarkSpecialTag.java

@@ -0,0 +1,69 @@
+package cn.com.qmth.stmms.biz.mark.model;
+
+import javax.persistence.*;
+
+/**
+ * @ClassName MarkSpecialTag
+ * @Description TODO
+ * @Author nikang
+ * @Date 2018/9/4 20:19
+ * @Version 1.0
+ */
+@Entity
+@Table(name = "m_special_tag")
+public class MarkSpecialTag {
+    @Id
+    @GeneratedValue
+    private Integer id;
+    @Column(name = "library_id", nullable = false)
+    private Integer libraryId;
+    @Column(name = "tag_name", nullable = false)
+    private String tagName;
+    @Column(name = "position_x", nullable = false)
+    private Double positionX;
+    @Column(name = "position_y", nullable = false)
+    private Double positionY;
+
+    public MarkSpecialTag() {
+    }
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Integer getLibraryId() {
+        return libraryId;
+    }
+
+    public void setLibraryId(Integer libraryId) {
+        this.libraryId = libraryId;
+    }
+
+    public String getTagName() {
+        return tagName;
+    }
+
+    public void setTagName(String tagName) {
+        this.tagName = tagName;
+    }
+
+    public Double getPositionX() {
+        return positionX;
+    }
+
+    public void setPositionX(Double positionX) {
+        this.positionX = positionX;
+    }
+
+    public Double getPositionY() {
+        return positionY;
+    }
+
+    public void setPositionY(Double positionY) {
+        this.positionY = positionY;
+    }
+}

+ 44 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/SpecialTagDTO.java

@@ -0,0 +1,44 @@
+package cn.com.qmth.stmms.biz.mark.model;
+
+import java.io.Serializable;
+
+/**
+ * @ClassName SpecialTagDTO
+ * @Description TODO
+ * @Author nikang
+ * @Date 2018/9/4 20:33
+ * @Version 1.0
+ */
+public class SpecialTagDTO implements Serializable {
+    private static final long serialVersionUID = -5424015292124065736L;
+    private String tagName;
+    private Double positionX;
+    private Double positionY;
+
+    public SpecialTagDTO() {
+    }
+
+    public String getTagName() {
+        return tagName;
+    }
+
+    public void setTagName(String tagName) {
+        this.tagName = tagName;
+    }
+
+    public Double getPositionX() {
+        return positionX;
+    }
+
+    public void setPositionX(Double positionX) {
+        this.positionX = positionX;
+    }
+
+    public Double getPositionY() {
+        return positionY;
+    }
+
+    public void setPositionY(Double positionY) {
+        this.positionY = positionY;
+    }
+}

+ 10 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/model/Task.java

@@ -118,6 +118,9 @@ public class Task implements Serializable {
 
     private String message;
 
+    //特殊标识:√ 或 ❌ 或 乄
+    private SpecialTagDTO [] tagList;
+
     public Task() {
 
     }
@@ -314,4 +317,11 @@ public class Task implements Serializable {
         return map;
     }
 
+    public SpecialTagDTO[] getTagList() {
+        return tagList;
+    }
+
+    public void setTagList(SpecialTagDTO[] tagList) {
+        this.tagList = tagList;
+    }
 }

+ 39 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/MarkSpecialTagServiceImpl.java

@@ -0,0 +1,39 @@
+package cn.com.qmth.stmms.biz.mark.service.Impl;
+
+import cn.com.qmth.stmms.biz.common.BaseQueryService;
+import cn.com.qmth.stmms.biz.mark.dao.MarkSpecialTagDao;
+import cn.com.qmth.stmms.biz.mark.model.MarkSpecialTag;
+import cn.com.qmth.stmms.biz.mark.service.MarkSpecialTagService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+ * @ClassName MarkSpecialTagServiceImpl
+ * @Description TODO
+ * @Author nikang
+ * @Date 2018/9/4 20:48
+ * @Version 1.0
+ */
+@Service
+public class MarkSpecialTagServiceImpl extends BaseQueryService<MarkSpecialTag> implements MarkSpecialTagService {
+    @Autowired
+    MarkSpecialTagDao markSpecialTagDao;
+
+    @Transactional
+    @Override
+    public MarkSpecialTag save(MarkSpecialTag tag){
+      return  markSpecialTagDao.save(tag);
+    }
+    @Transactional
+    @Override
+    public void deleteByLibraryId(Integer libraryId){
+        markSpecialTagDao.deleteByLibraryId(libraryId);
+    }
+    @Override
+    public List<MarkSpecialTag> findByLibraryId(Integer libraryId){
+        return markSpecialTagDao.findByLibraryIdOrderByIdAsc(libraryId);
+    }
+}

+ 39 - 5
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/Impl/TaskServiceImpl.java

@@ -5,7 +5,10 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
+import cn.com.qmth.stmms.biz.mark.model.*;
+import cn.com.qmth.stmms.biz.mark.service.MarkSpecialTagService;
 import org.apache.commons.lang.StringUtils;
+import org.hibernate.mapping.Collection;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeansException;
@@ -14,6 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
+import org.springframework.data.redis.connection.ConnectionUtils;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -24,11 +28,6 @@ import cn.com.qmth.stmms.biz.exam.model.Marker;
 import cn.com.qmth.stmms.biz.exam.service.ExamQuestionService;
 import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
 import cn.com.qmth.stmms.biz.exam.service.ExamSubjectService;
-import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
-import cn.com.qmth.stmms.biz.mark.model.MarkStepDTO;
-import cn.com.qmth.stmms.biz.mark.model.MarkTrack;
-import cn.com.qmth.stmms.biz.mark.model.Task;
-import cn.com.qmth.stmms.biz.mark.model.TrackDTO;
 import cn.com.qmth.stmms.biz.mark.query.MarkLibrarySearchQuery;
 import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
 import cn.com.qmth.stmms.biz.mark.service.MarkTrackService;
@@ -37,6 +36,7 @@ import cn.com.qmth.stmms.biz.utils.CurrentTaskUtil;
 import cn.com.qmth.stmms.biz.utils.MarkRedisUtil;
 import cn.com.qmth.stmms.common.enums.LibraryStatus;
 import cn.com.qmth.stmms.common.utils.PictureUrlBuilder;
+import org.springframework.util.CollectionUtils;
 
 /**
  * 评卷任务服务实现
@@ -68,6 +68,9 @@ public class TaskServiceImpl implements TaskService, ApplicationContextAware, In
     @Autowired
     private MarkTrackService trackService;
 
+    @Autowired
+    private MarkSpecialTagService markSpecialTagService;
+
     @Value("${use.redis}")
     private boolean useRedis;
     
@@ -89,6 +92,7 @@ public class TaskServiceImpl implements TaskService, ApplicationContextAware, In
         ExamStudent student = studentService.findByExamIdAndExamNumber(library.getExamId(), library.getExamNumber());
 
         Task task = new Task();
+        task.setTagList(getMarkSpecialTagList(library.getId()));
         task.setExist(true);
         task.setStudentId(library.getExamNumber());
         task.setLibraryId(library.getId());
@@ -234,6 +238,19 @@ public class TaskServiceImpl implements TaskService, ApplicationContextAware, In
                     trackService.save(dto.transform(library));
                 }
             }
+
+            SpecialTagDTO [] tagList = task.getTagList();
+            markSpecialTagService.deleteByLibraryId(library.getId());
+            if(tagList != null && tagList.length>0){
+                for(SpecialTagDTO s : tagList){
+                        MarkSpecialTag markSpecialTag = new MarkSpecialTag();
+                        markSpecialTag.setLibraryId(library.getId());
+                        markSpecialTag.setTagName(s.getTagName());
+                        markSpecialTag.setPositionX(s.getPositionX());
+                        markSpecialTag.setPositionY(s.getPositionY());
+                        markSpecialTagService.save(markSpecialTag);
+                }
+            }
         }
     }
 
@@ -340,4 +357,21 @@ public class TaskServiceImpl implements TaskService, ApplicationContextAware, In
     	}
     }
 
+    public SpecialTagDTO [] getMarkSpecialTagList(Integer libraryId){
+        SpecialTagDTO [] specialTags = null;
+        List<MarkSpecialTag> list =  markSpecialTagService.findByLibraryId(libraryId);
+        if(!CollectionUtils.isEmpty(list)){
+            specialTags = new SpecialTagDTO[list.size()] ;
+            for(int i =0;i<list.size();i++){
+                SpecialTagDTO specialTagDTO = new SpecialTagDTO();
+                specialTagDTO.setTagName(list.get(i).getTagName());
+                specialTagDTO.setPositionX(list.get(i).getPositionX());
+                specialTagDTO.setPositionY(list.get(i).getPositionY());
+                specialTags[i] = specialTagDTO;
+            }
+        }
+        return  specialTags;
+    }
+
+
 }

+ 19 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/mark/service/MarkSpecialTagService.java

@@ -0,0 +1,19 @@
+package cn.com.qmth.stmms.biz.mark.service;
+
+import cn.com.qmth.stmms.biz.mark.model.MarkSpecialTag;
+
+import javax.persistence.criteria.CriteriaBuilder;
+import java.util.List;
+
+/**
+ * @ClassName MarkSpecialTagService
+ * @Description TODO
+ * @Author nikang
+ * @Date 2018/9/4 20:48
+ * @Version 1.0
+ */
+public interface MarkSpecialTagService {
+    public MarkSpecialTag save(MarkSpecialTag tag);
+    public void deleteByLibraryId(Integer libraryId);
+    public List<MarkSpecialTag> findByLibraryId(Integer libraryId);
+}

+ 8 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/admin/exam/MarkTrackController.java

@@ -4,6 +4,8 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 
+import cn.com.qmth.stmms.biz.mark.model.MarkSpecialTag;
+import cn.com.qmth.stmms.biz.mark.service.MarkSpecialTagService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -33,6 +35,9 @@ public class MarkTrackController extends BaseParameterController {
 	@Autowired
 	private MarkLibraryService markLibraryService;
 
+	@Autowired
+    private MarkSpecialTagService markSpecialTagService;
+
 	/**
 	 * 
 	 * @param studentId
@@ -44,13 +49,16 @@ public class MarkTrackController extends BaseParameterController {
 		List<MarkTrack> markTracks = markTrackService.findByStudentId(studentId);
   		MarkLibrary markLibrary=markLibraryService.findByStudentId(studentId);
         List<String> picUrls = new ArrayList<String>();
+        List<MarkSpecialTag> markSpecialTagList = new ArrayList<MarkSpecialTag>();
 		if(markLibrary != null){
           picUrls = PictureUrlBuilder.getSliceUrls(markLibrary.getExamId(), markLibrary.getCampusId(), markLibrary.getSubjectCode(), markLibrary.getExamNumber(), markLibrary.getPicStart(), markLibrary.getPicCount());
+          markSpecialTagList = markSpecialTagService.findByLibraryId(markLibrary.getId());
 		}
 		HashMap<String, Object> map = new HashMap<String, Object>();
 		map.put("picUrls",picUrls);
 		map.put("markTracks", markTracks);
 		map.put("imageServer", imageServer);
+		map.put("markSpecialTagList",markSpecialTagList);
 		return map;
 	}
 

+ 6 - 1
stmms-web/src/main/webapp/WEB-INF/views/include/trackView.jsp

@@ -35,7 +35,12 @@ function initTrackPopoverContent(url){
 	        			ctx.fillText(data.markTracks[i].score,data.markTracks[i].positionX*canvas.width ,data.markTracks[i].positionY*canvas.height);
                 	}
         		}
-        	}); 
+        		for (var i = 0; i < data.markSpecialTagList.length; i++) {
+            		if(data.markSpecialTagList[i].positionX > 0 && data.markSpecialTagList[i].positionY > 0){
+	        			ctx.fillText(data.markSpecialTagList[i].tagName,data.markSpecialTagList[i].positionX*canvas.width ,data.markSpecialTagList[i].positionY*canvas.height);
+                	}
+        		}
+        	});
 		
 			imageModal.setContent($('#track-view-content'));
         } 

+ 3 - 0
stmms-web/src/main/webapp/WEB-INF/views/modules/mark/markTrack.jsp

@@ -27,6 +27,7 @@
 <script type="text/javascript" src="${ctxStatic}/mark-track/js/modules/change-name.js"></script>
 <script type="text/javascript" src="${ctxStatic}/mark-track/js/modules/tag-process.js"></script>
 <script type="text/javascript" src="${ctxStatic}/mark-track/js/modules/view-sidebar.js"></script>
+<script type="text/javascript" src="${ctxStatic}/mark-track/js/modules/specialTag.js"></script>
 </head>
 <body>
 	<div class="container-fluid" id="container"></div>
@@ -66,6 +67,8 @@
 					'tag-process':{
 						url : '${ctx}/mark/tags'
 					},
+                    'specialTag':{
+                    },
 					'sheet-view':{
                         server : '${sheetServer}'
                     },

+ 6 - 0
stmms-web/src/main/webapp/static/mark-track/css/style.css

@@ -1203,3 +1203,9 @@ i,em {
 .username-input{
     margin-left: 12px;
 }
+.buttonCss .selected{
+    background-image: -webkit-linear-gradient(top, #eaeaea, #ED5321);
+}
+.buttonCss{
+    border-bottom: 1px solid #b50505;!important;
+}

+ 4 - 1
stmms-web/src/main/webapp/static/mark-track/js/mark-control.js

@@ -510,8 +510,8 @@ MarkControl.prototype.submitTask = function(submitUrl) {
         task.answerUrl = undefined;
         var timestamp = new Date().getTime();
         task.spent = timestamp - task.spent;
-
         this.trigger('task.submit.before');
+        this.trigger('mark.specialTag.before');
         if (this.taskControl != undefined) {
             // 已定义任务引擎
             this.taskControl.submit(task, function(status) {
@@ -521,6 +521,7 @@ MarkControl.prototype.submitTask = function(submitUrl) {
                 }
                 // markControl.context.task = undefined;
                 markControl.trigger('task.submit.success');
+                markControl.trigger('mark.specialTag.success');
                 // markControl.getTask();
             }, function(message) {
                 markControl.trigger('task.submit.error', message);
@@ -535,6 +536,7 @@ MarkControl.prototype.submitTask = function(submitUrl) {
                     if (result.success == true) {
                         // markControl.context.task = undefined;
                         markControl.trigger('task.submit.success');
+                        markControl.trigger('mark.specialTag.success');
                         // markControl.getTask();
                     } else {
                         markControl.trigger('task.submit.error', result.message);
@@ -546,6 +548,7 @@ MarkControl.prototype.submitTask = function(submitUrl) {
             });
         } else {
             markControl.trigger('task.submit.success');
+            markControl.trigger('mark.specialTag.success');
             // markControl.getTask();
         }
     }

+ 20 - 0
stmms-web/src/main/webapp/static/mark-track/js/modules/mark-board.js

@@ -57,6 +57,21 @@ function MarkBoard(option) {
             }
         }
     });
+
+    this.markControl.on('click.specialTag.before', this, function(event, context, eventObject) {
+        this.resetScore();
+    });
+    this.markControl.on('show.track.event',this ,function(event,context,eventObject){
+        if(this.stepList == undefined) {
+            return;
+        }
+        for(var i = 0; i < this.stepList.length; i++) {
+            var step = this.stepList[i];
+            for(var j = 0; j < step.trackList.length; j++) {
+                this.markControl.trigger('mark.track.show', step.trackList[j]);
+            }
+        }
+    });
 }
 
 MarkBoard.prototype.init = function() {
@@ -79,6 +94,7 @@ MarkBoard.prototype.init = function() {
 		self.allZeroSubmit();
 	});
 	this.stepBoard.find('.undo-last-track-button').click(this, function() {
+        self.markControl.trigger('click.track.before');
 		if(self.currentStep != undefined && self.currentStep.trackList.length>0) {
 			self.currentStep.trackList.pop();
 			self.updateStepScore();
@@ -87,6 +103,7 @@ MarkBoard.prototype.init = function() {
 		}
 	});
 	this.stepBoard.find('.clear-current-track-button').click(this, function() {
+        self.markControl.trigger('click.track.before');
 		if(self.currentStep != undefined) {
 			self.currentStep.currentScore = undefined;
 			self.currentStep.trackList = [];
@@ -96,6 +113,7 @@ MarkBoard.prototype.init = function() {
 		}
 	});
 	this.stepBoard.find('.clear-all-track-button').click(this, function() {
+        self.markControl.trigger('click.track.before');
 		if(self.stepList != undefined) {
 			for(var i = 0; i < self.stepList.length; i++) {
 				self.stepList[i].currentScore = undefined;
@@ -258,6 +276,8 @@ MarkBoard.prototype.inputTimeout = function() {
 }
 
 MarkBoard.prototype.onScoreClick = function(scoreNumber) {
+    //禁止 特殊标识的使用
+    this.markControl.trigger('click.track.before');
 	if(this.task == undefined || this.currentStep == undefined) {
 		return;
 	}

+ 3 - 1
stmms-web/src/main/webapp/static/mark-track/js/modules/mark-history.js

@@ -21,7 +21,7 @@ function MarkHistory(option) {
 
 	this.markControl.on('history.get.success', this, function(event, context, data) {
 		var taskList = data.result;
-		this.taskList = [];
+        this.taskList = [];
 		this.loading = false;
 		this.container.list.empty();
 		if(isArray(taskList) && taskList.length > 0) {
@@ -153,6 +153,8 @@ MarkHistory.prototype.onSearch = function(pageNumber) {
 }
 
 MarkHistory.prototype.onTaskSelect = function(index) {
+    //初始化--特殊标识
+    this.markControl.trigger('mark.specialTag.success');
 	var number = new String(index);
 	if(this.taskList != undefined && index < this.taskList.length && this.loading != true) {
 		this.container.list.find('tr').each(function(index, obj) {

+ 25 - 0
stmms-web/src/main/webapp/static/mark-track/js/modules/single-image-view.js

@@ -31,8 +31,20 @@ function SingleImageView(option) {
         	this.drawScore(track);
         }
     });
+
+    this.markControl.on('mark.specialTag.show', this, function(event, context, specialTag){
+        if(this.task != undefined && specialTag != undefined){
+        	this.drawTag(specialTag);
+        }
+    });
     this.markControl.on('mark.track.clear', this, function(event, context, track){
         this.reloadImage();
+        //显示特殊标记的历史痕迹
+        this.markControl.trigger('show.specialTag.event');
+    });
+    this.markControl.on('mark.specialTag.clear', this, function(event, context, track){
+        this.reloadImage();
+        this.markControl.trigger('show.track.event');
     });
 }
 
@@ -54,6 +66,11 @@ SingleImageView.prototype.init = function() {
         		positionX: ((event.pageX - $(self.canvas).offset().left)/$(self.canvas).width()).toFixed(3),
                 positionY: ((event.pageY - $(self.canvas).offset().top)/$(self.canvas).height()).toFixed(3)
         	});
+
+        	self.markControl.trigger('mark.specialTag.set', {
+        		positionX: ((event.pageX - $(self.canvas).offset().left)/$(self.canvas).width()).toFixed(3),
+                positionY: ((event.pageY - $(self.canvas).offset().top)/$(self.canvas).height()).toFixed(3)
+        	});
         }
     });
 }
@@ -91,4 +108,12 @@ SingleImageView.prototype.drawScore = function(track){
     }
 }
 
+SingleImageView.prototype.drawTag = function(specialTag){
+    if(specialTag != undefined && specialTag.positionX > 0 && specialTag.positionY > 0){
+        this.ctx.font ="60px Arial";
+        this.ctx.fillStyle = 'red';
+        this.ctx.fillText(specialTag.tagName, specialTag.positionX*this.canvas.width, specialTag.positionY*this.canvas.height);
+    }
+}
+
 SingleImageView.prototype.container_dom = '<div style="overflow: scroll"><canvas></canvas></div>';

+ 165 - 0
stmms-web/src/main/webapp/static/mark-track/js/modules/specialTag.js

@@ -0,0 +1,165 @@
+//特殊标识模块
+var specialTag = function(option, success) {
+    var object = new SpecialTag(option);
+    success();
+    return object;
+}
+
+function SpecialTag(option) {
+    this.markControl = option.markControl;
+    this.maxWidth = option.width != undefined ? option.width : 200;
+    this.show = false;
+    this.tagList = [];
+    this.specialTag = undefined;
+    this.init();
+    this.markControl.on('mark.specialTag.set', this, function(event, context, specialTag) {
+        if(this.specialTag != undefined && this.tagList != undefined){
+            specialTag.tagName = this.specialTag;
+            this.tagList.push(specialTag);
+            this.markControl.trigger('mark.specialTag.show', specialTag);
+        }
+    })
+    //提交保存之前
+    this.markControl.on('mark.specialTag.before', this, function(event, context, eventObject) {
+        this.task = context.task;
+        if (this.tagList.length > 0) {
+            this.task.tagList = this.tagList;
+        } else {
+            this.task.tagList = undefined;
+        }
+    });
+    //提交保存成功后
+    this.markControl.on('mark.specialTag.success', this, function(event, context, eventObject) {
+        this.markControl.trigger('clear.specialTag.click');
+        this.specialTag = undefined;
+        this.tagList = [];
+    });
+
+    //禁止 特殊标识使用
+    this.markControl.on('click.track.before', this, function(event, context, eventObject) {
+        this.specialTag = undefined;
+        this.markControl.trigger('clear.specialTag.click');
+    });
+
+    //显示痕迹
+    this.markControl.on('show.specialTag.event', this, function(event, context, eventObject) {
+        this.task = context.task;
+        if(this.task != undefined ){
+            if(this.tagList.length == 0 && this.task.tagList != null && this.task.tagList.length>0){
+                this.tagList = this.task.tagList;
+            }
+            for(var j = 0; j <this.tagList.length; j++) {
+                this.markControl.trigger('mark.specialTag.show', this.tagList[j]);
+            }
+        }
+    });
+
+    //清除按钮选中
+    this.markControl.on('clear.specialTag.click', this, function(event, context, eventObject) {
+        this.specialTag = undefined;
+        var aList = this.onclickList.find('a');
+        for(var i =0 ;i < aList.length;i++){
+                $(aList[i]).removeClass('selected');
+        }
+    })
+}
+
+SpecialTag.prototype.init = function() {
+    var self = this;
+    this.container = getDom(this.container_dom, this.markControl).appendTo(this.markControl.container);
+    this.container.width(this.maxWidth);
+    this.container.offset({
+        top: 100,
+        left:800
+    });
+
+    this.container.header = getDom(this.container_header_dom, this.markControl).appendTo(this.container);
+    this.container.header.width('100%');
+
+    this.container.content = getDom(this.container_content_dom, this.markControl).appendTo(this.container);
+    this.container.content.width('100%');
+
+    this.onclickList = this.container.content.find('#problem-list');
+
+    this.clearList = this.container.content.find('#clear');
+
+    this.container.draggable({
+        containment: "window"
+    });
+
+    this.onclickList.find('a').click(function () {
+        self.specialTag = undefined;
+        self.markControl.trigger('click.specialTag.before');
+        if($(this).hasClass('selected')){
+            $(this).removeClass('selected');
+        }else {
+            self.specialTag = $(this).attr('value');
+            $(this).addClass('selected');
+            var aList = self.onclickList.find('a');
+            for(var i =0 ;i < aList.length;i++){
+                if($(aList[i]).attr('value') != $(this).attr('value')){
+                    $(aList[i]).removeClass('selected');
+                }
+            }
+        }
+    });
+
+    this.clearList.find('a').click(function () {
+        self.markControl.trigger('clear.specialTag.click');
+        self.markControl.trigger('click.specialTag.before');
+        if(self.tagList != undefined && self.tagList.length>0){
+            self.markControl.trigger('mark.specialTag.clear');
+            if($(this).attr('class') == 'goBack'){
+                    self.tagList.pop();
+                    self.markControl.trigger('show.specialTag.event');
+                }else if($(this).attr('class') == 'clearAll'){
+                    self.tagList = [];
+                    self.task.tagList = [];
+            }
+        }
+    });
+
+    this.container.header.find('#close-button').click(function() {
+        self.toggle(false);
+    });
+
+    this.control = getDom(this.control_dom, this.markControl).appendTo(this.markControl.container.assistant);
+    this.control.find('#show-SpecialTag-button').click(function() {
+        self.markControl.container.assistant.hide();
+        self.toggle(true);
+    });
+    this.control.find('#hide-SpecialTag-button').click(function() {
+        self.markControl.container.assistant.hide();
+        self.toggle(false);
+    });
+}
+
+SpecialTag.prototype.toggle = function(show) {
+    this.specialTag = undefined;
+    if (show == true) {
+        this.show = true;
+        this.container.show();
+    } else {
+        this.show = false;
+        this.container.hide();
+    }
+}
+
+SpecialTag.prototype.container_dom = '<div class="score-board score-board-popover" style="display:none"></div>';
+
+SpecialTag.prototype.container_header_dom = '<div class="header" style="border-radius: 15px 15px 0px 0px;">\
+<p class="fl" id="header">特殊标记</p>\
+<a class="header-close" id="close-button" href="#"><img src="{staticServer}/images/close.png"></a>\
+</div>';
+
+SpecialTag.prototype.container_content_dom = '<div class="content popover-content" style="padding:4px;border-radius: 0px 0px 15px 15px;">\
+<p id="problem-list" class="popover-list buttonCss">\
+    <a href="#" id="show-TrueTag-button" value="√">√</a>\
+    <a href="#" id="show-FalseTag-button" value="×">×</a>\
+    <a href="#" id="show-TrueAndFalseTag-button" value="乄">乄</a>\
+    </p><p id="clear"><a href="#" class="goBack" style="margin-left: 20px;">回&nbsp;&nbsp;&nbsp;退</a><a href="#" class="clearAll">全部清除</a></p></div>';
+
+SpecialTag.prototype.control_dom = '<h3 class="popover-title">特殊标记</h3>\
+<div class="popover-content"><p id="problem-list" class="popover-list">\
+<a href="#" id="show-SpecialTag-button">打开</a><a href="#" id="hide-SpecialTag-button">关闭</a>\
+</p></div>';