Browse Source

增加评卷个性化参数设置记忆功能

1.mark-control增加参数初始化与保存功能
2.图片缩放、侧边栏、缩略图、鼠标给分板四大功能的切换能自动记忆
3.服务端marker表增加字段记录个性化参数设置
4.MarkController增加保存接口
luoshi 6 years ago
parent
commit
cbe38c26f9

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

@@ -52,6 +52,10 @@ public interface MarkerDao extends PagingAndSortingRepository<Marker, Integer>,
     public void updateQualityById(Integer id, int finishCount, int validCount, double avgSpeed, double avgScore,
             double stdevScore);
 
+    @Modifying
+    @Query("update Marker m set m.markSetting=?2 where m.id=?1")
+    public void updateMarkSettingById(Integer id, String setting);
+
     @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")

+ 15 - 1
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/model/Marker.java

@@ -84,9 +84,15 @@ public class Marker implements Serializable {
     /**
      * 班级数量
      */
-    @Column(name = "class_count",nullable = false)
+    @Column(name = "class_count", nullable = false)
     private Integer classCount;
 
+    /**
+     * 个性化评卷参数设置
+     */
+    @Column(name = "mark_setting", nullable = true, length = 255)
+    private String markSetting;
+
     @Transient
     @ExcelField(title = "科目(导入时可为空)", align = 2, sort = 20)
     private String subjectName;
@@ -337,4 +343,12 @@ public class Marker implements Serializable {
         this.classCount = classCount;
     }
 
+    public String getMarkSetting() {
+        return markSetting;
+    }
+
+    public void setMarkSetting(String markSetting) {
+        this.markSetting = markSetting;
+    }
+
 }

+ 2 - 0
stmms-biz/src/main/java/cn/com/qmth/stmms/biz/exam/service/MarkerService.java

@@ -36,4 +36,6 @@ public interface MarkerService {
 
     long countByLoginName(String loginName);
 
+    void updateMarkSetting(Integer id, String setting);
+
 }

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

@@ -53,6 +53,12 @@ public class MarkerServiceImpl extends BaseQueryService<Marker> implements Marke
         }
     }
 
+    @Transactional
+    @Override
+    public void updateMarkSetting(Integer id, String setting) {
+        markerDao.updateMarkSettingById(id, setting);
+    }
+
     @Override
     public Marker findById(Integer id) {
         return markerDao.findOne(id);

+ 11 - 0
stmms-web/src/main/java/cn/com/qmth/stmms/mark/MarkController.java

@@ -181,6 +181,7 @@ public class MarkController extends BaseController {
         modelAndView.addObject("subject", subjectService.find(marker.getExamId(), marker.getSubjectCode()));
         Exam exam = examService.findById(marker.getExamId());
         modelAndView.addObject("forceSpecialTag", exam.isForceSpecialTag());
+        modelAndView.addObject("defaultSetting", StringUtils.trimToNull(marker.getMarkSetting()));
         releaseMarker(marker);
     }
 
@@ -424,6 +425,16 @@ public class MarkController extends BaseController {
         return result;
     }
 
+    @RequestMapping("/update-setting")
+    @ResponseBody
+    public JSONObject updateSetting(HttpServletRequest request, @RequestParam String setting) {
+        Marker marker = RequestUtils.getWebUser(request).getMarker();
+        JSONObject result = new JSONObject();
+        markerService.updateMarkSetting(marker.getId(), StringUtils.trimToNull(setting));
+        result.accumulate("success", true);
+        return result;
+    }
+
     @RequestMapping("/tags")
     @ResponseBody
     public JSONArray getTags(HttpServletRequest request) {

+ 5 - 1
stmms-web/src/main/webapp/WEB-INF/views/modules/mark/markNew.jsp

@@ -45,6 +45,7 @@
 				container : $('#container'),
 				staticServer : '${ctxStatic}',
 				imageServer : '${sliceServer}',
+				userId: '${marker.id}',
 				userName : '${web_user.name}',
 				logoutUrl: '${ctx}/mark/logout',
 				clearUrl: '${ctx}/mark/clear',
@@ -52,9 +53,12 @@
 				switchTrackUrl: '${ctx}/mark/index?mode=track',
 				</c:if>
 				forceSpecialTag : eval('${forceSpecialTag}'.toLowerCase()),
+				<c:if test="${defaultSetting!=null}">
+				defaultSetting: '${defaultSetting}',
+				</c:if>
+				settingSyncUrl: '${ctx}/mark/update-setting',
 				modules : {
 					'single-image-view' : {},
-			        //'simple-image-view' : {},
 					'image-builder': {},
 					'mark-status': {
 						simple : false,

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

@@ -37,6 +37,7 @@
 				container : $('#container'),
 				staticServer : '${ctxStatic}',
 				imageServer : '${sliceServer}',
+				userId: '${marker.id}',
 				userName : '${web_user.name}',
 				logoutUrl: '${ctx}/mark/logout',
 				clearUrl: '${ctx}/mark/clear',
@@ -44,6 +45,10 @@
 				switchCommonUrl: '${ctx}/mark/index?mode=common',
 				</c:if>
 				forceSpecialTag : eval('${forceSpecialTag}'.toLowerCase()),
+				<c:if test="${defaultSetting!=null}">
+                defaultSetting: '${defaultSetting}',
+                </c:if>
+                settingSyncUrl: '${ctx}/mark/update-setting',
 				modules : {
 					'single-image-view' : {},
 					'image-builder': {},

+ 87 - 39
stmms-web/src/main/webapp/static/mark-new/js/mark-control.js

@@ -18,6 +18,8 @@ function MarkControl(option) {
     this.initTriggers(option);
     //初始化功能模块
     this.initModules(option);
+    //初始化评卷配置
+    this.initSetting(option);
     //初始化成功回调方法
     //console.log('MarkControl init success!');
     //if (option.success != undefined && typeof(option.success) == 'function') {
@@ -39,10 +41,10 @@ MarkControl.prototype.initContainer = function() {
     }
     this.container.center = getDom(this.center_dom, this).appendTo(this.container);
     this.container.header = getDom(this.center_header_dom, this).appendTo(this.container.center).find('.header');
-    if(this.option.switchTrackUrl!=undefined && this.option.switchTrackUrl.length>0){
-    	var switchButton = this.container.header.find('#switch-track-button');
-    	switchButton.attr('href', this.option.switchTrackUrl);
-    	switchButton.show();
+    if (this.option.switchTrackUrl != undefined && this.option.switchTrackUrl.length > 0) {
+        var switchButton = this.container.header.find('#switch-track-button');
+        switchButton.attr('href', this.option.switchTrackUrl);
+        switchButton.show();
     }
     this.container.centerContent = getDom(this.center_content_dom, this).appendTo(this.container.center);
     this.container.imageContent = getDom(this.image_content_dom, this).appendTo(this.container.centerContent);
@@ -51,8 +53,8 @@ MarkControl.prototype.initContainer = function() {
     this.container.centerContent.css('height', height - this.container.header.parent().height());
 
     this.initHeaderAndAssistant();
-    
-	this.container.centerList = [];
+
+    this.container.centerList = [];
     this.navNumber = 0;
 }
 
@@ -92,6 +94,50 @@ MarkControl.prototype.initMarkFunction = function() {
     }
 }
 
+MarkControl.prototype.initSetting = function(option) {
+    this.userId = option.userId;
+    this.settingSyncUrl = option.settingSyncUrl;
+    this.localStore = window.localStorage;
+    this.setting = {};
+
+    if (option.defaultSetting != undefined) {
+        //读取外部初始化配置
+        this.setting = JSON.parse(option.defaultSetting);
+    } else if (this.localStore != undefined) {
+        //读取本地存储并判断用户标识
+        var store = JSON.parse(this.localStore.getItem('mark.setting'));
+        if (store != undefined && store.userId != undefined && store.userId == this.userId) {
+            this.setting = store.setting;
+        }
+    }
+    //强制刷新本地存储
+    this.localSettingSave();
+    //广播通知所有模块初始化设置
+    this.trigger('mark.setting.init', this.setting);
+}
+
+MarkControl.prototype.localSettingSave = function() {
+    if (this.localStore != undefined) {
+        this.localStore.setItem('mark.setting', JSON.stringify({
+            userId: this.userId,
+            setting: this.setting
+        }));
+    }
+}
+
+MarkControl.prototype.updateSetting = function(item) {
+    if (item == undefined) {
+        return;
+    }
+    for (var key in item) {
+        this.setting[key] = item[key];
+    }
+    this.localSettingSave();
+    if (this.syncUrl != undefined) {
+
+    }
+}
+
 //增加某个事件的监听方法
 MarkControl.prototype.on = function(eventName, caller, callback, async) {
     if (eventName && callback && eventName.length > 0 && typeof(callback) == 'function') {
@@ -184,12 +230,11 @@ MarkControl.prototype.initTriggers = function(option) {
         this.trigger('center.width.change');
     });
     this.on('task.load.finish', this, function(event, context, eventObject) {
-        if(context.task!=undefined){
-        	context.task.spent = new Date().getTime();
+        if (context.task != undefined) {
+            context.task.spent = new Date().getTime();
         }
     });
-    this.on('mark.focus.change', this, function(event, context, eventObject) {
-    });
+    this.on('mark.focus.change', this, function(event, context, eventObject) {});
     this.on('task.get.finish', this, function(event, context, eventObject) {
         context.prefetchCallback = undefined;
     });
@@ -251,6 +296,9 @@ MarkControl.prototype.initTriggers = function(option) {
         context.task = undefined;
         self.getTask();
     });
+    this.on('mark.setting.change', this, function(event, context, eventObject) {
+        self.updateSetting(eventObject);
+    });
 
     $(document).keypress(this, function(event) {
         if (self.context.listenKeyboard != false) {
@@ -505,26 +553,26 @@ MarkControl.prototype.submitTask = function(submitUrl) {
 
     if (task != undefined && this.context.submitting != true) {
         //开启强制标记
-        if(this.option.forceSpecialTag===true){
-        	if(task.tagList==undefined ||task.tagList==null ||task.tagList.length <= 0){
-        		markControl.trigger('task.submit.forceSpecialTag');
-        		return;
-        	}
+        if (this.option.forceSpecialTag === true) {
+            if (task.tagList == undefined || task.tagList == null || task.tagList.length <= 0) {
+                markControl.trigger('task.submit.forceSpecialTag');
+                return;
+            }
         }
-        
+
         var submitObj = {
-        	statusValue: task.statusValue,
-        	studentId: task.studentId,
-        	libraryId: task.libraryId,
-        	totalScore: task.totalScore,
-        	scoreList: task.scoreList,
-        	trackList: task.trackList,
-        	tagList: task.tagList,
-        	spent: new Date().getTime() - task.spent
+            statusValue: task.statusValue,
+            studentId: task.studentId,
+            libraryId: task.libraryId,
+            totalScore: task.totalScore,
+            scoreList: task.scoreList,
+            trackList: task.trackList,
+            tagList: task.tagList,
+            spent: new Date().getTime() - task.spent
         }
 
         this.trigger('task.submit.before');
-        
+
         if (this.taskControl != undefined) {
             //已定义任务引擎
             this.taskControl.submit(submitObj, function(status) {
@@ -541,9 +589,9 @@ MarkControl.prototype.submitTask = function(submitUrl) {
             $.ajax({
                 url: submitUrl,
                 type: 'POST',
-        		data: JSON.stringify(submitObj),
-        		dataType: "json",
-        		contentType : 'application/json;charset=utf-8',
+                data: JSON.stringify(submitObj),
+                dataType: "json",
+                contentType: 'application/json;charset=utf-8',
                 success: function(result) {
                     if (result.success == true) {
                         markControl.trigger('task.submit.success');
@@ -560,23 +608,23 @@ MarkControl.prototype.submitTask = function(submitUrl) {
         }
     }
 }
-MarkControl.prototype.addNavGroup = function(title, content){
+MarkControl.prototype.addNavGroup = function(title, content) {
     var self = this;
     self.navNumber++;
-    var nav = $('<a href="#"><span>'+title+'</span></a>').appendTo(self.container.centerNavbar);
+    var nav = $('<a href="#"><span>' + title + '</span></a>').appendTo(self.container.centerNavbar);
     nav.attr('data-number', self.navNumber);
     content.attr('data-number', self.navNumber);
-    nav.click(function(){
+    nav.click(function() {
         self.container.centerNavbar.find('a').removeClass('selected');
         $(this).addClass('selected');
-        
-        for(var i in self.container.centerList){
-        	var dom = self.container.centerList[i];
-        	if(dom.attr('data-number')==$(this).attr('data-number')){
-        		dom.show();
-        	}else{
-        		dom.hide();
-        	}
+
+        for (var i in self.container.centerList) {
+            var dom = self.container.centerList[i];
+            if (dom.attr('data-number') == $(this).attr('data-number')) {
+                dom.show();
+            } else {
+                dom.hide();
+            }
         }
     });
     self.container.centerList.push(content);

+ 18 - 5
stmms-web/src/main/webapp/static/mark-new/js/modules/mark-board.js

@@ -6,6 +6,7 @@ var mark_board = function(option, success) {
 }
 
 function MarkBoard(option) {
+    var self = this;
     this.markControl = option.markControl;
     this.needConfirm = option.needConfirm === true ? true : false;
     this.autoSubmit = option.autoSubmit === false ? false : true;
@@ -24,7 +25,7 @@ function MarkBoard(option) {
         this.initByTask(context.task);
     });
     this.markControl.on('mark.focus.change', this, function(event, context, eventObject) {
-    	this.onFocusChange();
+        this.onFocusChange();
     });
     this.markControl.on('mark.step.change', this, this.onStepSelect);
     this.markControl.on('key.press', this, function(e, context, event) {
@@ -104,13 +105,19 @@ function MarkBoard(option) {
             }
         }
     });
-
+    this.markControl.on('mark.setting.init', this, function(event, context, setting) {
+        var show = setting['score.board.show'];
+        if (show != undefined && show == true) {
+            self.showScoreBoard = true;
+        }
+    });
 }
 
 MarkBoard.prototype.init = function() {
+    var self = this;
     this.stepBoard = getDom(this.step_board_dom, this.markControl).appendTo(this.markControl.container.centerContent);
     this.stepBoard.height(this.markControl.container.centerContent.height());
-    
+
     this.stepBoard.selectiveHeader = this.stepBoard.find('#step-board-selective-header');
     this.stepBoard.stepHolder = this.stepBoard.find('.step-list');
     this.stepBoard.stepHolder.height(this.markControl.container.centerContent.height() - 120);
@@ -183,9 +190,15 @@ MarkBoard.prototype.init = function() {
     }
     this.scoreBoard.find('#score-board-close-button').click(this, function(event) {
         event.data.toggleScoreBoard(false);
+        self.markControl.trigger('mark.setting.change', {
+            'score.board.show': false
+        });
     });
     this.stepBoard.find('#show-score-board-button').click(this, function(event) {
         event.data.toggleScoreBoard(true);
+        self.markControl.trigger('mark.setting.change', {
+            'score.board.show': true
+        });
     });
     this.scoreBoard.find('.all-zero-button').click(this, function(event) {
         event.data.allZeroSubmit();
@@ -528,7 +541,7 @@ MarkBoard.prototype.render = function(task) {
                 markBoard.onScoreSubmit();
             }
         });
-        
+
         this.stepBoard.stepHolder.scrollTop(0);
     } else {
         this.initMarkBoardHeader();
@@ -649,7 +662,7 @@ MarkBoard.prototype.togglePopover = function(show, text, baseDom) {
 }
 
 MarkBoard.prototype.onFocusChange = function() {
-	this.currentStep = null;
+    this.currentStep = null;
 }
 
 MarkBoard.prototype.step_board_dom = '<div class="span2 mark-steps" style="display:none"><div class="step-board">\

+ 51 - 41
stmms-web/src/main/webapp/static/mark-new/js/modules/single-image-view.js

@@ -39,12 +39,12 @@ function SingleImageView(option) {
         this.image = undefined;
         this.render();
     });
-    this.markControl.on('mark.tag.show', this, function(event, context, tag){
-        if(this.task != undefined && tag != undefined){
-        	this.drawTag(tag);
+    this.markControl.on('mark.tag.show', this, function(event, context, tag) {
+        if (this.task != undefined && tag != undefined) {
+            this.drawTag(tag);
         }
     });
-    this.markControl.on('mark.tag.clear', this, function(event, context, track){
+    this.markControl.on('mark.tag.clear', this, function(event, context, track) {
         this.reloadImage();
         this.markControl.trigger('image.reload.event');
     });
@@ -53,37 +53,45 @@ function SingleImageView(option) {
             this.updateScrollTop(topPercent);
         }
     });
+    this.markControl.on('mark.setting.init', this, function(event, context, setting) {
+        var scale = setting['image.view.scale'];
+        if (scale != undefined) {
+            this.scale = Number(scale);
+        }
+    });
 }
 
 SingleImageView.prototype.init = function() {
     var self = this;
     this.container = this.markControl.container.imageContent;
     this.container.height(this.markControl.container.centerContent.height());
-    this.container.css('overflow','scroll');
-    
+    this.container.css('overflow', 'scroll');
+
     this.canvas = $('<canvas></canvas>').appendTo(this.container)[0];
     this.ctx = this.canvas.getContext("2d");
-    
-    $(this.canvas).click(function(event){
-        if(self.task != undefined){
-        	self.markControl.trigger('image.click.event', {
-        		positionX: ((event.pageX - $(self.canvas).offset().left)/$(self.canvas).width()).toFixed(3),
-                positionY: ((event.pageY - $(self.canvas).offset().top)/$(self.canvas).height()).toFixed(3)
-        	});
+    this.ctx.fillStyle = "#FFFFFF";
+    this.scale = 1.0;
+
+    $(this.canvas).click(function(event) {
+        if (self.task != undefined) {
+            self.markControl.trigger('image.click.event', {
+                positionX: ((event.pageX - $(self.canvas).offset().left) / $(self.canvas).width()).toFixed(3),
+                positionY: ((event.pageY - $(self.canvas).offset().top) / $(self.canvas).height()).toFixed(3)
+            });
         }
     });
-    
+
     this.imageControl = getDom(this.image_control_dom, this.markControl).insertBefore(this.markControl.container.assistantButton.parent());
     this.imageControl.find('.zoom-out-button').click(this, function(event) {
-    	self.reloadImage(0.2);
+        self.reloadImage(0.2);
         self.markControl.trigger('image.reload.event');
     });
     this.imageControl.find('.zoom-in-button').click(this, function(event) {
-    	self.reloadImage(-0.2);
+        self.reloadImage(-0.2);
         self.markControl.trigger('image.reload.event');
     });
     this.imageControl.find('.zoom-fit-button').click(this, function(event) {
-    	self.reloadImage();
+        self.reloadImage();
         self.markControl.trigger('image.reload.event');
     });
 }
@@ -95,42 +103,44 @@ SingleImageView.prototype.render = function() {
         //设置画布大小及背景颜色
         this.image = new Image();
         this.image.src = this.task.imageData;
-        this.image.scale = 1.0;
-        this.image.onload = function(){
-            self.canvas.width = Math.min(self.container.width(), self.image.width);
-            self.canvas.height = self.canvas.width * self.image.height / self.image.width;
-            self.ctx.fillStyle = "#FFFFFF";
-            self.ctx.drawImage(self.image, 0, 0, self.image.width, self.image.height, 0, 0, self.canvas.width, self.canvas.height);
+        this.image.onload = function() {
+            self.reloadImage();
             $(self.canvas).show();
-            
+
             self.markControl.trigger('task.load.finish');
         }
     }
 }
 
-SingleImageView.prototype.reloadImage = function(scale) {
-    if(this.image != undefined){
-    	if(scale != undefined){
-    		this.image.scale = this.image.scale + scale;
-    		if(this.image.scale < 0.2){
-    			this.image.scale = 0.2;
-    		}else if(this.image.scale > 3){
-    			this.image.scale = 3;
-    		}
-    	}else{
-    		this.image.scale = 1.0;
-    	}
-    	this.canvas.width = Math.min(this.container.width(), this.image.width) * this.image.scale;
+SingleImageView.prototype.reloadImage = function(scaleAddon) {
+    if (this.image != undefined) {
+        var scale = 1.0
+        if (scaleAddon != undefined) {
+            scale += scaleAddon;
+        }
+        if (scale < 0.2) {
+            scale = 0.2;
+        } else if (scale > 3) {
+            scale = 3;
+        }
+        if (scale != this.scale) {
+            this.markControl.trigger('mark.setting.change', {
+                'image.view.scale': scale
+            });
+            this.scale = scale;
+        }
+
+        this.canvas.width = Math.min(this.container.width(), this.image.width) * this.scale;
         this.canvas.height = this.canvas.width * this.image.height / this.image.width;
         this.ctx.drawImage(this.image, 0, 0, this.image.width, this.image.height, 0, 0, this.canvas.width, this.canvas.height);
     }
 }
 
-SingleImageView.prototype.drawTag = function(tag){
-    if(tag!=undefined && tag.positionX>0 && tag.positionY>0 && this.image!=undefined){
-        this.ctx.font = parseInt(60 * this.image.scale) + "px Arial";
+SingleImageView.prototype.drawTag = function(tag) {
+    if (tag != undefined && tag.positionX > 0 && tag.positionY > 0 && this.image != undefined) {
+        this.ctx.font = parseInt(60 * this.scale) + "px Arial";
         this.ctx.fillStyle = 'red';
-        this.ctx.fillText(tag.content, tag.positionX*this.canvas.width, tag.positionY*this.canvas.height);
+        this.ctx.fillText(tag.content, tag.positionX * this.canvas.width, tag.positionY * this.canvas.height);
     }
 }
 

+ 29 - 15
stmms-web/src/main/webapp/static/mark-new/js/modules/thumbnail.js

@@ -1,11 +1,13 @@
 //给分板模块
-var thumbnail = function (option, success) {
+var thumbnail = function(option, success) {
     var object = new Thumbnail(option);
     success();
     return object;
 }
 
 function Thumbnail(option) {
+    var self = this;
+
     this.markControl = option.markControl;
     this.maxWidth = option.width != undefined ? option.width : 100;
     this.show = false;
@@ -14,17 +16,23 @@ function Thumbnail(option) {
     this.mousePosition = undefined;
 
     this.init();
-    this.markControl.on('task.get.before', this, function (event, context, eventObject) {
+    this.markControl.on('task.get.before', this, function(event, context, eventObject) {
         this.task = undefined;
         this.render();
     });
-    this.markControl.on('task.get.success', this, function (event, context, eventObject) {
+    this.markControl.on('task.get.success', this, function(event, context, eventObject) {
         this.task = context.task;
         this.render();
     });
+    this.markControl.on('mark.setting.init', this, function(event, context, setting) {
+        var show = setting['thumbnail.show'];
+        if (show != undefined && show == true) {
+            self.toggle(true);
+        }
+    });
 }
 
-Thumbnail.prototype.init = function () {
+Thumbnail.prototype.init = function() {
     var self = this;
     this.container = getDom(this.container_dom, this.markControl).appendTo(this.markControl.container);
     this.container.width(this.maxWidth);
@@ -40,13 +48,13 @@ Thumbnail.prototype.init = function () {
     this.container.content.width('100%');
     this.imageObject = this.container.content.find('img');
     this.imageObject.width('100%');
-    this.imageObject.bind('mouseover', function (e) {
+    this.imageObject.bind('mouseover', function(e) {
         self.updatePosition(e);
-    }).bind('mousemove', function (e) {
+    }).bind('mousemove', function(e) {
         self.updatePosition(e);
-    }).bind('mouseout', function (e) {
+    }).bind('mouseout', function(e) {
         self.updatePosition();
-    }).bind('click', function () {
+    }).bind('click', function() {
         if (self.show == true && self.task != undefined && self.mousePosition != undefined) {
             self.markControl.trigger('image.position.change', self.mousePosition.y / self.imageObject.height())
         }
@@ -55,27 +63,33 @@ Thumbnail.prototype.init = function () {
     this.container.draggable({
         containment: "window"
     });
-    this.container.header.find('#close-button').click(function () {
+    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-thumbnail-button').click(function () {
+    this.control.find('#show-thumbnail-button').click(function() {
         self.markControl.container.assistant.hide();
         self.toggle(true);
+        self.markControl.trigger('mark.setting.change', {
+            'thumbnail.show': true
+        });
     });
-    this.control.find('#hide-thumbnail-button').click(function () {
+    this.control.find('#hide-thumbnail-button').click(function() {
         self.markControl.container.assistant.hide();
         self.toggle(false);
+        self.markControl.trigger('mark.setting.change', {
+            'thumbnail.show': false
+        });
     });
 }
 
-Thumbnail.prototype.render = function () {
+Thumbnail.prototype.render = function() {
     var self = this;
     var imageObject = this.imageObject;
     if (this.task != undefined) {
         imageObject[0].src = this.task.imageData;
-        imageObject[0].onload = function () {
+        imageObject[0].onload = function() {
             if (imageObject[0].height > (self.markControl.container.height() * 0.8)) {
                 self.container.content.height(self.markControl.container.height() * 0.8);
             } else {
@@ -89,7 +103,7 @@ Thumbnail.prototype.render = function () {
     }
 }
 
-Thumbnail.prototype.toggle = function (show) {
+Thumbnail.prototype.toggle = function(show) {
     if (show == true) {
         this.show = true;
         this.container.show();
@@ -99,7 +113,7 @@ Thumbnail.prototype.toggle = function (show) {
     }
 }
 
-Thumbnail.prototype.updatePosition = function (e) {
+Thumbnail.prototype.updatePosition = function(e) {
     var position = this.imageObject.offset();
     this.mousePosition = e != undefined ? {
         x: e.pageX - position.left,

+ 12 - 0
stmms-web/src/main/webapp/static/mark-new/js/modules/view-sidebar.js

@@ -39,11 +39,23 @@ ViewSidebar.prototype.init = function() {
         this.toggleButton = getDom(this.toggle_button_dom, this.markControl).appendTo(this.markControl.container.assistant.functionList);
         this.toggleButton.click(this, function(event) {
             self.toggle(true);
+            self.markControl.trigger('mark.setting.change', {
+                'view.sidebar.open': true
+            });
         });
     }
 
     this.container.find('#view-close-button').click(this, function(event) {
         self.toggle(false);
+        self.markControl.trigger('mark.setting.change', {
+            'view.sidebar.open': false
+        });
+    });
+    this.markControl.on('mark.setting.init', this, function(event, context, setting) {
+        var open = setting['view.sidebar.open'];
+        if (open != undefined && open == true) {
+            self.toggle(true);
+        }
     });
 }
 

+ 95 - 46
stmms-web/src/main/webapp/static/mark-track/js/mark-control.js

@@ -18,10 +18,12 @@ function MarkControl(option) {
     this.initTriggers(option);
     // 初始化功能模块
     this.initModules(option);
+    //初始化评卷配置
+    this.initSetting(option);
     // 初始化成功回调方法
     // console.log('MarkControl init success!');
     // if (option.success != undefined && typeof(option.success) == 'function')
-	// {
+    // {
     // option.success();
     // }
 }
@@ -39,10 +41,10 @@ MarkControl.prototype.initContainer = function() {
     }
     this.container.center = getDom(this.center_dom, this).appendTo(this.container);
     this.container.header = getDom(this.center_header_dom, this).appendTo(this.container.center).find('.header');
-    if(this.option.switchCommonUrl!=undefined && this.option.switchCommonUrl.length>0){
-    	var switchButton = this.container.header.find('#switch-common-button');
-    	switchButton.attr('href', this.option.switchCommonUrl);
-    	switchButton.show();
+    if (this.option.switchCommonUrl != undefined && this.option.switchCommonUrl.length > 0) {
+        var switchButton = this.container.header.find('#switch-common-button');
+        switchButton.attr('href', this.option.switchCommonUrl);
+        switchButton.show();
     }
     this.container.centerContainer = getDom(this.center_content_dom, this).appendTo(this.container.center);
     this.container.centerContent = this.container.centerContainer.find('.image-content');
@@ -92,29 +94,74 @@ MarkControl.prototype.initMarkFunction = function() {
     }
 }
 
-MarkControl.prototype.addNavGroup = function(title, content){
+MarkControl.prototype.addNavGroup = function(title, content) {
     var self = this;
     self.navNumber++;
-    var nav = $('<a href="#"><span>'+title+'</span></a>').appendTo(self.container.centerNavbar);
+    var nav = $('<a href="#"><span>' + title + '</span></a>').appendTo(self.container.centerNavbar);
     nav.attr('data-number', self.navNumber);
     content.attr('data-number', self.navNumber);
-    nav.click(function(){
+    nav.click(function() {
         self.container.centerNavbar.find('a').removeClass('selected');
         $(this).addClass('selected');
-        
-        for(var i in self.container.centerList){
-        	var dom = self.container.centerList[i];
-        	if(dom.attr('data-number')==$(this).attr('data-number')){
-        		dom.show();
-        	}else{
-        		dom.hide();
-        	}
+
+        for (var i in self.container.centerList) {
+            var dom = self.container.centerList[i];
+            if (dom.attr('data-number') == $(this).attr('data-number')) {
+                dom.show();
+            } else {
+                dom.hide();
+            }
         }
     });
     self.container.centerList.push(content);
     return nav;
 }
 
+
+MarkControl.prototype.initSetting = function(option) {
+    this.userId = option.userId;
+    this.settingSyncUrl = option.settingSyncUrl;
+    this.localStore = window.localStorage;
+    this.setting = {};
+
+    if (option.defaultSetting != undefined) {
+        //读取外部初始化配置
+        this.setting = JSON.parse(option.defaultSetting);
+    } else if (this.localStore != undefined) {
+        //读取本地存储并判断用户标识
+        var store = JSON.parse(this.localStore.getItem('mark.setting'));
+        if (store != undefined && store.userId != undefined && store.userId == this.userId) {
+            this.setting = store.setting;
+        }
+    }
+    //强制刷新本地存储
+    this.localSettingSave();
+    //广播通知所有模块初始化设置
+    this.trigger('mark.setting.init', this.setting);
+}
+
+MarkControl.prototype.localSettingSave = function() {
+    if (this.localStore != undefined) {
+        this.localStore.setItem('mark.setting', JSON.stringify({
+            userId: this.userId,
+            setting: this.setting
+        }));
+    }
+}
+
+MarkControl.prototype.updateSetting = function(item) {
+    if (item == undefined) {
+        return;
+    }
+    for (var key in item) {
+        this.setting[key] = item[key];
+    }
+    this.localSettingSave();
+    if (this.syncUrl != undefined) {
+
+    }
+}
+
 // 增加某个事件的监听方法
 MarkControl.prototype.on = function(eventName, caller, callback, async) {
     if (eventName && callback && eventName.length > 0 && typeof(callback) == 'function') {
@@ -186,12 +233,11 @@ MarkControl.prototype.initTriggers = function(option) {
     });
     this.on('task.load.finish', this, function(event, context, eventObject) {
         self.container.centerNavbar.find('a:first').trigger('click');
-        if(context.task!=undefined){
-        	context.task.spent = new Date().getTime();
+        if (context.task != undefined) {
+            context.task.spent = new Date().getTime();
         }
     });
-    this.on('mark.focus.change', this, function(event, context, eventObject) {
-    });
+    this.on('mark.focus.change', this, function(event, context, eventObject) {});
     this.on('task.get.finish', this, function(event, context, eventObject) {
         context.prefetchCallback = undefined;
     });
@@ -253,6 +299,9 @@ MarkControl.prototype.initTriggers = function(option) {
         context.task = undefined;
         self.getTask();
     });
+    this.on('mark.setting.change', this, function(event, context, eventObject) {
+        self.updateSetting(eventObject);
+    });
 
     $(document).keypress(this, function(event) {
         if (self.context.listenKeyboard != false) {
@@ -506,33 +555,33 @@ MarkControl.prototype.submitTask = function(submitUrl) {
     var submitUrl = submitUrl != undefined && submitUrl.length > 0 ? submitUrl : this.option.submitUrl;
 
     if (task != undefined && this.context.submitting != true) {
-		//开启强制标记
-        if(this.option.forceSpecialTag===true){
-        	var isTag = !(task.tagList==undefined ||task.tagList==null ||task.tagList.length <= 0);
-        	var isTrack = false;
-        	for(var i in task.trackList) {
-        		var track = task.trackList[i];
-        		if(track.positionX!=0 || track.positionY!=0 ){
-        			isTrack = true;
-        		}
-        	}
-        	if(!(isTag||isTrack)){
-        		markControl.trigger('task.submit.forceSpecialTag', '强制标记已开启,至少使用一个标记');
-        		return;
-        	}
-        }
-        
+        //开启强制标记
+        if (this.option.forceSpecialTag === true) {
+            var isTag = !(task.tagList == undefined || task.tagList == null || task.tagList.length <= 0);
+            var isTrack = false;
+            for (var i in task.trackList) {
+                var track = task.trackList[i];
+                if (track.positionX != 0 || track.positionY != 0) {
+                    isTrack = true;
+                }
+            }
+            if (!(isTag || isTrack)) {
+                markControl.trigger('task.submit.forceSpecialTag', '强制标记已开启,至少使用一个标记');
+                return;
+            }
+        }
+
         var submitObj = {
-        	statusValue: task.statusValue,
-        	studentId: task.studentId,
-        	libraryId: task.libraryId,
-        	totalScore: task.totalScore,
-        	scoreList: task.scoreList,
-        	trackList: task.trackList,
-        	tagList: task.tagList,
-        	spent: new Date().getTime() - task.spent
-        }
-        
+            statusValue: task.statusValue,
+            studentId: task.studentId,
+            libraryId: task.libraryId,
+            totalScore: task.totalScore,
+            scoreList: task.scoreList,
+            trackList: task.trackList,
+            tagList: task.tagList,
+            spent: new Date().getTime() - task.spent
+        }
+
         this.trigger('task.submit.before');
         this.trigger('mark.specialTag.before');
         if (this.taskControl != undefined) {

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

@@ -26,15 +26,21 @@ function SingleImageView(option) {
         this.image = undefined;
         this.render();
     });
-    this.markControl.on('mark.tag.show', this, function(event, context, tag){
-        if(this.task != undefined && tag != undefined){
-        	this.drawTag(tag);
+    this.markControl.on('mark.tag.show', this, function(event, context, tag) {
+        if (this.task != undefined && tag != undefined) {
+            this.drawTag(tag);
         }
     });
-    this.markControl.on('mark.tag.clear', this, function(event, context, track){
+    this.markControl.on('mark.tag.clear', this, function(event, context, track) {
         this.reloadImage();
         this.markControl.trigger('image.reload.event');
     });
+    this.markControl.on('mark.setting.init', this, function(event, context, setting) {
+        var scale = setting['image.view.scale'];
+        if (scale != undefined) {
+            this.scale = Number(scale);
+        }
+    });
 }
 
 SingleImageView.prototype.init = function() {
@@ -45,30 +51,32 @@ SingleImageView.prototype.init = function() {
     //    wheelSpeed: 20
     //});
     this.markControl.addNavGroup('答卷', this.container);
-    
+
     this.canvas = this.container.find('canvas')[0];
     this.ctx = this.canvas.getContext("2d");
-    
-    $(this.canvas).click(function(event){
-        if(self.task != undefined){
-        	self.markControl.trigger('image.click.event', {
-        		positionX: ((event.pageX - $(self.canvas).offset().left)/$(self.canvas).width()).toFixed(3),
-                positionY: ((event.pageY - $(self.canvas).offset().top)/$(self.canvas).height()).toFixed(3)
-        	});
+    this.ctx.fillStyle = "#FFFFFF";
+    this.scale = 1.0;
+
+    $(this.canvas).click(function(event) {
+        if (self.task != undefined) {
+            self.markControl.trigger('image.click.event', {
+                positionX: ((event.pageX - $(self.canvas).offset().left) / $(self.canvas).width()).toFixed(3),
+                positionY: ((event.pageY - $(self.canvas).offset().top) / $(self.canvas).height()).toFixed(3)
+            });
         }
     });
-    
+
     this.imageControl = getDom(this.image_control_dom, this.markControl).insertBefore(this.markControl.container.assistantButton.parent());
     this.imageControl.find('.zoom-out-button').click(this, function(event) {
-    	self.reloadImage(0.2);
+        self.reloadImage(0.2);
         self.markControl.trigger('image.reload.event');
     });
     this.imageControl.find('.zoom-in-button').click(this, function(event) {
-    	self.reloadImage(-0.2);
+        self.reloadImage(-0.2);
         self.markControl.trigger('image.reload.event');
     });
     this.imageControl.find('.zoom-fit-button').click(this, function(event) {
-    	self.reloadImage();
+        self.reloadImage();
         self.markControl.trigger('image.reload.event');
     });
 }
@@ -80,42 +88,44 @@ SingleImageView.prototype.render = function() {
         //设置画布大小及背景颜色
         this.image = new Image();
         this.image.src = this.task.imageData;
-        this.image.scale = 1.0;
-        this.image.onload = function(){
-            self.canvas.width = Math.min(self.container.width(), self.image.width);
-            self.canvas.height = self.canvas.width * self.image.height / self.image.width;
-            self.ctx.fillStyle = "#FFFFFF";
-            self.ctx.drawImage(self.image, 0, 0, self.image.width, self.image.height, 0, 0, self.canvas.width, self.canvas.height);
+        this.image.onload = function() {
+            self.reloadImage();
             $(self.canvas).show();
-            
+
             self.markControl.trigger('task.load.finish');
         }
     }
 }
 
-SingleImageView.prototype.reloadImage = function(scale) {
-    if(this.image != undefined){
-    	if(scale != undefined){
-    		this.image.scale = this.image.scale + scale;
-    		if(this.image.scale < 0.2){
-    			this.image.scale = 0.2;
-    		}else if(this.image.scale > 3){
-    			this.image.scale = 3;
-    		}
-    	}else{
-    		this.image.scale = 1.0;
-    	}
-    	this.canvas.width = Math.min(this.container.width(), this.image.width) * this.image.scale;
+SingleImageView.prototype.reloadImage = function(scaleAddon) {
+    if (this.image != undefined) {
+        var scale = 1.0
+        if (scaleAddon != undefined) {
+            scale += scaleAddon;
+        }
+        if (scale < 0.2) {
+            scale = 0.2;
+        } else if (scale > 3) {
+            scale = 3;
+        }
+        if (scale != this.scale) {
+            this.markControl.trigger('mark.setting.change', {
+                'image.view.scale': scale
+            });
+            this.scale = scale;
+        }
+
+        this.canvas.width = Math.min(this.container.width(), this.image.width) * this.image.scale;
         this.canvas.height = this.canvas.width * this.image.height / this.image.width;
         this.ctx.drawImage(this.image, 0, 0, this.image.width, this.image.height, 0, 0, this.canvas.width, this.canvas.height);
     }
 }
 
-SingleImageView.prototype.drawTag = function(tag){
-    if(tag != undefined && tag.positionX > 0 && tag.positionY > 0 && this.image!=undefined){
+SingleImageView.prototype.drawTag = function(tag) {
+    if (tag != undefined && tag.positionX > 0 && tag.positionY > 0 && this.image != undefined) {
         this.ctx.font = parseInt(60 * this.image.scale) + "px Arial";
         this.ctx.fillStyle = 'red';
-        this.ctx.fillText(tag.content, tag.positionX*this.canvas.width, tag.positionY*this.canvas.height);
+        this.ctx.fillText(tag.content, tag.positionX * this.canvas.width, tag.positionY * this.canvas.height);
     }
 }