Przeglądaj źródła

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

ting.yin 6 lat temu
rodzic
commit
d21f50a0d9

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

@@ -0,0 +1,21 @@
+package cn.com.qmth.stmms.biz.mark.dao;
+
+import java.util.List;
+
+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 cn.com.qmth.stmms.biz.mark.model.MarkSpecialTag;
+
+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);
+
+}

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

@@ -0,0 +1,62 @@
+package cn.com.qmth.stmms.biz.mark.model;
+
+import javax.persistence.*;
+
+@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;
+    }
+}

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

@@ -0,0 +1,37 @@
+package cn.com.qmth.stmms.biz.mark.model;
+
+import java.io.Serializable;
+
+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;
+    }
+}

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

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

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

@@ -0,0 +1,32 @@
+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;
+
+@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);
+    }
+}

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

@@ -21,12 +21,15 @@ 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.MarkGroupService;
 import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
+import cn.com.qmth.stmms.biz.mark.model.MarkSpecialTag;
 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.SpecialTagDTO;
 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.MarkSpecialTagService;
 import cn.com.qmth.stmms.biz.mark.service.MarkTrackService;
 import cn.com.qmth.stmms.biz.mark.service.TaskService;
 import cn.com.qmth.stmms.biz.utils.CurrentTaskUtil;
@@ -59,7 +62,10 @@ public class TaskServiceImpl implements TaskService {
 
     @Autowired
     private MarkGroupService groupService;
-
+    
+    @Autowired
+    private MarkSpecialTagService markSpecialTagService;
+    
     @Override
     public List<Task> findByQuery(MarkLibrarySearchQuery query) {
         List<Task> list = new LinkedList<Task>();
@@ -77,6 +83,7 @@ public class TaskServiceImpl implements TaskService {
         ExamStudent student = studentService.findByExamIdAndExamNumber(library.getExamId(), library.getExamNumber());
         MarkGroup group = groupService.findOne(library.getExamId(), library.getSubjectCode(), library.getGroupNumber());
         Task task = new Task();
+        task.setTagList(getMarkSpecialTagList(library.getId()));
         task.setExist(true);
         task.setStudentId(library.getExamNumber());
         task.setLibraryId(library.getId());
@@ -234,6 +241,19 @@ public class TaskServiceImpl implements TaskService {
                     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);
+                }
+            }
         }
     }
 
@@ -289,4 +309,20 @@ public class TaskServiceImpl implements TaskService {
     public void clearCurrent(Marker marker) {
         CurrentTaskUtil.clear(marker);
     }
+    
+    public SpecialTagDTO [] getMarkSpecialTagList(Integer libraryId){
+        SpecialTagDTO [] specialTags = null;
+        List<MarkSpecialTag> list =  markSpecialTagService.findByLibraryId(libraryId);
+        if(!list.isEmpty()){
+            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;
+    }
 }

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

@@ -0,0 +1,11 @@
+package cn.com.qmth.stmms.biz.mark.service;
+
+import java.util.List;
+
+import cn.com.qmth.stmms.biz.mark.model.MarkSpecialTag;
+
+public interface MarkSpecialTagService {
+    public MarkSpecialTag save(MarkSpecialTag tag);
+    public void deleteByLibraryId(Integer libraryId);
+    public List<MarkSpecialTag> findByLibraryId(Integer libraryId);
+}

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

@@ -19,8 +19,10 @@ import cn.com.qmth.stmms.biz.exam.model.MarkGroup;
 import cn.com.qmth.stmms.biz.exam.service.ExamStudentService;
 import cn.com.qmth.stmms.biz.exam.service.MarkGroupService;
 import cn.com.qmth.stmms.biz.mark.model.MarkLibrary;
+import cn.com.qmth.stmms.biz.mark.model.MarkSpecialTag;
 import cn.com.qmth.stmms.biz.mark.model.MarkTrack;
 import cn.com.qmth.stmms.biz.mark.service.MarkLibraryService;
+import cn.com.qmth.stmms.biz.mark.service.MarkSpecialTagService;
 import cn.com.qmth.stmms.biz.mark.service.MarkTrackService;
 import cn.com.qmth.stmms.common.utils.PictureUrlBuilder;
 
@@ -47,6 +49,9 @@ public class MarkTrackController extends BaseExamController {
 
     @Autowired
     private MarkLibraryService libraryService;
+    
+	@Autowired
+    private MarkSpecialTagService markSpecialTagService;
 
     /**
      * 
@@ -71,10 +76,12 @@ public class MarkTrackController extends BaseExamController {
             List<MarkTrack> markTracks = markTrackService.findByStudentIdAndGroupNumber(library.getStudentId(),
                     group.getNumber());
             HashMap<String, Object> groups = new HashMap<String, Object>();
+            List<MarkSpecialTag> markSpecialTagList = markSpecialTagService.findByLibraryId(library.getId());
             groups.put("picUrls", picUrls);
             groups.put("markTracks", markTracks);
             groups.put("groupTitle", group.getTitle());
             groups.put("groupNumber", group.getNumber());
+            groups.put("markSpecialTagList",markSpecialTagList);
             list.add(groups);
         }
         map.put("list", list);

+ 7 - 2
stmms-web/src/main/webapp/WEB-INF/views/include/trackView.jsp

@@ -50,7 +50,7 @@ function initTrackPopoverContent(url){
         		var pane = $('<div class="tab-pane fade" id="track_'+groupNumber+'" style="overflow: hidden;"><canvas id="track-builder-canvas_'+groupNumber+'"></canvas></div>').appendTo($('#right-track-content'));
         		var canvas = document.getElementById('track-builder-canvas_'+groupNumber);
         		var ctx = canvas.getContext('2d');
-	        	buildImages(data.imageServer,group.picUrls,canvas,ctx,group.markTracks); 
+	        	buildImages(data.imageServer,group.picUrls,canvas,ctx,group.markTracks,group.markSpecialTagList); 
         	}
         	$('#right-track-nav a:first').trigger('click');
 			imageModal.setContent($('#track-view-content'));
@@ -59,7 +59,7 @@ function initTrackPopoverContent(url){
 
 }
 
-function buildImages (imageServer,picUrls,canvas,ctx,markTracks) {
+function buildImages (imageServer,picUrls,canvas,ctx,markTracks,markSpecialTagList) {
     //调用图片预加载函数,实现回调函数
     var imageObjects = [];
     loadImages(imageObjects,imageServer, picUrls, 0,function(images) {
@@ -97,6 +97,11 @@ function buildImages (imageServer,picUrls,canvas,ctx,markTracks) {
     					markTracks[j].positionY*canvas.height);
     		}
         }
+		for (var i = 0; i < markSpecialTagList.length; i++) {
+    		if(markSpecialTagList[i].positionX > 0 && markSpecialTagList[i].positionY > 0){
+    			ctx.fillText(markSpecialTagList[i].tagName,markSpecialTagList[i].positionX*canvas.width ,markSpecialTagList[i].positionY*canvas.height);
+        	}
+		}
     });
 }
 

+ 5 - 1
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>
@@ -52,7 +53,8 @@
 					'mark-board' : {
 						showScoreBoard : false,
 						autoSubmit : false,
-						needConfirm : false
+						needConfirm : false,
+                      	showTotalScore:true
 					},
 					'warning-info': {
 					},
@@ -62,6 +64,8 @@
 					'tag-process':{
 						url : '${ctx}/mark/tags'
 					},
+                    'specialTag':{
+                    },
 					'sheet-view':{
                         server : '${sheetServer}'
                     },

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

@@ -403,6 +403,7 @@ i,em {
 .mark-steps  .score_board .score ul li.unable{ background-color: #dedede; border: solid 1px #dedede;}
 .mark-steps  .score_board .score ul li.unable p{ color: #999999;}
 /*打分板普通状态、选中状态和不可选状态*/
+
 .mark-steps  .picture-list{ height: 80px !important;overflow: auto; border-bottom: solid 1px #BBBBBB;}
 .mark-steps  .picture-list .pictureScore{ margin: 5px; overflow: hidden;}
 .mark-steps  .picture-list .pictureScore ul li{ float: left; height: 30px; width: 50px; border: solid 1px #cccccc; background-color: #FFFFFF; margin: 5px 5px;}

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

@@ -504,8 +504,9 @@ MarkControl.prototype.submitTask = function(submitUrl) {
         task.markTime = undefined;
         task.paperUrl = undefined;
         task.answerUrl = undefined;
-
+        
         this.trigger('task.submit.before');
+        this.trigger('mark.specialTag.before');
         if (this.taskControl != undefined) {
             // 已定义任务引擎
             this.taskControl.submit(task, function(status) {
@@ -515,6 +516,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);
@@ -529,6 +531,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);
@@ -540,6 +543,7 @@ MarkControl.prototype.submitTask = function(submitUrl) {
             });
         } else {
             markControl.trigger('task.submit.success');
+            markControl.trigger('mark.specialTag.success');
             // markControl.getTask();
         }
     }

+ 28 - 2
stmms-web/src/main/webapp/static/mark-track/js/modules/mark-board.js

@@ -11,7 +11,9 @@ function MarkBoard(option) {
 	this.needConfirm = option.needConfirm === true ? true : false;
 	this.autoSubmit = option.autoSubmit === false ? false : true;
 	this.enableSkip = option.enableSkip === true ? true : false;
-
+    //显分板上是否显示合分样式
+    this.showObjectScoreAndSubjectScore = option.showTotalScore === true ? true : false;
+    
 	this.init();
 	this.markControl.on('task.get.before', this, function(event, context, eventObject) {
 		this.task = undefined;
@@ -104,6 +106,16 @@ MarkBoard.prototype.init = function() {
 			//self.markControl.trigger('mark.track.clear');
 		}
 	});
+    var dom5 = this.stepBoard.find(".sublist");
+    var dom6 = this.stepBoard.find(".newSubListCss");
+    if(this.showObjectScoreAndSubjectScore){
+      dom6.show();
+      dom5.hide();
+    }else {
+      dom6.hide();
+      dom5.show();
+    }
+
 }
 
 MarkBoard.prototype.initByTask = function(task) {
@@ -147,8 +159,13 @@ MarkBoard.prototype.render = function(task) {
 
 		if(task.markFinish === true) {
 			this.stepBoard.find('#total-score').html(task.totalScore + '');
+            this.stepBoard.find('#subject-score').html(task.totalScore);
+            this.stepBoard.find('#ObjectiveAndSubjectScore').html((task.totalScore+task.objectiveScore) + '');
+ 
 		} else {
 			this.stepBoard.find('#total-score').html('');
+            this.stepBoard.find('#subject-score').html('');
+            this.stepBoard.find('#ObjectiveAndSubjectScore').html(task.objectiveScore);
 		}
 
 		for( var i in task.markStepList) {
@@ -169,6 +186,8 @@ MarkBoard.prototype.render = function(task) {
 		this.stepBoard.scoreContainer.empty();
 		this.stepArray = [];
 		this.stepBoard.find('#total-score').html('');
+        this.stepBoard.find('#subject-score').html('');
+        this.stepBoard.find('#ObjectiveAndSubjectScore').html('');
 	}
 }
 
@@ -358,6 +377,11 @@ MarkBoard.prototype.updateTotalScore = function() {
 		this.task.totalScore = totalScore;
 		this.task.markFinish = finish;
 		this.stepBoard.find('#total-score').html(totalScore);
+		
+        this.stepBoard.find('#subject-score').html(totalScore);
+        var ObjectiveAndSubjectScore = this.task.totalScore+this.task.objectiveScore;
+        this.stepBoard.find('#ObjectiveAndSubjectScore').html(ObjectiveAndSubjectScore);
+
 	}
 }
 
@@ -411,7 +435,9 @@ MarkBoard.prototype.onTaskSubmit = function() {
 }
 
 MarkBoard.prototype.step_board_dom = '<div class="span3 mark-steps"><div class="step-board">\
-<div class="sublist"><p class="fraction">总分 <i class="red" id="total-score"></i></p></div>\
+	<div class="newSubListCss"><span class="fraction" style="margin-right: 10px;">主观分<i class="red" id="subject-score"></i></span>\
+	<span class="fraction">总分<i class="red" id="ObjectiveAndSubjectScore"></i></span></div>\
+	<div class="sublist"><p class="fraction">总分 <i id="total-score">5</i></p></div>\
 <div class="button"><input type="submit" value="全零分" class="btn1 all-zero-button"/>\
 <input type="submit" value="提&nbsp;交" class="btn2 task-submit-button"/></div>\
 <div class="step-list"><div class="number"><ul></ul></div></div>\

+ 2 - 0
stmms-web/src/main/webapp/static/mark-track/js/modules/mark-history.js

@@ -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) {

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

@@ -31,8 +31,19 @@ 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 +65,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 +107,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; width: 100%"><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="#" value="√">√</a>\
+    <a href="#" value="X">×</a>\
+    <a href="#" 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>';