李勇

新增答题卡接口和答题卡模块

此 diff 太大无法显示。
@@ -27,11 +27,12 @@ import ArrayBufferUtil from 'libs/ArrayBufferUtil'; @@ -27,11 +27,12 @@ import ArrayBufferUtil from 'libs/ArrayBufferUtil';
27 import Server from "config/Server"; 27 import Server from "config/Server";
28 import MediaModule from 'apes/MediaModule'; 28 import MediaModule from 'apes/MediaModule';
29 import MediaSharedApe from 'apes/MediaSharedApe'; 29 import MediaSharedApe from 'apes/MediaSharedApe';
  30 +import QuestionApe from 'apes/QuestionApe';
30 31
31 import UTF8 from 'utf-8'; 32 import UTF8 from 'utf-8';
32 33
33 let loger = Loger.getLoger('McuClient'); 34 let loger = Loger.getLoger('McuClient');
34 -let _sdkInfo = {"version": "v1.31.3.20170609", "author": "www.3mang.com"}; 35 +let _sdkInfo = {"version": "v1.31.11.20170612", "author": "www.3mang.com"};
35 36
36 //APE 37 //APE
37 let _sass; 38 let _sass;
@@ -45,6 +46,7 @@ let _doc_ape; @@ -45,6 +46,7 @@ let _doc_ape;
45 let _whiteboard_ape; 46 let _whiteboard_ape;
46 let _recordPlayback; 47 let _recordPlayback;
47 let _mediaShareApe; 48 let _mediaShareApe;
  49 +let _questionApe;
48 50
49 //MCUClient 外部实例化主类 51 //MCUClient 外部实例化主类
50 export default class MessageEntrance extends Emiter { 52 export default class MessageEntrance extends Emiter {
@@ -135,6 +137,8 @@ export default class MessageEntrance extends Emiter { @@ -135,6 +137,8 @@ export default class MessageEntrance extends Emiter {
135 _doc_ape.on(MessageTypes.DOC_DELETE, this.docDeleteHandler.bind(this)); 137 _doc_ape.on(MessageTypes.DOC_DELETE, this.docDeleteHandler.bind(this));
136 _doc_ape.on(DocApe.DOC_JOIN_CHANNEL_SUCCESS, this.docJoinChannelSuccess.bind(this)); 138 _doc_ape.on(DocApe.DOC_JOIN_CHANNEL_SUCCESS, this.docJoinChannelSuccess.bind(this));
137 139
  140 + _questionApe=new QuestionApe();
  141 +
138 //公开外部调用的方法 142 //公开外部调用的方法
139 //class 143 //class
140 this.init = this._init.bind(this); 144 this.init = this._init.bind(this);
@@ -216,6 +220,7 @@ export default class MessageEntrance extends Emiter { @@ -216,6 +220,7 @@ export default class MessageEntrance extends Emiter {
216 this.getQuestion=this._getQuestion.bind(this); 220 this.getQuestion=this._getQuestion.bind(this);
217 this.getQuestionResult=this._getQuestionResult.bind(this); 221 this.getQuestionResult=this._getQuestionResult.bind(this);
218 this.sendAnswer=this._sendAnswer.bind(this); 222 this.sendAnswer=this._sendAnswer.bind(this);
  223 + this.stopQuestion=this._stopQuestion.bind(this);
219 224
220 this.setDeviceInfo = this._setDeviceInfo.bind(this);//设置设备信息(麦克风,摄像头等等.....) 225 this.setDeviceInfo = this._setDeviceInfo.bind(this);//设置设备信息(麦克风,摄像头等等.....)
221 this.setMessageDelay = this._setMessageDelay.bind(this);//设置是否延迟消息 226 this.setMessageDelay = this._setMessageDelay.bind(this);//设置是否延迟消息
@@ -1741,8 +1746,8 @@ export default class MessageEntrance extends Emiter { @@ -1741,8 +1746,8 @@ export default class MessageEntrance extends Emiter {
1741 loger.warn(GlobalConfig.getCurrentStatus()); 1746 loger.warn(GlobalConfig.getCurrentStatus());
1742 return; 1747 return;
1743 } 1748 }
1744 - if (_confer_ape) {  
1745 - _confer_ape.creatQuestion(_param); 1749 + if (_questionApe) {
  1750 + _questionApe.creatQuestion(_param);
1746 } 1751 }
1747 } 1752 }
1748 _getQuestion(_param){ 1753 _getQuestion(_param){
@@ -1750,8 +1755,8 @@ export default class MessageEntrance extends Emiter { @@ -1750,8 +1755,8 @@ export default class MessageEntrance extends Emiter {
1750 loger.warn(GlobalConfig.getCurrentStatus()); 1755 loger.warn(GlobalConfig.getCurrentStatus());
1751 return; 1756 return;
1752 } 1757 }
1753 - if (_confer_ape) {  
1754 - _confer_ape.getQuestion(_param); 1758 + if (_questionApe) {
  1759 + _questionApe.getQuestion(_param);
1755 } 1760 }
1756 } 1761 }
1757 _getQuestionResult(_param){ 1762 _getQuestionResult(_param){
@@ -1759,17 +1764,17 @@ export default class MessageEntrance extends Emiter { @@ -1759,17 +1764,17 @@ export default class MessageEntrance extends Emiter {
1759 loger.warn(GlobalConfig.getCurrentStatus()); 1764 loger.warn(GlobalConfig.getCurrentStatus());
1760 return; 1765 return;
1761 } 1766 }
1762 - if (_confer_ape) {  
1763 - _confer_ape.getQuestionResult(_param); 1767 + if (_questionApe) {
  1768 + _questionApe.getQuestionResult(_param);
1764 } 1769 }
1765 } 1770 }
1766 - _stopQuestion(){ 1771 + _stopQuestion(_param){
1767 if (!_mcu.connected) { 1772 if (!_mcu.connected) {
1768 loger.warn(GlobalConfig.getCurrentStatus()); 1773 loger.warn(GlobalConfig.getCurrentStatus());
1769 return; 1774 return;
1770 } 1775 }
1771 - if (_confer_ape) {  
1772 - _confer_ape.stopQuestion(_param); 1776 + if (_questionApe) {
  1777 + _questionApe.stopQuestion(_param);
1773 } 1778 }
1774 } 1779 }
1775 _sendAnswer(_param){ 1780 _sendAnswer(_param){
@@ -1777,8 +1782,8 @@ export default class MessageEntrance extends Emiter { @@ -1777,8 +1782,8 @@ export default class MessageEntrance extends Emiter {
1777 loger.warn(GlobalConfig.getCurrentStatus()); 1782 loger.warn(GlobalConfig.getCurrentStatus());
1778 return; 1783 return;
1779 } 1784 }
1780 - if (_confer_ape) {  
1781 - _confer_ape.sendAnswer(_param); 1785 + if (_questionApe) {
  1786 + _questionApe.sendAnswer(_param);
1782 } 1787 }
1783 } 1788 }
1784 1789
@@ -88,6 +88,16 @@ MessageTypes.DOC_BROADCAST= "doc_broadcast";// @@ -88,6 +88,16 @@ MessageTypes.DOC_BROADCAST= "doc_broadcast";//
88 MessageTypes.MEDIA_SHARED_DELETE="media_shared_delete";//删除媒体文件 88 MessageTypes.MEDIA_SHARED_DELETE="media_shared_delete";//删除媒体文件
89 MessageTypes.MEDIA_SHARED_UPDATE ="media_shared_update";//更新媒体文件(添加、变更) 89 MessageTypes.MEDIA_SHARED_UPDATE ="media_shared_update";//更新媒体文件(添加、变更)
90 90
  91 +//答题卡
  92 +MessageTypes.START_ANSWER_QUESTION="start_answer_question";//开始答题
  93 +MessageTypes.UPDATE_ANSWER_QUESTION="update_answer_question";//更新答题数据
  94 +MessageTypes.STOP_ANSWER_QUESTION="stop_answer_question";//停止答题
  95 +
  96 +//点名
  97 +MessageTypes.START_CALL_THE_ROLL="start_call_the_roll";//开始点名
  98 +MessageTypes.UPDATE_CALL_THE_ROLL="update_call_the_roll";//更新点名数据
  99 +MessageTypes.STOP_CALL_THE_ROLL="stop_call_the_roll";//停止点名
  100 +
91 101
92 //白板笔记事件定义 102 //白板笔记事件定义
93 MessageTypes.WHITEBOARD_ANNOTATION_UPDATE ="whiteboard_annotation_update";// 'whiteboard.annotation.update'; 103 MessageTypes.WHITEBOARD_ANNOTATION_UPDATE ="whiteboard_annotation_update";// 'whiteboard.annotation.update';
@@ -532,8 +532,15 @@ class Sass extends Emiter { @@ -532,8 +532,15 @@ class Sass extends Emiter {
532 if (ret.code== 0) { 532 if (ret.code== 0) {
533 //errorCode int 0 正常 1 没有指定的课堂 4 验证信息错误(authId) 533 //errorCode int 0 正常 1 没有指定的课堂 4 验证信息错误(authId)
534 // {"code":0,"id":1} 534 // {"code":0,"id":1}
535 - loger.log('创建答题数据->完成');  
536 - this._emit(Sass.SASS_CREAT_QUESTION_SUCCESS, ret); 535 + let question={};
  536 + question.questionId=ret.id;
  537 + question.type=type;
  538 + question.content=content;
  539 + question.timeLimit=timeLimit;
  540 + question.correct=correct;
  541 + question.options=options;
  542 + loger.log('创建答题数据->完成->',question);
  543 + this._emit(Sass.SASS_CREAT_QUESTION_SUCCESS, question);
537 } else { 544 } else {
538 loger.warn('创建答题数据->失败.', ret); 545 loger.warn('创建答题数据->失败.', ret);
539 this._emit(Sass.SASS_CREAT_QUESTION_FAILED); 546 this._emit(Sass.SASS_CREAT_QUESTION_FAILED);
@@ -601,8 +608,9 @@ class Sass extends Emiter { @@ -601,8 +608,9 @@ class Sass extends Emiter {
601 if (ret.code== 0) { 608 if (ret.code== 0) {
602 // 0 正常 1 没有指定的课堂 4 验证信息错误(authId) 5 没有指定的题目 6 题目不属于该课堂 609 // 0 正常 1 没有指定的课堂 4 验证信息错误(authId) 5 没有指定的题目 6 题目不属于该课堂
603 //{"code":0} 610 //{"code":0}
  611 + let question=_param;
604 loger.log('保存答题数据->完成'); 612 loger.log('保存答题数据->完成');
605 - this._emit(Sass.SASS_SEND_ANSWER_SUCCESS, ret); 613 + this._emit(Sass.SASS_SEND_ANSWER_SUCCESS, question);
606 } else { 614 } else {
607 loger.warn('保存答题数据->失败.', ret); 615 loger.warn('保存答题数据->失败.', ret);
608 this._emit(Sass.SASS_SEND_ANSWER_FAILED); 616 this._emit(Sass.SASS_SEND_ANSWER_FAILED);
@@ -651,9 +659,16 @@ class Sass extends Emiter { @@ -651,9 +659,16 @@ class Sass extends Emiter {
651 .then(ret => { 659 .then(ret => {
652 if (ret.code== 0) { 660 if (ret.code== 0) {
653 //0 正常 5 没有指定的题目 661 //0 正常 5 没有指定的题目
654 - //{"timeLimit":0,"content":"test question","id":11,"code":0,"type":3,"options":"["True", "False"]"} 662 + //{"timeLimit":90,"code":0,"options":"[\"A\",\"B\",\"C\"]","id":22,"type":2,"content":"题目"}
655 loger.log('查询题目数据->完成'); 663 loger.log('查询题目数据->完成');
656 - this._emit(Sass.SASS_GET_QUESTION_SUCCESS, ret); 664 + let question={};
  665 + question.questionId=ret.id||questionId;
  666 + question.type=ret.type;
  667 + question.timeLimit=ret.timeLimit;
  668 + question.options=ret.options;
  669 + question.content=ret.content;
  670 +
  671 + this._emit(Sass.SASS_GET_QUESTION_SUCCESS, question);
657 } else { 672 } else {
658 loger.warn('查询题目数据->失败.', ret); 673 loger.warn('查询题目数据->失败.', ret);
659 this._emit(Sass.SASS_GET_QUESTION_FAILED); 674 this._emit(Sass.SASS_GET_QUESTION_FAILED);
@@ -709,7 +724,10 @@ class Sass extends Emiter { @@ -709,7 +724,10 @@ class Sass extends Emiter {
709 {"timeLimit":0,"content":"test question","id":11,"code":0,"type":3,"options":"["True", "False"]"}*/ 724 {"timeLimit":0,"content":"test question","id":11,"code":0,"type":3,"options":"["True", "False"]"}*/
710 725
711 loger.log('查询答题结果数据->完成'); 726 loger.log('查询答题结果数据->完成');
712 - this._emit(Sass.SASS_GET_QUESTION_RESULT_SUCCESS, ret); 727 + let result=_param||{};
  728 + result.questionId=questionId;
  729 + result.list=ret.list;
  730 + this._emit(Sass.SASS_GET_QUESTION_RESULT_SUCCESS, result);
713 } else { 731 } else {
714 loger.warn('查询答题结果数据->失败.', ret); 732 loger.warn('查询答题结果数据->失败.', ret);
715 this._emit(Sass.SASS_GET_QUESTION_RESULT_FAILED); 733 this._emit(Sass.SASS_GET_QUESTION_RESULT_FAILED);
@@ -145,7 +145,7 @@ ApeConsts.WHITEBOARD_SESSION_ID = 18; @@ -145,7 +145,7 @@ ApeConsts.WHITEBOARD_SESSION_ID = 18;
145 ApeConsts.MEDIA_SESSION_ID = 19; 145 ApeConsts.MEDIA_SESSION_ID = 19;
146 ApeConsts.SCREENSHARING_SESSION_ID = 20; 146 ApeConsts.SCREENSHARING_SESSION_ID = 20;
147 ApeConsts.POLL_SESSION_ID = 21; 147 ApeConsts.POLL_SESSION_ID = 21;
148 - 148 +ApeConsts.QUESTION_SESSION_ID = 22;
149 // defs for common channel id 149 // defs for common channel id
150 ApeConsts.BROADCAST_CHANNEL_ID = 0; 150 ApeConsts.BROADCAST_CHANNEL_ID = 0;
151 ApeConsts.CONFERENCE_CHANNEL_ID = ApeConsts.CONFERENCE_SESSION_ID; 151 ApeConsts.CONFERENCE_CHANNEL_ID = ApeConsts.CONFERENCE_SESSION_ID;
@@ -157,6 +157,9 @@ ApeConsts.WHITEBOARD_CHANNEL_ID = ApeConsts.WHITEBOARD_SESSION_ID; @@ -157,6 +157,9 @@ ApeConsts.WHITEBOARD_CHANNEL_ID = ApeConsts.WHITEBOARD_SESSION_ID;
157 ApeConsts.MEDIA_CHANNEL_ID = ApeConsts.MEDIA_SESSION_ID; 157 ApeConsts.MEDIA_CHANNEL_ID = ApeConsts.MEDIA_SESSION_ID;
158 ApeConsts.SCREENSHARING_CHANNEL_ID = ApeConsts.SCREENSHARING_SESSION_ID; 158 ApeConsts.SCREENSHARING_CHANNEL_ID = ApeConsts.SCREENSHARING_SESSION_ID;
159 159
  160 +ApeConsts.QUESTION_CHANNEL_ID = ApeConsts.QUESTION_SESSION_ID;
  161 +
  162 +
160 // defs for common session name 163 // defs for common session name
161 ApeConsts.CONFERENCE_SESSION_NAME = "conference app"; 164 ApeConsts.CONFERENCE_SESSION_NAME = "conference app";
162 ApeConsts.CHAT_SESSION_NAME = "chat app"; 165 ApeConsts.CHAT_SESSION_NAME = "chat app";
@@ -168,6 +171,8 @@ ApeConsts.DOCSHARING_SESSION_NAME = "doc sharing app"; @@ -168,6 +171,8 @@ ApeConsts.DOCSHARING_SESSION_NAME = "doc sharing app";
168 ApeConsts.WHITEBOARD_SESSION_NAME = "whiteboard app"; 171 ApeConsts.WHITEBOARD_SESSION_NAME = "whiteboard app";
169 ApeConsts.MEDIA_SESSION_NAME = "media sharing app"; 172 ApeConsts.MEDIA_SESSION_NAME = "media sharing app";
170 ApeConsts.SCREENSHARING_SESSION_NAME = "screen sharing app"; 173 ApeConsts.SCREENSHARING_SESSION_NAME = "screen sharing app";
  174 +ApeConsts.QUESTION_SESSION_NAME = "question app";
  175 +
171 176
172 // def for common session tag 177 // def for common session tag
173 ApeConsts.CONFERENCE_SESSION_TAG = "con-tag"; 178 ApeConsts.CONFERENCE_SESSION_TAG = "con-tag";
@@ -180,6 +185,8 @@ ApeConsts.DOCSHARING_SESSION_TAG = "doc-tag"; @@ -180,6 +185,8 @@ ApeConsts.DOCSHARING_SESSION_TAG = "doc-tag";
180 ApeConsts.WHITEBOARD_SESSION_TAG = "wbd-tag"; 185 ApeConsts.WHITEBOARD_SESSION_TAG = "wbd-tag";
181 ApeConsts.MEDIA_SESSION_TAG = "med-tag"; 186 ApeConsts.MEDIA_SESSION_TAG = "med-tag";
182 ApeConsts.SCREENSHARING_SESSION_TAG = "scr-tag"; 187 ApeConsts.SCREENSHARING_SESSION_TAG = "scr-tag";
  188 +ApeConsts.QUESTION_SESSION_TAG = "qst-tag";
  189 +
183 190
184 ApeConsts.CONFERENCE_OBJ_ROSTER_ID = ((ApeConsts.CONFERENCE_SESSION_ID << 16) + 1); 191 ApeConsts.CONFERENCE_OBJ_ROSTER_ID = ((ApeConsts.CONFERENCE_SESSION_ID << 16) + 1);
185 ApeConsts.CONFERENCE_OBJ_ROSTER_NAME = "node list"; 192 ApeConsts.CONFERENCE_OBJ_ROSTER_NAME = "node list";
@@ -200,7 +207,7 @@ ApeConsts.CONFERENCE_OBJ_COUNTER_NAME = "id list"; @@ -200,7 +207,7 @@ ApeConsts.CONFERENCE_OBJ_COUNTER_NAME = "id list";
200 ApeConsts.CONFERENCE_OBJ_COUNTER_TAG = "id list tag"; 207 ApeConsts.CONFERENCE_OBJ_COUNTER_TAG = "id list tag";
201 208
202 //答题卡 209 //答题卡
203 -ApeConsts.CONFERENCE_OBJ_QUESTION_ID = ((ApeConsts.CONFERENCE_SESSION_ID << 16) + 5); 210 +ApeConsts.CONFERENCE_OBJ_QUESTION_ID = ((ApeConsts.QUESTION_SESSION_ID << 16) + 1);
204 ApeConsts.CONFERENCE_OBJ_QUESTION_NAME = "question list"; 211 ApeConsts.CONFERENCE_OBJ_QUESTION_NAME = "question list";
205 ApeConsts.CONFERENCE_OBJ_QUESTION_TAG = "question list tag"; 212 ApeConsts.CONFERENCE_OBJ_QUESTION_TAG = "question list tag";
206 213
  1 +// //////////////////////////////////////////////////////////////////////////////
  2 +//答题卡模块
  3 +// //////////////////////////////////////////////////////////////////////////////
  4 +
  5 +import Ape from './Ape';
  6 +import ApeConsts from './ApeConsts';
  7 +import ThirdMessage from './ThirdMessage';
  8 +import MessageTypes from 'MessageTypes';
  9 +import pdu from 'pdus';
  10 +import UTF8 from 'utf-8';
  11 +import Loger from 'Loger';
  12 +import GlobalConfig from 'GlobalConfig';
  13 +import EngineUtils from 'EngineUtils';
  14 +import TimerCounter from "TimerCounter";
  15 +import Sass from 'Sass';
  16 +
  17 +let loger = Loger.getLoger('QuestionApe');
  18 +
  19 +class QuestionApe extends Ape {
  20 + constructor() {
  21 + super(
  22 + ApeConsts.QUESTION_SESSION_ID,
  23 + ApeConsts.QUESTION_SESSION_NAME,
  24 + ApeConsts.QUESTION_SESSION_TAG
  25 + );
  26 + this.questionList={};//MCU同步的题目数据
  27 + this.questionDataList={};//Sass保存的题目内容数据
  28 +
  29 + //监听Sass事件
  30 + this._sass=Sass;
  31 + //创建答题卡
  32 + this._sass.on(Sass.SASS_CREAT_QUESTION_SUCCESS,this._sassCreatQuestionSuccessHandler.bind(this));
  33 + this._sass.on(Sass.SASS_CREAT_QUESTION_FAILED,this._sassCreatQuestionFailedHandler.bind(this));
  34 + //获取题目数据
  35 + this._sass.on(Sass.SASS_GET_QUESTION_SUCCESS,this._sassGetQuestionSuccessHandler.bind(this));
  36 + this._sass.on(Sass.SASS_GET_QUESTION_FAILED,this._sassGetQuestionFailedHandler.bind(this));
  37 + //获取答题结果
  38 + this._sass.on(Sass.SASS_GET_QUESTION_RESULT_SUCCESS,this._sassGetQuestionResultSuccessHandler.bind(this));
  39 + this._sass.on(Sass.SASS_GET_QUESTION_RESULT_FAILED,this._sassGetQuestionResultFailedHandler.bind(this));
  40 + //保存答题数据
  41 + this._sass.on(Sass.SASS_SEND_ANSWER_SUCCESS,this._sassSendAnswerSuccessHandler.bind(this));
  42 + this._sass.on(Sass.SASS_SEND_ANSWER_FAILED,this._sassSendAnswerFailedHandler.bind(this));
  43 +
  44 + // Ape Models
  45 + this.registerKey(this._session_id, this._session_name, this._session_tag, new ArrayBuffer);
  46 +
  47 + this.registerObj(pdu.RCPDU_REG_REGISTER_TABLE, ApeConsts.CONFERENCE_OBJ_QUESTION_ID,
  48 + ApeConsts.CONFERENCE_OBJ_QUESTION_NAME, ApeConsts.CONFERENCE_OBJ_QUESTION_TAG, 0, new ArrayBuffer);
  49 + }
  50 +
  51 + //更新信息
  52 + sendUpdaterTable(_param) {
  53 + loger.log('答题卡->发送更新信息->');
  54 + if (_param == null || EngineUtils.isEmptyObject(_param)) {
  55 + loger.log('答题卡->发送更新信息->参数错误');
  56 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  57 + return;
  58 + }
  59 + let itemIdx = ApeConsts.CONFERENCE_OBJ_QUESTION_ID;
  60 + let modelPdu = this.packPdu(_param, itemIdx);
  61 +
  62 + if (modelPdu == null) {
  63 + loger.log('答题卡->发送更新信息->参数错误');
  64 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  65 + return;
  66 + }
  67 + console.log("modelPdu",modelPdu);
  68 + let tableItemPdu = new pdu['RCRegistryTableItemPdu'];
  69 + tableItemPdu.itemIdx = itemIdx;
  70 + tableItemPdu.owner = 0;//收到flash的是这个值,不清楚先写固定
  71 + tableItemPdu.registerObjId = ApeConsts.CONFERENCE_OBJ_QUESTION_ID;
  72 + loger.log('答题卡->发送更新信息->1aaaaaa');
  73 + tableItemPdu.itemData = modelPdu.toArrayBuffer();
  74 +
  75 + //updater
  76 + let tableUpdateItem = new pdu['RCRegistryTableUpdateItemPdu'];
  77 + //optional RCPduType_E type = 1 [default = RCPDU_REG_TABLE_UPDATE_PDU];
  78 + //repeated RCRegistryTableItemPdu items = 2;
  79 + tableUpdateItem.type = pdu.RCPDU_REG_TABLE_UPDATE_PDU;//
  80 + tableUpdateItem.items.push(tableItemPdu);
  81 +
  82 + let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
  83 + updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_QUESTION_ID;
  84 + updateObjPdu.subType = tableUpdateItem.type;
  85 + updateObjPdu.userData = tableUpdateItem.toArrayBuffer();
  86 +
  87 + //同步
  88 + let adapterItemPdu = new pdu['RCAdapterItemPdu'];
  89 + adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
  90 + adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
  91 +
  92 + let adapterPdu = new pdu['RCAdapterPdu'];
  93 + adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
  94 + adapterPdu.item.push(adapterItemPdu);
  95 + this.sendUniform(adapterPdu, true);
  96 + }
  97 +
  98 + //删除
  99 + tableDelete(_param) {
  100 + let tableDeleteItemPdu = new pdu['RCRegistryTableDeleteItemPdu'];
  101 + tableDeleteItemPdu.type = pdu.RCPDU_REG_TABLE_DELETE_PDU;//
  102 + tableDeleteItemPdu.itemIdx = parseInt(_param.itemIdx);//这里需要设置要删除的数据的itemIdx,每条数据的这个id都不一样
  103 +
  104 + let updateObjPdu = new pdu['RCRegistryUpdateObjPdu'];
  105 + updateObjPdu.objId = ApeConsts.CONFERENCE_OBJ_QUESTION_ID;//
  106 + updateObjPdu.subType = tableDeleteItemPdu.type;
  107 + updateObjPdu.userData = tableDeleteItemPdu.toArrayBuffer();
  108 +
  109 + //同步
  110 + let adapterItemPdu = new pdu['RCAdapterItemPdu'];
  111 + adapterItemPdu.type = pdu.RCPDU_REG_UPDATE_OBJ;
  112 + adapterItemPdu.itemData = updateObjPdu.toArrayBuffer();
  113 +
  114 + let adapterPdu = new pdu['RCAdapterPdu'];
  115 + adapterPdu.type = pdu.RCPDU_REG_ADAPTER;
  116 + adapterPdu.item.push(adapterItemPdu);
  117 + loger.log("答题卡删除数据->" + tableDeleteItemPdu.itemIdx);
  118 + this.sendUniform(adapterPdu, true);
  119 + }
  120 +
  121 + /////收到消息处理/////////////////////////////////////////////////////////////////////////////////
  122 + //答题卡更新数据
  123 + tableUpdateHandler(owner, itemIdx, itemData) {
  124 + try {
  125 + let model = this.unPackPdu(owner, itemIdx, itemData);
  126 + loger.log('答题卡更新数据->',model);
  127 + this.questionList[itemIdx]=model;
  128 + console.log('this.questionList',this.questionList);
  129 + if(model){
  130 + switch (model.type){
  131 + case 1:
  132 + case 2:
  133 + case 3:
  134 + //停止答题
  135 + loger.log("更新答题数据");
  136 + if(GlobalConfig.isHost){
  137 + //老师,只统计数据,不答题
  138 + this.getQuestionResult(model);
  139 + }else if(GlobalConfig.isNormal) {
  140 + //学生->如果自己已经提交过答案就不需要再显示
  141 + if(model.totalUserList.indexOf(GlobalConfig.userId)>=0){
  142 + loger.log("已经提交过答案->userId:"+GlobalConfig.userId);
  143 + }else {
  144 + //显示答题卡数据
  145 + this._emit(MessageTypes.START_ANSWER_QUESTION,model);
  146 + }
  147 + }
  148 + break;
  149 + case 4:
  150 + //停止点名
  151 + loger.log("更新点名数据");
  152 + this._emit(MessageTypes.UPDATE_CALL_THE_ROLL,model);
  153 + break;
  154 + default :
  155 + break;
  156 + }
  157 + }
  158 +
  159 + } catch (err) {
  160 + loger.warn('答题卡更新数据->解析失败->err', err.message);
  161 + }
  162 + }
  163 + tableDeleteHandler(object_id, tableDeleteData) {
  164 + loger.log('答题卡删除数据->', object_id, tableDeleteData);//["tableDeleteHandler",1179649,{"type":231,"itemIdx":[1486301768]}]
  165 + if (tableDeleteData && tableDeleteData.itemIdx) {
  166 + let len = tableDeleteData.itemIdx.length;
  167 + let itemIdxs = tableDeleteData.itemIdx;
  168 + for (let i = 0; i < len; i++) {
  169 + if (this.questionList[itemIdxs[i]]) {
  170 + loger.log("答题卡删除数据:", itemIdxs[i]);
  171 + let itemDataInfo = this.questionList[itemIdxs[i]];
  172 + if(itemDataInfo){
  173 + switch (itemDataInfo.type){
  174 + case 1:
  175 + case 2:
  176 + case 3:
  177 + //停止答题
  178 + loger.log("停止答题");
  179 + this._emit(MessageTypes.STOP_ANSWER_QUESTION,itemDataInfo);
  180 + break;
  181 + case 4:
  182 + //停止点名
  183 + loger.log("停止点名");
  184 + this._emit(MessageTypes.STOP_CALL_THE_ROLL,itemDataInfo);
  185 + break;
  186 + default :
  187 + break;
  188 + }
  189 + }
  190 + delete this.questionList[itemIdxs[i]];
  191 + }
  192 + }
  193 + }
  194 + }
  195 +
  196 + ///////数据的封包和解包/////////////////////////////////////////
  197 + packPdu(_param, _itemIdx) {
  198 + //验证坐标点集合数组是否合法
  199 + if (_param == null || _itemIdx == null) {
  200 + loger.log("答题卡->packPdu->参数错误",_itemIdx,_param);
  201 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  202 + return null;
  203 + }
  204 + /*optional uint32 item_idx=1;
  205 + optional uint32 from=2;
  206 + optional uint32 owner=3;
  207 + optional uint32 type=4;//类型
  208 + optional uint32 questionId=5;//题目id
  209 + optional uint32 timeLimit=6;//有效时间
  210 + optional uint32 timestamp=7;//创建的时间
  211 + repeated string totalUserList=8;//参与的人员userId列表*/
  212 +
  213 + let modelPdu = new pdu['RCQuestionDataModelPdu'];
  214 + modelPdu.itemIdx = _itemIdx;
  215 + modelPdu.from = _param.nodeId||GlobalConfig.nodeId;
  216 + modelPdu.owner = _param.owner||GlobalConfig.nodeId;
  217 + modelPdu.type = parseInt(_param.type)||0;
  218 + modelPdu.questionId= parseInt(_param.questionId)||0;
  219 + modelPdu.timeLimit= parseInt(_param.timeLimit)||1;//有效时间
  220 + modelPdu.timestamp= parseInt(_param.timestamp)||EngineUtils.creatTimestamp();//创建的时间
  221 + modelPdu.content= _param.content||"";//题干
  222 + modelPdu.options= _param.options||"";//选项列表
  223 + modelPdu.answer= _param.answer||"";//用户选择的选项索引
  224 + modelPdu.correct= _param.correct||"";//正确答案索引
  225 + modelPdu.totalUserList=_param.totalUserList||[];//参加的人员userId列表
  226 + loger.log("答题卡->packPdu",modelPdu);
  227 + return modelPdu;
  228 + }
  229 +
  230 + unPackPdu(owner, itemIdx, itemData) {
  231 + loger.log("答题卡->unPackPdu ");
  232 + if (owner == null || itemIdx == null || itemData == null) {
  233 + this._emit(MessageTypes.MCU_ERROR, MessageTypes.ERR_APE_INTERFACE_PARAM_WRONG);
  234 + return null;
  235 + }
  236 +
  237 + try {
  238 + let modelPdu = pdu['RCQuestionDataModelPdu'].decode(itemData);
  239 + return modelPdu;
  240 + } catch (err) {
  241 + loger.log("答题卡->Pdu解析错误,itemIdx=" + itemIdx + " err:" + err.message);
  242 + }
  243 + return null;
  244 + }
  245 +
  246 + //答题卡接口-------------------------------------------------------------------
  247 + creatQuestion(_param){
  248 + if(!_param){
  249 + loger.warn("创建答题卡->参数错误",_param);
  250 + return;
  251 + }
  252 + loger.log("创建答题卡->",_param);
  253 + if(this._sass){
  254 + /*{
  255 + "type": 1,//1单选,2多选,3判断,4点名
  256 + "content": "题目",//没有就传""
  257 + "timeLimit": 88,//有效时间(秒)
  258 + "correct": "[]",//正确答案,没有就传[]
  259 + "options": [],//选项数组,没有就传[]
  260 + "answer": []//学生选择的答案,没有就传[]
  261 + }*/
  262 + let paramObj=_param;
  263 + paramObj.classId=GlobalConfig.classId;
  264 + this._sass.creatQuestion(paramObj);
  265 + }
  266 + }
  267 + getQuestion(_param){
  268 + if(!_param){
  269 + loger.warn("获取答题卡数据->参数错误",_param);
  270 + return;
  271 + }
  272 + loger.log("获取答题卡数据->.",_param);
  273 + if(this.questionList[_param.itemIdx]){
  274 + this._emit(MessageTypes.START_ANSWER_QUESTION,this.questionList[_param.itemIdx]);
  275 + }else {
  276 + if(this._sass){
  277 + this._sass.getQuestion(_param);
  278 + }
  279 + }
  280 +
  281 + }
  282 + getQuestionResult(_param){
  283 + if(!_param){
  284 + loger.warn("获取答题卡结果->参数错误",_param);
  285 + return;
  286 + }
  287 + loger.log("获取答题卡结果->",_param);
  288 + if(this._sass){
  289 + this._sass.getQuestionResult(_param);
  290 + }
  291 + }
  292 + sendAnswer(_param){
  293 + if(!_param){
  294 + loger.warn("保存答题答案->参数错误",_param);
  295 + return;
  296 + }
  297 +
  298 + if(this._sass){
  299 + if(this.questionList[_param.itemIdx]){
  300 + loger.log("保存答题答案->",_param);
  301 + let paramObj=_param;
  302 + paramObj.classId=GlobalConfig.classId;
  303 + paramObj.userId = GlobalConfig.userId;
  304 + paramObj.userName = GlobalConfig.userName;
  305 + this._sass.sendAnswer(paramObj);
  306 + }else {
  307 + loger.log("保存答题答案->数据不存在",_param);
  308 + console.log("questionList",this.questionList);
  309 + }
  310 + }
  311 + }
  312 + stopQuestion(_param){
  313 + if(!_param){
  314 + loger.warn("停止答题->参数错误",_param);
  315 + return;
  316 + }
  317 + loger.log("停止答题->",_param);
  318 + this.tableDelete({itemIdx:ApeConsts.CONFERENCE_OBJ_QUESTION_ID})
  319 + }
  320 + //Sass 事件监听
  321 + _sassCreatQuestionSuccessHandler(_data){
  322 + loger.log("创建答题卡成功",_data);
  323 + if(_data){
  324 + //this.questionDataList[_data.questionId]=_data;//保存题目数据
  325 +
  326 + let questionItem=_data;
  327 + questionItem.itemIdx=ApeConsts.CONFERENCE_OBJ_QUESTION_ID;
  328 + this.sendUpdaterTable(questionItem);
  329 + }
  330 +
  331 + }
  332 + _sassCreatQuestionFailedHandler(_data){
  333 + loger.log("创建答题卡失败",_data);
  334 + }
  335 + _sassGetQuestionSuccessHandler(_data){
  336 + loger.log("获取答题卡数据成功",_data);
  337 + }
  338 + _sassGetQuestionFailedHandler(_data){
  339 + loger.log("获取答题卡数据失败",_data);
  340 + }
  341 + _sassGetQuestionResultSuccessHandler(_data){
  342 + loger.log("获取答题卡结果成功",_data);
  343 + //返回值结构
  344 + /* {
  345 + "questionId": 11,
  346 + "list": [
  347 + {
  348 + "answer": "",
  349 + "userName": "visitor_995083397",
  350 + "userId": "0"
  351 + },
  352 + {
  353 + "answer": "0",
  354 + "userName": "visitor_995083397",
  355 + "userId": "0"
  356 + }
  357 + ]
  358 + }*/
  359 + if(_data){
  360 + let resultObj= this.questionList[_data.itemIdx];
  361 + /* {
  362 + "type": 1,//1 单选、2多选、3判断、4点名
  363 + "questionId": 15,
  364 + "content": "题目",
  365 + "timeLimit": 88,
  366 + "totalUser":5,//当前参与的总人数
  367 + "correct": "[]",//正确答案
  368 + "options": ["A","B","C"],
  369 + //各个选项参与人数的百分比和参与人的名字
  370 + "answers":[
  371 + {"percent":40,"userNames":"张三、asdas"},
  372 + {"percent":40,"userNames":"历史、asdas"},
  373 + {"percent":20,"userNames":"bdb"},
  374 + ]
  375 + }*/
  376 + if(resultObj){
  377 + let list=_data.list||[];
  378 + let listLen=list.length;
  379 + resultObj.totalUser=listLen;
  380 + resultObj.answers=[];
  381 +
  382 + //根据选项的个数,把选项分开
  383 + let options=JSON.parse(resultObj.options);
  384 + for(let i=0;i<options.length;i++){
  385 + let optionObj=new Object();
  386 + optionObj.percent=0;//百分比 选择的人数和总参与人数的比
  387 + optionObj.userNames=[];
  388 + resultObj.answers.push(optionObj)
  389 + }
  390 +
  391 + //把list选择的答案和人员分配到各个选项数组
  392 + for(let k=0;k<listLen;k++){
  393 + let listItem=list[k];
  394 + if(listItem){
  395 + let answerIndex=parseInt(listItem.answer);
  396 + let optionObj=resultObj.answers[answerIndex];
  397 + if(optionObj){
  398 + optionObj.userNames.push(listItem.userName);
  399 + optionObj.percent=parseInt(optionObj.userNames.length/listLen*100);
  400 + }
  401 + }
  402 + }
  403 + loger.log("获取答题卡结果统计->",resultObj);
  404 + this._emit(MessageTypes.UPDATE_ANSWER_QUESTION,resultObj);
  405 + }
  406 + }
  407 + }
  408 + _sassGetQuestionResultFailedHandler(_data){
  409 + loger.log("获取答题卡结果失败",_data);
  410 + }
  411 + _sassSendAnswerSuccessHandler(_data){
  412 + loger.log("保存答案成功",_data);
  413 + let questionItem=this.questionList[_data.itemIdx];
  414 + if(questionItem){
  415 + if(questionItem.totalUserList.indexOf(GlobalConfig.userId)<0){
  416 + questionItem.totalUserList.push(""+GlobalConfig.userId);
  417 + }
  418 + this.sendUpdaterTable(questionItem);
  419 + }
  420 + }
  421 + _sassSendAnswerFailedHandler(_data){
  422 + loger.log("保存答案失败",_data);
  423 + }
  424 +
  425 +}
  426 +
  427 +export default QuestionApe;
  428 +
@@ -998,6 +998,20 @@ message RCConferenceRecordRequestPdu { @@ -998,6 +998,20 @@ message RCConferenceRecordRequestPdu {
998 optional string filename = 4; // 录像文件名称,filename中增加目录部分 998 optional string filename = 4; // 录像文件名称,filename中增加目录部分
999 } 999 }
1000 1000
  1001 +message RCQuestionDataModelPdu {
  1002 + optional uint32 item_idx=1;
  1003 + optional uint32 from=2;
  1004 + optional uint32 owner=3;
  1005 + optional uint32 type=4;//类型
  1006 + optional uint32 questionId=5;//题目id
  1007 + optional uint32 timeLimit=6;//有效时间
  1008 + optional string content=7;//题干
  1009 + optional uint32 timestamp=8;//创建的时间
  1010 + optional string options=9;//选项列表
  1011 + optional string answer=10;//用户选择的答案选项索引
  1012 + optional string correct=11;//正确答案索引
  1013 + repeated string totalUserList=12;//参与的人员userId列表
  1014 +}
1001 //end 1015 //end
1002 `; 1016 `;
1003 1017