ソースを参照

修改多媒体阅卷界面显示,包括loading效果,rich-text渲染工具等

luoshi 5 年 前
コミット
98b1d6ff64

+ 6 - 6
stmms-web/src/main/webapp/static/mark-json/js/json-loader.js

@@ -12,17 +12,17 @@ function JsonLoader(option) {
 
 JsonLoader.prototype.build = function (task, callback) {
     var self = this;
-    if (task != undefined && task.jsonUrl != undefined) {
+    if (task !== undefined && task.jsonUrl !== undefined) {
 //      TODO-测试代码,读取固定的json文件
-//    	var result ='[{"mainNumber": 2,"subNumber": 10,"body": {"sections": [{ "blocks":[{"type": "text","value": "我是题目我是题目我是题目"}]}]},"answer": {"sections": [{"blocks":[{"type": "image","value": "https://ecs-test-static.qmth.com.cn/oe-answer-file/3/8/20/3_8_20_15748452889591137.jpeg"},{"type": "audio","value": "https://ecs-test-static.qmth.com.cn/oe-answer-file/3/8/19/3_8_19_15748452552644264.mp3"}]}]},"studentAnswer": {"sections": [{"blocks":[{"type": "image","value": "https://ecs-test-static.qmth.com.cn/oe-answer-file/3/8/20/3_8_20_15748452889591137.jpeg"},{"type": "image","value": "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1582709869784&di=39683b1330bd09bebd93c95fe925ca70&imgtype=0&src=http%3A%2F%2Fn.sinaimg.cn%2Fsinacn10108%2F170%2Fw600h370%2F20190222%2Fd6de-htknpmh2595255.jpg"},{"type": "text","value": "我是答案答案daan"}]}]}}]';
-//    	task.jsonData = JSON.parse(result);
-//    	callback();
-    	var url = this.jsonServer + task.jsonUrl;
+//         var result = '[{"mainNumber": 2,"subNumber": 10,"body": {"sections": [{ "blocks":[{"type": "text","value": "我是题目我是题目我是题目"}]}]},"answer": {"sections": [{"blocks":[{"type": "image","value": "https://ecs-test-static.qmth.com.cn/oe-answer-file/3/8/20/3_8_20_15748452889591137.jpeg"}]},{"blocks":[{"type": "audio","value": "https://ecs-test-static.qmth.com.cn/oe-answer-file/3/8/19/3_8_19_15748452552644264.mp3"}]}]},"studentAnswer": {"sections": [{"blocks":[{"type": "image","value": "https://ecs-test-static.qmth.com.cn/oe-answer-file/3/8/20/3_8_20_15748452889591137.jpeg"},{"type": "image","value": "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1582709869784&di=39683b1330bd09bebd93c95fe925ca70&imgtype=0&src=http%3A%2F%2Fn.sinaimg.cn%2Fsinacn10108%2F170%2Fw600h370%2F20190222%2Fd6de-htknpmh2595255.jpg"},{"type": "text","value": "我是答案答案daan"}]}]}}]';
+//         task.jsonData = JSON.parse(result);
+//         callback();
+        var url = this.jsonServer + task.jsonUrl;
         $.get(url, function (result) {
             task.jsonData = result;
             callback();
         }).error(function () {
-        	console.log('json load error:'+url);
+            console.log('json load error:' + url);
             callback('json load error');
         });
     }

+ 73 - 40
stmms-web/src/main/webapp/static/mark-json/js/json-view.js

@@ -7,7 +7,6 @@ var json_view = function (option, success) {
 
 function JsonView(option) {
     this.markControl = option.markControl;
-    this.loading = false;
     this.init();
     this.markControl.on('step.board.show', this, function (event, context, eventObject) {
         this.container.removeClass('span12');
@@ -29,60 +28,94 @@ function JsonView(option) {
         this.task = undefined;
         this.render();
     });
-    this.markControl.on('mark.setting.init', this, function (event, context, setting) {
-        var scale = setting['image.view.scale'];
-        if (scale != undefined) {
-            this.scale = Number(scale);
-        }
-    });
 }
 
 JsonView.prototype.init = function () {
-    var self = this;
     this.container = this.markControl.container.imageContent;
-    this.container.empty();
     this.container.height(this.markControl.container.centerContent.height());
     this.container.css('overflow', 'scroll');
-    this.container.addClass('rich-text');
-    this.container.loading = getDom(this.loading_dom, this.markControl).appendTo(this.container);
+
+    this.holder = getDom(this.holder_dom, this.markControl).appendTo(this.container);
+    this.holder.empty();
 }
 
 JsonView.prototype.render = function () {
-    if (this.task != undefined && this.task.jsonData != undefined) {
-    	var questionNumberArr = new Array();
-    	for (var i in this.task.markStepList) {
-            var step = this.task.markStepList[i];
-            questionNumberArr[i] = step.questionNumber;
-        }
-    	
+    if (this.task !== undefined && this.task.jsonData !== undefined) {
+        let questionNumbers = {};
+        this.task.markStepList.forEach(step => {
+            questionNumbers[step.questionNumber] = true;
+        });
+
         let questions = this.task.jsonData || [];
         questions.forEach(question => {
             // 按题号过滤
-        	if(questionNumberArr.indexOf(question.mainNumber+"."+question.subNumber) == -1){
- 				return true; 
- 			}
- 		 	var questionTitle = '<span>题号:'+ question.mainNumber+'-'+question.subNumber +'<span><br/>';
- 			$(questionTitle).appendTo($(this.container)); 
- 			$("<span>题干:<span>"+renderRichText(question.body)).appendTo($(this.container));
-        	$("<span>考生答案:<span>"+renderRichText(question.studentAnswer,true)).appendTo(this.container);
-            $("<span>标准答案:<span>"+renderRichText(question.answer)).appendTo(this.container);
-        });
-        var viewer = new Viewer($('.image-content')[0], {
-        });
-        viewer.destroy();
-        viewer = new Viewer($('.image-content')[0], {
+            if (questionNumbers[question.mainNumber + "." + question.subNumber] === true) {
+                let numberTitle = {
+                    "blocks": [{
+                        "type": "text",
+                        "param": {"bold": true},
+                        "value": "题号:" + question.mainNumber + "-" + question.subNumber
+                    }]
+                };
+                let bodyTitle = {
+                    "blocks": [{
+                        "type": "text",
+                        "param": {"bold": true},
+                        "value": "题干:"
+                    }]
+                };
+                let answerTitle = {
+                    "blocks": [{
+                        "type": "text",
+                        "param": {"bold": true},
+                        "value": "考生答案:"
+                    }, {
+                        "type": "text",
+                        "param": {
+                            "italic": true,
+                            "danger": true
+                        },
+                        "value": "(字数统计:" + this.textCount(question.studentAnswer) + ")"
+                    }]
+                };
+                let standardTitle = {
+                    "blocks": [{
+                        "type": "text",
+                        "param": {"bold": true},
+                        "value": "标准答案:"
+                    }]
+                };
+                $(renderSection(numberTitle)).appendTo(this.holder);
+                $(renderSection(bodyTitle)).appendTo(this.holder);
+                $(renderRichText(question.body)).appendTo(this.holder);
+                $(renderSection(answerTitle)).appendTo(this.holder);
+                $(renderRichText(question.studentAnswer)).appendTo(this.holder);
+                $(renderSection(standardTitle)).appendTo(this.holder);
+                $(renderRichText(question.answer)).appendTo(this.holder);
+            }
         });
-        this.loading = false;
-        this.updateLoading();
+        if (this.viewer !== undefined) {
+            this.viewer.destroy();
+        }
+        this.viewer = new Viewer(this.container[0], {});
         this.markControl.trigger('task.load.finish');
+    } else {
+        this.holder.empty();
     }
 }
 
-JsonView.prototype.updateLoading = function() {
-    if (this.loading) {
-        this.container.find('#json-loading').show();
-    } else {
-        this.container.find('#json-loading').hide();
-    }
+JsonView.prototype.textCount = function (jsonBody) {
+    let sections = jsonBody.sections || [];
+    let count = 0;
+    sections.forEach(section => {
+        let blocks = section.blocks || [];
+        blocks.forEach(block => {
+            if (block.type === 'text' && block.value !== undefined) {
+                count += block.value.length;
+            }
+        });
+    });
+    return count;
 }
-JsonView.prototype.loading_dom = '<div id="json-loading"><img src="{staticServer}/mark-new/images/loding.gif"/><p>正在加载请稍候</p></div>';
+
+JsonView.prototype.holder_dom = '<div class="rich-text"></div>';

+ 91 - 89
stmms-web/src/main/webapp/static/mark-new/js/mark-control.js

@@ -27,7 +27,7 @@ function MarkControl(option) {
     //}
 }
 
-MarkControl.prototype.initContainer = function() {
+MarkControl.prototype.initContainer = function () {
 
     var height = this.option.height;
     if (height == undefined) {
@@ -58,13 +58,13 @@ MarkControl.prototype.initContainer = function() {
     this.navNumber = 0;
 }
 
-MarkControl.prototype.initHeaderAndAssistant = function() {
+MarkControl.prototype.initHeaderAndAssistant = function () {
     var self = this;
     this.container.header.find('#mark-user-name').html(this.option.userName);
     if (this.option.logoutTitle != undefined) {
         this.container.header.find('#logout-title').html(this.option.logoutTitle);
     }
-    this.container.header.find('#logout-link').click(function() {
+    this.container.header.find('#logout-link').click(function () {
         self.trigger('logout.link.click');
         return true;
     })
@@ -73,7 +73,7 @@ MarkControl.prototype.initHeaderAndAssistant = function() {
     this.container.assistant.positionSet = false;
     this.container.assistantButton = this.container.header.find('#assistant-button');
 
-    this.container.assistantButton.click(this, function(event) {
+    this.container.assistantButton.click(this, function (event) {
         if (self.container.assistant.positionSet == false) {
             self.container.assistant.offset({
                 top: self.container.assistantButton.position().top + self.container.assistantButton.height() + 5,
@@ -86,7 +86,7 @@ MarkControl.prototype.initHeaderAndAssistant = function() {
 
 }
 
-MarkControl.prototype.initMarkFunction = function() {
+MarkControl.prototype.initMarkFunction = function () {
     var functionList = this.container.assistant.functionList;
     if (functionList == undefined) {
         functionList = getDom(this.mark_function_dom, this).appendTo(this.container.assistant).find('#function-list');
@@ -94,7 +94,7 @@ MarkControl.prototype.initMarkFunction = function() {
     }
 }
 
-MarkControl.prototype.initSetting = function(option) {
+MarkControl.prototype.initSetting = function (option) {
     this.userId = option.userId;
     this.settingSyncUrl = option.settingSyncUrl;
     this.settingSyncing = false;
@@ -117,7 +117,7 @@ MarkControl.prototype.initSetting = function(option) {
     this.trigger('mark.setting.init', this.setting);
 }
 
-MarkControl.prototype.localSettingSave = function() {
+MarkControl.prototype.localSettingSave = function () {
     if (this.localStore != undefined) {
         this.localStore.setItem('mark.setting', JSON.stringify({
             userId: this.userId,
@@ -126,7 +126,7 @@ MarkControl.prototype.localSettingSave = function() {
     }
 }
 
-MarkControl.prototype.updateSetting = function(item) {
+MarkControl.prototype.updateSetting = function (item) {
     if (item == undefined) {
         return;
     }
@@ -137,7 +137,7 @@ MarkControl.prototype.updateSetting = function(item) {
     if (this.settingSyncUrl != undefined && this.settingSyncing == false) {
         this.settingSyncing = true;
         var self = this;
-        setTimeout(function() {
+        setTimeout(function () {
             //同步个性化设置
             $.post(self.settingSyncUrl, {
                 setting: JSON.stringify(self.setting)
@@ -148,8 +148,8 @@ MarkControl.prototype.updateSetting = function(item) {
 }
 
 //增加某个事件的监听方法
-MarkControl.prototype.on = function(eventName, caller, callback, async) {
-    if (eventName && callback && eventName.length > 0 && typeof(callback) == 'function') {
+MarkControl.prototype.on = function (eventName, caller, callback, async) {
+    if (eventName && callback && eventName.length > 0 && typeof (callback) == 'function') {
         if (async) {
             this.container.bind(eventName, callback);
         } else {
@@ -165,7 +165,7 @@ MarkControl.prototype.on = function(eventName, caller, callback, async) {
 }
 
 //触发某个事件,并传递事件相关内容
-MarkControl.prototype.trigger = function(eventName, eventObject) {
+MarkControl.prototype.trigger = function (eventName, eventObject) {
     var result = true;
     if (eventName && eventName.length > 0) {
         var array = this.triggers[eventName];
@@ -183,7 +183,7 @@ MarkControl.prototype.trigger = function(eventName, eventObject) {
 }
 
 //初始化事件监听
-MarkControl.prototype.initTriggers = function(option) {
+MarkControl.prototype.initTriggers = function (option) {
     if (this.triggers == undefined) {
         this.triggers = {};
     }
@@ -194,7 +194,7 @@ MarkControl.prototype.initTriggers = function(option) {
     }
 
     var self = this;
-    this.on('view.sidebar.open', this, function(event, context, eventObject) {
+    this.on('view.sidebar.open', this, function (event, context, eventObject) {
         this.container.assistant.hide();
         if (this.container.center.hasClass('span12')) {
             this.container.center.removeClass('span12');
@@ -205,7 +205,7 @@ MarkControl.prototype.initTriggers = function(option) {
         }
         this.trigger('center.width.change');
     });
-    this.on('view.sidebar.close', this, function(event, context, eventObject) {
+    this.on('view.sidebar.close', this, function (event, context, eventObject) {
         this.container.assistant.hide();
         if (this.container.center.hasClass('span7')) {
             this.container.center.removeClass('span7');
@@ -216,7 +216,7 @@ MarkControl.prototype.initTriggers = function(option) {
         }
         this.trigger('center.width.change');
     });
-    this.on('mark.sidebar.open', this, function(event, context, eventObject) {
+    this.on('mark.sidebar.open', this, function (event, context, eventObject) {
         this.container.assistant.hide();
         if (this.container.center.hasClass('span12')) {
             this.container.center.removeClass('span12');
@@ -227,7 +227,7 @@ MarkControl.prototype.initTriggers = function(option) {
         }
         this.trigger('center.width.change');
     });
-    this.on('mark.sidebar.close', this, function(event, context, eventObject) {
+    this.on('mark.sidebar.close', this, function (event, context, eventObject) {
         this.container.assistant.hide();
         if (this.container.center.hasClass('span10')) {
             this.container.center.removeClass('span10');
@@ -238,68 +238,70 @@ MarkControl.prototype.initTriggers = function(option) {
         }
         this.trigger('center.width.change');
     });
-    this.on('task.load.finish', this, function(event, context, eventObject) {
+    this.on('task.load.finish', this, function (event, context, eventObject) {
         if (context.task != undefined) {
             context.task.spent = new Date().getTime();
         }
     });
-    this.on('mark.focus.change', this, function(event, context, eventObject) {});
-    this.on('task.get.finish', 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;
     });
-    this.on('task.get.none', this, function(event, context, eventObject) {
+    this.on('task.get.none', this, function (event, context, eventObject) {
         self.getStatus();
         if (context.task == undefined && self.option.clearUrl != undefined) {
-            $.post(self.option.clearUrl, {}, function() {});
+            $.post(self.option.clearUrl, {}, function () {
+            });
         }
-        context.prefetchCallback = function() {
+        context.prefetchCallback = function () {
             context.prefetchCallback = undefined;
             if (self.context.task == undefined && self.context.prefetchTask.length > 0) {
                 self.getTask();
             }
         }
     });
-    this.on('task.prefetch.success', this, function(event, context, eventObject) {
+    this.on('task.prefetch.success', this, function (event, context, eventObject) {
         if (context.prefetchCallback != undefined) {
             context.prefetchCallback();
         }
-        setTimeout(function() {
+        setTimeout(function () {
             self.prefetch();
         }, 500);
     });
-    this.on('task.prefetch.error', this, function(event, context, eventObject) {
-        setTimeout(function() {
+    this.on('task.prefetch.error', this, function (event, context, eventObject) {
+        setTimeout(function () {
             self.prefetch();
         }, 500);
     });
-    this.on('task.prefetch.none', this, function(event, context, eventObject) {
+    this.on('task.prefetch.none', this, function (event, context, eventObject) {
         if (context.prefetchCallback != undefined) {
             context.prefetchCallback();
         }
         if (context.isFinish != true) {
-            setTimeout(function() {
+            setTimeout(function () {
                 self.prefetch();
             }, 1000);
         }
     });
-    this.on('task.prefetch.finish', this, function(event, context, eventObject) {
+    this.on('task.prefetch.finish', this, function (event, context, eventObject) {
         self.getTask();
     });
-    this.on('task.submit.before', this, function(event, context, eventObject) {
+    this.on('task.submit.before', this, function (event, context, eventObject) {
         context.submitting = true;
     });
-    this.on('history.submit.success', this, function(event, context, eventObject) {
+    this.on('history.submit.success', this, function (event, context, eventObject) {
         context.submitting = false;
     });
-    this.on('task.submit.success', this, function(event, context, eventObject) {
+    this.on('task.submit.success', this, function (event, context, eventObject) {
         context.submitting = false;
         context.task = undefined;
         self.getTask();
     });
-    this.on('task.submit.error', this, function(event, context, eventObject) {
+    this.on('task.submit.error', this, function (event, context, eventObject) {
         context.submitting = false;
     });
-    this.on('task.pass.success', this, function(event, context, eventObject) {
+    this.on('task.pass.success', this, function (event, context, eventObject) {
         if (context.task != undefined && self.option.clearUrl != undefined) {
             $.post(self.option.clearUrl, {
                 libraryId: context.task.libraryId
@@ -308,26 +310,26 @@ MarkControl.prototype.initTriggers = function(option) {
         context.task = undefined;
         self.getTask();
     });
-    this.on('mark.setting.change', this, function(event, context, eventObject) {
+    this.on('mark.setting.change', this, function (event, context, eventObject) {
         self.updateSetting(eventObject);
     });
-    $(document).keypress(this, function(event) {
+    $(document).keypress(this, function (event) {
         if (self.context.listenKeyboard != false) {
             return self.trigger('key.press', event);
         }
     });
-    $(document).keydown(this, function(event) {
+    $(document).keydown(this, function (event) {
         if (self.context.listenKeyboard != false) {
             return self.trigger('key.down', event);
         }
     });
-    $(document).keyup(this, function(event) {
+    $(document).keyup(this, function (event) {
         if (self.context.listenKeyboard != false) {
             return self.trigger('key.up', event);
         }
     });
 
-    window.onbeforeunload = function(e) {
+    window.onbeforeunload = function (e) {
         if (self.option.clearUrl != undefined) {
             $.post(self.option.clearUrl);
         }
@@ -335,7 +337,7 @@ MarkControl.prototype.initTriggers = function(option) {
 }
 
 //初始化功能模块
-MarkControl.prototype.initModules = function(option) {
+MarkControl.prototype.initModules = function (option) {
     if (this.modules == undefined) {
         this.modules = {};
     }
@@ -361,18 +363,18 @@ MarkControl.prototype.initModules = function(option) {
 }
 
 //指定初始化某个名称的模块
-MarkControl.prototype.initModule = function(names, options, success) {
+MarkControl.prototype.initModule = function (names, options, success) {
     for (var i in names) {
         var name = names[i];
         var option = options[name];
         var moduleInit = name.replace(/-/g, '_');
-        if (option == undefined || typeof(option) != 'object') {
+        if (option == undefined || typeof (option) != 'object') {
             option = {};
         }
         option.markControl = this;
         eval('this.modules[name]=' + moduleInit + '(option, function(){})');
     }
-    if (success != undefined && typeof(success) == 'function') {
+    if (success != undefined && typeof (success) == 'function') {
         success();
     }
 }
@@ -385,12 +387,12 @@ function initModuleAsync(markControl, names, index, option) {
         var moduleInit = name.replace(/-/g, '_');
         var modules = markControl.modules;
         if (modules[name] == undefined) {
-            if (typeof(moduleOption) != 'object') {
+            if (typeof (moduleOption) != 'object') {
                 moduleOption = {};
             }
             moduleOption.markControl = markControl;
-            $.getScript(moduleUrl, function() {
-                var success = function() {
+            $.getScript(moduleUrl, function () {
+                var success = function () {
                     initModule(markControl, names, index + 1, option);
                 }
                 eval('modules[name]=' + moduleInit + '(moduleOption, success)');
@@ -399,27 +401,27 @@ function initModuleAsync(markControl, names, index, option) {
             initModule(markControl, names, index + 1, option);
         }
     } else {
-        if (markControl.option.success != undefined && typeof(markControl.option.success) == 'function') {
+        if (markControl.option.success != undefined && typeof (markControl.option.success) == 'function') {
             markControl.option.success();
         }
     }
 }
 
-MarkControl.prototype.start = function(taskOption) {
+MarkControl.prototype.start = function (taskOption) {
     taskOption.markControl = this;
     var markControl = this;
-    taskOption.success = function() {
-        markControl.context.prefetchCallback = function() {
+    taskOption.success = function () {
+        markControl.context.prefetchCallback = function () {
             markControl.context.prefetchCallback = undefined;
             markControl.getTask();
         }
-        markControl.context.statusCallback = function() {
+        markControl.context.statusCallback = function () {
             markControl.context.statusCallback = undefined;
             markControl.prefetch();
         }
         markControl.getStatus();
     };
-    taskOption.error = function(message) {
+    taskOption.error = function (message) {
         alert('初始化失败,请刷新页面重新加载');
     };
     this.taskControl = new TaskControl(taskOption);
@@ -427,7 +429,7 @@ MarkControl.prototype.start = function(taskOption) {
 }
 
 //task预加载
-MarkControl.prototype.prefetch = function() {
+MarkControl.prototype.prefetch = function () {
     var taskControl = this.taskControl;
     var markControl = this;
     var context = this.context;
@@ -442,9 +444,9 @@ MarkControl.prototype.prefetch = function() {
             context.prefetching = true;
             markControl.trigger('task.prefetch.before');
 
-            taskControl.fetch(function(task) {
+            taskControl.fetch(function (task) {
                 if (imageBuilder != undefined) {
-                    imageBuilder.build(task, function(error) {
+                    imageBuilder.build(task, function (error) {
                         if (error) {
                             context.prefetching = false;
                             markControl.trigger('task.prefetch.error');
@@ -461,11 +463,11 @@ MarkControl.prototype.prefetch = function() {
                     context.prefetching = false;
                     markControl.trigger('task.prefetch.success');
                 }
-            }, function(task) {
+            }, function (task) {
                 context.prefetchStatus = task.message;
                 context.prefetching = false;
                 markControl.trigger('task.prefetch.none');
-            }, function() {
+            }, function () {
                 context.prefetching = false;
                 markControl.trigger('task.prefetch.none');
             });
@@ -475,12 +477,12 @@ MarkControl.prototype.prefetch = function() {
     }
 }
 
-MarkControl.prototype.getStatus = function() {
+MarkControl.prototype.getStatus = function () {
     if (this.taskControl == undefined) {
         return;
     }
     var self = this;
-    this.taskControl.status(function(status) {
+    this.taskControl.status(function (status) {
         self.context.status = status;
         if (status != undefined) {
             self.context.isFinish = status.blockTotalCount > 0 && status.blockTotalCount == (status.blockMarkedCount + status.blockExceptionCount);
@@ -492,7 +494,7 @@ MarkControl.prototype.getStatus = function() {
     })
 }
 
-MarkControl.prototype.getTask = function() {
+MarkControl.prototype.getTask = function () {
     if (this.taskControl == undefined) {
         return;
     }
@@ -523,20 +525,20 @@ MarkControl.prototype.getTask = function() {
     }
 }
 
-MarkControl.prototype.getHistory = function(data) {
+MarkControl.prototype.getHistory = function (data) {
     if (this.taskControl == undefined) {
         return;
     }
-    this.taskControl.history(data, function(result) {
+    this.taskControl.history(data, function (result) {
         data.result = result;
         this.option.markControl.trigger('history.get.success', data);
-    }, function(message) {
+    }, function (message) {
         data.message = message;
         this.option.markControl.trigger('history.get.error', data);
     });
 }
 
-MarkControl.prototype.setTask = function(task) {
+MarkControl.prototype.setTask = function (task) {
     var imageBuilder = this.modules['image-builder'];
     var self = this;
 
@@ -545,7 +547,7 @@ MarkControl.prototype.setTask = function(task) {
     }
     this.trigger('task.get.before');
     if (imageBuilder != undefined && task != undefined) {
-        imageBuilder.build(task, function(error) {
+        imageBuilder.build(task, function (error) {
             self.context.task = task;
             self.trigger('task.get.success');
         });
@@ -557,7 +559,7 @@ MarkControl.prototype.setTask = function(task) {
     }
 }
 
-MarkControl.prototype.submitTask = function(submitUrl) {
+MarkControl.prototype.submitTask = function (submitUrl) {
     var task = this.context.task;
     var markControl = this;
     var submitUrl = submitUrl != undefined && submitUrl.length > 0 ? submitUrl : this.option.submitUrl;
@@ -580,15 +582,15 @@ MarkControl.prototype.submitTask = function(submitUrl) {
             trackList: [],
             tagList: task.tagList,
             spent: new Date().getTime() - task.spent,
-            problem : task.problem,
-            reason : task.reason
+            problem: task.problem,
+            reason: task.reason
         }
 
         this.trigger('task.submit.before');
 
         if (this.taskControl != undefined) {
             //已定义任务引擎
-            this.taskControl.submit(submitObj, function(status) {
+            this.taskControl.submit(submitObj, function (status) {
                 if (status != undefined && status.valid == true) {
                     markControl.context.status = status;
                     markControl.trigger('mark.status.change', status);
@@ -598,7 +600,7 @@ MarkControl.prototype.submitTask = function(submitUrl) {
                 } else {
                     markControl.trigger('task.submit.success');
                 }
-            }, function(message) {
+            }, function (message) {
                 markControl.trigger('task.submit.error', message);
             });
         } else if (submitUrl != undefined && submitUrl.length > 0) {
@@ -609,14 +611,14 @@ MarkControl.prototype.submitTask = function(submitUrl) {
                 data: JSON.stringify(submitObj),
                 dataType: "json",
                 contentType: 'application/json;charset=utf-8',
-                success: function(result) {
+                success: function (result) {
                     if (result.success == true) {
                         markControl.trigger('task.submit.success');
                     } else {
                         markControl.trigger('task.submit.error', result.message);
                     }
                 },
-                error: function(message) {
+                error: function (message) {
                     markControl.trigger('task.submit.error', message);
                 }
             });
@@ -625,13 +627,13 @@ 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);
     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');
 
@@ -677,15 +679,15 @@ MarkControl.prototype.mark_function_dom = '<h3 class="popover-title" data-i18n-t
 </p></div>';
 
 //其他通用方法
-String.prototype.startWith = function(prefix) {
+String.prototype.startWith = function (prefix) {
     return this.indexOf(prefix) === 0;
 }
-String.prototype.endWith = function(suffix) {
+String.prototype.endWith = function (suffix) {
     return this.match(suffix + "$") == suffix;
 };
 
 //日期格式化
-Date.prototype.format = function(fmt) { //author: meizz 
+Date.prototype.format = function (fmt) { //author: meizz
     var o = {
         "M+": this.getMonth() + 1, //月份 
         "d+": this.getDate(), //日 
@@ -718,15 +720,15 @@ function getDom(content, markControl) {
         content = content.replace(/{logoutUrl}/g, markControl.option.logoutUrl);
     }
     var result = $(content);
-    result.find("[data-i18n-value]").each(function() {
-		$(this).val($.i18n.prop($(this).data("i18n-value")));
-	});
-    result.find("[data-i18n-text]").each(function() {
-		$(this).text($.i18n.prop($(this).data("i18n-text")));
-	});
-    result.find("[data-i18n-placeholder]").each(function() {
-		$(this).attr('placeholder',$.i18n.prop($(this).data("i18n-placeholder")));
-	});
+    result.find("[data-i18n-value]").each(function () {
+        $(this).val($.i18n.prop($(this).data("i18n-value")));
+    });
+    result.find("[data-i18n-text]").each(function () {
+        $(this).text($.i18n.prop($(this).data("i18n-text")));
+    });
+    result.find("[data-i18n-placeholder]").each(function () {
+        $(this).attr('placeholder', $.i18n.prop($(this).data("i18n-placeholder")));
+    });
     return result;
 }
 
@@ -734,6 +736,6 @@ function isArray(obj) {
     return obj != undefined && Object.prototype.toString.call(obj) === '[object Array]';
 }
 
-function getMessage(message) { 
-	return $.i18n.prop(message);
+function getMessage(message) {
+    return $.i18n.prop(message);
 }

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

@@ -1,5 +1,5 @@
 //给分板模块
-var mark_board = function(option, success) {
+var mark_board = function (option, success) {
     var object = new MarkBoard(option);
     success();
     return object;
@@ -14,25 +14,25 @@ function MarkBoard(option) {
     this.enableSkip = option.enableSkip === true ? true : false;
 
     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.stepList = undefined;
         this.currentStep = undefined;
         this.stepCount = undefined;
         this.render();
     });
-    this.markControl.on('task.load.finish', this, function(event, context, eventObject) {
+    this.markControl.on('task.load.finish', this, function (event, context, eventObject) {
         this.initByTask(context.task);
     });
-    this.markControl.on('history.submit.success', this, function(event, context, eventObject) {
+    this.markControl.on('history.submit.success', this, function (event, context, eventObject) {
         this.initByTask(context.task);
     });
-    this.markControl.on('mark.focus.change', this, function(event, context, eventObject) {
+    this.markControl.on('mark.focus.change', this, function (event, context, eventObject) {
         this.onFocusChange();
     });
     this.markControl.on('mark.step.change', this, this.onStepSelect);
-    this.markControl.on('key.press', this, function(e, context, event) {
+    this.markControl.on('key.press', this, function (e, context, event) {
         var code = event.keyCode;
         //console.log('key press:' + code);
         if (this.currentStep != undefined && this.task != undefined) {
@@ -63,7 +63,7 @@ function MarkBoard(option) {
             }
         }
     });
-    this.markControl.on('key.down', this, function(e, context, event) {
+    this.markControl.on('key.down', this, function (e, context, event) {
         var code = event.keyCode;
         //console.log('key down:' + code);
         if (this.currentStep != undefined && this.task != undefined) {
@@ -81,9 +81,9 @@ function MarkBoard(option) {
             }
         }
     });
-    this.markControl.on('key.up', this, function(e, context, event) {
+    this.markControl.on('key.up', this, function (e, context, event) {
         var code = event.keyCode;
-        console.log('key up:' + code);
+        //console.log('key up:' + code);
         if (this.currentStep != undefined && this.task != undefined) {
             if (code == 32) {
                 //空格键提交步骤分
@@ -109,7 +109,7 @@ function MarkBoard(option) {
             }
         }
     });
-    this.markControl.on('mark.setting.init', this, function(event, context, setting) {
+    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;
@@ -117,7 +117,7 @@ function MarkBoard(option) {
     });
 }
 
-MarkBoard.prototype.init = function() {
+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());
@@ -145,13 +145,13 @@ MarkBoard.prototype.init = function() {
         containment: "window"
     });
 
-    this.scoreBoard.find('#task-submit-button').click(this, function(event) {
+    this.scoreBoard.find('#task-submit-button').click(this, function (event) {
         var markBoard = event.data;
         if (markBoard.task != undefined && markBoard.currentStep.markFinish === true) {
             markBoard.onTaskSubmit();
         }
     });
-    this.scoreBoard.find('#resetBtn').click(this, function(event) {
+    this.scoreBoard.find('#resetBtn').click(this, function (event) {
         var markBoard = event.data;
         var selectedBlockId = $(".block-id-list  option:selected").val();
         if (markBoard.task != undefined) {
@@ -168,7 +168,7 @@ MarkBoard.prototype.init = function() {
             }
         }
     });
-    $('#resetBtn').click(this, function(event) {
+    $('#resetBtn').click(this, function (event) {
         var markBoard = event.data;
         var selectedBlockId = $(".block-id-list  option:selected").val();
         if (markBoard.task != undefined) {
@@ -187,27 +187,27 @@ MarkBoard.prototype.init = function() {
     });
     if (this.enableSkip) {
         this.scoreBoard.find('#task-pass-button').show();
-        this.scoreBoard.find('#task-pass-button').click(this, function(event) {
+        this.scoreBoard.find('#task-pass-button').click(this, function (event) {
             var markBoard = event.data;
             markBoard.markControl.trigger('task.pass.success');
         });
     }
-    this.scoreBoard.find('#score-board-close-button').click(this, function(event) {
+    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) {
+    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) {
+    this.scoreBoard.find('.all-zero-button').click(this, function (event) {
         event.data.allZeroSubmit();
     });
-    this.stepBoard.find('.all-zero-button').click(this, function(event) {
+    this.stepBoard.find('.all-zero-button').click(this, function (event) {
         event.data.allZeroSubmit();
     });
 
@@ -221,7 +221,7 @@ MarkBoard.prototype.init = function() {
     //this.popover.title.width('100');
 }
 
-MarkBoard.prototype.initByTask = function(task) {
+MarkBoard.prototype.initByTask = function (task) {
     this.task = task;
     this.stepList = task.markStepList;
     this.currentStep = undefined;
@@ -252,9 +252,9 @@ MarkBoard.prototype.initByTask = function(task) {
     }
 }
 
-MarkBoard.prototype.onDecimalInput = function() {
+MarkBoard.prototype.onDecimalInput = function () {
     var score = this.currentStep.score;
-    if ( !score.endWith('.')) {
+    if (!score.endWith('.')) {
         score = score + '.';
     }
     this.currentStep.score = score;
@@ -262,13 +262,13 @@ MarkBoard.prototype.onDecimalInput = function() {
     this.onScoreChange();
 }
 
-MarkBoard.prototype.onNumberInput = function(number) {
+MarkBoard.prototype.onNumberInput = function (number) {
     this.currentStep.score = this.currentStep.score + '' + number;
     this.currentStep.markFinish = false;
     this.onScoreChange();
 }
 
-MarkBoard.prototype.onNumberDelete = function(number) {
+MarkBoard.prototype.onNumberDelete = function (number) {
     var score = this.currentStep.score;
     if (score.length > 1) {
         score = score.substring(0, score.length - 1);
@@ -280,7 +280,7 @@ MarkBoard.prototype.onNumberDelete = function(number) {
     this.onScoreChange();
 }
 
-MarkBoard.prototype.onNumberSubmit = function() {
+MarkBoard.prototype.onNumberSubmit = function () {
     var score = this.currentStep.score;
     var interval = this.currentStep.interval;
     if (score.length > 0) {
@@ -301,7 +301,7 @@ MarkBoard.prototype.onNumberSubmit = function() {
 
 //切换步骤时,重置当前步骤的状态
 //若当前分数未提交,则还原之前已给的分数;若之前还未给分,则清空分数显示
-MarkBoard.prototype.resetCurrentStep = function() {
+MarkBoard.prototype.resetCurrentStep = function () {
     var step = this.currentStep;
     if (step != undefined) {
         if (step.markScore != undefined) {
@@ -315,7 +315,7 @@ MarkBoard.prototype.resetCurrentStep = function() {
     }
 }
 
-MarkBoard.prototype.onStepSelect = function(event, context, stepNumber) {
+MarkBoard.prototype.onStepSelect = function (event, context, stepNumber) {
     if (stepNumber <= this.stepCount && stepNumber > 0) {
         //还是点击当前步骤,不触发任何动作
         if (this.currentStep != undefined && this.currentStep.number == stepNumber) {
@@ -358,7 +358,7 @@ MarkBoard.prototype.onStepSelect = function(event, context, stepNumber) {
     }
 }
 
-MarkBoard.prototype.onScoreChange = function() {
+MarkBoard.prototype.onScoreChange = function () {
     if (this.currentStep != undefined) {
         var dom = this.stepBoard.stepArray[this.currentStep.number - 1];
         dom.find('.current-score').html(this.currentStep.score);
@@ -367,7 +367,7 @@ MarkBoard.prototype.onScoreChange = function() {
     }
 }
 
-MarkBoard.prototype.onScoreSubmit = function(autoNext) {
+MarkBoard.prototype.onScoreSubmit = function (autoNext) {
     if (this.currentStep != undefined) {
         this.currentStep.markScore = parseFloat(this.currentStep.score);
         this.currentStep.markFinish = true;
@@ -377,7 +377,7 @@ MarkBoard.prototype.onScoreSubmit = function(autoNext) {
         this.stepBoard.find('#total-score').html(this.task.totalScore);
         this.scoreBoard.footer.html(this.task.totalScore);
         var currentScore = this.currentStep.score;
-        this.scoreBoard.stepArray[this.currentStep.number - 1].find('.score-select').each(function(index, obj) {
+        this.scoreBoard.stepArray[this.currentStep.number - 1].find('.score-select').each(function (index, obj) {
             if ($(obj).attr('data-score') == currentScore) {
                 $(obj).addClass('active');
             } else {
@@ -393,7 +393,7 @@ MarkBoard.prototype.onScoreSubmit = function(autoNext) {
     }
 }
 
-MarkBoard.prototype.updateTotalScore = function() {
+MarkBoard.prototype.updateTotalScore = function () {
     if (this.task != undefined) {
         var totalScore = 0;
         var finish = true;
@@ -409,7 +409,7 @@ MarkBoard.prototype.updateTotalScore = function() {
     }
 }
 
-MarkBoard.prototype.allZeroSubmit = function() {
+MarkBoard.prototype.allZeroSubmit = function () {
     if (this.task != undefined && this.stepList != undefined && this.stepList.length > 0) {
         for (var i in this.stepList) {
             this.stepList[i].markScore = 0;
@@ -421,7 +421,7 @@ MarkBoard.prototype.allZeroSubmit = function() {
     }
 }
 
-MarkBoard.prototype.onTaskSubmit = function() {
+MarkBoard.prototype.onTaskSubmit = function () {
     var totalScore = 0;
     var scoreList = [];
     var finish = true;
@@ -446,7 +446,7 @@ MarkBoard.prototype.onTaskSubmit = function() {
     }
 }
 
-MarkBoard.prototype.validateScore = function(step, scoreString) {
+MarkBoard.prototype.validateScore = function (step, scoreString) {
     var stepDom = this.stepBoard.stepArray[this.currentStep.number - 1].find('.current-score');
     if (!$.isNumeric(scoreString)) {
         this.togglePopover(true, '不是合法数字', stepDom);
@@ -481,7 +481,7 @@ MarkBoard.prototype.validateScore = function(step, scoreString) {
     return true;
 }
 
-MarkBoard.prototype.render = function(task) {
+MarkBoard.prototype.render = function (task) {
     if (task != undefined) {
         var self = this;
         var title = task.blockTitle;
@@ -518,7 +518,7 @@ MarkBoard.prototype.render = function(task) {
             } else {
                 dom.addClass('todo');
             }
-            dom.click(function() {
+            dom.click(function () {
                 self.onStepSelect(undefined, undefined, $(this).attr('data-number'));
             })
             this.stepBoard.stepArray.push(dom.appendTo(this.stepBoard.stepHolder));
@@ -545,7 +545,7 @@ MarkBoard.prototype.render = function(task) {
         }
         this.toggleScoreBoard(this.showScoreBoard);
 
-        this.scoreBoard.find('.score-select').click(this, function(event) {
+        this.scoreBoard.find('.score-select').click(this, function (event) {
             var markBoard = event.data;
             if (markBoard.task != undefined) {
                 var object = $(event.target);
@@ -570,7 +570,7 @@ MarkBoard.prototype.render = function(task) {
     }
 }
 
-MarkBoard.prototype.initMarkBoardHeader = function() {
+MarkBoard.prototype.initMarkBoardHeader = function () {
     var self = this;
     if (this.task == undefined) {
         this.stepBoard.selectiveHeader.hide();
@@ -589,7 +589,7 @@ MarkBoard.prototype.initMarkBoardHeader = function() {
                     blockSelect.append('<option value="' + block.id + '" ' + selected + '>' + block.title + '</option>');
                 }
             }
-            blockSelect.change(function() {
+            blockSelect.change(function () {
                 self.onBlockChange($(this).val());
             });
 
@@ -605,7 +605,7 @@ MarkBoard.prototype.initMarkBoardHeader = function() {
                 }
             }
             blockSelect.unbind();
-            blockSelect.change(function() {
+            blockSelect.change(function () {
                 self.onBlockChange($(this).val());
             });
             this.stepBoard.selectiveHeader.show();
@@ -616,7 +616,7 @@ MarkBoard.prototype.initMarkBoardHeader = function() {
     }
 }
 
-MarkBoard.prototype.toggleScoreBoard = function(show) {
+MarkBoard.prototype.toggleScoreBoard = function (show) {
     this.resetCurrentStep();
     if (show) {
         this.markControl.trigger('step.board.hide');
@@ -631,7 +631,7 @@ MarkBoard.prototype.toggleScoreBoard = function(show) {
     }
 }
 
-MarkBoard.prototype.onBlockChange = function(blockId) {
+MarkBoard.prototype.onBlockChange = function (blockId) {
     if (this.task != undefined && this.task.selectiveGroup != undefined) {
         this.task.blockId = parseInt(blockId);
         this.task.totalScore = 0;
@@ -653,7 +653,7 @@ MarkBoard.prototype.onBlockChange = function(blockId) {
     }
 }
 
-MarkBoard.prototype.togglePopover = function(show, text, baseDom) {
+MarkBoard.prototype.togglePopover = function (show, text, baseDom) {
     var popover = this.popover;
     if (show == true && baseDom != undefined) {
         //console.log(baseDom.offset().top + ',' + baseDom.offset().left);
@@ -674,7 +674,7 @@ MarkBoard.prototype.togglePopover = function(show, text, baseDom) {
     }
 }
 
-MarkBoard.prototype.onFocusChange = function() {
+MarkBoard.prototype.onFocusChange = function () {
     this.currentStep = null;
 }
 

+ 6 - 3
stmms-web/src/main/webapp/static/rich-text/css/rich-text.css

@@ -4,7 +4,7 @@
 }
 
 .rich-text {
-    padding: 10px 0;
+    padding: 10px 20px;
     background: #FFF;
 }
 
@@ -25,7 +25,10 @@
 
 .rich-text .text.italic {
     font-style: italic;
-    color:red;
+}
+
+.rich-text .text.danger {
+    color: red;
 }
 
 .rich-text .text.sup {
@@ -50,7 +53,7 @@
     vertical-align: middle;
 }
 
-.rich-text .image.inline>img {
+.rich-text .image.inline > img {
     width: auto;
     max-height: 2em;
 }

+ 31 - 22
stmms-web/src/main/webapp/static/rich-text/js/render.js

@@ -1,45 +1,54 @@
-function renderRichText(body,isCount) {
+const _richText_text_styles_ = ['bold', 'underline', 'italic', 'danger', 'sup', 'sub'];
+
+function renderRichText(body) {
     let sections = body.sections || [];
-    let html = [];
+    let nodes = [];
     sections.forEach(section => {
-        html.push(renderSection(section,isCount));
+        nodes.push(renderSection(section));
     });
-    return html.join('');
+    return nodes;
 }
 
-function renderSection(section,isCount) {
+function renderSection(section) {
     let blocks = section.blocks || [];
     let inline = blocks.length > 1;
-    let html = [];
-    let count = 0;
+    let node = document.createElement('p');
     blocks.forEach(block => {
-        html.push(renderBlock(block, inline));
-        if(isCount && block.type === 'text'){
-        	count = count + block.value.length;
-        }
+        node.appendChild(renderBlock(block, inline));
     });
-    if(isCount){
-    	html.push('<span class="text italic">(字数统计' + count + ')</span>');
-    }
-    return '<p>' + html.join('') + '</p>';
+    return node;
 }
 
 function renderBlock(block, inline) {
+    let container = document.createElement('span');
     let type = '';
-    let inner = '';
     if (block.type === 'text') {
         type = 'text';
-        inner = block.value;
+        if (block.param !== undefined) {
+            _richText_text_styles_.forEach(style => {
+                if (block.param[style] === true) {
+                    type += ' ' + style;
+                }
+            })
+        }
+        container.textContent = block.value;
     } else if (block.type === 'image') {
-        type = 'image';
+        type = 'image loading';
         if (inline === true) {
             type += ' inline';
         }
-//        inner = '<img src="' + block.value + '" width="' + block.param.width + '" height="' + block.param.height + '"/>';
-        inner = '<img src="' + block.value + '"/>';
+        let img = container.appendChild(new Image());
+        img.src = block.value;
+        img.onload = function () {
+            this.parentNode.className = this.parentNode.className.replace(/loading/g, '');
+        }
     } else if (block.type === 'audio') {
         type = 'audio';
-        inner = '<audio controls><source src="' + block.value + '" type="audio/mpeg"></audio>';
+        let audio = container.appendChild(new Audio());
+        audio.src = block.value;
+        audio.controls = true;
+        audio.setAttribute("type", "audio/mpeg");
     }
-    return '<span class="' + type + '">' + inner + '</span>';
+    container.className = type;
+    return container;
 }