var env = (function (defaultEnv) { var isProduction = ~location.href.indexOf('zhixinhuixue') var isLocal = ~location.href.indexOf('localhost') || ~location.href.indexOf('192.168') if (isLocal) return defaultEnv if (isProduction) return 'online' return 'testing' })('localxx') //环境配置 var envConfig = envConfigs[env] //登陆态'/username/pc002/time/1567499908/sig/7d9ca3d40b7422b759ce9a7e08b2de20/sessionid/session_93482f6cf1c865b7a2e2793c66f2c595' var loginStatus = envConfig.loginStatus //当前环境域名'http://192.168.1.51/index.php' var domain = envConfig.domain + "/index.php" //当前环境转pdf所需css 相对路径 var printCssPath = envConfig.printCssPath //当前环境转pdf所要请求的域 var printPdfIp = envConfig.printPdfIp var editorIndexLi = 1 var editorIndexUp = '' var isShowPreview = -1 var isShowEdit = -1 Print = { apis: { //获取答题卡信息 getTopicsDetailAPi: domain + '/print/getPaperWithTopicsDetails' + loginStatus, //保存答题卡信息 saveTopicsDetailsApi: domain + '/print/saveCardOnline' + loginStatus, //保存为pdf htmlToPdfApi: domain + '/print/htmlToPdf' + loginStatus, //上传图片===富文本编辑试题的时候需要 uploadFileApi: domain + '/online/uploadFile' + loginStatus, //考试学生重置接口 /** schoolId examGroupId 两个参数 */ resetExamStudentApi: domain + '/rest/answer_card_online/resetStudentStatus' + loginStatus, //下载pdf downPdfApi: domain + '/print/downOnlinePdf' + loginStatus, downOnlinePdfApi: domain + '/third/download' + loginStatus, getPdfApi: '//' + printPdfIp + '/getPdf', // getOnlinePdf getOnlinePdfApi: domain + '/third/getOnlinePdf' + loginStatus, delPdfApi: '//' + printPdfIp + '/delPdf', //直接下载node服务器上的pdf 模版 //192.168.1.84:8001/download/ downloadPdfUrl: '//' + printPdfIp + '/download/', batchGeneratePdfApi: '//' + printPdfIp + '/batchGeneratePdf', //latex 转 公式图片 getMathtexApi: domain + '/print/ajaxGetMathtex' + loginStatus, //保存全学科试卷信息 saveAllSubjectInfoApi: domain + '/third/createThirdOnline' + loginStatus, //保存为我的模版信息 saveTemplateByOnlineApi: domain + '/third/saveTemplateByOnline' + loginStatus, //获取模版 getTplListApi: domain + '/third/tplList' + loginStatus, //第三方创建答题卡的时候获取准考证配置信息 getExamNumberConfigApi: domain + '/third/getCardStatusByGrade' + loginStatus }, init: function (config) { this.modal = hgc_modal //是否第一次进入页面 this.firstEnterPage = true //需要同时保存用来记忆布局的有:纸张规格,纸张方向,是否有装订线,考号配置(填涂考号or条形码,是否使用二维码) this.paper = 'A3' this.direction = 'horizontal' //装订线 this.hasBindingLine = false //信息栏 this.hasPaperMsg = true //考号配置 this.examNumberConfig = { //条形码 barCode: true, //准考证号 ticketNumber: true } this.cardStatus = 0, //考号配置 this.examInfoConfig = { //时间 wpTimes: true, //满分 fullScore: true, //命卷人 wpAuthor: true, //审核人 wpReviewer: true } this.examInfoConfigText = { //时间 wpTimes: '', //满分 fullScore: '', //命卷人 wpAuthor: '', //审核人 wpReviewer: '' } //是否使用二维码 this.useQrCode = false this.config = simpleCopy(config[this.paper]) this.configOrigin = simpleCopy(this.config) //分栏 this.columns = 2 //页面页码计算 //当前分页 this.currentPage = 1 //总分页 this.totalPage = 1 //当前纸张-包括正反两面 ceil(totalPage/(column*2)) this.currentPaper = 0 //当前纸张正面1正面2 反面1 反面2 this.currentPaperPage = 0 //初始化页面数据 /** * 核心功能模块盒模型设计 */ //解答区域--最小高度 this.moduleMinHeight = 10 //解答区域--默认高度 this.moduleDefaultHeihgt = 54 //解答区域--左右内边距之和 this.modulePaddingSide = 20 //解答区域--上内边距 this.modulePaddingTop = 42 //解答区域--下内边距 this.modulePaddingBottom = 12 this.modulePadding = this.modulePaddingTop + this.modulePaddingBottom //每个分页答题区域的--上下内边距 this.pagePadding = 50 //这个答题区域布局外边距 this.layoutPadding = 20 //每页的左右间距 this.pagePaddingSide = 30 //用于页面 mm 和 px 之间单位转换 //96dpi 打印出来300dpi纸张上面的的比例 this.dpiRadio = 1 this.unitConversion = new UnitConversion() this.pageHeight = this.unitConversion.mmConversionPx(this.config.height) this.pageWidth = this.unitConversion.mmConversionPx(this.config.width) //富文本编辑 ==>> 全局富文本编辑构造函数 this.EDITOR = window.wangEditor //富文本菜单配置文件 this.EDITOR_CONFIG = [ 'underline', // 下划线 'justify', // 对齐方式 'image', // 插入图片 'table', // 表格 'undo', // 撤销 'redo', // 重复 'lineheight', 'Hline', 'formula' ] this.EDITOR_CONFIG_ZW = [ 'underline', // 下划线 'justify', // 对齐方式 'image', // 插入图片 'table', // 表格 'undo', // 撤销 'redo', // 重复 'lineheight', 'composition', 'Hline', 'formula' ] //题型配置 不定向选择 判断 作文 定位点c++ this.questionTypeMapForPhp = { //0单选 singleSelect: 0, //8多选 moreSelect: 8, //填空 fillInBlank: 3, //解答 answer: 1, //选做 chooseAnswer: 2, //必做题 mustAnswer: 27, //不定项 uncertainOption: 5 } //类型 1 单选 2 多选 5 填空 7 解答 17 选做 11不定项 php this.questionTypeMapForC = { 1: 'singleSelect', 2: 'moreSelect', 11: 'uncertainOption', 5: 'fillInBlank', 7: 'shortAnswer', 27: 'mustAnswer', 17: 'chooseAnswer', '7c': 'composition' } //题型名称映射 this.questionNameMap = { singleSelect: '单选题', moreSelect: '多选题', fillInBlank: '填空题', shortAnswer: '解答题', chooseAnswer: '选做题', uncertainOption: '不定项', mustAnswer: '必做题', composition: '作文' } //题型数据存储 this.questionMap = [] if (isNewBuild) { this.subjectId = subjectId } else { //全局groupId this.examGroupId = examGroupId || 0 this.examIds = examIds this.schoolId = schoolId } //如果是创建考试,则唯一标识符 自定义,用来创建考试页面下载答题卡 this.identifier = isNewBuild ? _symbolId() : self.examGroupId //当前区域定位信息,用来简单判断两次保存是否有改动,来防止重复提交数据 this.saveLocationPosition = {} //首次保存 this.alreadySave = false //当前答题卡模块是否在编辑状态--是否可以 编辑当前答题卡模板 /** * 刚进页面 * 1如果是之前没有保存,就属于编辑状态 * 2如果之前有保存过,就属于保存在状态(页面所有操作按钮不可操作,需要点击编辑才可操作) * 页面中 * 1如果点击了保存,就是保存状态 */ this.isCanEditCard = true //是否已经有打印的班级 this.printClassStatus = false //题卡合一 的type值 this.subjectCardToOneType = 1 //是否需要题卡合一 this.isSubjectInfoToCard = false //替换富文本没用内容 this.replaceEditorRegexp = /(


<\/p>)|(


<\/div>)/g //所有打分框的分值上线标准 this.answerScoreLimitKeyArr = [15, 16, 29, 49, 69] this.initDom() //初始化打印面积 this.initPageStyle() //初始化页面渲染 this.initPage() //解答题图片移动 this.shortAnswerImgPositionChange() }, tpls: PRINT_TPL, initPageStyle: function () { var self = this var $headEL = $('head') var $styleTag = $('#pageSizeStyle') self.pageHeight = self.unitConversion.mmConversionPx(self.config.height) self.pageWidth = self.unitConversion.mmConversionPx(self.config.width) if ($styleTag.length) $styleTag.remove() var initPrintPageStyle = self.tpls.printPageStyle.substitute({ pageWidth: self.pageWidth / self.columns, pageHeight: self.pageHeight }) $headEL.append(initPrintPageStyle) }, /** * 初始化打印区域宽高 mm 转 px * 纸张方向,纸张大小,纸张分栏 * 默认A3 两栏 */ initPrintContentArea: function () { var self = this self.initPageStyle() //列举属于小版面的配置,统一使用小版面的布局 var isHorizontal = self.direction === 'horizontal' var isLayoutWhite = ~[ 'A3-3', 'A4-2', 'A4-3', '8Ks-3', '8Kb-3', '16K-2', '16K-3' ].indexOf(self.paper + '-' + self.columns) var isSmallLayout = isHorizontal && isLayoutWhite self.$firstPageContent[isSmallLayout ? 'addClass' : 'removeClass']( 'smallLayout' ) //判断第一页有没有题型模块,如果第一页没有题型模块,则直接跳到第二页做题型重排处理 var hasSurplus = false var $secondPage = self.$firstPageContent.find('.examNumberLayout').next() var $secondPageFirstModule = $secondPage.find('.module').eq(0) var secondPageFirstModuleType = $secondPage .find('.answerModule') .eq(0) .attr('data-type') if ( !$secondPage.length || !$secondPageFirstModule.length || !secondPageFirstModuleType ) { hasSurplus = true } else { var curpageSurplusHeight = self.getCurPageSurplusHeight( self.$firstPageContent ) var nextPageFirstModuleHeight = self.getNextPageFirstModuleHeight( $secondPageFirstModule, secondPageFirstModuleType ) hasSurplus = curpageSurplusHeight > nextPageFirstModuleHeight } self.changePrintArea( hasSurplus ? self.$firstPageContent : self.$firstPageContent.next() ) self.editNoScoringWidth() }, //render page initPage: function () { var self = this isShowPreview = window.location.href.indexOf('isPreview') isShowEdit = window.location.href.indexOf('isEdit') $('#hgc_print').height($(window).height()) if (isNewBuild) { $('.switch_ewm').hide() self.initPageForNewBuild() } else { self.getTopicDetails() } if (isShowPreview > -1) { setTimeout(function () { self.previewPrintDiv('printcontent') }, 200) } if (isShowEdit > -1) { setTimeout(function () { self.isCanEditCard = false self.changeCardEditStatus() }, 200) } if(localStorage.examStatus && isShowEdit > -1){ let examStatus = JSON.parse(localStorage.getItem('examStatus')); if(examStatus==2){ $('#saveBtn').unbind(); $('#saveBtn').addClass('disabled') } } }, //创建答题卡部分----------------------------------- //get buildQuestions getBuildQuestions: function () { var self = this // 当前的数据包 // var originQuestions = localStorage.getItem('buildQuestions') var localSavePrintInfo = localStorage.getItem('savePrintInfo') var localBuildQuestions = localSavePrintInfo ? JSON.parse(localSavePrintInfo) : {} var buildQuestions = localBuildQuestions.position ? self.reTopicNum(localBuildQuestions.position.buildQuestions) : {} // var buildQuestions = originQuestions ? JSON.parse(originQuestions) : {} if (isShowPreview > -1) { buildQuestions = JSON.parse(localStorage.getItem('previewBuildQuestions')) } if(localBuildQuestions.position){ self.rePagesId(localBuildQuestions.position.pages) self.reQuestionInfoNum(localBuildQuestions.question_info.content) } self.questionMap = buildQuestions self.setBuildQuestions() return buildQuestions }, reTopicNum: function(data){ jQuery.each(data, function (i, bigTopicData){ jQuery.each(bigTopicData.questions, function (i, minTopicData){ minTopicData.questionNum = minTopicData.alias }) jQuery.each(bigTopicData.pages, function (i, pages){ jQuery.each(pages, function (i, pages){ pages.questionNum = pages.alias }) }) }) return data }, rePagesId: function(data){ jQuery.each(data, function (i, page){ jQuery.each(page.questions, function (i, minTopicData){ minTopicData.id = minTopicData.name }) }) }, reQuestionInfoNum: function(data){ jQuery.each(data, function (i, minTopicData){ minTopicData.questionNum = minTopicData.alias }) }, setBuildQuestions: function () { localStorage.setItem('buildQuestions', JSON.stringify(this.questionMap)) }, //获取记忆配置信息 getMemoryPosition: function () { var self = this var originPosition = JSON.parse(localStorage.getItem('position')) var savePrintInfoData = JSON.parse(localStorage.getItem('savePrintInfo')) savePrintInfoData = savePrintInfoData ? savePrintInfoData : {} originPosition = originPosition ? originPosition : savePrintInfoData.position var position = originPosition ? originPosition : {} return position }, initPageForNewBuild: function () { var self = this localStorage.removeItem('position'); localStorage.removeItem('buildQuestions'); $('#addQustionBtn').show() self.getExamNumConfig() // 当前的数据包 var buildQuestions = self.getBuildQuestions() if ($.isEmptyObject(buildQuestions)) { $('.addTips').show(); } else { $('.addTips').hide(); } /** * //如果是创建考试,则唯一标识符 自定义,用来创建考试页面下载答题卡 var identifier = isNewBuild?_symbolId():self.examGroupId; */ //先进行配置话记忆 --- 正常流式布局 --- 然后记忆布局 var res = self.getMemoryPosition() // if (Object.keys(buildQuestions).length) { // //初始化内容区域,所有的pages 归1 // self.renderSubjectInfo( // self.renderSubjectDataFormatForNewCard(buildQuestions) // ) // //重新定义超出部分布局 // self.changePrintArea(self.$firstPageContent) // } self.bindEvent() self.initEvent() if (Object.keys(res).length) { self.memoryLayout(res) } if (Object.keys(buildQuestions).length) { //初始化内容区域,所有的pages 归1 self.renderSubjectInfo( self.renderSubjectDataFormatForNewCard(buildQuestions) ) //重新定义超出部分布局 self.changePrintArea(self.$firstPageContent) } if (Object.keys(res).length) { self.memoryLayout(res) } }, reInitPageForNewBuild: function () { var self = this // $('#addQustionBtn').show() // self.getExamNumConfig() // 当前的数据包 var buildQuestions = self.questionMap /** * //如果是创建考试,则唯一标识符 自定义,用来创建考试页面下载答题卡 var identifier = isNewBuild?_symbolId():self.examGroupId; */ // printcontent $('#printcontent').find('.pageContent').each(function (index) { if (index === 0) { $(this).find('.dtk-content').find('.answerModule').remove(); } else { $(this).remove(); } }) self.totalPage = 1 $(".pageContent .totalPage").html(self.totalPage) // 试题删除后 隐藏右边操作栏试题显示 if ($('.answerModule').length > 0) { $('#subjectList').html(listHtml) } else { $('#subjectList').html('') } //先进行配置话记忆 --- 正常流式布局 --- 然后记忆布局 var res = self.getMemoryPosition() if (Object.keys(buildQuestions).length) { //初始化内容区域,所有的pages 归1 self.renderSubjectInfo( self.renderSubjectDataFormatForNewCard(buildQuestions) ) //重新定义超出部分布局 self.changePrintArea(self.$firstPageContent) } // self.bindEvent() // self.initEvent() if (Object.keys(res).length) { self.memoryLayout(res) } }, getExamNumConfig: function () { var self = this $.post( self.apis.getExamNumberConfigApi, { grade: localStorage.getItem('grade') }, function (res) { var result = JSON.parse(res) if (result.success === 1) { //初始化默认title var savePrintInfoData = JSON.parse(localStorage.getItem('savePrintInfo')) var testFormData = JSON.parse(localStorage.getItem('testFormData')) var paperName = '' self.cardStatus = result.data.card_status if (savePrintInfoData != null) { paperName = savePrintInfoData.title if (paperName == undefined) { paperName = testFormData ? testFormData.examName : '' } } else { paperName = testFormData ? testFormData.examName : '' } self.renderExamBaseInfo({ school_card_length: +result.data.card_length, school_card_status: 1, paperName: paperName, wpTimes: 90, fullScore: '', wpAuthor: '', wpReviewer: '', }) self.editNoticeDetail(self.useQrCode,result.data.card_status) } } ) }, editNoticeDetail: function (qrStatus,cardStatus) { let noticeDetailMsgBoxXT = '

1、考生务必正确书写班级、姓名,请填涂系统准考证号。

' + '

2、考生务必用2B铅笔填涂。

' + '

3、考生务必在答题卡指定位置作答,并保持卷面整洁。

' + '

4、如需要条形码,则考生务必要在指定位置正确贴好条形码。

' + '

5、教师务必使用红笔阅卷。

'; let noticeDetailMsgBoxXX = '

1、考生务必正确书写班级、姓名,请填涂学校准考证号。

' + '

2、考生务必用2B铅笔填涂。

' + '

3、考生务必在答题卡指定位置作答,并保持卷面整洁。

' + '

4、如需要条形码,则考生务必要在指定位置正确贴好条形码。

' + '

5、教师务必使用红笔阅卷。

'; let noticeDetailMsgBoxQR = '

1、考生务必用2B铅笔填涂。

' + '

2、考生务必在答题卡指定位置作答,并保持卷面整洁。

' + '

3、如需要条形码,则考生务必要在指定位置正确贴好条形码。

' + '

4、教师务必使用红笔阅卷。

'; if(qrStatus){ $('#noticeDetailMsgBox').html(noticeDetailMsgBoxQR) } else { $('#noticeDetailMsgBox').html(cardStatus==0 ? noticeDetailMsgBoxXT : noticeDetailMsgBoxXX) } }, //创建答题卡部分----------------------------------- getTopicDetails: function () { var self = this //如果之前保存过,则需要记忆之前的答题卡排版 $.post( self.apis.getTopicsDetailAPi, { examGroupId: self.examGroupId }, function (res) { res = JSON.parse(res) if (res.success) { //判断是否已经保存过,如果已经保存过,需要记忆布局 self.alreadySave = res.position ? true : false //判断是否题卡合一 self.isSubjectInfoToCard = res.paperTplType == self.subjectCardToOneType if (self.alreadySave) { var memoryPosition = JSON.parse(res.position) self.saveLocationPosition = res.position self.memoryColumns = memoryPosition.columns self.isCanEditCard = false //是否已经有打印班级 self.printClassStatus = res.printClassStatus self.initPrintContentArea() self.renderPage(res, memoryPosition) self.memoryLayout(memoryPosition) self.changeCardEditStatus() } else { self.isCanEditCard = true self.renderPage(res) self.changeCardEditStatus() } } else { hgc_layer.msg('获取试卷题目信息失败') } } ) }, /* -------------------------------------------------------------------------------------------------------------------- 初始页面布局功能开始 --------------------------------------------------------------------------------------------------------------------- */ renderPage: function (renderJSON, memoryPosition) { var self = this memoryPosition = memoryPosition || null self.renderExamBaseInfo(renderJSON.object) //格式化题型题号信息 -- 可重复执行 self.renderSubjectInfo( self.renderSubjectDataFormat(renderJSON.object.questions), memoryPosition ) if (!self.alreadySave) { //重新定义超出部分布局 self.changePrintArea(self.$firstPageContent) } self.bindEvent() self.initEvent() }, //渲染答题卡基本信息 准考证号、名称、考试时间等 renderExamBaseInfo: function (examInfo) { var self = this //答题卡题目类型 self.$dtkName.val(examInfo.paperName) // var examInfoHtml = self.tpls.examInfoTpl.substitute(examInfo) // $('#examInfo').html(examInfoHtml) // self.examInfoConfigText.wpTimes = examInfo.wpTimes // self.examInfoConfigText.fullScore = examInfo.fullScore // self.examInfoConfigText.wpAuthor = examInfo.wpAuthor // self.examInfoConfigText.wpReviewer = examInfo.wpReviewer let examInfoConfigText = { wpTimes: examInfo.wpTimes, fullScore: examInfo.fullScore, wpAuthor: examInfo.wpAuthor, wpReviewer: examInfo.wpReviewer } self.examInfoConfigText = examInfoConfigText self.showExamInfoHtml() //准考证号信息 self.renderExamNumberInfo(examInfo) }, //准考证号信息 renderExamNumberInfo: function (examInfo) { var self = this //准考证号类型 1学校准考证 0系统准考证 self.school_card_status = examInfo.school_card_status //准考证号长度 var school_card_length = examInfo.school_card_length var examNumberHtml = '' var examNumberForOnlyCodeHtml = '' for (var colIndex = 0; colIndex < school_card_length; colIndex++) { examNumberHtml += self.tpls.examNumberItemTpl examNumberForOnlyCodeHtml += '' } $('#hgc_examNumber .ticketNumber').html(examNumberHtml) $('#hgc_examNumberForOnlyBarcode .ticketNumber p').html( examNumberForOnlyCodeHtml ) }, renderSubjectDataFormat: function (questions) { var self = this //大题分类 var curGuid = '' var questionClassify = {} self.questionMap = questionClassify questions.forEach(function (question, index) { var curType = self.questionTypeMapForC[question.questionTypeId] var prevIndex = index - 1 var prevQuestionTypeId = questions[prevIndex] ? questions[prevIndex].questionTypeId : '' var prevType = prevQuestionTypeId ? self.questionTypeMapForC[prevQuestionTypeId] : '' //如果之前的题型type和现在的题型type不一样,新建一个key做大题类型 if (prevType !== curType) { curGuid = guid() questionClassify[curGuid] = { questions: [question] } } else { questionClassify[curGuid].questions.push(question) } }) var titleTPls = { singleSelect: '、选择题(本大题共{subjectCount}小题,{subjectPointText}共{totalPoint}分。在每小题给出的四个选项中,只有一项是符合题目要求的。把答案填涂在答题卡上。)', moreSelect: '、多选题(本大题共{subjectCount}小题,{subjectPointText}共{totalPoint}分。在每小题给出的四个选项中,有两项及以上是符合题目要求的。把答案填涂在答题卡上。)', fillInBlank: '、填空题(本大题共{subjectCount}小题,{subjectPointText}共{totalPoint}分。把答案填写在答题卡相应的题号后的横线上。)', shortAnswer: '、解答题(本大题共{subjectCount}小题,{subjectPointText}共{totalPoint}分。解答写出相应的文字说明、证明过程或演算步骤。)', chooseAnswer: '、选做题(本题包括{chooseOption}{chooseOptionLength}小题,请选定其中{chooseCount}小题,并在相应的答题区域内作答,请用2B铅笔涂黑(示例:■)。若多做,则按作答的前一小题评分。解答应写出文字说明、证明过程或演算步骤。)
{chooseSubjectContent}
', mustAnswer: '、必做题(本大题共{subjectCount}小题,{subjectPointText}共{totalPoint}分。解答写出相应的文字说明、证明过程或演算步骤。)' //一、选做题( 本题包括A、B两小题,请选定其中一小题,并在相应的答题区域内作答,请用2B铅笔涂黑(示例:■)。若多做,则按作答的前一小题评分。解答应写出文字说明、证明过程或演算步骤。) } var objectiveTitleTpl = { singleSelect: '、选择题题文', moreSelect: '、多选题题文', fillInBlank: '、填空题题文' } //填空题,选择题超出控制数据 var numberIndex = 0 for (var uid in questionClassify) { var questionClassifyItem = questionClassify[uid] //题型单个大题下面所有小题 var questionClassifyItemQuestions = questionClassifyItem.questions var typeId = questionClassifyItem.questions[0].questionTypeId var type = self.questionTypeMapForC[typeId] questionClassifyItem.questionType = typeId numberIndex++ var titleFormatData = {} var isChooseAnswer = type === 'chooseAnswer' var isMoreSelect = type === 'moreSelect' //选做题题干信息 var chooseSubjectContent = '' //选做题标题特殊对待 if (isChooseAnswer) { var chooseOptionLength = SectionToChinese( questionClassifyItemQuestions.length ) var chooseOption = questionClassifyItemQuestions .map(function (questionItem, index) { chooseSubjectContent += '
' + questionItem.questionNum + '、' + questionItem.queBody + '
' return String.fromCharCode(65 + index) }, []) .join(',') var chooseCount = SectionToChinese( questionClassifyItemQuestions[0].required ) titleFormatData = { chooseOption: chooseOption, chooseCount: chooseCount === '二' ? '两' : chooseCount, chooseOptionLength: chooseOptionLength === '二' ? '两' : chooseOptionLength } } else { var subjectCount = questionClassifyItemQuestions.length var subjectPoint = questionClassifyItemQuestions[0].fullScore var totalPoint = 0 var isSameScore = questionClassifyItemQuestions.every(function (item) { return item.fullScore === subjectPoint }) var subjectPointText = '' if (isSameScore) { subjectPointText = '每小题{subjectPoint}分,'.substitute({ subjectPoint: subjectPoint }) totalPoint = subjectPoint * subjectCount } else { subjectPointText = questionClassifyItemQuestions.reduce( (total, cur) => { total += '第{questionNum}题{fullScore}分,'.substitute(cur) totalPoint += cur.fullScore return total }, '' ) } titleFormatData = { subjectCount: subjectCount, subjectPoint: subjectPoint, totalPoint: totalPoint, subjectPointText: subjectPointText } } //如果需要题卡合一的话 //选做题的题干信息不可编辑 if (self.isSubjectInfoToCard && isChooseAnswer) { titleFormatData.chooseSubjectContent = '
' + chooseSubjectContent + '
' } //试卷大题默认title 如果是接口传入,则使用接口传入的字段 questionClassifyItem.bigTitle = SectionToChinese(numberIndex) + titleTPls[type].substitute(titleFormatData) //题干信息title---只针对客观题 if (objectiveTitleTpl[type]) { questionClassifyItem.objectiveTitle = '

' + SectionToChinese(numberIndex) + objectiveTitleTpl[type] + '

' } questionClassifyItem.pages = { page1: simpleCopy(questionClassifyItemQuestions), page2: [] } } return questionClassify }, //所有的pages 数据归1 renderSubjectDataFormatForNewCard: function (buildQuestions) { var self = this for (var modelId in buildQuestions) { var buildQuestionsItem = buildQuestions[modelId] var allPageData = [] for (var page in buildQuestionsItem.pages) { allPageData = allPageData.concat(buildQuestionsItem.pages[page]) } buildQuestionsItem.pages = { page1: allPageData, page2: [] } } return buildQuestions }, titleHtml: function (title) { var self = this return title ? self.tpls.moduleTitleTpl.substitute({ title: title }) : '' }, //渲染答题卡题目题型信息 renderSubjectInfo: function (questionClassify, memoryPosition) { var self = this //渲染右侧操作栏 题目列表信息 -- 可重复执行 self.renderSubjectListInfo(questionClassify) //保存题目定位点的时候 获取 题目数量 分数 等信息 -- 可重复执行 self.getSaveSubjectInfo(questionClassify) //批量渲染所有题型模块 if (!self.firstEnterPage) return var dtkContentEl = $('.dtk-content') for (var uid in questionClassify) { var questionClassifyItem = questionClassify[uid] var questionType = questionClassifyItem.questionType var subjectType = self.questionTypeMapForC[questionType] questionClassifyItem.modelId = uid if (subjectType === 'shortAnswer' && !isNewBuild) { //或者一开始进来就是题卡合一 if (!self.alreadySave && self.isSubjectInfoToCard) { self.renderObjective() //有记忆的时候先渲染题卡合一,主要是缓存原题干信息内容 } else if ( memoryPosition && memoryPosition.stemInfo && memoryPosition.stemInfo.length ) { self.renderObjective() } } self[subjectType + 'Render'](questionClassifyItem, dtkContentEl) } }, //右侧题目列表模块-布局 renderSubjectListInfo: function (questionClassify) { var self = this var listItemTpl = '
{name}
{quantityList}
' var listItemNoTpl = '
{quantityStart}~{quantityEnd}
' var listItemNoXzTpl = '
{quantityStart}
' var listHtml = '' for (var uid in questionClassify) { let questions = questionClassify[uid].questions let configData = questionClassify[uid].commonFields if (!questions[0]) continue let listItemNoHtml = '' jQuery.each(configData.questionTypeArr, function (i, configItem) { let Start = configItem.startNo let End = configItem.endNo if (configData.questionType == 17) { listItemNoHtml += listItemNoXzTpl.substitute({ quantityStart: Start }) } else { listItemNoHtml += listItemNoTpl.substitute({ quantityStart: Start, quantityEnd: End }) } }); let questionType = questionClassify[uid].questionType if (questionType == 7) { questionType = questionClassify[uid].markQuestionType } listHtml += listItemTpl.substitute({ name: self.questionNameMap[self.questionTypeMapForC[questionType]], quantityList: listItemNoHtml }) } $('#subjectList').html(listHtml) }, /** ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— 客观题题干内容渲染 开始 ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— */ renderObjective: function (cb) { var self = this questionClassify = self.questionMap self.originStemInfos = [] //,'shortAnswer','chooseAnswer','mustAnswer' var quesTypeOrder = ['fillInBlank', 'moreSelect', 'singleSelect'] function getDataFromSubjectType(subjectType) { var subjectData for (var uid in questionClassify) { var questionType = questionClassify[uid].questionType if (self.questionTypeMapForC[questionType] === subjectType) { subjectData = questionClassify[uid].pages break } } return subjectData } //判断第一次出现的分页 var lastPageIndex var lastPageType quesTypeOrder.forEach(function (type) { if (lastPageType) return var subjectData = getDataFromSubjectType(type) if (subjectData) { var pageIndex = Object.keys(subjectData).length function getLastPageIndex() { var pageData = subjectData['page' + pageIndex] if (pageData && pageData.length) { lastPageIndex = pageIndex lastPageType = type } else { pageIndex-- getLastPageIndex() } } getLastPageIndex() } }) //找到最后一个分页处理 var $afterPage = $('.pageContent').eq(lastPageIndex - 1) var $afterContent = $afterPage.children('.dtk-content') var $afterModule //根据type 来判断题干信息该放在哪个元素后面 if (lastPageType === 'fillInBlank') { $afterModule = $afterContent.children('.completion-topic') } else if (lastPageType === 'moreSelect') { $afterModule = $afterContent.children('.moreSelect') } else if (lastPageType === 'singleSelect') { $afterModule = $afterContent.children('.single-select:last()') } quesTypeOrder.forEach(function (quesType) { //找到对应的模块,所有的主观题的题干信息 var quesTypeData for (var modelId in questionClassify) { var questionClassItem = questionClassify[modelId] var typeId = questionClassItem.questionType var type = self.questionTypeMapForC[typeId] if (type === quesType) { quesTypeData = questionClassItem break } } if (quesTypeData.questions && quesTypeData.questions.length) { self[quesType + 'StemRender'](quesTypeData, $afterModule) } }) //图片加载时间 self.judegeImgsLoaded('.objectiveItem') cb && cb($afterPage) }, //公式自带的行内样式转换mm changeUnitForFormulaPic: function (parent, type) { var self = this parent = parent || $('.answerModule') parent.find('img').each(function () { var oh = $(this).attr('height') var ow = $(this).attr('width') if (!/^\d+$/.test(oh) || !/^\d+$/.test(ow)) return var widthMatch = $(this)[0].outerHTML.match(/width="(\d{1,3})"/) || [0, 0] var heightMatch = $(this)[0].outerHTML.match(/height="(\d{1,3})"/) || [ 0, 0 ] var pxWidth = +widthMatch[1] var pxHeight = +heightMatch[1] if (!pxWidth && !pxHeight) return //给你图片最大宽度的阀值 var isMaxWidth = pxWidth > 430 var mmWidth = self.unitConversion.pxConversionMm(pxWidth) + 'mm' var mmHeight = type === 'origin' || !isMaxWidth ? self.unitConversion.pxConversionMm(pxHeight) + 'mm' : 'auto' var originStyle = $(this).attr('style') || '' $(this).attr( 'style', originStyle + ';width:' + mmWidth + ';height:' + mmHeight + ';max-width:100%;' ) }) }, queBodyRegExp: /^/, singleSelectStemRender: function (questionClassItem, $afterModule) { var self = this var htmls = questionClassItem.objectiveTitle var data = questionClassItem.questions var stemInfos = [] data.forEach(function (item) { //一排排列几个 //0一排一个 1一排4个 2一排两个', var columnNumber = typeof item.listType === 'number' ? !item.listType ? 1 : item.listType === 1 ? 4 : 2 : '' var columnClass = columnNumber ? 'column-' + columnNumber : '' var content = item.queBody.replace( self.queBodyRegExp, '' + item.questionNum + '、' ) var optionsHtml = '
' item.queOptions.forEach(function (option, index) { optionsHtml += '

' + String.fromCharCode(65 + index) + '.

' + option.content + '
' }) optionsHtml += '
' var stemItemHtml = self.tpls.objectiveItemTpl.substitute({ content: content, options: optionsHtml }) //如果是题卡合一并且是保存状态的时候 才会保存原题信息 if (self.isSubjectInfoToCard) { stemInfos.push(encodeURIComponent(stemItemHtml)) } htmls += stemItemHtml }) self.originStemInfos = stemInfos.concat(self.originStemInfos) htmls = self.tpls.objectiveWrapTpl.substitute({ editModule: htmls }) $afterModule.after(htmls) }, moreSelectStemRender: function (questionClassItem, $afterModule) { var self = this var htmls = questionClassItem.objectiveTitle var data = questionClassItem.questions var stemInfos = [] data.forEach(function (item) { var columnNumber = typeof item.listType === 'number' ? !item.listType ? 1 : item.listType === 1 ? 4 : 2 : '' var columnClass = columnNumber ? 'column-' + columnNumber : '' var content = item.queBody.replace( self.queBodyRegExp, '' + item.questionNum + '、' ) var optionsHtml = '
' item.queOptions.forEach(function (option, index) { optionsHtml += '

' + String.fromCharCode(65 + index) + '.

' + option.content + '
' }) optionsHtml += '
' var stemItemHtml = self.tpls.objectiveItemTpl.substitute({ content: content, options: optionsHtml }) //如果是题卡合一并且是保存状态的时候 才会保存原题信息 if (self.isSubjectInfoToCard) { stemInfos.push(encodeURIComponent(stemItemHtml)) } htmls += stemItemHtml }) self.originStemInfos = stemInfos.concat(self.originStemInfos) htmls = self.tpls.objectiveWrapTpl.substitute({ editModule: htmls }) $afterModule.after(htmls) }, fillInBlankStemRender: function (questionClassItem, $afterModule) { var self = this var htmls = questionClassItem.objectiveTitle var data = questionClassItem.questions var stemInfos = [] data.forEach(function (item) { var content = item.queBody.replace( self.queBodyRegExp, '' + item.questionNum + '、' ) var stemItemHtml = self.tpls.objectiveItemTpl.substitute({ content: content }) //如果是题卡合一并且是保存状态的时候 才会保存原题信息 if (self.isSubjectInfoToCard) { stemInfos.push(encodeURIComponent(stemItemHtml)) } htmls += stemItemHtml }) htmls = self.tpls.objectiveWrapTpl.substitute({ editModule: htmls }) self.originStemInfos = stemInfos.concat(self.originStemInfos) $afterModule.after(htmls) }, /** * ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— 主观题题干内容渲染 结束 ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— */ getSingleSelectHtml: function (datas, type) { var self = this //判断是否多选 var isMoreSelect = type === 'more' var moreSelectClass = isMoreSelect ? 'more-option' : '' var singleSelectHtml = '' var singleColHtml = '' datas.forEach(function (singleItem, index) { var singleContent = '' for (var i = 0; i < singleItem.optionCount; i++) { var option = String.fromCharCode(65 + i) singleContent += '[{option}]'.substitute( { option: option } ) } singleColHtml += self.tpls.singleSelectOptionTpl.substitute({ _index: ++index, singleContent: singleContent, questionNum: singleItem.questionNum, answer: singleItem.answer, alias: singleItem.alias }) if (!(index % 5)) { singleSelectHtml += '
    ' + singleColHtml + '
' singleColHtml = '' } }) singleSelectHtml += !datas.length % 5 ? '' : '
    ' + singleColHtml + '
' return singleSelectHtml }, /** * @param {多选 or 单选} title * @param {选择题布局方向} direction * @param {选择题内容} selectContent */ getSelectRenderContent: function (data) { //selectContent, title, direction,hasTitle var self = this data.settingBtn = typeof data.settingBtn === 'boolean' ? data.settingBtn : true /** * vertical 竖向布局 * horizontal 横向布局 */ var direction = data.direction || 'vertical' var hasTitle = typeof data.hasTitle === 'undefined' ? true : data.hasTitle var SingleSelectModuleHtml = self.tpls.selectTpl.substitute({ title: hasTitle ? self.titleHtml(data.bigTitle) : '', direction: direction, moduleType: data.moduleType, selectContent: data.selectContent, modelId: data.modelId, settingBtn: data.settingBtn ? '
'.substitute({ moduleType: data.title }) : '' }) return SingleSelectModuleHtml }, //单选题--布局 // { // bigTitle:'', // question:[] // } getDirection: function (direction) { if (typeof direction === 'number') { return direction ? 'vertical' : 'horizontal' } else { return direction ? direction : 'vertical' } }, singleSelectRender: function (questionModelData, appendEl, replaceEl) { var self = this var datas = questionModelData.questions var modelId = questionModelData.modelId var direction = self.getDirection(questionModelData.direction) var singleSelectHtml = self.getSingleSelectHtml(datas, 'single') //selectContent, title, direction,hasTitle var SingleSelectModuleHtml = self.getSelectRenderContent({ selectContent: singleSelectHtml, moduleType: 'singleSelect', bigTitle: questionModelData.bigTitle, modelId: modelId, direction: direction }) if (replaceEl) { replaceEl[0].outerHTML = SingleSelectModuleHtml var $settingBtn = self.getSettingBtn(modelId) self.selectStyleChange($settingBtn, direction) } else { appendEl.append(SingleSelectModuleHtml) } }, //多选题--布局 moreSelectRender: function (questionModelData, appendEl, replaceEl) { var self = this var datas = questionModelData.questions var modelId = questionModelData.modelId var direction = self.getDirection(questionModelData.direction) //获取选项html var singleSelectHtml = self.getSingleSelectHtml(datas, 'more') //获取整个选择题区域模块html //selectContent, title, direction,hasTitle var SingleSelectModuleHtml = self.getSelectRenderContent({ selectContent: singleSelectHtml, moduleType: 'moreSelect', bigTitle: questionModelData.bigTitle, modelId: modelId, direction: direction }) if (replaceEl) { replaceEl[0].outerHTML = SingleSelectModuleHtml var $settingBtn = self.getSettingBtn(modelId) self.selectStyleChange($settingBtn, direction) } else { appendEl.append(SingleSelectModuleHtml) } }, //不定项--布局 uncertainOptionRender: function (questionModelData, appendEl, replaceEl) { var self = this var datas = questionModelData.questions var modelId = questionModelData.modelId var direction = self.getDirection(questionModelData.direction) //获取选项html var singleSelectHtml = self.getSingleSelectHtml(datas, 'more') //获取整个选择题区域模块html //selectContent, title, direction,hasTitle var SingleSelectModuleHtml = self.getSelectRenderContent({ selectContent: singleSelectHtml, moduleType: 'uncertainOption', bigTitle: questionModelData.bigTitle, modelId: modelId, direction: direction }) if (replaceEl) { replaceEl[0].outerHTML = SingleSelectModuleHtml var $settingBtn = self.getSettingBtn(modelId) self.selectStyleChange($settingBtn, direction) } else { appendEl.append(SingleSelectModuleHtml) } }, getFillInBlankHtml: function (datas) { var self = this var fillInBlankHtml = '' var getScoreHtml = function (scoreStyle) { if (!scoreStyle) return '' return scoreStyle.split('/').reduce(function (total, score) { total += '' + score + '' return total }, '') } datas.forEach(function (fillInBlankItem) { fillInBlankItem.scoreStyle = fillInBlankItem.scoreStyle || '' fillInBlankItem.scoreHtml = getScoreHtml(fillInBlankItem.scoreStyle) fillInBlankHtml += self.tpls.fillInBlankItemTpl.substitute( fillInBlankItem ) }) return fillInBlankHtml }, getFillInBlankRenderContent: function ( fillInBlankHtml, title, scoreStyle, modelId, rowLineHeight, columns ) { var self = this title = title || '' var fillInBlankModuleHtml = self.tpls.fillInBlankTpl.substitute({ fillInBlankContent: fillInBlankHtml, scoreStyle: scoreStyle, title: title, modelId: modelId, rowLineHeight, columns }) return fillInBlankModuleHtml }, //填空题--布局 formatRenderDataForFillInBlank: function (datas, scoreStyle) { var renderData = JSON.parse(JSON.stringify(datas)) return renderData.map(function (item) { item.scoreStyle = scoreStyle return item }) }, fillInBlankRender: function (questionModelData, appendEl, replaceEl) { var self = this var datas = questionModelData.questions var bigTitle = questionModelData.bigTitle var modelId = questionModelData.modelId var column = questionModelData.columns || 1 var rowLinHeight = questionModelData.rowLineHeight || 40 var scoreStyle = questionModelData.scoreStyle || '' var renderData = self.formatRenderDataForFillInBlank(datas, scoreStyle) var fillInBlankHtml = self.getFillInBlankHtml(renderData) var fillInBlankModuleHtml = self.getFillInBlankRenderContent( fillInBlankHtml, self.titleHtml(bigTitle), scoreStyle, modelId, rowLinHeight, column ) if (replaceEl) { replaceEl[0].outerHTML = fillInBlankModuleHtml var $settingBtn = self.getSettingBtn(modelId) self.fillInBlankStyleChange($settingBtn, column, rowLinHeight, scoreStyle) } else { appendEl.append(fillInBlankModuleHtml) } }, //重新渲染填空题 reRenderFillInBlank: function (modelId) { var self = this var pageIndex = 1 while (self.questionMap[modelId]['page' + pageIndex]) { var pageFillInBlank = self.questionMap[modelId]['page' + pageIndex] var scoreStyle = self.questionMap[modelId].scoreStyle || '' if (!pageFillInBlank.length) { pageIndex++ continue } var $curPage = $('#printcontent .pageContent').eq(pageIndex - 1) var $pageFillInBlank = null $curPage.find('.completion-topic').each(function () { var findModelId = $(this).attr('data-modelId') if (modelId === findModelId) { $pageFillInBlank = $(this).find('.subjectCol') } }) $pageFillInBlank .attr('data-scorestyle', scoreStyle) .html(self.getFillInBlankHtml(pageFillInBlank)) pageIndex++ } }, //解答题获取最小可选分值 getAnswerMinScoreLimit: function (limit) { var self = this var minLimit = 16 for (var i = 0, item; (item = self.answerScoreLimitKeyArr[i++]);) { if (item >= limit) { minLimit = item break } } return minLimit }, //解答题--布局 shortAnswerRender: function (questionModelData, appendEl, replaceEl) { var self = this var shortAnswerTpl = self.tpls.shortAnswerItemTpl var shortAnswerHtml = '' var datas = questionModelData.questions datas.forEach(function (shortAnswerItem) { shortAnswerItem.editorContentHeight = shortAnswerItem.editorContentHeight ? shortAnswerItem.editorContentHeight : self.moduleDefaultHeihgt //scorelimitkey 15 16 29 49 isHalf 是否有半分的概念 var minLimit = self.getAnswerMinScoreLimit(shortAnswerItem.fullScore) if (Number(shortAnswerItem.fullScore) < questionModelData.dialogData.scoreLimit) { minLimit = questionModelData.dialogData.scoreLimit } shortAnswerItem.scoreColumnHtml = self.generateScoreBox(minLimit, questionModelData.isAddHalf, shortAnswerItem.fullScore) shortAnswerItem.scoreLimit = minLimit shortAnswerHtml += shortAnswerTpl.substitute(shortAnswerItem) //保存原题信息 self.editorAreaOriginContent[shortAnswerItem.questionNum] = shortAnswerItem.queBody || '' }) var shortAnswerModuleHtml = self.tpls.shortAnswerTpl.substitute({ shortAnswerContent: shortAnswerHtml, title: questionModelData.bigTitle, modelId: questionModelData.modelId }) if (replaceEl) { replaceEl[0].outerHTML = shortAnswerModuleHtml } else { appendEl.append(shortAnswerModuleHtml) } //初始化解答题富文本插件 datas.forEach(function (item) { var questionNum = item.questionNum var answerContent = '' let topicType = item.questionTypeId if (topicType == 7) { topicType = item.markQuestionType } //题卡合一渲染原题信息 if (!self.alreadySave && self.isSubjectInfoToCard) { answerContent = self.editorAreaOriginContent[questionNum] } // self.createShortAnswer(questionNum, answerContent) self.createShortAnswer(item.topicEditorIndex, answerContent, topicType) }) }, //选做题--布局 chooseAnswerRender: function (questionModelData, appendEl, replaceEl) { var self = this var chooseAnswerTpl = self.tpls.chooseAnswerItemTpl var editorCreateIds = [] var datas = questionModelData.questions var bigTigle = questionModelData.bigTitle var modelId = questionModelData.modelId //m 选 n 的n var requiredCount = datas[0].required || 1 var chooseAnswerHtml = '' //外显题号 var questionNumShow = 0 for (var i = 0; i < requiredCount; i++) { var selOptionHtml = '' var startChooseNumber = 0 var titleNumber = '' var fullScore = 16 datas.forEach(function (item, index) { if (index === i) { if (!questionNumShow) questionNumShow = item.topicNo // item.questionNum + '~' + (+item.questionNum + datas.length - 1) startChooseNumber = item.questionNum editorCreateIds.push(item.questionNum) self.editorAreaOriginContent[item.questionNum] = item.queBody || '' fullScore = item.fullScore } // titleNumber += item.questionNum + ',' titleNumber = item.topicNo selOptionHtml += '[{char}]'.substitute( { char: String.fromCharCode(65 + index), titleNumber: item.questionNum } ) }) var minLimit = self.getAnswerMinScoreLimit(fullScore) if (Number(datas[0].fullScore) < questionModelData.dialogData.scoreLimit) { minLimit = questionModelData.dialogData.scoreLimit } var scoreColumnHtml = self.generateScoreBox(minLimit, questionModelData.isAddHalf, datas[0].fullScore) chooseAnswerHtml += chooseAnswerTpl.substitute({ questionNum: startChooseNumber, questionNumShow: questionNumShow, //4,5,6, // titleNumber: titleNumber.substring(0, titleNumber.length - 1), titleNumber: titleNumber, selOptionHtml: selOptionHtml, scoreColumnHtml: scoreColumnHtml, editorContentHeight: self.moduleDefaultHeihgt, scoreLimit: minLimit, fullScore:datas[0].fullScore }) } //先渲染多选题 //选做题题干信息单独处理 var chooseAddTitle = '' var hasObjective = self.chooseAnswerObjective && !self.alreadySave if (hasObjective) { chooseAddTitle = self.chooseAnswerObjective } var chooseAnswerModuleHtml = self.tpls.chooseAnswerTpl.substitute({ chooseAnswerContent: chooseAnswerHtml, title: bigTigle, modelId: modelId }) if (replaceEl) { replaceEl[0].outerHTML = chooseAnswerModuleHtml } else { appendEl.append(chooseAnswerModuleHtml) } //如果有题干信息 if (hasObjective) { self.judegeImgsLoaded( '.answerModule[data-type="chooseAnswer"] .originSubjectInfo' ) } editorCreateIds.forEach(function (editorId) { self.createShortAnswer(editorId) }) }, //必做题--布局 mustAnswerRender: function (datas, appendEl, replaceEl) { var self = this var shortAnswerTpl = self.tpls.shortAnswerItemTpl var shortAnswerHtml = '' datas.forEach(function (shortAnswerItem) { shortAnswerItem.editorContentHeight = shortAnswerItem.editorContentHeight ? shortAnswerItem.editorContentHeight : self.moduleDefaultHeihgt var minLimit = self.getAnswerMinScoreLimit(shortAnswerItem.fullScore) shortAnswerItem.scoreColumnHtml = self.generateScoreBox(minLimit, false) shortAnswerItem.scoreLimit = minLimit shortAnswerHtml += shortAnswerTpl.substitute(shortAnswerItem) //保存原题信息 self.editorAreaOriginContent[shortAnswerItem.questionNum] = shortAnswerItem.queBody || '' }) var shortAnswerModuleHtml = self.tpls.shortAnswerTpl.substitute({ shortAnswerContent: shortAnswerHtml, title: questionModelData.bigTigle, modelId: questionModelData.modelId }) if (replaceEl) { replaceEl[0].outerHTML = shortAnswerModuleHtml } else { appendEl.append(shortAnswerModuleHtml) } //初始化解答题富文本插件 datas.forEach(function (item) { var questionNum = item.questionNum var answerContent = '' if (!self.alreadySave && self.isSubjectInfoToCard) { answerContent = self.editorAreaOriginContent[questionNum] } self.createShortAnswer(questionNum, answerContent) }) }, /*-------------------------------------------------------------------------------------------------------------------- 初始页面布局功能结束 -----------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------- 记忆布局功能开始 ------------------------------------------------------------------------------------------------------------------------------------*/ memoryLayout: function (res) { var self = this var formatData = self.memoryDataFormat(res) var shortAnswerData = formatData.shortAnswerData // 先控制是否有装订线,纸张大小,方向,分栏,装订线考号 //{paper,direction,hasBindingLine,examNumberConfig:{barCode,ticketNumber},useQrCode} self.memoryHasBindLine(res.hasBindingLine) self.memoryPaperDirectColumn(res.paper, res.direction, res.columns) //记忆布局--考号配置 self.memoryExamNumberConfig(res.examNumberConfig, res.useQrCode) // 信息栏 self.memoryHasPaperMsgConfig(res) //如果不是创建答题卡 if (!isNewBuild) { //记忆布局--选择题选项排列方向设置 var singleSelectData = formatData.singleSelectData var moreSelectData = formatData.moreSelectData var fillInBlankData = formatData.fillInBlankData if (singleSelectData.length) { self.memorySelectData(singleSelectData[0].direction, 'singleSelect') } if (moreSelectData.length) { self.memorySelectData(moreSelectData[0].direction, 'moreSelect') } if (fillInBlankData.length) { self.memoryFillInBlank(fillInBlankData) } if (res.stemInfo && res.stemInfo.length) { self.memoryObjective(res.stemInfo, res.chooseAnswerStemInfo) } } //然后再布局 self.memoryShortAnswer(shortAnswerData) }, //把每一题的数据整合到一起 memoryDataFormat: function (res) { var self = this //选择题可以设置选项排列方向 var singleSelectData = [] var moreSelectData = [] //填空题可以设置每行列数、分值格式等 var fillInBlankData = [] var shortAnswerData = [] var linkQuestionData = {} res.pages.forEach(function (pageData, index) { for ( var i = 0, questionItem; (questionItem = pageData.questions[i++]); ) { var questionType = questionItem.type switch (questionType) { //选择题 case self.questionTypeMapForPhp.singleSelect: singleSelectData.push(questionItem) break case self.questionTypeMapForPhp.moreSelect: moreSelectData.push(questionItem) break //填空题 case self.questionTypeMapForPhp.fillInBlank: fillInBlankData.push(questionItem) break //解答题 or 选做题 case self.questionTypeMapForPhp.answer: case self.questionTypeMapForPhp.chooseAnswer: case self.questionTypeMapForPhp.mustAnswer: //非多选题 var isShortAnswer = questionType === 1 var linkParm = isShortAnswer ? questionItem.cut.linkparm : questionItem.selectqts[0].cut.linkparm //linkParm > 0 补充模块 如果存在补充模块 , 则先合并 if (linkParm) { //第一个补充模块 if (linkParm === 1) { if (JSON.stringify(linkQuestionData) !== '{}') { shortAnswerData.push(linkQuestionData) linkQuestionData = {} } linkQuestionData = questionItem } else { //后面几个补充模块 if (isShortAnswer) { linkQuestionData.cut.height += questionItem.cut.height } else { linkQuestionData.selectqts[0].cut.height += questionItem.selectqts[0].cut.height } linkQuestionData.contents += questionItem.contents } if ( ((res.pages[index + 1] && !res.pages[index + 1].questions.length) || index + 1 === res.pages.length) && !pageData.questions[i + 1] ) { shortAnswerData.push(linkQuestionData) } } else { if (JSON.stringify(linkQuestionData) !== '{}') { shortAnswerData.push(linkQuestionData) linkQuestionData = {} } shortAnswerData.push(questionItem) } break } } }) return { shortAnswerData: shortAnswerData, fillInBlankData: fillInBlankData, singleSelectData: singleSelectData, moreSelectData: moreSelectData } }, memoryHasBindLine: function (hasBindingLine) { if (hasBindingLine) { $('#hasBindingLine .h_radioItem').eq(0).trigger('click') } }, //基本布局 纸张规格方向分栏 memoryPaperDirectColumn: function (paper, direction, column) { var self = this $('#paperOptions .h_radioItem').each(function () { if ($(this).attr('data-paper') === paper) { $(this).trigger('click') } }) $('#paperDirection .h_radioItem').each(function () { if ($(this).attr('data-direction') === direction) { $(this).trigger('click') } }) $('.layoutList .layoutItem').each(function () { //column type:number if ($(this).attr('data-column') == column) { $(this).trigger('click') } }) }, //记忆布局--考号配置 memoryExamNumberConfig: function (examNumberConfig, useQrCode) { var self = this $('#examNumberConfig .h_checkItem').each(function () { var configName = $(this).attr('data-value') var isChecked = $(this).hasClass('checked') if (examNumberConfig[configName]) { if (!isChecked) $(this).trigger('click') } else { if (isChecked) $(this).trigger('click') } }) //是否使用二维码 var useQrCodeStatus = $('#useQrCode').hasClass('open') if (useQrCode) { if (!useQrCodeStatus) { $('#useQrCode').trigger('click') } } else { if (useQrCodeStatus) { $('#useQrCode').trigger('click') } } }, //记忆布局--信息栏 memoryHasPaperMsgConfig: function (hasPaperMsgConfig) { var self = this // $('#hasPaperMsg .h_checkItem').each(function () { // var configName = $(this).attr('data-value') // var isChecked = $(this).hasClass('checked') // if (hasPaperMsgConfig[hasPaperMsg]) { // if (!isChecked) $(this).trigger('click') // } else { // if (isChecked) $(this).trigger('click') // } // }) self.examInfoConfigText=hasPaperMsgConfig.examInfoConfigText; self.examInfoConfig=hasPaperMsgConfig.examInfoConfig; self.hasPaperMsg=hasPaperMsgConfig.hasPaperMsg; self.isShowPaperMsg(); }, memorySelectData: function (direction, type) { var self = this var $this = $('.' + type) .eq(0) .find('.settingBtn') self.selectStyleChange($this, direction) }, memoryFillInBlank: function (fillInBlankData) { var self = this var questionItem = fillInBlankData[0] var modelId = questionItem.modelId //当前答题卡只有一大填空题大题的情况下 var $this = null var column = questionItem.column || 1 var rowLinHeight = questionItem.rowLinHeight || 40 var scoreStyle = questionItem.scoreStyle || '' $('.completion-topic').each(function () { if ($(this).attr('data-modelId') === modelId) { $this = $(this) return false } }) self.fillInBlankStyleChange($this, column, rowLinHeight, scoreStyle) }, /** * * ajax 异步图片加载完成 * srcList * _img = new Image() * _img.src = srcList[i] */ judegeImgsLoaded: function (imgBoxSelector, cb) { var imgList = [] var $imgBox = $(imgBoxSelector) $imgBox.find('img').each(function () { var imge = $(this) var styles = imge.attr('style') if (styles) { styles = styles.replace(/height:auto;/g, '') imge.attr('style', styles) } imgList.push($(this).attr('src')) }) if (!imgList.length) return var self = this var i = 0 var imgLen = imgList.length function imgLoad() { var _img = new Image() _img.src = imgList[i] _img.onload = function () { i++ if (i >= imgLen) { self.changeUnitForFormulaPic($(imgBoxSelector)) cb && cb() } else { imgLoad() } } _img.onerror = function () { i++ if (i >= imgLen) { self.changeUnitForFormulaPic($(imgBoxSelector)) cb && cb() } else { imgLoad() } } } imgLoad() }, memoryObjective: function (stemInfo, chooseAnswerStemInfo) { var self = this stemInfo = typeof stemInfo === 'object' ? stemInfo : stemInfo.split('|end|') var isBase64Save = isBase64(stemInfo[0]) var imgList = [] $('.objectiveItem').each(function (index) { var replaceStr = '' if (isBase64Save) { replaceStr = decode(stemInfo[index]); } else { replaceStr = decodeURIComponent(stemInfo[index]); } $(this)[0].outerHTML = replaceStr }) //选做题单独处理 if (chooseAnswerStemInfo) { var $chooseAnswer = $('.answerModule[data-type="chooseAnswer"]') var $chooseAnswerObjective = $chooseAnswer.find('.originSubjectInfo') var memoryObjectiveHtml = decodeURIComponent(chooseAnswerStemInfo) var delHMemory = memoryObjectiveHtml.replace(/height:auto;/g, '') if ($chooseAnswerObjective.length) { $chooseAnswerObjective[0].outerHTML = delHMemory } else { $chooseAnswer.eq(0).children('h3').append(delHMemory) } //重置图片高度 self.judegeImgsLoaded( '.answerModule[data-type="chooseAnswer"] .originSubjectInfo' ) } }, memoryShortAnswer: function (shortAnswerData) { var self = this //2 解答题区域高度修改 //shortAnswerData 所有解答题的区域信息 //多选题特殊处理 var checkQuestionData = {} var checkmoduleEl = {} for (var i = 0, questionItem; i < shortAnswerData.length; i++) { var questionItem = shortAnswerData[i] var moduleHeight = questionItem.cut ? questionItem.cut.height : questionItem.selectqts[0].cut.height var scoreLimitKey = questionItem.scoreLimit var isAddHalf = questionItem.isAddHalf $('#printcontent .pageContent .short-answer .module').each(function ( pageIndex, moduleItem ) { var $pageItem = $(moduleItem).closest('.pageContent') var $moduleItem = $(moduleItem) var isOverPage = false var titleNumber = Number($moduleItem.attr('title-number')) var dataEditorIndex = $moduleItem.attr('data-editorindex') if (self.isSurplusModule($moduleItem)) return //该题已经布局就无需重复布局--针对选择题 if ( titleNumber === Number(questionItem.name) && !checkQuestionData[questionItem.editorId] && !checkQuestionData[dataEditorIndex] ) { checkQuestionData[questionItem.editorId] = true checkQuestionData[dataEditorIndex] = true //同步之前设置的内容 if (questionItem.contents) { // var editorId = questionItem.id var editorId = dataEditorIndex self.editorArea['editor' + editorId].txt.html( decodeURIComponent(questionItem.contents) ) } var $this = $moduleItem.children('.settingBtn') let isAddHalf = questionItem.scorebox.point==1 ? true: false; self.shortAnswerStyleChange($this, scoreLimitKey, isAddHalf, questionItem.scorebox.limit) //设置大题区域高度 $moduleItem .children('.editorContent') .height(moduleHeight - self.modulePadding) // $moduleItem // .children('.editorContent') // .css('min-height',moduleHeight - self.modulePadding) curPageEl = $pageItem //如果当前有page分栏页有超出 则直接调到下一个分页 isOverPage = self.getOverModule(curPageEl) self.changePrintArea(curPageEl) } if (isOverPage) return false // if (isOverPage) { // isOverPage = false // } }) } }, /*-------------------------------------------------------------------------------------------------------------------------------- 记忆布局功能结束 ------------------------------------------------------------------------------------------------------------------------------------*/ /** * -------------------------------------------------------------------------------------------------------------------------------- 还原原题题干信息开始 -------------------------------------------------------------------------------------------------------------------------------- */ restoreObjectiveInfo: function (data) { var self = this var clearStatus = data.clearStatus if (clearStatus) { var $pageContent $('.answerModule').each(function () { if ($(this).attr('data-type') === 'objective') { if (!$pageContent) { $pageContent = $(this).closest('.pageContent') } $(this).remove() } }) self.changePrintArea($pageContent) return } $('.objectiveItem').each(function (index) { $(this)[0].outerHTML = decodeURIComponent(self.originStemInfos[index]) }) //图片加载时间 self.judegeImgsLoaded('.objectiveItem') }, restoreAnswerInfo: function (data) { var self = this var clearStatus = data.clearStatus /** * 清空之前所有的内容 * 包括清空统一题的本体模块和补充模块 * 然后用新内容放在本体模块里面 */ var overPageEl = [] //第一次出现 var firstChooseAnswer = true $('.short-answer').each(function () { var $shortAnswer = $(this) var $modules = $(this).find('.module') if ($shortAnswer.attr('data-type') === 'chooseAnswer') { if (!firstChooseAnswer) { $shortAnswer.find('h3').remove() return } firstChooseAnswer = false var chooseObjectiveEl = $shortAnswer.find('.originSubjectInfo') if (chooseObjectiveEl.length) { if (clearStatus) { chooseObjectiveEl.remove() } else { chooseObjectiveEl[0].outerHTML = self.chooseAnswerObjective } } else { $shortAnswer.find('h3').append(self.chooseAnswerObjective) } var overHeight = self.getOverHeight($shortAnswer) if (overHeight > 0) { overPageEl.push($shortAnswer.closest('.pageContent')) } return } $modules.each(function () { var $module = $(this) var questionNum = $(this).attr('title-number') var editorIndex = $(this).attr('data-editorIndex') var $moduleEditorContent = $(this).find('.w-e-text') var $moduleContentWrap = $(this).find('.w-e-text-container') //如果是补充模块直接清空内容 if (self.isSurplusModule($(this))) { $moduleEditorContent.html('') } else { var flexibleIconHtml = '
' var questionNumHtml = '
' + questionNum + '、
' var baseContent = questionNumHtml + flexibleIconHtml $moduleEditorContent.html( baseContent + (clearStatus ? '' : self.editorAreaOriginContent[questionNum]) ) var minHeight = self.calcEditorContentHeight($moduleEditorContent) if ($moduleContentWrap.height() < minHeight) { $moduleContentWrap.height(minHeight) } var overHeight = self.getOverHeight($module) if (overHeight > 0) { overPageEl.push($module.closest('.pageContent')) } } }) }) //图片加载时间 self.judegeImgsLoaded('.short-answer') if (overPageEl.length) { overPageEl.forEach(function (pageEl) { self.changePrintArea($(pageEl)) }) } }, /** * -------------------------------------------------------------------------------------------------------------------------------- 还原原题题干信息结束 -------------------------------------------------------------------------------------------------------------------------------- */ initDom: function () { var self = this self.$layoutItem = $('#hgc_print .layoutItem') self.$checkBindLineItem = $('.selOptions input[name="hasBinding"]') //第一个page分页的元素,永远不会变 self.$firstPageContent = $('#printcontent .pageContent').eq(0) //答题卡名称 self.$dtkName = $('#dtkName textarea') }, initEvent: function () { var self = this //当前默认是 A3 两栏 有装订线 有条形码 有准考证号 self.linkageForPaper(self.paper) }, /** * * @param {$element} $editorContentWrapEl 富文本包装内容的div * 语文作文格子需要格外加高度10 */ calcEditorContentHeight: function ($editorContentWrapEl) { var self = this var minScaleHeight = 0 $editorContentWrapEl.children().each(function () { var boxWrap = $(this).hasClass('composition-column') ? 10 : 0 if($(this).hasClass('en')){ boxWrap = 33 } minScaleHeight += $(this)[0].getBoundingClientRect().height + boxWrap }) return minScaleHeight }, bindEvent: function () { var self = this var testFormData = JSON.parse(localStorage.getItem('testFormData')) let exam_group_id = '' if (testFormData) { exam_group_id = testFormData.examGroupId; self.examGroupId = testFormData.examGroupId; } var base64_img = jrQrcode.getQrBase64(exam_group_id) $('#dtkEwm').attr('src', base64_img) //编辑标题 $('#printcontent').on('blur', 'h3', function () { var curPageEl = $(this).closest('.pageContent') self.changePrintArea(curPageEl) }) $('#printcontent').on('blur', '.objectiveItem', function () { var curPageEl = $(this).closest('.pageContent') self.changePrintArea(curPageEl) }) // 限制标题输入内容 $('#printcontent').on('keypress', 'h3', function () { let lock = true; let fullContent = ''; let modelId = $(this).parent().attr('data-modelid'); $('h3').on('compositionstart', function () { lock = false; }); $('h3').on('compositionend', function (event) { lock = true; addInput(event, $(this)); }); $('h3').on('keyup input propertychange', function (event) { addInput(event, $(this)); }); // 字数限制 function addInput(event, that) { let _words = that.text(); if (lock) { let num = _words.length; if (num >= 10) { event.target.innerText = fullContent; event.target.innerText = _words.substring(0, 12); fullContent = _words.substring(0, 12); set_focus(event); seBigTopicTitle(fullContent,modelId) } else { fullContent = '' seBigTopicTitle(_words,modelId) } } else if (fullContent) { event.target.innerText = fullContent; lock = true; set_focus(event); seBigTopicTitle(fullContent,modelId) } } // 超过字数光标定位到末端 function set_focus(e) { let el = document.getElementById(e.target.id); el.focus(); if ($.support.msie) { let range = document.selection.createRange(); this.last = range; range.moveToElementText(el); range.select(); document.selection.empty(); } else { let range = document.createRange(); range.selectNodeContents(el); range.collapse(false); let sel = window.getSelection(); sel.removeAllRanges(); sel.addRange(range); } } // 设置大题title function seBigTopicTitle(text,modId) { let reg2 = /([^、/]+)$/; questionTypeTitle = text.match(reg2)[1]; self.questionMap[modId].bigTitle=text self.questionMap[modId].commonFields.questionTypeTitle = questionTypeTitle } }) //图片可扩展 //控制答题卡区域缩放事件 $('#printcontent').on('mousedown', '.short-answer .dragBtn', function (e) { e.stopPropagation() if (!self.isCanEditCard) return e.preventDefault() var inscreaseTop = $('#contentWrap').scrollTop() //当前操作的分页 var curPageEl = $(this).closest('.pageContent') var curPageOffsetTop = curPageEl.offset().top + inscreaseTop //当前缩放分页下面的按钮 var curDtkModelEl = $(this).closest('.module') var curDtkModelOffsetTop = curDtkModelEl.offset().top + inscreaseTop //只要改变高度的模块 var changeEl = $(this).siblings('.editorContent') //改变之前的初始高度 var startHeight = changeEl.height() var startPageY = e.pageY var distance = 0 //计算可以缩放的最小高度 var scaleMinHeight = self.calcEditorContentHeight( changeEl.children('.w-e-text') ) // console.log('scaleMinHeight', scaleMinHeight) // console.log('startHeight', startHeight) // 如果题卡合一的话,最小高度就是里面内容的高度 // 否则最小高度就是默认的高度 // if(this.isSubjectInfoToCard){ // } /** * 超过当前纸张的情况下 当鼠标松开的时候 * 1先把当前纸张放满 * 2剩余高度重新新到下个版本新建一个富文本高度一样没有内容 * 3单词拖动鼠标控制解答题区域缩放只能拖动到当前页面最底部 */ document.onmousemove = function (e) { distance = e.pageY - startPageY var newHeight = startHeight + distance if (newHeight < scaleMinHeight) { newHeight = scaleMinHeight changeEl.height(newHeight) document.onmouseup(e) return } changeEl.height(newHeight) } //判断是否超过了一页 /** * 1当前模块已经缩放超过了当前页 * a>该区域后面的内容板块自动清空 * b>该区域不可再移动,自动新建一页,然后在下一页新建一个富文本默认是上一页超出的区域 * 2后面的模块超过了当前缩放页面 * a>直接把后面的题放到新排版页面 */ document.onmouseup = function (e) { e.stopPropagation() self.changePrintArea(curPageEl) document.onmouseup = null document.onmousemove = null self.initPageTopic(); } }) //删除一个分页超出的部分 $('#printcontent').on('click', '.delBtn', function (e) { if (!self.isCanEditCard) return var $this = $(this) self.delPageOverPart($this, 'surplus', true) }) //预览 $('#previewBtn').click(function () { self.previewPrintDiv('printcontent') }) //保存 $('#saveBtn').click(function () { if (!self.isCanEditCard) { if (self.isSubjectInfoToCard) { self.modal.init({ content: '当前考试为“题卡合一”模式,是否需要重新替换成原题干内容?', sureCb: function () { //针对数学非第三方试卷:题卡分离的,原题信息都在改问题的后面,试卷固定顺序 选择--填空--解答--必答 //渲染客观题题目信息 //如果第一次题卡分离 if (!$('.objectiveItem').length) { self.renderObjective(function (pageEl) { self.changePrintArea(pageEl) }) } else { self.restoreObjectiveInfo({ clearStatus: false }) } self.restoreAnswerInfo({ clearStatus: false }) } }) self.isCanEditCard = true self.changeCardEditStatus() } else { // hgc_layer.msg('考试已被设置为【题卡分离】,请注意答题卡已被重置!') // if ($('.objectiveItem').length) { // self.restoreObjectiveInfo({ clearStatus: true }) // } // self.restoreAnswerInfo({ clearStatus: true }) self.isCanEditCard = true self.changeCardEditStatus() } return } self.totalPage = $('.pageContent').length if (self.totalPage > self.columns * 2) { hgc_layer.msg('答题卡最多支持' + self.columns * 2 + '页') return } // 如果是全学科答题卡,保存并且返回 需要先设置主观题答案 if (isNewBuild) { if ($.isEmptyObject(self.questionMap)) { hgc_layer.msg('请添加试题') return false } var allSetAnswer = true var buildQuestions = self.questionMap for (var modelId in buildQuestions) { var modelItem = buildQuestions[modelId] if (~[1, 2, 11].indexOf(modelItem.questionType)) { allSetAnswer = modelItem.questions.every(function (question) { return question.answer }) if (!allSetAnswer) break } } if (!allSetAnswer) { self.modal.init({ title: '提示', content: '请先设置客观题答案', ensureText: '去设置', cancelText: '关闭', sureCb: function () { $('#setAnswerBtn').trigger('click') } }) return } if (self.$dtkName.val() == '') { self.modal.init({ title: '提示', content: '请先设置标题', cancelText: '关闭' }) return } // self.$dtkName.val() self.savePrintPosition('printcontent') return } if (!self.isCanEditCard) { self.isCanEditCard = true self.changeCardEditStatus() return } self.judgeHasPrintClass(function () { self.savePrintPosition('printcontent') }) }) //下载pdf $('#downLoadBtn').click(function () { if (self.isCanEditCard && !isNewBuild) return var $this = $(this) if (self.totalPage > self.columns * 2) { hgc_layer.msg('答题卡最多支持' + self.columns * 2 + '页') return } /** * 1 可编辑状态 编辑-保存 --编辑状态不可直接生成或者下载,只有保存状态下,才能生成或者下载 * 2 是否和接口返回的记忆布局数据一样 --如果一样,默认没有修改,可直接下载或者生成 * 3 判断是否已经存在在打印的班级 --如果已经存在正在打印的班级学生,则提示是否覆盖,然后才能生成或者下载 * 4 是否使用二维码 --如果使用二维码,则使用生成pdf的那套逻辑 * * 如果是创建答题卡 直接下载 */ if (isNewBuild) { self.downLoadPdf() return } //保存状态不用重新执行保存逻辑直接下载或者批量生成 if (!self.isCanEditCard) { if (self.useQrCode) { self.judgeHasPrintClass(function () { setTimeout(function () { self.modal.init({ title: '批量生成', content: '该操作会把该场考试下面的所有班级学生考试模板进行批量生成', sureCb: function () { self.batchGeneratePdf() } }) }, 0) }) } else { self.downLoadPdf() } return } //如果使用了二维码后台批量生成,不影响当前页面 var nowPosition = JSON.stringify(self.getPositions()) if (self.useQrCode) { if (nowPosition !== self.saveLocationPosition) { self.judgeHasPrintClass(function () { self.savePrintPosition('printcontent', function () { self.modal.init({ title: '批量生成', content: '该操作会把该场考试下面的所有班级学生考试模板进行批量生成', sureCb: function () { self.batchGeneratePdf() } }) }) }) } else { self.judgeHasPrintClass(function () { setTimeout(function () { self.modal.init({ title: '批量生成', content: '该操作会把该场考试下面的所有班级学生考试模板进行批量生成', sureCb: function () { self.batchGeneratePdf() } }) }, 0) }) } } else { //保存状态不用重新执行保存逻辑直接下载或者批量生成 if (!self.isCanEditCard) { self.downLoadPdf() return } if (nowPosition !== self.saveLocationPosition) { self.judgeHasPrintClass(function () { self.savePrintPosition('printcontent', function () { self.downLoadPdf() }) }) } else { self.downLoadPdf() } } }) //答题卡布局 //选择纸张 new RadioBoxItem($('#paperOptions'), function ($radioItem, status) { var paper = $radioItem.attr('data-paper') self.paper = paper self.linkageForPaper(paper) // self.reInitPageForNewBuild(); }) //选择排版方向 new RadioBoxItem($('#paperDirection'), function ($radioItem, status) { var direction = $radioItem.attr('data-direction') self.direction = direction self.setPageWidthHeightForDirection(direction) self.linkageForDirection(self.config.direction[direction]) }) //选择分栏 self.$layoutItem.click(function () { var column = +$(this).attr('data-column') //|| $(this).hasClass('current') if ($(this).hasClass('disabled')) return $(this).addClass('current').siblings().removeClass('current') self.columns = column self.initPrintContentArea() }) //选择是否有装订线 new RadioBoxItem($('#hasBindingLine'), function ($radioItem, status) { var bindingLineStatus = $radioItem.attr('data-value') === 'yes' self.hasBindingLine = bindingLineStatus self.ifBindingLine() }) //选择是否显示信息栏 new RadioBoxItem($('#hasPaperMsg'), function ($radioItem, status) { var bindingPaperMsgStatus = $radioItem.attr('data-value') === 'yes' self.hasPaperMsg = bindingPaperMsgStatus self.isShowPaperMsg() }) //信息栏设置 $('#printcontent').on('click', '.btn-examInfo', function () { if (!self.isCanEditCard) return $('#examInfoEditDialog').show() }) $('#examInfoEditDialog').on('click', '.btn-hide-dialog', function () { $('#examInfoEditDialog').hide() }) $('#examInfoEditDialog').on('click', '.btn-save-examInfo', function () { $('#examInfoEditDialog').hide() self.showExamInfoHtml(); self.getSaveSubjectInfo(self.questionMap) }) $('.opratorArea').on('mouseover', '.hgc_notice', function (e) { let el = e.target let noticeEl = $(this).parent('.notice-item').find('.noticeContent'); let triangleEl = $(this).parent('.notice-item').find('.noticeContent').find('b'); $(noticeEl).show(); let noticeH = $(noticeEl).get(0).offsetHeight let noticeW = $(noticeEl).get(0).offsetWidth let { top, left } = el.getBoundingClientRect(); $(noticeEl).css('top', top - noticeH - 10 + 'px') $(noticeEl).css('left', left - noticeW / 2 + 'px'); $(triangleEl).css('top', top - 10 + 'px'); $(triangleEl).css('left', left + 'px'); }) $('.opratorArea').on('mouseout', '.hgc_notice', function (e) { let el = e.target let noticeEl = $(this).parent('.notice-item').find('.noticeContent'); $(noticeEl).hide(); }) //考号配置 new CheckBoxItem( $('#examNumberConfig'), function () { }, self.selExamNumberStyle.bind(self) ) //信息栏弹窗配置 new CheckBoxItem( $('#examInfoConfig'), function () { }, self.selExamInfoStyle.bind(self) ) //是否使用二维码 new Switch($('#useQrCode'), function (status) { var $examNumberConfigOptions = $('#examNumberConfig .h_checkItem') var $examNumberLayout = $('.examNumberLayout') var $downLoadBtn = $('#downLoadBtn') var $ewmTips = $('#ewmTips') self.useQrCode = status $downLoadBtn.html(status ? '生成' : '下载') $examNumberConfigOptions.each(function () { $(this)[status ? 'addClass' : 'removeClass']('disabled') }) $('.className').html(status ? self.tpls.systemClassNoticeInfoTpl : '') $('.examineeName').html(status ? self.tpls.systemNameNoticeInfoTpl : '') $('.bindLineClassName').html( status ? self.tpls.systemClassNoticeInfoForLineTpl : '' ) $('.bindLineExamineeName').html( status ? self.tpls.systemNameNoticeInfoForLineTpl : '' ) self.editNoticeDetail(status,self.cardStatus) $examNumberLayout[status ? 'addClass' : 'removeClass']('useqrcode') $ewmTips.css('display', status ? 'flex' : 'none') self.changePrintArea(self.$firstPageContent) }) //单模块设置 $('#printcontent').on('click', '.settingBtn', function () { if (!self.isCanEditCard) return var $this = $(this) var type = $this.attr('data-type') var modelId = $this.closest('.answerModule').attr('data-modelId') //如果是创建答题卡则跳转到编辑页面 if (isNewBuild) { self.setBuildQuestions() window.QE.questionEditStatus = true window.QE.questionData = JSON.parse( JSON.stringify({ ...self.questionMap[modelId], subjectId: subjectId, isAdd: false, SelectbigNoArr: getSelectbigNoArr(self.questionMap) }) ) $('#questionEdit').show() return } //填空 if (type === 'fillInBlank') { self.fillInBlankSet($this) //选择 单选-多选 } else if (~type.indexOf('Select')) { self.selectSetLayout($this, type) } else { self.shortAnswerSet($this) } }) //单模块删除 $('#printcontent').on('click', '.delTopicBtn', function () { if (!self.isCanEditCard) return var $this = $(this); var type = $this.attr('data-type'); var modelId = $this.closest('.answerModule').attr('data-modelId'); let $replaceEl = null self.modal.init({ title: '提示', content: '确定要删除当前题目吗?', ensureText: '确定', cancelText: '取消', sureCb: function () { $('.answerModule').each(function () { if ($(this).attr('data-modelId') === modelId) { $replaceEl = $(this) } }) if(type!=='shortAnswer'){ $this.parents('.answerModule').remove(); } //填空 if (type === 'fillInBlank') { delete self.questionMap[modelId] //选择 单选-多选 } else if (~type.indexOf('Select')) { delete self.questionMap[modelId] } else if (~type.indexOf('uncertain')) { delete self.questionMap[modelId] } else if (~type.indexOf('chooseAnswer')) { delete self.questionMap[modelId] $('.pageContent').find('.short-answer').each(function(){ let modelid = $(this).attr('data-modelid'); if(modelid = modelId){ $(this).remove(); } }) } else if (~type.indexOf('shortAnswer')) { let titleNumber = $this.closest('.module').attr('title-number'); let questionsAll = JSON.parse(JSON.stringify(self.questionMap[modelId].questions)); questionsAll.forEach((topic, index) => { if (topic.questionNum == titleNumber) { if (self.questionMap[modelId].questions.length === 1) { delete self.questionMap[modelId] // $this.parents('.answerModule').remove(); $('.pageContent').find('.short-answer').each(function(){ let modelid = $(this).attr('data-modelid'); if(modelid = modelId){ $(this).remove(); } }) } else { // $this.parents('.module').remove(); $('.pageContent').find('.short-answer .module').each(function(){ let moduleTitleNumber = $(this).attr('title-number'); if(moduleTitleNumber = titleNumber){ $(this).remove(); } }) self.questionMap[modelId].questions.splice(index, 1); self.questionMap[modelId].originQuestions.splice(index, 1); self.questionMap[modelId].commonFields.questionTypeArr.forEach((n, ni) => { if (titleNumber == n.startNo || titleNumber == n.endNo) { if (n.startNo == n.endNo) { self.questionMap[modelId].commonFields.questionTypeArr.splice(ni, 1); } else { if (titleNumber == n.startNo) { n.startNo = Number(n.startNo) + 1 } else { n.endNo = Number(n.endNo) - 1 } } } else if (titleNumber > n.startNo && titleNumber < n.endNo) { let ndata = JSON.parse(JSON.stringify(n)) let questionType = { startNo: '', endNo: n.endNo, score: ndata.score }; n.endNo = Number(titleNumber) - 1; questionType.startNo = Number(titleNumber) + 1; self.questionMap[modelId].commonFields.questionTypeArr.splice(ni + 1, 0, questionType); } }) } } }) } //重新设置 localStorage.setItem('buildQuestions', JSON.stringify(self.questionMap)) var DelPosition = self.getPositions(); localStorage.setItem('position', JSON.stringify(DelPosition)) self.reInitPageForNewBuild(); if ($.isEmptyObject(self.questionMap)) { $('.addTips').show(); // 当答题卡没有题时设置总分为空 $('.fraction').val('') } } }) }) // 给模块标题设置高度 $('#printcontent').on('click', '.answerModule h3', function () { $(this).css('height','auto') }) function isPx(str) { return /^\d+$/.test(str) } document.addEventListener( 'error', function (e) { var elem = e.target if (elem.tagName.toLowerCase() === 'img') { var oh = $(elem).attr('height') var ow = $(elem).attr('width') if (!isPx(oh) || !isPx(ow)) return var h = parseInt($(elem).attr('height')) var w = parseInt($(elem).attr('width')) var hmm = self.unitConversion.pxConversionMm(h) var wmm = self.unitConversion.pxConversionMm(w) $(elem).attr( 'style', $(elem).attr('style') + ';height:' + hmm + 'mm !important;width:' + wmm + 'mm !important;' ) } }, true ) document.addEventListener( 'load', function (e) { var elem = e.target if ( elem.tagName.toLowerCase() === 'img' && typeof $(elem).attr('word_img') === 'string' ) { var h = parseInt($(elem).attr('height')) var w = parseInt($(elem).attr('width')) var hmm = self.unitConversion.pxConversionMm(h) var wmm = self.unitConversion.pxConversionMm(w) $(elem).attr( 'style', $(elem).attr('style') + ';height:' + hmm + 'mm !important;width:' + wmm + 'mm !important;' ) } }, true ) function getSelectbigNoArr(data) { var SelectbigNoArr = []; for (var i in data) { // console.log(i,":",obj[i]); SelectbigNoArr.push(data[i].commonFields.bigNo) } // for(var i = 0; i < data.length; i++) { // 这里的i是代表数组的下标 // let key = 'modelId' + i+1; // SelectbigNoArr.push(data[key].commonFields.bigNo) // } return SelectbigNoArr } //添加试题 $('#addQustionBtn').click(function () { var modelId = guid() window.QE.questionEditStatus = true window.QE.questionData = JSON.parse( JSON.stringify({ ...window.defaultQuestionData, modelId: modelId, isAdd: true, subjectId: subjectId, SelectbigNoArr: getSelectbigNoArr(self.questionMap) }) ) $('#questionEdit').show() }) //设置答案 //保存备选答案 var tempQuestions = null $('#setAnswerBtn').click(function () { self.showSettingAnswerArea() tempQuestions = JSON.parse(JSON.stringify(self.questionMap)) $('#setAnswer').show() }) $('#returnAnswer').click(function () { tempQuestions = null $('#setAnswer').hide() }) $('#saveAnswer').click(function () { self.questionMap = tempQuestions tempQuestions = null self.getSaveSubjectInfo(self.questionMap); $('#setAnswer').hide() }) //设置备选答案 $('.answerList').on('click', '.answesOption', function () { var modelId = $(this).attr('data-id') var _index = +$(this).attr('data-index') var answer = $(this).attr('data-answer') var modelQuestionType = tempQuestions[modelId].questionType if (modelQuestionType === 1) { if ($(this).hasClass('active')) return $(this).addClass('active').siblings('i').removeClass('active') tempQuestions[modelId].questions[_index].answer = answer } else { $(this).toggleClass('active'); // $(this).addClass('active'); var arrAnswer = "" $(this).parent().find('.active').each(function (index) { arrAnswer = arrAnswer + (arrAnswer.length > 0 ? ',' : '') + $(this).attr('data-answer') // arrAnswer = arrAnswer + $(this).attr('data-answer') }) tempQuestions[modelId].questions[_index].answer = arrAnswer // console.log(tempQuestions,arrAnswer,22) } }) //公式编辑器插件 self.eventForFormula() }, //公式编辑器相关事件 eventForFormula: function () { var self = this var curEditorFormula = null $('body').on('click', '.kfformula,.gsImgLatex', function () { if (!self.isCanEditCard) return self.formulaing = true $('#formulaBox').show() curEditorFormula = $(this) var imgLatex = $(this).attr('data-latex') || $(this).attr('src').split('?')[1] var latexUse = decodeURIComponent(imgLatex) if (window.kfe) { window.kfe.execCommand('render', latexUse || '\\placeholder') } else { window.factory = window.kf.EditorFactory.create( $('#kfEditorContainer')[0], { render: { fontsize: 18 }, resource: { path: './kityformula/resource/' } } ) window.factory.ready(function (KFEditor) { KFEditor.execCommand('render', latexUse || '\\placeholder') KFEditor.execCommand('focus') window.kfe = KFEditor }) $('#kf-formula-ensure')[0].onclick = function () { window.kfe.execCommand('get.image.data', function (data) { var latex = window.kfe.execCommand('get.source') $.post(self.apis.getMathtexApi, { mathtex: latex }, function (res) { var newh = self.unitConversion.pxConversionMm(res.height) var neww = self.unitConversion.pxConversionMm(res.width) var newLatexImg = '' curEditorFormula[0].outerHTML = newLatexImg.substitute({ url: res.url, latex: latex, newh: newh, neww: neww }) }) return true }) $('#formulaBox').hide() self.formulaing = false return false } $('#kf-formula-cancel') .off('click') .click(function () { $('#formulaBox').hide() self.formulaing = false }) } }) }, showSettingAnswerArea: function () { var self = this var answerItemTpl = '
\ {questionNum}\ {questionName}\

{answers}

\
' //拿到主观题数据 // 通过modelId 和 题目索引来定位一个题 var questionClassify = self.questionMap var answerHtml = '' for (var modelId in questionClassify) { var modelData = questionClassify[modelId] var modelType = modelData.questionType if (!~[1, 2, 11].indexOf(modelType)) continue answerHtml += modelData.questions.reduce(function ( answerItemHtml, cur, index ) { var selectHtml = '' for (var i = 0; i < cur.optionCount; i++) { var content = String.fromCharCode(65 + i) var activeClass = '' var isActiveOption = cur.answer.indexOf(content) if (isActiveOption > -1) activeClass = 'active' selectHtml += '{content}'.substitute( { content: content, modelId: modelId, index: index, activeClass: activeClass } ) } answerItemHtml += answerItemTpl.substitute({ questionNum: cur.questionNum, questionName: self.questionNameMap[self.questionTypeMapForC[modelType]], answers: selectHtml }) return answerItemHtml }, '') } $('#answerList').html(answerHtml) }, //修改答题卡编辑状态 changeCardEditStatus: function () { var self = this $('#dtkName textarea').prop('disabled', !self.isCanEditCard) $('#examInfo input').prop('disabled', !self.isCanEditCard) $('#saveBtn').html(self.isCanEditCard ? '保存' : '编辑') $('#downLoadBtn')[self.isCanEditCard ? 'addClass' : 'removeClass']( 'disabled' ) //右侧操作栏目 $('#disabledCover')[self.isCanEditCard ? 'hide' : 'show']() //题干信息 $('.objectiveItem').each(function () { $(this).prop('contenteditable', self.isCanEditCard) }) //编辑器 for (var editorId in self.editorArea) { self.editorArea[editorId].$textElem.attr( 'contenteditable', self.isCanEditCard ) } //标题 $('.answerModule h3').each(function () { $(this).prop('contenteditable', self.isCanEditCard) }) }, //检测是否有已经生成的答题卡 judgeHasPrintClass: function (cb) { var self = this if (self.printClassStatus) { self.modal.init({ title: '批量生成', content: '保存后,会重置原答题卡数据,将恢复班级/学生的打印状态,且可能会导致已打印出的答题卡扫描无效,请谨慎操作!', sureCb: function () { cb && cb() } }) } else { cb && cb() } }, //根据选择排版方向设置答题卡的视觉排版宽高 setPageWidthHeightForDirection: function (direction) { var self = this var isVertical = direction === 'vertical' //设置横竖版面 self.config[isVertical ? 'width' : 'height'] = self.configOrigin.width self.config[isVertical ? 'height' : 'width'] = self.configOrigin.height }, //点击选择纸张联动,纸张方向和纸张分栏选择 linkageForPaper: function (paper) { var self = this // '8K': { // width: 267, // height: 390, // direction: { // horizontal: [2, 3] // } // }, //layoutList self.config = simpleCopy(sizeConfig[paper]) self.configOrigin = simpleCopy(sizeConfig[paper]) var directions = self.config.direction var isPaperDirectionStop = false $('#paperDirection .h_radioItem').each(function () { var direction = $(this).attr('data-direction') if (direction in directions) { $(this).removeClass('disabled') if (!isPaperDirectionStop) { isPaperDirectionStop = true $(this).trigger('click') } } else { $(this).addClass('disabled') } }) }, //点击选择纸张方向联动 分栏选择 linkageForDirection: function (columns) { var self = this var isLayoutItemStop = false let isClick = 0 self.$layoutItem.each(function () { var $this = $(this) var dataColumn = +$this.attr('data-column') if (~columns.indexOf(dataColumn)) { if(isClick==0){ isClick = dataColumn } else { if(self.columns == dataColumn){ isClick = dataColumn } } } }) self.columns = isClick self.$layoutItem.each(function () { var $this = $(this) var dataColumn = +$this.attr('data-column') if (~columns.indexOf(dataColumn)) { $this.removeClass('disabled') if(self.columns){ if(self.columns == dataColumn){ isLayoutItemStop = true $this.trigger('click') } } else { if (!isLayoutItemStop) { isLayoutItemStop = true $this.trigger('click') } } } else { $this.addClass('disabled') } }) }, //获取settingBtn getSettingBtn: function (modelId) { var $settingBtn = null $('#printcontent .answerModule').each(function () { if ($(this).attr('data-modelId') === modelId && !$settingBtn) { $settingBtn = $(this).find('.settingBtn') } }) return $settingBtn }, //获取大题模块 getAnswerModuleForModelId: function (modelId) { var $answerModule = null $('#printcontent .answerModule').each(function () { if ($(this).attr('data-modelId') === modelId && !$answerModule) { $answerModule = $(this) } }) return $answerModule }, //选择题 selectSetLayout: function ($this, type) { var self = this var memoryDirection = $this.closest('.answerModule').attr('data-direction') var directionCheckMap = { vertical: 'verticalChecked', horizontal: 'horizontalChecked' } var substituteData = {} substituteData[directionCheckMap[memoryDirection]] = 'checked' var tempDirection = '' self.modal.init({ title: '选择题设置', content: self.tpls.selectSetTpl.substitute(substituteData), afterCb: function () { new RadioBoxItem($('#selectDirection'), function ($radioItem, status) { var direction = $radioItem.attr('data-value') tempDirection = direction }) }, sureCb: function () { self.selectStyleChange($this, tempDirection) } }) }, selectStyleChange: function ($this, direction) { var self = this var curPageIndex = $this.closest('.pageContent').index() + 1 var $selectModule = $this.closest('.single-select') var $curPage = $this.closest('.pageContent') var modelId = $selectModule.attr('data-modelId') var modelData = self.questionMap[modelId] var modelPagesData = modelData.pages //modelData.direction = direction function setDirection($selectModule) { if (!$selectModule.hasClass(direction)) { var isHorizontal = direction === 'horizontal' $selectModule .removeClass(isHorizontal ? 'vertical' : 'horizontal') .addClass(isHorizontal ? 'horizontal' : 'vertical') .attr('data-direction', direction) } curPageIndex++ if (modelPagesData[curPageIndex]) { var $nextPage = $('.pageContent').eq(curPageIndex - 1) var $nextPageFirstSelect = $nextPage.find('.single-select').eq(0) if ($nextPageFirstSelect.attr('data-modelId') === modelId) { setDirection($nextPageFirstSelect) } } } setDirection($selectModule) self.changePrintArea($curPage) }, //填空题设置 fillInBlankSet: function ($this) { var self = this var $subjectCol = $this.siblings('.subjectCol') var columnSelectedMap = { 1: 'columnOneSelected', 2: 'columnTwoSelected', 3: 'columnThreeSelected' } var rowLineHeightSelectedMap = { 25: 'rowLineOneSelected', 30: 'rowLineTwoSelected', 35: 'rowLineThreeSelected', 40: 'rowLineFourSelected', 45: 'rowLineFiveSelected', 50: 'rowLineSixSelected' } var scoreSelectedMap = { '2/3/5': 'scoreOneSelected', '2/3/4/6': 'scoreTwoSelected', '2/4': 'scoreThreeSelected' } var memoryColumn = $subjectCol.attr('data-column') || 1 var memoryColumnRowLineHeight = $subjectCol.attr('data-rowLineHeight') || 40 var memoryScoreStyle = $subjectCol.attr('data-scoreStyle') || '' var maxScore = $subjectCol .children('.subjectItem') .eq(0) .attr('data-fullScore') var substituteData = {} substituteData[columnSelectedMap[memoryColumn]] = 'selected' substituteData[rowLineHeightSelectedMap[memoryColumnRowLineHeight]] = 'selected' substituteData[scoreSelectedMap[memoryScoreStyle]] = 'selected' for (var scoreFormat in scoreSelectedMap) { if (!~scoreFormat.split('/').indexOf(maxScore)) { substituteData[scoreSelectedMap[scoreFormat]] = 'disabled' } } self.modal.init({ title: '填空题设置', content: self.tpls.fillInBlankSetTpl.substitute(substituteData), sureCb: function () { //每行列数 var column = $('#fillInBlankColumn').val() //行间距 var rowLinHeight = $('#fillInBlankLineHeight').val() //手写打分 var scoreStyle = $('#scoringBox').val() //修改填空题样式 self.fillInBlankStyleChange($this, column, rowLinHeight, scoreStyle) } }) }, fillInBlankStyleChange: function ($this, column, rowLinHeight, scoreStyle) { var self = this var curPageEl = $this.closest('.pageContent') var modelId = $this.closest('.answerModule').attr('data-modelId') var $fillInBlankCol = $('.pageContent').find('.subjectCol') scoreStyle = scoreStyle || '' //重新计算fillInBlank 查看是否需要修改手动打分样式 self.calcFillInBlankData(modelId, scoreStyle) self.reRenderFillInBlank(modelId) $fillInBlankCol.attr({ 'data-column': column, 'data-rowLineHeight': rowLinHeight, 'data-scoreStyle': scoreStyle, class: 'subjectCol clearfix col-' + column + ' rowLineHeight-' + rowLinHeight }) //如果填空题由原来的一行变成多行,就有可能影响所有的布局样式,重新布局整个答题卡 //fiexd:curPageEl 需要修改成该填空题答题最后数据所在的pageEl self.changePrintArea(curPageEl) }, //解答题设置 shortAnswerSet: function ($this) { var self = this var $module = $this.closest('.module') var memoryScoreLimitKey = $module.attr('scoreLimit') var fullScore = +$module.attr('data-fullScore') var memoryIsAddHalf = $module.attr('isAddHalf') === 'true' var disabledScoreKey var limitSelectedMap = { 15: 'limit15selected', 16: 'limit16selected', 29: 'limit29selected', 49: 'limit49selected' } //禁用标识 var disabledSelectMap = { 15: 'disabled15', 16: 'disabled16', 29: 'disabled29', 49: 'disabled49' } var formatParam = {} formatParam[limitSelectedMap[memoryScoreLimitKey]] = 'selected' formatParam.isAddHalfChecked = memoryIsAddHalf ? 'checked' : '' for (var scoreLimit in self.answerScoreLimitKeyArr) { if (scoreLimit < fullScore) { formatParam[disabledSelectMap[scoreLimit]] = 'disabled' } } self.modal.init({ title: '解答题设置', content: self.tpls.shortAnswerOptionTpl.substitute(formatParam), sureCb: function () { var scoreLimitKey = $('#scoreLimit').val() var isAddHalf = $('#isAddHalf').prop('checked') self.shortAnswerStyleChange($this, scoreLimitKey, isAddHalf) } }) }, /** * @param {当前要修改的解答题区域内的标示符} $this * @param {分值上限} scoreLimitKey */ shortAnswerStyleChange: function ($this, scoreLimitKey, isAddHalf, topicScore) { var self = this var scorePartEl = $this.siblings('.scortColumn') var colClass = 'col-' + scoreLimitKey var scoreModuleHtml = self.generateScoreBox(scoreLimitKey, isAddHalf, topicScore) //解答题分值上限配置 scorePartEl .html(scoreModuleHtml) .attr('class', 'scortColumn clearfix ' + colClass) .parent('.module') .attr('scoreLimit', scoreLimitKey) .attr('isAddHalf', isAddHalf) }, generateScoreBox: function (scoreLimitKey, isAddHalf, topicScore) { var self = this function rendScore(score) { return '' + score + '' } var bit = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] //各个分值对应的分值 布局格式 var scoreLimitMap = { '16': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], '15': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], '29': { tenPlace: [1, 2], bit: bit }, '49': { tenPlace: [1, 2, 3, 4], bit: bit }, '69': { tenPlace: [1, 2, 3, 4, 5, 6], bit: bit } } var scoreLimit = scoreLimitMap[scoreLimitKey] var scoreModuleHtml = '' var scoreLimitArr = [] var noScoringW = 42 let pw = $('#printcontent').width(); noScoringW = pw/17 // switch (self.paper) { // case 'A4': // case '16K': // noScoringW = 22 // break // default: // noScoringW = 42 // break // } if (~'16|15'.indexOf(scoreLimitKey)) { if (Number(topicScore) < Number(scoreLimitKey)) { for (let index = 0; index < topicScore; index++) { scoreLimitArr.push(index + 1) } } else { scoreLimitArr = scoreLimit } } else { scoreLimitArr.push('十位') scoreLimitArr = scoreLimitArr.concat(scoreLimit.tenPlace) scoreLimitArr.push('个位') scoreLimitArr = scoreLimitArr.concat(scoreLimit.bit) } //是否增加0.5分机制 isAddHalf && scoreLimitArr.push('0.5') scoreLimitArr.forEach(function (score, index) { scoreModuleHtml += rendScore(score) }) if (Number(topicScore) < Number(scoreLimitKey) && Number(scoreLimitKey) < 17) { let width = (15 - topicScore) * noScoringW; if (width < 48) { width = 48 } scoreModuleHtml += "禁打分区" } return scoreModuleHtml }, editNoScoringWidth: function () { let pw = $('#printcontent').width(); $('.scortColumn').each(function(i,k){ let kL = $(k).find('span').length; let kw = pw/17*(16-kL); if(kw<48){ kw = 48 } $(k).find('.no-scoring').width(kw); }) }, //是否有装订线 ifBindingLine: function () { var self = this var curPageEl = self.$firstPageContent var isUseClass = self.hasBindingLine ? 'addClass' : 'removeClass' var isHideBinding = self.hasBindingLine ? 'show' : 'hide' var isHideExamineeInfo = !self.hasBindingLine ? 'show' : 'hide' $('#printcontent') [isUseClass]('hasBindingLine') .find('.bindingLine') [isHideBinding]() $('#examineeInfoForLayout')[isHideExamineeInfo]() //隐藏考生的姓名 班级信息也会影响布局 self.changePrintArea(curPageEl) }, //是否显示信息栏 isShowPaperMsg: function () { var self = this if (self.hasPaperMsg) { // let examInfo ={} // var examInfoHtml = self.tpls.examInfoTpl.substitute(examInfo) // $('#examInfo').html(examInfoHtml) self.showExamInfoHtml(); self.getSaveSubjectInfo(self.questionMap) $('#examInfo').css('display', 'flex'); $('#hasPaperMsg').find('.h_radioItem').eq(0).addClass('checked') $('#hasPaperMsg').find('.h_radioItem').eq(1).removeClass('checked') } else { $('#hasPaperMsg').find('.h_radioItem').eq(0).removeClass('checked') $('#hasPaperMsg').find('.h_radioItem').eq(1).addClass('checked') $('#printcontent').find('#examInfo').html(''); $('#examInfo').css('display', 'none'); } }, //是否只使用条形码 isOnlyBarCode: function () { var self = this return self.examNumberConfig.barCode && !self.examNumberConfig.ticketNumber }, //判断当前选中个数 getExamConfigSeledCount: function () { var self = this var seledCount = 0 //条形码 和 考号 至少选择一个 for (var examKey in self.examNumberConfig) { if (self.examNumberConfig[examKey]) { seledCount += 1 } } return seledCount }, //选择考号版式 selExamNumberStyle: function ($this, singleStatus) { var self = this var value = $this.attr('data-value') //当前选考号配置的数量 var curExamConfigCount = self.getExamConfigSeledCount() if (!singleStatus && curExamConfigCount === 1) { hgc_layer.msg('不使用二维码的情况下,填涂考号和条形码至少选择一个') $this.trigger('click') return } self.examNumberConfig[value] = singleStatus $('#hgc_examNumber .' + value)[singleStatus ? 'show' : 'hide']() //只使用条形码 var isOnlyBarCode = self.isOnlyBarCode() $('#hgc_examNumber').css('display', isOnlyBarCode ? 'none' : 'flex') $('#hgc_examNumberForOnlyBarcode').css( 'display', isOnlyBarCode ? 'flex' : 'none' ) self.changePrintArea(self.$firstPageContent) }, //选择信息栏显示模块 selExamInfoStyle: function ($this, singleStatus) { var self = this let value = $this.attr('data-value'); self.examInfoConfig[value] = singleStatus; }, //更新label显示文本 refrushPageLabel: function () { var self = this $('.pageLabel').each(function (index, $label) { var curTotalPage = index + 1 var currentPaper = Math.ceil((index + 1) / (self.columns * 2)) //第一张纸 正面1 正面2 第一张至反面1 反面2 var paperDirection = (curTotalPage % (self.columns * 2) ? curTotalPage % (self.columns * 2) : self.columns * 2) <= self.columns ? '正面' : '反面' var pageForPaperDirection = curTotalPage % self.columns ? curTotalPage % self.columns : self.columns var currentPaperPage = paperDirection + pageForPaperDirection var labelHtml = self.tpls.pageLabelTpl.substitute({ currentPage: curTotalPage, totalPage: self.totalPage, currentPaper: currentPaper, currentPaperPage: currentPaperPage }) $(this).html(labelHtml) }) }, //重新计算同一题相同模块的 //存储当前超出缺没有被执行超出事件的模块 forgetOverPage: null, saveForgetPage: function (forgetPage) { var self = this //之前当前被遗忘的分页在前面,就可以直接替换 if (self.forgetOverPage) { if (forgetPage.index() < self.forgetOverPage.index()) { self.forgetOverPage = forgetPage } } else { self.forgetOverPage = forgetPage } }, resetPrevEditorContent: function ($surplusModule, $prevModule) { var self = this var surplusModuleContentHeight = self.calcEditorContentHeight( $surplusModule.find('.w-e-text') ) var prevPage = $prevModule.closest('.pageContent') var prevPageContentHeight = prevPage.height() - self.pagePadding * 2 //内容区域 var $prevContentArea = $prevModule.find('.w-e-text-container') var prevEditorIndex = $prevModule.attr('data-editorIndex') var surplusEditorIndex = $surplusModule.attr('data-editorIndex') var surplusEditorContent = self.editorArea[ 'editor' + surplusEditorIndex ].txt .html() .clearFixible() var prevEditorContent = self.editorArea['editor' + prevEditorIndex].txt .html() .clearFixible() var prevCalcHeight = $prevContentArea.height() + surplusModuleContentHeight self.editorArea['editor' + prevEditorIndex].txt.html( ( prevEditorContent + surplusEditorContent + self.tpls.flexibleIconTpl ).replace(self.replaceEditorRegexp, '') ) $prevContentArea.height(prevCalcHeight) if (self.getOverHeight($prevModule) > 0) { //之前当前被遗忘的分页在前面,就可以直接替换 self.saveForgetPage(prevPage) } }, /** * 删除一个分页超出的部分 * @param {*} $delBtn 删除按钮 * @param {el} type 下面两种类型的值 over surplus * @param {boolean} isUserTrigger 是否用户主动手动触发---触发 * 1 上一页有超出模块,下一页的补充模块需要删除的情况 * 2 上一页有剩余空间,下一页的补充模块一样需要删除的情况 * 两种情况计算当前需要删除的补充模块的上一个模块的方式有所不同 */ //判断是不是补充模块 isSurplusModule: function (module) { return typeof module.attr('isSurplus') === 'string' }, //需要把内容部分全部移到上面的部分,然后上面的高度要重置一下 delPageOverPart: function ($delBtn, type, isUserTrigger) { var self = this var answerModel = $delBtn.closest('.short-answer') var delModel = $delBtn.closest('.module') var delPage = delModel.closest('.pageContent') var prevPage = delPage.prev() //默认上一页有超出模块的时候计算方式 var memoryPrevModule = delModel .closest('.answerModule') .prev('.answerModule') .children('.module:last()') var prevPageLastEditor = memoryPrevModule.children('.editorContent') //如果是上一页有剩余空间才来的话 if (type === 'surplus') { var loopPrevPage = delPage.prev() while (!memoryPrevModule.length) { memoryPrevModule = loopPrevPage.find('.module:last()') loopPrevPage = loopPrevPage.prev() } } self.resetPrevEditorContent(delModel, memoryPrevModule) prevPageLastEditor.height( prevPageLastEditor.height() - self.modulePaddingBottom ) delModel.remove() self.updatePageElement(delPage, answerModel) //判断上一个模块是否是第一个链接模块 // if (prevPageLastModule.attr('data-linkparm') === '1') { // prevPageLastModule.removeAttr('data-linkparm') // } if (!answerModel.children('.module').length) answerModel.remove() if (isUserTrigger) { self.changePrintArea(delPage) } }, /** * 获取超出当前page的模块 作答大题区域模块 作答小题区域模块 * @return {answerModule,subjectModule} */ getOverModule: function (curPageEl) { var self = this var overPart = false //当前第几页,用做后面计算的高度距离的倍数 var times = curPageEl.index() + 1 //判断超出当前页面的条件 var overHeight = self.pageHeight * times + self.layoutPadding - self.pagePadding //判断当前区域是否超出 function isOver(el) { var moduleTop = $(el).outerHeight() + $(el).offset().top + $('#contentWrap').scrollTop() return moduleTop >= overHeight } /** * 1 判断当前页面里面的答题区域内容是否超过了当前页面所能承受的内容的高度 * a 如果超出了,从当前移动的那个模块开始向后判断,取出所有超出的模块 * I 在下一页的排版中,如果下一页存在直接插入最前面,如果不存在,直接新建一页==>>然后循环【1】操作 * b 如果没有超出直接退出 */ //需要判断当前page里面所有模块是否有超出 //当前答题卡区域 var curDtkPartEl = curPageEl.children('.dtk-content') if (curDtkPartEl.height() + self.pagePadding * 2 >= self.pageHeight) { //区分原题题干和答题区域 var shortAnswerEl = [].splice.call( curDtkPartEl.children('.answerModule'), 0 ) //var shortAnswerEl = objectiveModule.concat(shortANswerModule) for (var i = 0, ilen = shortAnswerEl.length; i < ilen; i++) { var shortAnswerItem = $(shortAnswerEl[i]) //找到第一个超过当前页面的元素,把这个以及以后的模块提取出来在下一个版面进行重新排版 //得到第一个大题的index 第一个大题下面小题的index if (isOver(shortAnswerItem)) { var answerType = shortAnswerItem.attr('data-type') var isChooseAnswer = answerType === 'chooseAnswer' var hasObjective = shortAnswerItem.find('.originSubjectInfo').length var isObjective = answerType === 'objective' var childrenSelector = isChooseAnswer && hasObjective ? '' : isObjective ? '.objectiveItem' : '.module' var moduleEl = $(shortAnswerItem).children(childrenSelector) for (var m = 0, mlen = moduleEl.length; m < mlen; m++) { var moduleItem = moduleEl.eq(m) if (isOver(moduleItem)) { var subjectModule = null //选做题如果题干信息超出的话,也特殊模块超出,因为选做题模块可能很长 var objectiveModule = null if (isChooseAnswer) { if (moduleItem[0].tagName === 'H3') { objectiveModule = moduleItem if (moduleItem.next().length) { subjectModule = moduleItem.next() } } else { subjectModule = moduleItem } } else { subjectModule = moduleItem } overPart = { curPage: curPageEl, //当前超出的answerModule answerModule: shortAnswerItem, //当前超出的module subjectModule: subjectModule, //当前超出的选做题题干信息 objectiveModule: objectiveModule } return overPart } } } } } return overPart }, //获取超出模块高度 getOverHeight: function (el) { var self = this var curPageEl = $(el).closest('.pageContent') //当前第几页,用做后面计算的高度距离的倍数 var times = curPageEl.index() + 1 var overHeight = self.pageHeight * times + self.layoutPadding - self.pagePadding var moduleTop = $(el).outerHeight() + $(el).offset().top + $('#contentWrap').scrollTop() return moduleTop - overHeight - 4 }, //根据缩放的要求拓宽需要打印的区域 /* * 1拓宽打印区域 * 2减小打印区域 */ changePrintArea: function (curPageEl) { var self = this if (self.forgetOverPage && self.forgetOverPage[0] === curPageEl[0]) { self.forgetOverPage = null } //找出超出的区域 var overPart = self.getOverModule(curPageEl) if (overPart) { //填空题选择题特殊对待 var moduleType = overPart.answerModule.attr('data-type') if (moduleType === 'fillInBlank') { self.addPrintForFillInBlank(curPageEl, overPart) } else if (~moduleType.indexOf('Select') ||~moduleType.indexOf('uncertainOption')) { self.addPrintForSelect(curPageEl, overPart, moduleType) } else if (moduleType === 'objective') { self.addPrintForObjective(curPageEl, overPart) self.judegeImgsLoaded('.objectiveItem') } else { self.addPrintForAnswer(curPageEl, overPart) } } else { self.reducePrintArea(curPageEl) } }, showExamInfoHtml: function () { if(!this.hasPaperMsg){ return false } let examInfoHtml = ''; if (this.examInfoConfig.wpTimes) { if(this.examInfoConfigText.wpTimes == undefined) { this.examInfoConfigText.wpTimes = '' } examInfoHtml += '时间:分钟' } if (this.examInfoConfig.fullScore) { if(this.examInfoConfigText.fullScore == undefined) { this.examInfoConfigText.fullScore = '' } examInfoHtml += '满分:' } if (this.examInfoConfig.wpAuthor) { if(this.examInfoConfigText.wpAuthor == undefined) { this.examInfoConfigText.wpAuthor = '' } examInfoHtml += '命卷人:' } if (this.examInfoConfig.wpReviewer) { if(this.examInfoConfigText.wpReviewer == undefined) { this.examInfoConfigText.wpReviewer = '' } examInfoHtml += '审核人:' } examInfoHtml += '
' $('#examInfo').html(examInfoHtml); if (examInfoHtml.length < 33) { $('#hasPaperMsg').find('.h_radioItem').removeClass('checked') $('#hasPaperMsg').find('.h_radioItem').eq(1).addClass('checked') $('#examInfo').css('display', 'none') } else { $('#hasPaperMsg').find('.h_radioItem').removeClass('checked') $('#hasPaperMsg').find('.h_radioItem').eq(0).addClass('checked') $('#examInfo').css('display', 'flex') } }, //重新计算填空题渲染数据,改变填空题手动打分分值样式 calcFillInBlankData: function (modelId, scoreStyle) { var fillInBlankData = this.questionMap[modelId].pages for (var pageKey in fillInBlankData) { if (fillInBlankData[pageKey].length) { fillInBlankData[pageKey] = fillInBlankData[pageKey].map(function ( item ) { item.scoreStyle = scoreStyle return item }) } } }, //题干区域超出 addPrintForObjective: function (curPageEl, overPart) { var self = this var curPageIndex = curPageEl.index() var times = curPageIndex + 1 var part = overPart.subjectModule //判断超出简答题区域 var overAnswerModule = overPart.answerModule //超出区域模块的题型 var overAnswerModuleType = overAnswerModule.attr('data-type') || 'objective' var resetEditorIds = [] //简答小题 var subjectHtml = '' //合并的简答题区域 var overAnswerHtml = '' //通过缩放确定每个页面需要移除的元素 var removeElements = [] var nextPageEl = curPageEl.next() //首先判断是要删除下一个分页的补充模块如果下一个分页存在的话 var nextPageFirstModule = null if (nextPageEl.length) { nextPageFirstModule = nextPageEl.find('.module').eq(0) } while (part.length) { subjectHtml += self.addNewModuleForObjective( part, overAnswerModuleType, removeElements ) part = part.next() } //根据module 的data-type来确定使用的module 模板 var tplForTypeMap = { singleSelect: 'selectTpl', moreSelect: 'selectTpl', fillInBlank: 'answerModulForFillInBlankTpl', answer: 'answerModuleTpl', chooseAnswer: 'answerModuleTpl', mustAnswer: 'answerModuleTpl', objective: 'objectiveWrapTpl' } //超出模块 while (overAnswerModule.length) { var editModuleHtml = '' var moduleTitle = '' overAnswerModuleType = overAnswerModule.attr('data-type') var modelId = overAnswerModule.attr('data-modelId') var isObjective = overAnswerModuleType === 'objective' var direction = overAnswerModule.attr('data-direction') var isSelect = ~overAnswerModuleType.indexOf('Select') //如果是当前超出模块,则直接用上面的多余的moduleHtml来填充 //否则,直接用answerModule的内容来填充 if (overAnswerModule[0] === overPart.answerModule[0]) { editModuleHtml = subjectHtml } else { //如果下一个大模块是选做题,并且只有选做题提文字信息 if ( overAnswerModuleType === 'chooseAnswer' && !overAnswerModule.find('.module').length && overAnswerModule.children().length && overAnswerModule.find('.originSubjectInfo').length ) { var objectiveReg = /
(.*)<\/div>/ var objectiveRegG = /
(.*)<\/div>/g //超出的选做题标题元素 var overAnswerModuleH3Html = overAnswerModule.find('h3')[0].outerHTML //超出选做题标题的题干内容 var overAnswerModuleH3ObjectiveHtml = overAnswerModuleH3Html.match( objectiveReg )[1] var nextPageFirstH3 = nextPageFirstAnswerModule.children('h3') if (nextPageFirstH3.length) { var nextPageFIrstH3ObjectiveHtml = nextPageFirstH3 .children('.originSubjectInfo') .html() //如果下一页存在选做题h3 则 需要拿当前的h3 做替换 nextPageFirstH3[0].outerHTML = overAnswerModuleH3Html.replace( objectiveRegG, '
' + overAnswerModuleH3ObjectiveHtml + nextPageFIrstH3ObjectiveHtml + '
' ) } else { //如果下一页没有标题,直接插入到下一个模块的 // subjectHtml = nextPageFirstH3.children('.originSubjectInfo').prepend(overAnswerModule[0].outerHTML.replace(objectiveRegG,'
'+curPageH3ObjectiveHtml+'<\/div>')) subjectHtml = overAnswerModule.children('h3')[0].outerHTML nextPageFirstAnswerModule.prepend(subjectHtml) } overAnswerModule.remove() break } var isSelect = ~overAnswerModuleType.indexOf('Select') var isFillInBlank = overAnswerModuleType === 'fillInBlank' self.resetPageDataForSubject( overAnswerModule, times, resetEditorIds, nextPageEl ) if (isSelect || isFillInBlank) { moduleTitle = self.titleHtml(self.questionMap[modelId].bigTitle) if (isSelect) { editModuleHtml = '
' + overAnswerModule.find('.single-option').html() + '
' } } if (!isSelect) editModuleHtml = overAnswerModule.html() removeElements.push(overAnswerModule) } overAnswerHtml += self.tpls[ tplForTypeMap[overAnswerModuleType] ].substitute({ editModule: editModuleHtml, moduleType: overAnswerModuleType, selectType: overAnswerModuleType, selectContent: editModuleHtml, direction: direction, title: moduleTitle }) overAnswerModule = overAnswerModule.next() } /** * 【优化】 * 模块删除关系需要优化 */ removeElements.forEach(function (element) { $(element).remove() }) if (!overPart.answerModule.children('.objectiveItem').length) overPart.answerModule.remove() //是否存在下一个分页 if (nextPageEl.length) { nextPageEl.children('.dtk-content').prepend(overAnswerHtml) if (self.isSurplusModule(nextPageFirstModule)) { self.delPageOverPart(nextPageFirstModule.children('.delBtn'), 'over') } } else { self.addPage(overAnswerHtml) nextPageEl = $('#printcontent').children('.pageContent:last()') } //重置富文本 resetEditorIds.length && self.resetAddNewModuleEditor(resetEditorIds) //递归轮询判断 self.changePrintArea(nextPageEl) }, //超出的大模块计算 addPrintForAnswerModule: function ( overPart, curPageIndex, subjectHtml, resetEditorIds, removeElements, nextPageEl ) { var self = this var moduleTitle = '' var overAnswerHtml = '' var overAnswerModule = overPart.answerModule //根据module 的data-type来确定使用的module 模板 var tplForTypeMap = { singleSelect: 'selectAnswerTpl', moreSelect: 'selectAnswerTpl', uncertainOption: 'selectAnswerTpl', fillInBlank: 'answerModulForFillInBlankTpl', answer: 'answerModuleTpl', chooseAnswer: 'answerModuleTpl', mustAnswer: 'answerModuleTpl', objective: 'objectiveWrapTpl' } //超出模块 选择-填空 while (overAnswerModule.length) { var editModuleHtml = '' var overAnswerModuleType = overAnswerModule.attr('data-type') var modelId = overAnswerModule.attr('data-modelId') var direction = overAnswerModule.attr('data-direction') //如果是当前超出模块,则直接用上面的多余的moduleHtml来填充 //否则,直接用answerModule的内容来填充 if (overAnswerModule[0] === overPart.answerModule[0]) { editModuleHtml = subjectHtml } else { //如果下一个大模块是选做题,并且只有选做题提文字信息 if ( overAnswerModuleType === 'chooseAnswer' && !overAnswerModule.find('.module').length && overAnswerModule.children().length && overAnswerModule.find('.originSubjectInfo').length ) { var objectiveReg = /
(.*)<\/div>/ var objectiveRegG = /
(.*)<\/div>/g //超出的选做题标题元素 var overAnswerModuleH3Html = overAnswerModule.find('h3')[0].outerHTML //超出选做题标题的题干内容 var overAnswerModuleH3ObjectiveHtml = overAnswerModuleH3Html.match( objectiveReg )[1] var nextPageFirstH3 = nextPageFirstAnswerModule.children('h3') if (nextPageFirstH3.length) { var nextPageFIrstH3ObjectiveHtml = nextPageFirstH3 .children('.originSubjectInfo') .html() //如果下一页存在选做题h3 则 需要拿当前的h3 做替换 nextPageFirstH3[0].outerHTML = overAnswerModuleH3Html.replace( objectiveRegG, '
' + overAnswerModuleH3ObjectiveHtml + nextPageFIrstH3ObjectiveHtml + '
' ) } else { //如果下一页没有标题,直接插入到下一个模块的 // subjectHtml = nextPageFirstH3.children('.originSubjectInfo').prepend(overAnswerModule[0].outerHTML.replace(objectiveRegG,'
'+curPageH3ObjectiveHtml+'<\/div>')) subjectHtml = overAnswerModule.children('h3')[0].outerHTML nextPageFirstAnswerModule.prepend(subjectHtml) } overAnswerModule.remove() break } var isSelect = ~overAnswerModuleType.indexOf('Select') var isFillInBlank = overAnswerModuleType === 'fillInBlank' self.resetPageDataForSubject( overAnswerModule, curPageIndex, resetEditorIds, nextPageEl ) if (isSelect || isFillInBlank) { moduleTitle = self.titleHtml(self.questionMap[modelId].bigTitle) if (isSelect) { editModuleHtml = overAnswerModule.html() } } if (!isSelect) editModuleHtml = overAnswerModule.html() removeElements.push(overAnswerModule) } overAnswerHtml += self.tpls[ tplForTypeMap[overAnswerModuleType] ].substitute({ editModule: editModuleHtml, moduleType: overAnswerModuleType, selectType: overAnswerModuleType, selectContent: editModuleHtml, direction: direction, title: moduleTitle, modelId: modelId }) overAnswerModule = overAnswerModule.next() } return overAnswerHtml }, /** * 超出情况 * ** 如果下一页的模块有补充模块,最终都需要删除,增加新的补充模块 * 1 如果剩余解答区域小于默认解答区域高度--则直接全部拿到下一页,高度和下一个区域的补充模块高度累加,下一页的补充模块自动移除 * 2 如果剩余解答区域大于默认解答区域高度--则超出部分高度和之前下一区域的补充模块高度累加,下一页补充模块高度自动移除 * 缺失情况 * 1 如果剩余空间大于下一个模块 * -如果是补充模块,直接拿上来,高度累加该补充模块的高度 * -如果不是补充模块,直接拿上来,然后递归下一页的下一个模块,直到该页面没有剩余空间 * 2 如果剩余空间小于下一个模块 * a如果有标题 * - 如果小于标题加题号的空间,则不动,递归下一页的缺失情况 * - 如果大于标题加题号的空间,则直接拿上去,下一页保留多余高度的作答区域 (可以高度缩小直接拿上去,然后再补一个剩余高度的拓展模块) * b如果没有标题(小题或者补充模块) * - 如果下一页的第一个模块是补充模块,直接缩小对应的高度,上一个页面增加对应的高度 * - 如果下一个面是小题模块,则直接拿上去,下一页保留多余高度的作答区域 (可以高度缩小直接拿上去,然后再补一个剩余高度的拓展模块) */ addPrintForAnswer: function (curPageEl, overPart) { var self = this var curPageIndex = curPageEl.index() var times = curPageIndex + 1 var part = overPart.subjectModule //判断超出简答题区域 var overAnswerModule = overPart.answerModule //超出区域模块的题型 var overAnswerModuleType = overAnswerModule.attr('data-type') //简答小题 var subjectHtml = '' //合并的简答题区域 var overAnswerHtml = '' //判断是否是当前鼠标操作答题区域的坐标 //var curOperation = part[0] === self.curDtkModelEl[0] //通过缩放确定每个页面需要移除的元素 var removeElements = [] //需要重置富文本编辑功能区域的id var resetEditorIds = [] //判断是否有需要新增的富文本 var hasNewRichText = false //超出的富文本的内容部分 var editorOverContent = '' var nextPageEl = curPageEl.next() //首先判断是要删除下一个分页的补充模块如果下一个分页存在的话 var nextPageFirstModule = null var nextPageFirstAnswerModule = null if (nextPageEl.length) { nextPageFirstModule = nextPageEl.find('.module').eq(0) nextPageFirstAnswerModule = nextPageEl.find('.answerModule').eq(0) } while (part && part.length) { /** * 如果是当前缩放的模块超出,直接在下一模块新建当前模块的子模块 * 如果不是,则直接拷贝超出模块所有内容到下一页 */ //当前缩放的模块没有超出规定区域 则超出的所有模块全局复制 if (part !== overPart.subjectModule) { //1 新增新模块resetEditorIds removeElements subjectHtml += self.addNewModule( part, overAnswerModuleType, resetEditorIds, removeElements ) } else { //如果剩余模块的高度小于 最小高度,直接放到下一页 var surplusHeight = self.getOverHeight(part) if (part.outerHeight() - surplusHeight <= 100) { //判断超出简答题区域 var overAnswerModule = part.closest('.answerModule') //超出区域模块的题型 var overAnswerModuleType = overAnswerModule.attr('data-type') //1 新增新模块resetEditorIds removeElements subjectHtml += self.addNewModule( part, overAnswerModuleType, resetEditorIds, removeElements ) } else { //1 拓展新模块 hasNewRichText = true //当前超出的模块height //计算超出文本内容区域,同时原来的富文本区域对应超出的内容 var overContentObj = self.getOverContent( part, surplusHeight, removeElements ) editorOverContent = overContentObj.overContent var editorOverHeight = overContentObj.overHeight subjectHtml += self.expandModule(part, editorOverHeight) } } part = part.next() } //当前超出小模块只是选做题题干信息 if (!subjectHtml) { var removeTemps = [] var $itemBodys = overPart.objectiveModule.find('.questionItemBody') for (var i = 0; i < $itemBodys.length; i++) { var $itemBody = $itemBodys.eq(i) if (self.getOverHeight($itemBody) > 0) { subjectHtml += $itemBody[0].outerHTML removeTemps.push($itemBody) } } var objectiveReg = /
(.*)<\/div>/ var objectiveRegG = /
(.*)<\/div>/g var curPageH3ObjectiveHtml = overPart.objectiveModule[0].outerHTML.match( objectiveReg )[1] if (removeTemps.length >= $itemBodys.length) { //如果下一页存在标题 var nextPageFirstH3 = nextPageFirstAnswerModule.children('h3') if (nextPageFirstH3.length) { var nextPageFirstH3Html = nextPageFirstH3 .children('.originSubjectInfo') .html() subjectHtml = overPart.objectiveModule[0].outerHTML.replace( objectiveRegG, '
' + curPageH3ObjectiveHtml + nextPageFirstH3Html + '
' ) nextPageFirstH3[0].outerHTML = subjectHtml } else { subjectHtml = overPart.objectiveModule[0].outerHTML.replace( objectiveRegG, '
' + curPageH3ObjectiveHtml + '
' ) nextPageFirstAnswerModule.prepend(subjectHtml) } overPart.objectiveModule.closest('.answerModule').remove() } else { //如果下一页存在标题 var nextPageFirstH3 = nextPageFirstAnswerModule.children('h3') if (nextPageFirstH3.length) { nextPageFirstH3.children('.originSubjectInfo').prepend(subjectHtml) } else { //overPart.objectiveModule[0].outerHTML.replace(objectiveRegG,''); nextPageFirstAnswerModule.prepend( '

' + subjectHtml + '

' ) } removeTemps.forEach(function (el) { $(el).remove() }) } self.changePrintArea(nextPageEl) return } //计算超出大模块 overAnswerHtml += self.addPrintForAnswerModule( overPart, times, subjectHtml, resetEditorIds, removeElements, nextPageEl ) //重置上一页第一个超出模块的高度 = pageHeight - subject.offset().top - subjectModullePadding的模块高度 //上一个页面其他剩余模块的所占的高度 //如果上一页本来就是一个超出的模块,那modulePadding 就要少点了打分区域的高度 var linkparm = overPart.subjectModule.attr('data-linkparm') var isLinkparmModule = linkparm && linkparm !== '1' var preOtherModuleHeight = overPart.subjectModule.offset().top + $('#contentWrap').scrollTop() + self.pagePadding + self.modulePadding - (isLinkparmModule ? 30 : 0) //上一个页面第一个超出模块所能占用的高度 var preFirstOverModuleHeight = self.pageHeight * times - preOtherModuleHeight overPart.subjectModule .children('.editorContent') .height(preFirstOverModuleHeight) // overPart.subjectModule // .children('.editorContent') // .css('min-height',preFirstOverModuleHeight) /** * 【优化】 * 模块删除关系需要优化 */ removeElements.forEach(function (element) { $(element).remove() }) if ( !overPart.answerModule.children('.module').length && !overPart.answerModule.find('h3').length ) overPart.answerModule.remove() //是否存在下一个分页 if (nextPageEl.length) { nextPageEl.children('.dtk-content').prepend(overAnswerHtml) } else { self.addPage(overAnswerHtml) nextPageEl = $('#printcontent').children('.pageContent:last()') } //curOperation hasNewRichText && self.createShortAnswer(editorIndexUp != '' ? editorIndexUp : self.editorIndex, editorOverContent) //下一页存在上一页最后一个模块的拓展模块,也必须等上一页的新拓展(超出模块)放到下一页之后再执行老拓展模块的删除 //因为删除功能会进行下一页是否有内容模块,对下一页整个页面进行选择性的删除,如果删除了下一页,超出的内容就不知道放到哪里了 if (nextPageFirstModule && self.isSurplusModule(nextPageFirstModule)) { self.delPageOverPart(nextPageFirstModule.children('.delBtn'), 'over') } //重置富文本 self.resetAddNewModuleEditor(resetEditorIds) //递归轮询判断 self.changePrintArea(nextPageEl) }, //填空题超出 addPrintForFillInBlank: function (curPageEl, overPart) { var self = this var part = overPart.subjectModule var modelId = overPart.answerModule.attr('data-modelId') var curPageIndex = curPageEl.index() + 1 //合并的简答题区域 var overAnswerHtml = '' //通过缩放确定每个页面需要移除的元素 var removeElements = [] //需要重置富文本编辑功能区域的id var resetEditorIds = [] var nextPageEl = curPageEl.next() //首先判断是要删除下一个分页的补充模块如果下一个分页存在的话 var nextPageFirstModule = null if (nextPageEl.length) { nextPageFirstModule = nextPageEl.find('.module').eq(0) //按照模块id 归类删除 nextPageEl.find('.answerModule').each(function () { if ($(this).attr('data-modelId') === modelId) { $(this).remove() } }) } //当前超出的模块height var overHeight = self.getOverHeight(part) //一行几栏 var $firstColForInfoEl = part.children('.subjectCol') var dataColumns = $firstColForInfoEl.attr('data-column') var scoreStyle = $firstColForInfoEl.attr('data-scoreStyle') var columns = dataColumns ? +dataColumns : 1 var rowLineHeight = $firstColForInfoEl.attr('data-rowlineheight') //计算每个填空题item的高度 默认40 padding 10 border 1 var fillInBlankItemHeight = (+rowLineHeight || 40) + 11 //当前模块有几个填空题 var fillInBlankCount = part.find('.subjectItem').length //最后一排几个 var lastRowCount = fillInBlankCount % columns ? fillInBlankCount % columns : columns //需要复制几个填空题 //超出的行数量 var overRows = Math.ceil(overHeight / fillInBlankItemHeight) //如果最后一行计算最后一行有几个 var copyFillInBlankLength = lastRowCount + (overRows - 1) * columns var curModuleDataIndex = 'page' + curPageIndex var nextExpendDataIndex = 'page' + (curPageIndex + 1) var modelData = self.questionMap[modelId] var modelPagesData = modelData.pages var nextExpendDataLength = modelPagesData[curModuleDataIndex].length if(modelPagesData[curModuleDataIndex].length<1){ let upModuleDataIndex = 'page' + (curPageIndex -1) modelPagesData[curModuleDataIndex] = modelPagesData[upModuleDataIndex] modelPagesData[upModuleDataIndex] = [] nextExpendDataLength = modelPagesData[curModuleDataIndex].length } copyFillInBlankLength = copyFillInBlankLength > nextExpendDataLength ? nextExpendDataLength : copyFillInBlankLength //原页面保留的题目 modelPagesData[nextExpendDataIndex] = modelPagesData[nextExpendDataIndex] || [] let modelPagesDatas = JSON.parse(JSON.stringify(modelPagesData)) modelPagesData = modelPagesDatas modelPagesData[nextExpendDataIndex] = modelPagesData[curModuleDataIndex] .splice(nextExpendDataLength - copyFillInBlankLength) .concat(modelPagesData[nextExpendDataIndex]) modelData.pages = modelPagesData // var renderData = self.formatRenderDataForFillInBlank(modelPagesData[curModuleDataIndex], modelData.scoreStyle) var originPageRetainHtml = self.getFillInBlankHtml( self.formatRenderDataForFillInBlank(modelPagesData[curModuleDataIndex], modelData.scoreStyle) ) var overFillInBlankItemsHtml = self.getFillInBlankHtml( // modelPagesData[nextExpendDataIndex] self.formatRenderDataForFillInBlank(modelPagesData[nextExpendDataIndex], modelData.scoreStyle) ) if (!originPageRetainHtml) { removeElements.push(part.closest('.completion-topic')) } else { part.find('.subjectCol').html(originPageRetainHtml) } //超出的放在新页面上 如果原页面没有保留模块则需要加上title 并且需要setting按钮 overFillInBlankItemsHtml = self.titleHtml(!originPageRetainHtml ? modelData.bigTitle : '') + self.tpls.fillInBlankContentTpl.substitute({ addFillInBlankHtml: overFillInBlankItemsHtml, columns: columns, scoreStyle: scoreStyle, rowLineHeight: rowLineHeight, settingBtn: !originPageRetainHtml ? self.tpls.fillInBlankSettingBtnTpl : '' }) //计算超出大模块 //判断超出简答题区域 var overAnswerModule = overPart.answerModule overAnswerHtml += self.addPrintForAnswerModule( overPart, curPageIndex, overFillInBlankItemsHtml, resetEditorIds, removeElements, nextPageEl ) /** * 【优化】 * 模块删除关系需要优化 */ removeElements.forEach(function (element) { $(element).remove() }) //是否存在下一个分页 if (nextPageEl.length) { nextPageEl.children('.dtk-content').prepend(overAnswerHtml) if (self.isSurplusModule(nextPageFirstModule)) { self.delPageOverPart(nextPageFirstModule.children('.delBtn'), 'over') } } else { self.addPage(overAnswerHtml) nextPageEl = $('#printcontent').children('.pageContent:last()') } //重置富文本 self.resetAddNewModuleEditor(resetEditorIds) //递归轮询判断 self.changePrintArea(nextPageEl) }, //选择题超出 /** * * @param {*} curPageEl * @param {*} overPart */ addPrintForSelect: function (curPageEl, overPart, type) { var self = this //是否存在下一页 var nextPageEl = curPageEl.next() //超出选择题的题目 var curPageIndex = curPageEl.index()+1 // var curPageIndex = curPageEl.index()==0?curPageEl.index()+1:curPageEl.index() //合并的简答题区域 var overAnswerHtml = '' //通过缩放确定每个页面需要移除的元素 var removeElements = [] //需要重置富文本编辑功能区域的id var resetEditorIds = [] //当前超出的模块height var part = overPart.subjectModule var modelId = overPart.answerModule.attr('data-modelId') var modDataType = overPart.answerModule.attr('data-type') var selectItemType = overPart.answerModule.attr('data-direction') //模块数据 var curModuleDataIndex = 'page' + curPageIndex var nextExpendDataIndex = 'page' + (curPageIndex + 1) var modelData = self.questionMap[modelId] var modelPagesData = modelData.pages if(modelPagesData[curModuleDataIndex].length<1){ let upModuleDataIndex = 'page' + (curPageIndex -1) modelPagesData[curModuleDataIndex] = modelPagesData[upModuleDataIndex] modelPagesData[upModuleDataIndex] = [] } //每小题的高度 var overHeight = self.getOverHeight(part) // 单个选项高度 let optItemHeight = overPart.answerModule.find('.single-option li').eq(0).outerHeight() //20 选择题一个题组的padding值 var selectItemHeight = optItemHeight * 5 + 20 if(selectItemType=='vertical'){ selectItemHeight = optItemHeight + 20 } //针对选择题竖版一行排几个 var curConfigForLine = self.config[self.direction][self.hasBindingLine ? 'yesLine' : 'noLine'] var rowLength = curConfigForLine[self.columns] //一共多少个选择ul module var optionsModuleLength = part.children('.single-option').length //当前布局下面有几排 var optionsRowLength = Math.floor(part.outerHeight() / selectItemHeight) //一排几个options 模块 var optionsModule = rowLength / 5 //最后一个排放几个选项 // var lastRowOptionLength = // optionsModuleLength - (optionsRowLength - 1) * optionsModule var lastRowOptionLength = modelPagesData[curModuleDataIndex].length - (optionsRowLength - 1) * optionsModule * 5 //如果当前页面超过一排的情况下,则超出的数量需要计算到最后一排没有排满的情况 /** * 超出的计算单位以 一整排为单位 * 每一排的一列以5题为单位 计算 * */ //计算超出多少小题 var overSelectItemsLength var overRowLength = Math.ceil(overHeight / selectItemHeight) if (overRowLength <= 1) { overSelectItemsLength = lastRowOptionLength } else { overSelectItemsLength = (overRowLength - 1) * rowLength + lastRowOptionLength } var nextExpendDataLength = modelPagesData['page' + curPageIndex].length //超出的放在新页面上,顺表保存一份用来给下一次使用 modelPagesData[nextExpendDataIndex] = modelPagesData[nextExpendDataIndex] || [] let modelPagesDatas = JSON.parse(JSON.stringify(modelPagesData)) modelPagesData = modelPagesDatas modelPagesData[nextExpendDataIndex] = modelPagesData[curModuleDataIndex] .splice(nextExpendDataLength - overSelectItemsLength) .concat(modelPagesData[nextExpendDataIndex]) //首先判断是要删除下一个分页的补充模块如果下一个分页存在的话 var nextPageFirstModule = null var nextPageFirstAnswerModule = null if (nextPageEl.length) { nextPageFirstAnswerModule = nextPageEl.find('.answerModule').eq(0) nextPageFirstModule = nextPageEl.find('.module').eq(0) //按照模块id 归类删除 nextPageEl.find('.answerModule').each(function () { if ($(this).attr('data-modelId') === modelId) { $(this).remove() } }) } //计算留在当前页面的和下一个页面的数据 var originPageRetainHtml = self.getSingleSelectHtml( modelPagesData[curModuleDataIndex] ) var overSelectItemsHtml = self.getSingleSelectHtml( modelPagesData[nextExpendDataIndex] ) let btnHtml = '
X
' if (!originPageRetainHtml) { removeElements.push(part.closest('.single-select')) } else { part.html(btnHtml + originPageRetainHtml) } overSelectItemsHtml = self.titleHtml(!originPageRetainHtml ? modelData.bigTitle : '') + self.tpls.selectContentTpl.substitute({ selectContent: overSelectItemsHtml, moduleType: overPart.answerModule.attr('data-type') }) var overAnswerModule = overPart.answerModule overAnswerHtml += self.addPrintForAnswerModule( overPart, curPageIndex, overSelectItemsHtml, resetEditorIds, removeElements, nextPageEl ) /** * 【优化】 * 模块删除关系需要优化 */ removeElements.forEach(function (element) { $(element).remove() }) //是否存在下一个分页 if (nextPageEl.length) { nextPageEl.children('.dtk-content').prepend(overAnswerHtml) if (self.isSurplusModule(nextPageFirstModule)) { self.delPageOverPart(nextPageFirstModule.children('.delBtn'), 'over') } } else { self.addPage(overAnswerHtml) nextPageEl = $('#printcontent').children('.pageContent:last()') } //重置富文本 self.resetAddNewModuleEditor(resetEditorIds) //递归轮询判断 self.changePrintArea(nextPageEl) }, //重新计算分页数据 resetPageDataForSubject: function ( overAnswerModule, curPageIndex, resetEditorIds, nextPageEl ) { var self = this //page data index var curModuleDataIndex = 'page' + curPageIndex var nextExpendDataIndex = 'page' + (curPageIndex + 1) var overModuleType = overAnswerModule.attr('data-type') //如果下一个页面的第一个模块是选择题或者填空题的补充模块,则特殊处理 var isSelect = ~overModuleType.indexOf('Select') var isFillInBlank = overModuleType === 'fillInBlank' if (isSelect || isFillInBlank) { var modelId = overAnswerModule.attr('data-modelId') // var modelPagesData = self.questionMap[modelId].pages var modelPagesData = JSON.parse(JSON.stringify(self.questionMap[modelId].pages)) var bigTitle = self.questionMap[modelId].bigTitle var nextHasData = false modelPagesData[nextExpendDataIndex] = modelPagesData[nextExpendDataIndex] || [] modelPagesData[curModuleDataIndex] = modelPagesData[curModuleDataIndex] || [] var nextExpendData = modelPagesData[nextExpendDataIndex] var curModuleData = modelPagesData[curModuleDataIndex] if (nextExpendData.length) { nextHasData = true modelPagesData[nextExpendDataIndex] = curModuleData.concat( nextExpendData ) } else { modelPagesData[nextExpendDataIndex] = [].concat(curModuleData) } modelPagesData[curModuleDataIndex].length = 0 //如果是选择题下一页的数据处理 if (isSelect) { if (nextHasData) { var $expendModule = overAnswerModule.find('.singleContent') var $nextRemoveModule = nextPageEl.find('.single-select').eq(0) var $expendHtml = self.titleHtml(bigTitle) + self.getSingleSelectHtml(modelPagesData[curModuleDataIndex]) $expendModule.html($expendHtml) //如果下一页的第一个模块是当前超出这个模块的补充模块,则直接删除 if ($nextRemoveModule.attr('data-modelId') === modelId) { $nextRemoveModule.remove() } } } else if (overModuleType === 'fillInBlank') { if (nextHasData) { var $expendModule = overAnswerModule.find('.subjectCol') var $nextRemoveModule = nextPageEl.find('.completion-topic').eq(0) var $expendHtml = self.getFillInBlankHtml( modelPagesData[nextExpendDataIndex] ) $expendModule.html($expendHtml) //如果下一页的第一个模块是当前超出这个模块的补充模块,则直接删除 if ($nextRemoveModule.attr('data-modelId') === modelId) { $nextRemoveModule.remove() } } } } else { //解答题重置富文本 //2 判断是否有需要重置的富文本 var editorEls = overAnswerModule.find('.editorContent') editorEls.length && editorEls.each(function () { resetEditorIds.push({ editorId: $(this).attr('id'), toolbarId: $(this).prev().attr('id') }) }) } }, //新建分栏 /** * @param {上一栏超出的模块html} overAnswerHtml */ addPage: function (overAnswerHtml) { var self = this //新建的分页 self.totalPage++ self.currentPage++ self.currentPaper = Math.ceil(self.totalPage / (self.columns * 2)) //第一张纸 正面1 正面2 第一张至反面1 反面2 var paperDirection = (self.totalPage % (self.columns * 2) ? self.totalPage % (self.columns * 2) : self.columns * 2) <= self.columns ? '正面' : '反面' var pageForPaperDirection = self.totalPage % self.columns ? self.totalPage % self.columns : 2 var currentPaperPage = paperDirection + pageForPaperDirection //新建page var newPage = self.tpls.pageModuleTpl.substitute({ subjectModule: overAnswerHtml, currentPage: self.currentPage, totalPage: self.totalPage, currentPaper: self.currentPaper, currentPaperPage: currentPaperPage }) $('#printcontent').append(newPage) self.refrushPageLabel() }, //重新初始化移动的富文本题目编辑区域 resetAddNewModuleEditor: function (resetEditorIds) { var self = this /** * editorId * toolbarId */ resetEditorIds.forEach(function (resetEditorId) { if (!$('#' + resetEditorId.toolbarId).length) return // var editorIndex = resetEditorId.editorId.match(/\d+/g)[0] // var reg = /(?<=editorContent).+(?=")/; var reg = /([^editorContent]+)$/; var editorIndex = resetEditorId.editorId.match(reg)[1]; var editTopic = {}; jQuery.each(self.questionMap, function (i, bigTopic) { jQuery.each(bigTopic.questions, function (j, Topic) { if (editorIndex == Topic.questionNum) { editTopic = Topic } }) }) let topicType = editTopic.questionTypeId if (topicType == 7) { topicType = editTopic.markQuestionType } $('#' + resetEditorId.toolbarId).html('') var editor = new self.EDITOR( '#' + resetEditorId.toolbarId, '#' + resetEditorId.editorId ) editor.customConfig.menus = topicType == '7c' ? self.EDITOR_CONFIG_ZW : self.EDITOR_CONFIG editor.customConfig.onfocus = function () { if (!self.isCanEditCard) return $('#' + resetEditorId.editorId) .siblings('.toolbar') .addClass('seled') } editor.customConfig.onblur = function () { //如果当前答题卡模板不在编辑状态,或者 正在使用公式编辑器,都不用启动这个事件 if (!self.isCanEditCard || self.formulaing) return $('#' + resetEditorId.editorId) .siblings('.toolbar') .removeClass('seled') //过滤所有的空标签 换行产生的标签 var newEditorHtml = editor.txt .html() .replace(self.replaceEditorRegexp, '') editor.txt.html(newEditorHtml) } editor.customConfig.linkImgCallback = function (url) { editor.$textElem.find('img').forEach(function (el) { var src = $(el).attr('src') if (src === url) { $(el).addClass('customImg') } return false }) } // 关闭粘贴样式的过滤 editor.customConfig.pasteFilterStyle = true editor.customConfig.customUploadImg = function (files, insert) { self.addImgToEditor(files, editor) } //#747474 editor.create() //记录模块信息 var editorText = self.editorArea['editor' + editorIndex].txt .html() .clearFixible() if (!~editorText.indexOf('flexible_icon')) { //设置图片伸缩使用icon editorText += self.tpls.flexibleIconTpl } editor.txt.html(editorText) self.editorArea['editor' + editorIndex] = editor }) }, //可编辑区域 editorArea: {}, editorIndex: 0, editorAreaOriginContent: {}, //解答题区域添加图片 addImgToEditor: function (files, editor) { var self = this var uploadForm = new FormData() uploadForm.append('editor_file', files[0]) $.ajax({ url: self.apis.uploadFileApi, method: 'POST', processData: false, contentType: false, dataType: 'json', data: uploadForm, success: function (result) { var imgTpl = '' var editorContetEl = editor.$textContainerElem.children('.w-e-text') var contentHeihgt = self.calcEditorContentHeight($(editorContetEl)) var maxHeight = contentHeihgt + 64 editor.txt.html( editor.txt.html() + imgTpl.substitute({ maxHeight: maxHeight, imgUrl: result.data }) ) } }) }, //创建作答区域模块 createShortAnswer: function (editorIndex, originContent, topicType) { var self = this originContent = originContent || '' //this.createShortAnswer("#toolbar2", "#editorContent2", 2); if (!$('#toolbar' + editorIndex).length) return var editor = new self.EDITOR( '#toolbar' + editorIndex, '#editorContent' + editorIndex ) // 自定义菜单配置 editor.customConfig.menus = topicType == '7c' ? self.EDITOR_CONFIG_ZW : self.EDITOR_CONFIG editor.customConfig.onfocus = function () { if (!self.isCanEditCard) return $('#editorContent' + editorIndex) .siblings('.toolbar') .addClass('seled') } editor.customConfig.onblur = function () { if (!self.isCanEditCard || self.formulaing) return $('#editorContent' + editorIndex) .siblings('.toolbar') .removeClass('seled') //过滤所有的空标签 换行产生的标签 var newEditorHtml = editor.txt .html() .replace(self.replaceEditorRegexp, '') editor.txt.html(newEditorHtml) } //网络图片自定义类名 editor.customConfig.linkImgCallback = function (url) { editor.$textElem.find('img').forEach(function (el) { var src = $(el).attr('src') if (src === url) { $(el).addClass('customImg') } return false }) } // 关闭粘贴样式的过滤 editor.customConfig.pasteFilterStyle = false //editor.customConfig.uploadImgShowBase64 = true editor.customConfig.customUploadImg = function (files, insert) { self.addImgToEditor(files, editor) } editor.create() //记录模块信息 var editorText = editor.txt.html().clearFixible() if (!~editorText.indexOf('flexible_icon')) { //设置图片伸缩使用icon editorText += self.tpls.flexibleIconTpl } editorText += originContent.clearFixible() editor.txt.html(editorText.replace(self.replaceEditorRegexp, '')) // if(editorIndexUp==''){ self.editorIndex = editorIndex // } editorIndexUp = '' self.editorArea['editor' + editorIndex] = editor }, //答题区域文本图片位置更换 shortAnswerImgPositionChange: function () { var self = this var curOpratorImg = null var fa = null $('#hgc_print').on('mousedown', '.editorContent .customImg', function (e) { e.preventDefault() var moveImgEl = $(this)[0] var boundaryEl = $(moveImgEl).closest('.module')[0] var flexibleIcon = $(this).closest('.module').find('.flexible_icon')[0] var moveElHeight = moveImgEl.offsetHeight var moveElWidth = moveImgEl.offsetWidth var oldX = e.clientX var oldY = e.clientY var startLeft = moveImgEl.offsetLeft var startTop = moveImgEl.offsetTop document.onmousemove = function (ev) { var maxTop = boundaryEl.offsetHeight - self.modulePaddingBottom - moveElHeight var maxLeft = boundaryEl.offsetWidth - self.modulePaddingSide - moveElWidth var distanceX = ev.clientX - oldX var distanceY = ev.clientY - oldY var newLeft = startLeft + distanceX var newTop = startTop + distanceY if (newLeft <= self.modulePaddingSide / 2) newLeft = self.modulePaddingSide / 2 if (newTop <= self.modulePaddingTop) newTop = self.modulePaddingTop if (newTop >= maxTop) newTop = maxTop if (newLeft >= maxLeft) newLeft = maxLeft moveImgEl.style.left = newLeft + 'px' moveImgEl.style.top = newTop + 'px' flexibleIcon.style.left = newLeft + moveElWidth - 20 + 'px' flexibleIcon.style.top = newTop + moveElHeight - 20 + 'px' } document.onmouseup = function () { document.onmousemove = null document.onmouseup = null flexibleIcon.style.display = 'none' } }) function resetFlexibleIcon($flexibleIcon, $curImg) { $flexibleIcon.css({ left: parseFloat($curImg.css('left')) + $curImg.width() - 20, top: parseFloat($curImg.css('top')) + $curImg.height() - 20 }) } //图片缩放 $('#hgc_print').on('mouseover', '.editorContent .customImg', function (e) { //缩放icon var $curImg = $(this) var $curModule = $curImg.closest('.module') var $flexibleIcon = $curModule.find('.flexible_icon') $flexibleIcon.show() curOpratorImg = $curImg[0] fa = $curModule[0] $flexibleIcon.show() resetFlexibleIcon($flexibleIcon, $curImg) }) $('#hgc_print').on('mouseout', '.editorContent .customImg', function (e) { e.stopPropagation() //缩放icon var $curImg = $(this) var $curModule = $curImg.closest('.module') var $flexibleIcon = $curModule.find('.flexible_icon') $flexibleIcon.hide() }) $('#hgc_print').on('mouseover', '.editorContent .flexible_icon', function ( e ) { //缩放icon var $curImg = $(this) var $curModule = $curImg.closest('.module') var $flexibleIcon = $curModule.find('.flexible_icon') $flexibleIcon.show() }) //图片缩放 $('#hgc_print').on('mousedown', '.editorContent .flexible_icon', function ( e ) { // 阻止冒泡,避免缩放时触发移动事件 e.stopPropagation() e.preventDefault() var $flexibleIcon = $(this) var pos = { w: curOpratorImg.offsetWidth, h: curOpratorImg.offsetHeight, x: e.clientX, y: e.clientY } fa.onmousemove = function (ev) { ev.preventDefault() // 设置图片的最小缩放为30*30 var w = Math.max(30, ev.clientX - pos.x + pos.w) var h = Math.max(30, ev.clientY - pos.y + pos.h) // console.log(w,h) // 设置图片的最大宽高 w = w >= fa.offsetWidth - curOpratorImg.offsetLeft ? fa.offsetWidth - curOpratorImg.offsetLeft : w h = h >= fa.offsetHeight - curOpratorImg.offsetTop ? fa.offsetHeight - curOpratorImg.offsetTop : h curOpratorImg.style.width = w + 'px' curOpratorImg.style.height = h + 'px' resetFlexibleIcon($flexibleIcon, $(curOpratorImg)) // console.log(box.offsetWidth,box.offsetHeight) } fa.onmouseup = function () { fa.onmousemove = null fa.onmouseup = null } }) }, //新模块 part addNewModule: function (part, moduleType, resetEditorIds, removeElements) { var self = this var moduleTitle = '' var modulePrev = part.prev() var hasTitle = modulePrev.length && modulePrev[0].tagName === 'H3' //1 新增新模块resetEditorIds removeElements //2 判断是否有需要重置的富文本 var editorEl = part.children('.editorContent') if (editorEl.length) { resetEditorIds.push({ editorId: editorEl.attr('id'), toolbarId: editorEl.prev().attr('id') }) } //3 移除老模块 removeElements.push(part) if (hasTitle) { //self.titleHtml(modulePrev.html()) moduleTitle = modulePrev[0].outerHTML removeElements.push(modulePrev) } return moduleTitle + part[0].outerHTML }, addNewModuleForObjective: function (part, moduleType, removeElements) { var self = this var moduleTitle = '' var modulePrev = part.prev() var hasTitle = modulePrev.length && modulePrev[0].tagName === 'H3' //3 移除老模块 removeElements.push(part) if (hasTitle) { moduleTitle = self.singleSelectObjectiveTitle removeElements.push(modulePrev) } return moduleTitle + part[0].outerHTML }, //拿到富文本超出的内容 顺便计算一下下一个模块该有的最低高度 getOverContent: function (part, surplusHeight, removeElements) { var self = this var editorContentEl = part.find('.w-e-text') var overContent = [] var overHeight = 0 //富文本可视化高度 var surplusEditorViewportHeight = // editorContentEl.height() - surplusHeight + 30 editorContentEl.height() - surplusHeight //看看当前富文本内容的高度有没有被超出的高度区域截掉 var editorContentHeight = self.calcEditorContentHeight(editorContentEl) //如果剩余高度还能装的下答题文本 直接返回空 if (surplusEditorViewportHeight > editorContentHeight) return { overContent: overContent.reverse().join(''), overHeight: overHeight } //当前超出富文本内容元素集合,倒序递归删除放到下一页 var editorContentElements = [].slice .call(part.find('.w-e-text').children(), 0) .reverse() for (var i = 0, elItem; (elItem = editorContentElements[i++]);) { if ($(elItem).hasClass("flexible_icon")) continue if (editorContentHeight < surplusEditorViewportHeight) break var elItemHeight = $(elItem).height() + 10 if ($(elItem).hasClass("en")){ elItemHeight = 34 } editorContentHeight -= elItemHeight overHeight += elItemHeight removeElements.push($(elItem)) overContent.push(elItem.outerHTML) } return { overContent: overContent.reverse().join(''), overHeight: overHeight > surplusHeight ? overHeight + 50 : surplusHeight } }, //上一个模块的拓展模块 expandModule: function (part, nextContentMinHeight) { var self = this var titleNumber = part.attr('title-number') var partEditorIndexUp = part.attr('data-editorindex') //当前超出的模块height var overHeight = self.getOverHeight(part) var $nextPage = part.closest('.pageContent').next() var $nextPageFirstModule = $nextPage.find('.module').eq(0) var $nextPageModuleTitleNumber = $nextPageFirstModule.attr('title-number') overHeight = overHeight < self.moduleMinHeight ? self.moduleDefaultHeihgt : overHeight //如果下一页已经存在当前模块的 高度累加 if ($nextPageModuleTitleNumber === titleNumber) { overHeight += 0 //$nextPageFirstModule.height() } //如果该模块超出区域 这需要通过linkparam 去 排列超出的顺序 editorIndexUp = titleNumber + '-' + editorIndexLi if(partEditorIndexUp!=undefined){ editorIndexUp = partEditorIndexUp+'-' + editorIndexLi } ++editorIndexLi var linkparm = 1 var cutId = editorIndexUp //如果该模块是首次超出 则直接从1开始计数,否则从当前位置开始计数 if (!part.attr('data-linkparm')) { part.attr({ 'data-cutId': editorIndexUp, 'data-linkparm': linkparm }) linkparm++ } else { linkparm = +part.attr('data-linkparm') cutId = +part.attr('data-cutId') linkparm++ } return self.tpls.overModuleTpl.substitute({ overIndex: editorIndexUp, cutId: cutId, linkparm: linkparm, titleNumber: titleNumber, editorContentHeight: overHeight < nextContentMinHeight ? nextContentMinHeight : overHeight }) }, reduceFillInBlank: function (part, surplusHeight, $dtKContent) { var self = this var curPageIndex = $dtKContent.closest('.pageContent').index() + 1 var fromPageIndex = part.closest('.pageContent').index() + 1 var $answerModule = part.closest('.answerModule') var modelId = $answerModule.attr('data-modelId') var modelData = self.questionMap[modelId] var modelPagesData = modelData.pages //一行几栏 var $firstColForInfoEl = part.children('.subjectCol') var dataColumns = $firstColForInfoEl.attr('data-column') var columns = dataColumns ? +dataColumns : 1 //计算每个填空题item的高度 var rowLinHeight = $firstColForInfoEl.attr('data-rowlineheight') var fillInBlankItemHeight = (+rowLinHeight || 40) + 11 var scoreStyle = $firstColForInfoEl.attr('data-scoreStyle') //需要复制几个填空题-如果有标题要减去比哀痛的高度 if (part.prev().length && part.prev()[0].tagName === 'H3') { surplusHeight -= part.prev().height() } var copyFillInBlankLength = Math.floor(surplusHeight / fillInBlankItemHeight) * columns //原页面保留的题目 //超出的放在新页面上 var curModuleDataIndex = 'page' + curPageIndex var nextExpendDataIndex = 'page' + fromPageIndex modelPagesData[curModuleDataIndex] = modelPagesData[curModuleDataIndex] || [] modelPagesData[curModuleDataIndex] = modelPagesData[ curModuleDataIndex ].concat( modelPagesData[nextExpendDataIndex].splice(0, copyFillInBlankLength) ) //原页面残留 var originPageRetainHtml = self.getFillInBlankHtml( modelPagesData[curModuleDataIndex] ) //新页面超出 var overFillInBlankItemsHtml = self.getFillInBlankHtml( modelPagesData[nextExpendDataIndex] ) var $overFillInBlank = part.closest('.completion-topic') var $overDtkContent = $overFillInBlank.closest('.dtk-content') $overFillInBlank.remove() if (overFillInBlankItemsHtml) { overFillInBlankItemsHtml = self.titleHtml(originPageRetainHtml ? '' : modelData.bigTitle) + self.tpls.fillInBlankContentTpl.substitute({ addFillInBlankHtml: overFillInBlankItemsHtml, columns: columns, scoreStyle: scoreStyle, rowLinHeight: rowLinHeight, settingBtn: originPageRetainHtml ? '' : self.tpls.fillInBlankSettingBtnTpl }) overFillInBlankItemsHtml = self.tpls.answerModulForFillInBlankTpl.substitute( { editModule: overFillInBlankItemsHtml, moduleType: 'fillInBlank', modelId: modelId } ) $overDtkContent.prepend(overFillInBlankItemsHtml) } //老页面残留填空题模块--寻找模块id 相同的模块 var $prevFillInBlank = { length: 0 } $dtKContent.find('.completion-topic').each(function () { if ($(this).attr('data-modelId') === modelId) { $prevFillInBlank = $(this) } }) if (!$prevFillInBlank.length) { originPageRetainHtml = self.titleHtml(modelData.bigTitle) + self.tpls.fillInBlankContentTpl.substitute({ addFillInBlankHtml: originPageRetainHtml, columns: columns, scoreStyle: scoreStyle, rowLinHeight: rowLinHeight, settingBtn: self.tpls.fillInBlankSettingBtnTpl }) originPageRetainHtml = self.tpls.answerModulForFillInBlankTpl.substitute({ editModule: originPageRetainHtml, moduleType: 'fillInBlank', modelId: modelId }) $dtKContent.append(originPageRetainHtml) } else { $prevFillInBlank.find('.subjectCol').html(originPageRetainHtml) } return !overFillInBlankItemsHtml }, reduceSingleSelect: function (part, surplusHeight, $dtKContent) { var self = this var curPageIndex = $dtKContent.closest('.pageContent').index()==0?$dtKContent.closest('.pageContent').index() + 1:$dtKContent.closest('.pageContent').index() // var fromPageIndex = part.closest('.pageContent').index()==0?part.closest('.pageContent').index() + 1:part.closest('.pageContent').index() var fromPageIndex = curPageIndex +1 var $answerModule = part.closest('.answerModule') var type = $answerModule.attr('data-type') var modelId = $answerModule.attr('data-modelId') var direction = $answerModule.attr('data-direction') var prevTag = part.prev()[0] if (prevTag && prevTag.tagName === 'H3') { surplusHeight -= part.prev().height() } //每小题的高度 var selectItemHeight = $('.single-option').eq(0).outerHeight() //当前超出的模块height if (Math.floor(surplusHeight / selectItemHeight) < 1) return //针对选择题竖版一行排几个 /** * 超出的计算单位以 一整排为单位 * 每一排的一列以5题为单位 计算 */ var rowSubjectNum = self.config[self.direction][self.hasBindingLine ? 'yesLine' : 'noLine'][ self.columns ] //计算超出多少小题 var overSelectItemsLength = Math.floor(surplusHeight / selectItemHeight) * rowSubjectNum //该模块的数据 var modelPagesData = self.questionMap[modelId].pages //超出的放在新页面上 var curModuleDataIndex = 'page' + curPageIndex var nextExpendDataIndex = 'page' + fromPageIndex modelPagesData[curModuleDataIndex] = modelPagesData[curModuleDataIndex] || [] modelPagesData[curModuleDataIndex] = modelPagesData[ curModuleDataIndex ].concat( modelPagesData[nextExpendDataIndex].splice(0, overSelectItemsLength) ) //计算留在当前页面的和下一个页面的数据 var originPageRetainHtml = self.getSingleSelectHtml( modelPagesData[curModuleDataIndex] ) var overSelectItemsHtml = self.getSingleSelectHtml( modelPagesData[nextExpendDataIndex] ) //超出页面的数据处理 var $overAnswerModule = part.closest('.single-select') var $overDtkContent = $overAnswerModule.closest('.dtk-content') $overAnswerModule.remove() if (overSelectItemsHtml) { //获取超出选择题区域模块html //selectContent, title, direction, hasTitle overSelectItemsHtml = self.getSelectRenderContent({ selectContent: overSelectItemsHtml, moduleType: type, direction: direction, hasTitle: originPageRetainHtml ? false : true, bigTitle: self.questionMap[modelId].bigTitle, modelId: modelId }) $overDtkContent.prepend(overSelectItemsHtml) } //老页面残留填空题模块处理 var $originAnswerModule = self.getAnswerModuleForModelId(modelId) if (!$originAnswerModule || !$originAnswerModule.length) { //获取整个选择题区域模块html originPageRetainHtml = self.getSelectRenderContent({ selectContent: originPageRetainHtml, direction: direction, moduleType: type, bigTitle: self.questionMap[modelId].bigTitle, modelId: modelId }) $dtKContent.append(originPageRetainHtml) } else { let btnHtml = '
X
' $originAnswerModule.find('.singleContent').html(btnHtml + originPageRetainHtml) } return !overSelectItemsHtml }, reducePrintArea: function (curPageEl) { var self = this var nextPage = curPageEl.next() if (!nextPage.length) { //在delPageOverModule 的方法中可能存在被遗忘的超出模块此时做重置 if (self.forgetOverPage) { self.changePrintArea(self.forgetOverPage) } return } var curPageIndex = curPageEl.index() //当前模块下面所有的模块都可以上移,只要当前剩余空间足够大 var canUpMovePage = $('#printcontent').children( '.pageContent:gt(' + curPageIndex + ')' ) /** * 首先通过判断当前页面的剩余空间是否够下一个页面的第一个模块使用 * 1 如果下一页第一个是第一页的模块补充模块 直接合并 * 2 如果下一页第一个不是补充模块,如果上一页的空间大于当前这一页 * a. 直接把标题带着第一个模块一起拿上去 * b. 如果是一个小题 直接把当前小题拿上去,归并到上一个页面的大题下面 */ //var answerModule = [].splice.call(canUpMovePage.find('.answerModule'), 0) //var objectiveModule = [].splice.call(canUpMovePage.find('.objectiveModule'), 0) var nextPageAllModule = [].splice.call( canUpMovePage.find('.answerModule'), 0 ) var isContiune = true nextPageAllModule.forEach(function (answerEl, index) { if (!isContiune) return false var firstAnswer = $(answerEl) var nextUpPage = firstAnswer.closest('.pageContent') var answerModuleType = firstAnswer.attr('data-type') //题干信息 var isObjective = answerModuleType === 'objective' var isSelect = ~answerModuleType.indexOf('Select') || ~answerModuleType.indexOf('uncertainOption') var isFillInBlank = answerModuleType === 'fillInBlank' var isChooseAnswer = answerModuleType === 'chooseAnswer' var firstModule = firstAnswer.children('.module').eq(0) var curPageContent = curPageEl.children('.dtk-content') //具体分页内容容器的宽度 var contentAndHeight = curPageContent.outerHeight() //当前分页剩余空间 var surplusHeight = curPageEl.height() - contentAndHeight if (surplusHeight <= 10) { //如果当前分页超出直接重新计算排版方式 if ( surplusHeight < -10 && curPageEl.find('.answerModule:last()').children('.module').length ) { self.changePrintArea(curPageEl) } isContiune = false return false } if (isFillInBlank) { //下一页面第一个填空题的高度 var firstModuleHeight = self.getNextPageFirstModuleHeight( firstModule, 'fillInBlank' ) if (surplusHeight >= firstModuleHeight) { self.reduceFillInBlank(firstModule, surplusHeight, curPageContent) self.updatePageElement(nextUpPage, firstAnswer) } else { isContiune = false return false } } else if (isSelect) { var firstModuleHeight = self.getNextPageFirstModuleHeight( firstModule, 'singleSelect' ) if (surplusHeight >= firstModuleHeight) { self.reduceSingleSelect(firstModule, surplusHeight, curPageContent) self.updatePageElement(nextUpPage, firstAnswer) } else { isContiune = false return false } } else if (isObjective) { $(answerEl) .children('.objectiveItem') .each(function (idx, moduleEl) { //解答题一个小题就是一个module firstModule = $(moduleEl) contentAndHeight = curPageContent.outerHeight() surplusHeight = curPageEl.height() - contentAndHeight //下一个页面第一个解答题模块 var firstModuleHeight = self.getNextPageFirstModuleHeight( firstModule, 'objective' ) if (surplusHeight >= firstModuleHeight) { self.copyModuleForObjective(firstModule, firstAnswer, curPageEl) self.updatePageElement(nextUpPage, firstAnswer, 'objective') } else { isContiune = false return false } }) } else { //选做题特殊处理,题干信息一个一个往上拿 var $chooseAnswerObjectiveItems = $(answerEl).find('.questionItemBody') //如果有单独的模块还是可以 // && !$(answerEl).children('.module').length if (isChooseAnswer && $chooseAnswerObjectiveItems.length) { contentAndHeight = curPageContent.outerHeight() surplusHeight = curPageEl.height() - contentAndHeight - $(answerEl).find('h3').children('span').height() var removeItems = [] $chooseAnswerObjectiveItems.each(function () { //如果上一页有选做题模块 var prePageLastAnswer = curPageEl.find('.answerModule:last') var prevLastModuleIsChooseAnswer = prePageLastAnswer.length ? prePageLastAnswer.attr('data-type') === 'chooseAnswer' : false var $item = $(this) var itemHeight = $(this).height() var itemHtml = $(this)[0].outerHTML if (surplusHeight > itemHeight) { if (prePageLastAnswer.length && prevLastModuleIsChooseAnswer) { prePageLastAnswer .children('h3') .children('.originSubjectInfo') .append(itemHtml) surplusHeight -= itemHeight removeItems.push($item) } else { //如果上一页没有多选题模块 //1 先拿到当前多选题的基础信息 var $h3 = $(answerEl).find('h3') var baseInfo = $h3[0].outerHTML.replace( /
(.*)<\/div>/g, '
' + itemHtml + '
' ) curPageContent.append( '
' + baseInfo + '
' ) surplusHeight -= itemHeight removeItems.push($item) } } else { isContiune = false return false } }) if (removeItems.length >= $chooseAnswerObjectiveItems.length) { $(answerEl).find('h3').remove() } else { if (removeItems.length) { removeItems.forEach(function (el) { $(el).remove() }) $(answerEl) .find('h3') .html( '
' + $(answerEl) .find('h3') .children('.originSubjectInfo') .html() + '
' ) } } self.updatePageElement(nextUpPage, firstAnswer, 'chooseAnswer') //self.reducePrintArea(nextPage) return } $(answerEl) .children('.module') .each(function (idx, moduleEl) { var resetEditorIds = [] //解答题一个小题就是一个module firstModule = $(moduleEl) contentAndHeight = curPageContent.outerHeight() surplusHeight = curPageEl.height() - contentAndHeight //如果是补充模块--直接删除再计算其他高度 if (self.isSurplusModule(firstModule)) { self.delPageOverPart(firstModule.find('.delBtn'), 'surplus') return } //下一个页面第一个解答题模块 var firstModuleHeight = self.getNextPageFirstModuleHeight( firstModule, 'answer' ) if (surplusHeight >= firstModuleHeight) { self.copyModuleToSurplus( firstModule, firstAnswer, curPageEl, resetEditorIds ) } else { //判断是否是一个大题的开始 var modulePrev = firstModule.prev() var hasTitle = modulePrev.length && modulePrev[0].tagName === 'H3' var titleHeight = hasTitle ? modulePrev.height() : 0 if (surplusHeight <= titleHeight + 100) { isContiune = false return false } else { self.copyModuleToSurplus( firstModule, firstAnswer, curPageEl, resetEditorIds ) if (self.getOverHeight(curPageEl.find('.module:last()'))) { self.saveForgetPage(curPageEl) } } } self.updatePageElement(nextUpPage, firstAnswer) //重置富文本 self.resetAddNewModuleEditor(resetEditorIds) }) } }) self.changePrintArea(nextPage) }, //复制一个模块到上一个页面的剩余空间 type whole | few表示整体模块上移还是部分模块上去 copyModuleToSurplus: function ( firstModule, firstAnswer, curPageEl, resetEditorIds ) { var self = this //判断是否是一个大题的开始 var modulePrev = firstModule.prev() var hasTitle = modulePrev.length && modulePrev[0].tagName === 'H3' var moduleType = firstAnswer.attr('data-type') var modelId = firstAnswer.attr('data-modelId') var cloneHtml = '' //准备重新初始化富文本所需要的 editorId var editorEl = firstModule.children('.editorContent') if (editorEl.length) { resetEditorIds.push({ editorId: editorEl.attr('id'), toolbarId: editorEl.prev().attr('id') }) } //如果没有标题 则认为是 上一页最后一大题的一个小题 var moduleHtml = firstModule[0].outerHTML var $dtkContent = curPageEl.children('.dtk-content') var $shortAnswerLast = curPageEl.find('.short-answer:last()') if (hasTitle) { var editModuleHtml = modulePrev[0].outerHTML + moduleHtml cloneHtml = self.tpls.answerModuleTpl.substitute({ editModule: editModuleHtml, moduleType: moduleType, modelId: modelId }) $dtkContent.append(cloneHtml) modulePrev.remove() } else { var $shortAnswerLast = curPageEl.find('.short-answer:last()') cloneHtml = moduleHtml //可能中间出现真空区域 if (!$shortAnswerLast.length) { cloneHtml = self.tpls.answerModuleTpl.substitute({ editModule: cloneHtml, moduleType: moduleType, modelId: modelId }) $dtkContent.append(cloneHtml) } else { $shortAnswerLast.append(cloneHtml) } } //清理模块 firstModule.remove() }, //题干信息copy copyModuleForObjective: function (firstModule, firstAnswer, curPageEl) { var self = this //判断是否是一个大题的开始 var modulePrev = firstModule.prev() var hasTitle = modulePrev.length && modulePrev[0].tagName === 'H3' var cloneHtml = '' //如果没有标题 则认为是 上一页最后一大题的一个小题 var moduleHtml = firstModule[0].outerHTML // self.tpls.objectiveItemTpl.substitute({ // content: firstModule.html() // }) var $dtkContent = curPageEl.children('.dtk-content') if (hasTitle) { var editModuleHtml = modulePrev[0].outerHTML + moduleHtml cloneHtml = self.tpls.objectiveWrapTpl.substitute({ editModule: editModuleHtml }) $dtkContent.append(cloneHtml) modulePrev.remove() } else { var $shortAnswerLast = curPageEl.find('.objectiveModule:last()') cloneHtml = moduleHtml //可能中间出现真空区域 if (!$shortAnswerLast.length) { cloneHtml = self.tpls.objectiveWrapTpl.substitute({ editModule: cloneHtml }) $dtkContent.append(cloneHtml) } else { $shortAnswerLast.append(cloneHtml) } } //清理模块 firstModule.remove() }, //获取当前也页面的剩余空间 getCurPageSurplusHeight: function (curPageEl) { var curPageContent = curPageEl.children('.dtk-content') //具体分页内容容器的宽度 var contentAndHeight = curPageContent.outerHeight() //当前分页剩余空间 return curPageEl.height() - contentAndHeight }, //获取下一个页面第一个模块的高度,用来和上一个页面的剩余高度做对比 getNextPageFirstModuleHeight: function (firstModule, type) { var self = this //判断是否是一个大题的开始 var modulePrev = firstModule.prev() var hasTitle = modulePrev.length && modulePrev[0].tagName === 'H3' //如果包含title 必须满足上一页面剩余的高度大于 当前页面第一个模块的高度加上模块对应title的高度 //留点空间余地不能抵到最底下 var titleHeight = (hasTitle ? modulePrev.height() : 0) + 10 //type包含选择,填空,解答题 if (type === 'fillInBlank') { var firstFillInBlank = firstModule.find('.subjectItem').eq(0) return firstFillInBlank.outerHeight() + titleHeight } else if (~type.indexOf('Select')) { var firstSelect = firstModule.find('.single-option').eq(0) return firstSelect.outerHeight() + titleHeight } else { return firstModule.outerHeight() + titleHeight } }, //页面之间模版串位之后更新每个页面的元素 updatePageElement: function (nextUpPage, firstAnswer, type) { var self = this //题干信息单独处理 var nextPage = nextUpPage var isObjective = type === 'objective' //选做题如果有题干信息 var isChooseAnswer = type === 'chooseAnswer' && firstAnswer.find('.originSubjectInfo').length if (firstAnswer) { if ( !firstAnswer.children(isObjective ? '.objectiveItem' : '.module') .length && !isChooseAnswer ) { firstAnswer.remove() } } if ( !nextPage.find('.answerModule').length && !nextPage.find('.objectiveModule').length ) { // 判断当前页面是否最后一页----如果最后一页为空才直接删除该页面 // 选择题和填空题的数据是根据页面显示的,如果你删除了,选择题和填空题的数据就错位了 if ($('#printcontent .pageContent').length === nextPage.index() + 1) { var prevPage = nextPage.prev() nextPage.remove() self.currentPage-- //新建的分页 self.totalPage-- self.refrushPageLabel() if (prevPage.length) { self.updatePageElement(prevPage) } } } }, //新页面预览 previewPrintDiv: function (printPart) { var self = this var priviewHtml = self.formatPrintHtml(printPart, 'preview') var iframe = document.createElement('iframe') iframe.setAttribute('id', 'preview-iframe') document.body.appendChild(iframe) var doc = iframe.contentWindow.document doc.write( '' ) doc.write(priviewHtml) if (isShowPreview > -1) { $('body').append('') } else { $('body').append('
关闭
') $('body').on('click', '#closeIframeBtn', function () { $('#preview-iframe').remove() $(this).remove() }) } }, //保存题目坐标信息 //保存的时候传点坐标和原图 /** * timu:{"KeGuanTi":5,"TianKongTi":10,"ZhuGuanTi":1,"XuanZuoTi":0} sheet_answer:{"1":"A","2":"A","3":"A","4":"A","5":"A"} sheet_score:{"1":"2","2":"2","3":"2","4":"2","5":"2","6":"2","7":"3","8":"4","9":"5","10":"6","11":"6","12":"7","13":"8","14":"9","15":"10","16":"20"} title:22 exam_id:17464269385543527633 position imgFiles:[fileobj,fileobj] */ //保存题目定位点的时候 获取 题目数量 分数 等信息 getSaveSubjectInfo: function (questionClassify) { var self = this var title = self.$dtkName.val() // examInfo //信息栏 //数量 var timu = { KeGuanTi: 0, TianKongTi: 0, ZhuGuanTi: 0, XuanZuoTi: 0 } //选择题答案 var sheet_answer = {} //每题对应分数 var sheet_score = {} // 半对分 var sheet_halfscore = {} // 总分 var scoreAll = 0 let pId = 0 var key = 0 for (var uid in questionClassify) { questionClassify[uid].questions.forEach(function (question, index) { //计算每个题目数量 var type = question.questionTypeId if (~[1, 2, 11].indexOf(type)) { timu.KeGuanTi += 1 } else if (type === 5) { timu.TianKongTi += 1 } else if (type === 7) { timu.ZhuGuanTi += 1 } else { timu.XuanZuoTi += 1 } key += 1 if(question.answer!=''){ sheet_answer[key] = question.answer } sheet_score[key] = '' + question.fullScore sheet_halfscore[key] = question.halfScore if (type == 17) { if (pId != question.topicNo) scoreAll = scoreAll + Number(question.fullScore) pId = question.topicNo } else { scoreAll = scoreAll + Number(question.fullScore) } }) } self.savePrintInfo = { title: title, timu: timu, sheet_answer: sheet_answer, sheet_score: sheet_score, sheet_halfscore: sheet_halfscore } self.examInfoConfigText.wpTimes = $('#examInfo input[name|="wpTimes"]').val() // self.examInfoConfigText.fullScore = $('#examInfo input[name|="fullScore"]').val() self.examInfoConfigText.fullScore = scoreAll self.examInfoConfigText.wpAuthor = $('#examInfo input[name|="wpAuthor"]').val() self.examInfoConfigText.wpReviewer = $('#examInfo input[name|="wpReviewer"]').val() self.examInfoConfigText.fullScore = self.showExamInfoHtml() }, //printcontent --- printPart savePrintPosition: function (printPart, cb) { var self = this // 给模块标题设置高度 $('.answerModule').find('h3').each(function (){ $(this).css('height',$(this).height()) }) var position = self.getPositions() //保存当前坐标点用于和下次一点击保存做对比,如果没有变化就可以防止重复提交 self.saveLocationPosition = JSON.stringify(position) //console.log(JSON.stringify(position, null, 4)) var printHtml = self.formatPrintHtml(printPart) var iframe = document.createElement('iframe') iframe.setAttribute('id', 'print-iframe') iframe.setAttribute('style', 'position:fixed;') document.body.appendChild(iframe) var doc = iframe.contentWindow.document doc.write( '' ) doc.write(printHtml) doc.close() iframe.contentWindow.focus() iframe.contentWindow.onload = function () { var pages = doc.getElementsByClassName('printIframeContent') //生成的pdf所需要的html var pdfHtml = ( self.tpls.htmlSkeleton + printHtml + '' ).replace(/\'/g, '"') hgc_layer.msg('pdf生成中,请稍后...', { time: 0, shade: 0.4 }) $.post( self.apis.getOnlinePdfApi, { width: self.config.width + 'mm', height: self.config.height + 'mm', identifier: self.identifier, examGroupId:self.examGroupId || '26566294892575975', pdfHtml: pdfHtml }, function (res) { var pdfFileUrl = '' let resData = JSON.parse(res) if(resData.success==1){ pdfFileUrl = resData.data // hgc_layer.closeAll() // location.href = self.apis.downloadPdfUrl + self.identifier } else { hgc_layer.msg(resData.message) return false } //处理模版html var pdfHtmlStream = new Blob([pdfHtml], { type: 'text/plain;charset=utf-8' }) self.savePrintInfo.title = self.$dtkName.val() self.savePrintInfo.pdfHtml = pdfHtml self.savePrintInfo.position = position //pdf 模版唯一标识符--主要用于创建考试页面模版下载 self.savePrintInfo.identifier = self.identifier self.savePrintInfo.examGroupId = self.examGroupId self.savePrintInfo.useQrCode = self.useQrCode ? 1 : 0 self.savePrintInfo.columns = self.columns self.savePrintInfo.pdfTemplate = pdfHtmlStream self.savePrintInfo.pdf_url = pdfFileUrl var formData = new FormData() formData.append('pdfTemplate', pdfHtmlStream, 'pdfTepmlate.txt') //pdf链接 formData.append('pdf_url', pdfFileUrl) //针对全学科,在保留题型数据的同时,也需要当前定位点的所有信息 if (isNewBuild) { var questions = [] var buildQuestions = self.questionMap for (var modelId in buildQuestions) { questions = questions.concat(buildQuestions[modelId].questions) } //题号重新排序 let PositionData = JSON.parse(JSON.stringify(questions)) function compare(key){ return function(value1,value2){ var val1=value1[key]; var val2=value2[key]; return val1-val2; } } PositionData.sort(compare('questionNum')); jQuery.each( PositionData, function( i, topicItem ) { topicItem.name = i+1 }); jQuery.each( questions, function( q, questionsItem ) { questionsItem.isEdit = false }); let score = {}; let halfScore = {}; let answer = {}; jQuery.each( questions, function( j, paperTopicItem ) { jQuery.each( PositionData, function( k, topicAllItem ) { if(!paperTopicItem.isEdit){ if(paperTopicItem.questionNum == topicAllItem.questionNum){ let topic = JSON.parse(JSON.stringify(topicAllItem)) let key = topic.name.toString(); paperTopicItem.questionNum = topic.name.toString() paperTopicItem.isEdit = true if(paperTopicItem.answer!=''){ answer[key] = paperTopicItem.answer } score[key] = '' + paperTopicItem.fullScore halfScore[key] = paperTopicItem.halfScore } } }); }); self.savePrintInfo.sheet_score = score; self.savePrintInfo.sheet_halfscore = halfScore; self.savePrintInfo.sheet_answer = answer; self.savePrintInfo.question_info = { content: questions } console.log(JSON.stringify(self.savePrintInfo)) //全学科,该页面还是做编辑使用,不做任何的操作 localStorage.setItem( 'savePrintInfo', JSON.stringify(self.savePrintInfo) ) hgc_layer.closeAll() self.isCanEditCard = false self.changeCardEditStatus() // location.href = document.referrer // if(localStorage.referrerUrl){ // var referrerUrl = JSON.parse(localStorage.getItem('referrerUrl')); // window.location.href = referrerUrl+"/isCardReturn=true" // }else{ // window.history.back(); // } return } for (var field in self.savePrintInfo) { if (typeof self.savePrintInfo[field] === 'object') { formData.append(field, JSON.stringify(self.savePrintInfo[field])) } else { formData.append(field, self.savePrintInfo[field]) } } //localStorage.setItem('savePrintInfo',JSON.stringify(self.savePrintInfo)) /** * 新页面需要特殊处理的地方 * var pdfHtmlStream = new Blob([pdfHtml], { type: 'text/plain;charset=utf-8' }) * formData.append('pdfTemplate', pdfHtmlStream, 'pdfTepmlate.txt') * imgFiles * formData.append('imgFiles' + index, img) * * examNumberConfig */ $.ajax({ //'//192.168.1.51/index.php/print/saveCardOnline' + loginStatus, url: self.apis.saveTopicsDetailsApi, method: 'POST', processData: false, contentType: false, dataType: 'json', data: formData, success: function (data) { hgc_layer.closeAll() if (data.success === 1) { hgc_layer.msg('保存成功') self.isCanEditCard = false self.changeCardEditStatus() self.alreadySave = true //如果使用二维码 //考号 和 条形码 都没有了,导致试卷内所有定位点错误,需要重新保存定位点 cb && cb() } else { hgc_layer.msg('保存失败') } } }) document.body.removeChild(iframe) } ) } }, //重置学生状态 resetExamStudentStatus: function (cb) { var self = this $.post( self.apis.resetExamStudentApi, { schoolId: this.schoolId, examGroupId: this.examGroupId }, function (res) { // console.log(res) cb && cb() } ) }, //后台批量生成examgroupid下面的所有考试 batchGeneratePdf: function () { var self = this var printHtml = self.formatPrintHtml('printcontent') var pdfHtml = ( self.tpls.htmlSkeleton + printHtml + '' ).replace(/\'/g, '"') var batchParams = { width: self.config.width + 'mm', height: self.config.height + 'mm', examGroupId: self.examGroupId, examIds: self.examIds, schoolId: self.schoolId, direction: self.direction, pdfTpl: pdfHtml //savedInfoUrl: 'http://zxhx-test.cn-bj.ufileos.com/zsyas2%2Fcardonline%2F3865%2F2020%2F04%2F10%2F565798454967058432.zip?r=888' } // hgc_layer.msg('学生模板批量生成中,请稍后...', { time: 0, shade: 0.4 }) $.ajax({ url: self.apis.batchGeneratePdfApi, method: 'POST', data: batchParams, success: function (res) { hgc_layer.closeAll() hgc_layer.msg(res.msg) } }) // batchInstance = $.post(self.apis.batchGeneratePdfApi, batchParams, function(res) { // }) }, downLoadPdf: function () { var self = this if (!self.alreadySave && !isNewBuild) { hgc_layer.msg('请先保存答题卡') return } //如果是创建答题卡,直接下载即可 if (isNewBuild) { hgc_layer.msg('pdf生成中,请稍后...', { time: 0, shade: 0.4 }) var printHtml = self.formatPrintHtml('printcontent') var pdfHtml = ( self.tpls.htmlSkeleton + printHtml + '' ).replace(/\'/g, '"') $.post( self.apis.getOnlinePdfApi, { width: self.config.width + 'mm', height: self.config.height + 'mm', identifier: self.identifier, examGroupId:self.examGroupId, pdfHtml: pdfHtml }, function (res) { let resData = JSON.parse(res) if(resData.success==1){ hgc_layer.closeAll() // location.href = self.apis.downloadPdfUrl + self.identifier location.href = self.apis.downOnlinePdfApi + '?url=' + resData.data + '&title=pdf-'+self.examGroupId+'.pdf' // location.href = resData.data } else { hgc_layer.msg(resData.message) } } ) return } var downloadUrl = // self.apis.downPdfApi + '?exam_group_id=' + self.examGroupId self.apis.downOnlinePdfApi + '?url=' + self.downPdfUrl + '&title='+self.examGroupId location.href = downloadUrl }, /** * 处理需要打印的html * 返回处理之后直接可以打印的html */ formatPrintHtml: function (elId, type) { //format-需要打印的iframe里面的内容 //origin-原网页的内容 var self = this $('#examInfo').find('.input-examInfo').each(function(i ,item){ $(this).attr('value',$(this).val()) }) //type 预览效果存储的html 和 用于转pdf 的不一样 var isPreview = type === 'preview' var $formatContent = $('#formatContent').html($('#' + elId).html()) var $formatPageContent = $formatContent.children('.pageContent') var $formatPageObjective = $formatPageContent.find('.objectiveItem') var $formatDtkTitle = $formatPageContent.eq(0).find('.dtkName') var $formatDtkNoticeDetail = $formatPageContent.eq(0).find('.noticeDetail') var $formatShortAnswer = $formatContent.find('.short-answer') var $originShortAnswer = $('#' + elId + ' .short-answer') var $originShortAnswer = $('#' + elId + ' .short-answer') var $originDtkTitle = $('#' + elId + ' .pageContent') .eq(0) .find('.dtkName') //设置每个分页的高度 $formatPageContent.height(self.config.height + 'mm') $formatPageContent.find('.pageLabel .size').remove() //设置答题卡title $formatDtkTitle.html($originDtkTitle.children('textarea').val()) //设置注意事项-所有标题预览页面不可编辑 $formatDtkNoticeDetail.prop('contenteditable', false) $formatPageContent.find('h3').prop('contenteditable', false) $formatPageObjective.prop('contenteditable', false) //模块格式化html $originShortAnswer.each(function (index, el) { $(el) .children('.module') .each(function (idx, elm) { var $formatModuleItem = $formatShortAnswer .eq(index) .children('.module') .eq(idx) var $scortColumn = $(elm).children('.scortColumn') var $chooseArea = $(elm).children('.selTopic') var editorIndex = $(elm).attr('data-editorIndex') if (!editorIndex) return //富文本编辑内容 var textareaContent = self.editorArea[ 'editor' + editorIndex ].txt.html() //打分区域 var scortAreaContent = $scortColumn.length ? $scortColumn[0].outerHTML : '' //多选区域 var chooseAreaHtml = '' if ($chooseArea.length) { chooseAreaHtml += $chooseArea[0].outerHTML } //height content var modulePrintHeight = self.unitConversion.pxConversionMm( $(elm).height() ) $formatModuleItem .height(modulePrintHeight + 'mm') .html( scortAreaContent + chooseAreaHtml + '
' + textareaContent + '
' ) }) }) //第三方静态资源识别 var linkSrc = '' var scriptSrc = '' //用几张纸 var paperLength = Math.ceil($formatPageContent.length / self.columns) paperLength = paperLength < 2 ? paperLength + 1 : paperLength var printHtmlForPaperHtml = '' for (var j = 0; j < paperLength; j++) { var printHtml = '' //判断奇数页 还是 偶数页 var isEvenPaper = !((j + 1) % 2) var isFirstPaper = !j var scanDotPaperIndex = (j + 1) % 2 ? 1 : 2 for (var k = 0; k < self.columns; k++) { var pageItem = $formatPageContent.eq(j * self.columns + k) var pageClass = pageItem.attr('class') || 'pageContent' var dtkContentHtml = pageItem.length ? pageItem.html() : self.tpls.forbiddenAreaTpl var bindingLineHtml = '' //奇数页面装订线在左边,偶数页面装订线在右边 //奇数页面的第一个分栏 和 偶数页面的最后一个分栏 加上装订线,除了第一个 if (self.hasBindingLine) { if (isEvenPaper && k + 1 === self.columns) { bindingLineHtml = self.tpls.bindLineTpl.substitute({ pos: 'right' }) } else if (!isEvenPaper && !k && !isFirstPaper) { bindingLineHtml = self.tpls.bindLineTpl.substitute({ pos: 'left' }) } } printHtml += '
' + bindingLineHtml + dtkContentHtml + '
' } var scanDotHtml = self.tpls['scanDotPaper' + scanDotPaperIndex] printHtmlForPaperHtml += self.tpls.printIframeContentTpl.substitute({ bindingLine: self.hasBindingLine ? 'hasBindingLine' : '', previewClass: isPreview ? 'previewIframe' : '', columns: self.columns, widthMm: self.config.width, printHtml: printHtml + scanDotHtml, linkSrc: linkSrc, scriptSrc: scriptSrc }) } //清空 $('#formatContent').html('') return printHtmlForPaperHtml }, //获取定位的基准点 getPositionOriginPoint: function () { var self = this //每个分页的定位基准点都是当前分页的左上角 self.printAreaLeft = $('#printcontent').offset().left self.printAreaTop = $('#printcontent').offset().top }, //获取扫描点信息 getScanPointInfo: function (currentPaper) { var self = this self.dotWidth = 40 self.dotHeight = 20 //大定位点上下间隙 self.dotTBGap = 20 //为了区分正反面,大定位点上面中间的那个点,需要正反面反向偏移一定距离 self.offsetDistance = self.pageWidth / 2 - 50 //获取页面的扫描点 /** * 1.产品定义的区域 * 2.客观题区域 * 3.图片考号区域 * 4.选做题区域 */ var hasBinding = self.hasBindingLine var pagePaddingSide = self.pagePaddingSide + (hasBinding ? 20 : 0) var location = [ //上左 { x: pagePaddingSide * self.dpiRadio, y: self.dotTBGap * self.dpiRadio, width: self.dotWidth * self.dpiRadio, height: self.dotHeight * self.dpiRadio, type: 1 }, //上右 { x: (self.pageWidth - self.pagePaddingSide - self.dotWidth) * self.dpiRadio, y: self.dotTBGap * self.dpiRadio, width: self.dotWidth * self.dpiRadio, height: self.dotHeight * self.dpiRadio, type: 1 }, //下右 { x: (self.pageWidth - self.pagePaddingSide - self.dotWidth) * self.dpiRadio, y: (self.pageHeight - self.dotTBGap - self.dotHeight) * self.dpiRadio, width: self.dotWidth * self.dpiRadio, height: self.dotHeight * self.dpiRadio, type: 1 }, //下左 { x: pagePaddingSide * self.dpiRadio, y: (self.pageHeight - self.dotTBGap - self.dotHeight) * self.dpiRadio, width: self.dotWidth * self.dpiRadio, height: self.dotHeight * self.dpiRadio, type: 1 } ] if (currentPaper === 1) { //上靠左边 location.splice(1, 0, { x: self.offsetDistance * self.dpiRadio, y: self.dotTBGap * self.dpiRadio, width: self.dotWidth * self.dpiRadio, height: self.dotHeight * self.dpiRadio, type: 1 }) } else { //上靠右边 location.splice(1, 0, { x: (self.pageWidth - self.offsetDistance - self.dotWidth) * self.dpiRadio, y: self.dotTBGap * self.dpiRadio, width: self.dotWidth * self.dpiRadio, height: self.dotHeight * self.dpiRadio, type: 1 }) } return location }, getElementWidth: function (el, type) { var self = this var width = $(el).outerWidth() return width * self.dpiRadio }, getElementHeight: function (el, type) { var self = this var height = $(el).outerHeight() return height * self.dpiRadio }, getPositions: function () { var self = this /** * {paper,direction,hasBindingLine,examNumberConfig:{barCode,ticketNumber},useQrCode} */ //Math.ceil(self.totalPage / self.columns) //每次获取每张纸的每一页定位信息,先确定 x轴,y轴的定位基准点 self.getPositionOriginPoint() //是否合并题卡信息 var $chooseAnswerInfo = $('.answerModule[data-type="chooseAnswer"]') var isConcat = self.isSubjectInfoToCard && $('.objectiveItem').length && $chooseAnswerInfo.length && $chooseAnswerInfo.find('.originSubjectInfo').length //存储供新建答题卡的以及答题卡信息使用 var memoryDtkInfo = {} if (isNewBuild) { var buildQuestions = self.questionMap if(self.$dtkName.val()){ self.savePrintInfo.title = self.$dtkName.val() } // self.savePrintInfo.title = self.$dtkName.val() memoryDtkInfo = { ...self.savePrintInfo, buildQuestions, examInfoConfigText:self.examInfoConfigText, examInfoConfig:self.examInfoConfig, hasPaperMsg:self.hasPaperMsg } } var printPositionInfo = { totalPage: 2, //准考证类型 school_card_status: self.school_card_status, //需要记录本次的paperTplType 是否为题卡合一 isSubjectInfoToCard: self.isSubjectInfoToCard, //选做题题干信息单独保存 chooseAnswerStemInfo: isConcat ? encodeURIComponent( $chooseAnswerInfo.find('.originSubjectInfo')[0].outerHTML ) : '', //纸张大小、方向、分栏、装订线、考号配置等,需要记忆布局 columns: self.columns, paper: self.paper, direction: self.direction, hasBindingLine: self.hasBindingLine, examNumberConfig: self.examNumberConfig, useQrCode: self.useQrCode, width: self.config.width, height: self.config.height, ...memoryDtkInfo, pages: [] } //每张纸的一面 var examNumberAreaData = self.getExamNumberPosition() var paperPosition = { 1: { pageNo: 1, //四个定位点信息 location: self.getScanPointInfo(1), //条形码 studentcode_bar: examNumberAreaData.studentcode_bar, //准考证号码 studentcode_fill: examNumberAreaData.studentcode_fill, //缺考标记定位信息 absent: self.getAbsentMarkPostion(), //学生二维码信息 QrCode: self.getQrCodePosition(), //打印区域宽高 imge: { width: self.pageWidth * self.dpiRadio, //self.config.width, height: self.pageHeight * self.dpiRadio //self.config.height }, //题目坐标信息 questions: [] }, 2: { pageNo: 2, //四个定位点信息 location: self.getScanPointInfo(2), //打印区域宽高 imge: { width: self.pageWidth * self.dpiRadio, //self.config.width, height: self.pageHeight * self.dpiRadio //self.config.height }, //题目坐标信息 questions: [] } } //首先获取每个纸张一页的扫描点信息 $('#printcontent .pageContent').each(function (pageIndex, pageItem) { var $pageItem = $(pageItem) //判断纸张的第一面还是第二面 or 正面还是反面 var paperNo = Math.ceil((pageIndex + 1) / self.columns) $pageItem.find('.answerModule').each(function (k, moduleItem) { var type = $(moduleItem).attr('data-type') var modelId = $(moduleItem).attr('data-modelId') var moduleInfo = { type: self.questionTypeMapForPhp[type], modelId: modelId } var positionInfos = [] switch (type) { case 'singleSelect': case 'moreSelect': case 'uncertainOption': positionInfos = self.getSingleSelectPositions( moduleItem, moduleInfo ) break case 'answer': case 'mustAnswer': positionInfos = self.getAswerPositions(moduleItem, moduleInfo) break case 'chooseAnswer': positionInfos = self.getChooseAswerPositions(moduleItem, moduleInfo) break case 'fillInBlank': positionInfos = self.getFillInBlankPOsitions(moduleItem, moduleInfo) break } paperPosition[paperNo].questions = paperPosition[ paperNo ].questions.concat(positionInfos) }) }) //题号重新排序 let PositionData = JSON.parse(JSON.stringify(paperPosition)) let TopicAll = []; jQuery.each(PositionData, function (i, val) { TopicAll = TopicAll.concat(val.questions) }); function compare(key) { return function (value1, value2) { var val1 = value1[key]; var val2 = value2[key]; return val1 - val2; } } TopicAll.sort(compare('id')); let no = 0 let pId = 0 jQuery.each(TopicAll, function (i, topicItem) { if (topicItem.ChooseNum === undefined) { if (pId == topicItem.id) { topicItem.name = no } else { topicItem.name = no + 1 no = no + 1 } pId = topicItem.id } else { if (pId == topicItem.id) { topicItem.name = no } else { let tName = ''; for (let ChooseNum = 0; ChooseNum < Number(topicItem.ChooseNum); ChooseNum++) { tName = tName + (tName != '' ? ',' : '') + (no + 1) no = no + 1 } topicItem.name = tName pId = topicItem.id } } }); jQuery.each(paperPosition, function (i, paperTopic) { jQuery.each(paperTopic.questions, function (j, paperTopicItem) { jQuery.each(TopicAll, function (k, topicAllItem) { if (!paperTopicItem.name) { if (Number(paperTopicItem.id) == Number(topicAllItem.id)) { let topic = JSON.parse(JSON.stringify(topicAllItem)) paperTopicItem.id = topic.name.toString(); paperTopicItem.name = topic.id; } } }); }); }); for (var paperKey in paperPosition) { printPositionInfo.pages.push(paperPosition[paperKey]) } printPositionInfo.identifier = self.identifier; // console.log(printPositionInfo) return printPositionInfo }, //获取填空题获取选择题的题干信息 getStemInfo: function () { var self = this var memoryObjectiveHtmls = '' $('.objectiveItem').each(function () { memoryObjectiveHtmls += encodeURIComponent($(this)[0].outerHTML) + '|end|' }) return memoryObjectiveHtmls }, //准考证和条形码区域 getExamNumberPosition: function () { var self = this //是否使用二维码 if (self.useQrCode) return {} //是否只是使用条形码 var isOnlyBarCode = self.isOnlyBarCode() //判断显示的是准考证号还是条形码 var isTicketNumber = self.examNumberConfig.ticketNumber var isBarCode = self.examNumberConfig.barCode var studentcodePosition = { studentcode_bar: {}, studentcode_fill: {} } //准考证号 if (isTicketNumber) { var numberWidth = false var numberHeight = false var $ticketNumberCol = $('#hgc_examNumber ul.ticketNumber').children( '.numberCol' ) studentcodePosition.studentcode_fill = { object: [] } $ticketNumberCol.each(function (k, numberColItem) { var group = [] var $ticketNumberItem = $(numberColItem).find('i') $ticketNumberItem.each(function (m, numberItem) { var numberPosition = self.getItemPosition(numberItem, 'examNumber') numberWidth = numberWidth || self.getElementWidth(numberItem) numberHeight = numberHeight || self.getElementHeight(numberItem) group.push({ x: numberPosition.x, y: numberPosition.y, width: numberWidth, height: numberHeight, optName: m }) }) studentcodePosition.studentcode_fill.object.push({ group: group }) }) } //条形码 if (isBarCode) { var examMarkEl = isOnlyBarCode ? $('#hgc_examNumberForOnlyBarcode .barCode') : $('#hgc_examNumber .barCode') var barCodePosition = self.getItemPosition(examMarkEl, 'barCode') studentcodePosition.studentcode_bar = { object: { x: barCodePosition.x, y: barCodePosition.y, width: self.getElementWidth(examMarkEl), height: self.getElementHeight(examMarkEl) } } } return studentcodePosition }, //缺考标记 getAbsentMarkPostion: function () { var self = this var $absentMark = $('.absentMark') var absentMarkPosition = self.getItemPosition($absentMark) var absentWidth = self.getElementWidth($absentMark) var absentHeight = self.getElementHeight($absentMark) return { x: absentMarkPosition.x, y: absentMarkPosition.y, width: absentWidth, height: absentHeight } }, //二维码定位信息 getQrCodePosition: function () { var self = this var $dtkEwm = $('#dtkEwm') var dtkEwmPosition = self.getItemPosition($dtkEwm) var dtkEwmWidth = self.getElementWidth($dtkEwm) var dtkEwmHeight = self.getElementHeight($dtkEwm) //if (!self.useQrCode) return {} return { x: dtkEwmPosition.x, y: dtkEwmPosition.y, width: dtkEwmWidth, height: dtkEwmHeight } }, //单选题坐标获取 getSingleSelectPositions: function (moduleItem, moduleInfo) { var self = this var optionInfos = [] var direction = $(moduleItem).attr('data-direction') $(moduleItem) .find('li') .each(function (i, optionItems) { var optionInfo = { type: moduleInfo.type, modelId: moduleInfo.modelId, answer: $(optionItems).attr('data-answer'), score: { full: 5 }, id: $(optionItems).attr('title-number'), opt: [], direction: direction } $(optionItems) .children('span') .each(function (k, option) { var optionPosition = self.getItemPosition(option, 'select') var width = self.getElementWidth(option) var height = self.getElementHeight(option) var optName = $(option).attr('data-option') optionInfo.opt.push({ x: optionPosition.x, y: optionPosition.y, width: width, height: height, optName: optName }) }) optionInfos.push(optionInfo) }) return optionInfos }, //填空题 getFillInBlankPOsitions: function (moduleItem, moduleInfo) { var self = this var optionInfos = [] $(moduleItem) .find('.subjectItem') .each(function (i, optionItems) { var $subjectCol = $(optionItems).parent('.subjectCol') var $score = $(optionItems).children('strong') var column = $subjectCol.attr('data-column') var scoreStyle = $subjectCol.attr('data-scoreStyle') var rowLineHeight = $subjectCol.attr('data-rowLineHeight') var optionPosition = self.getItemPosition(optionItems, 'fillInBlank') var width = self.getElementWidth(optionItems, 'fillInBlank') var height = self.getElementHeight(optionItems, 'fillInBlank') var scorePosition = self.getItemPosition($score) var scoreWidth = self.getElementWidth($score) var scoreHeight = self.getElementHeight($score) var optionInfo = { type: moduleInfo.type, modelId: moduleInfo.modelId, scorebox: { type: 3, Score: scoreStyle.split('/'), x: scorePosition.x, y: scorePosition.y, width: scoreWidth, height: scoreHeight }, score: { full: 5 }, column: column || 1, scoreStyle: scoreStyle || '', rowLinHeight: rowLineHeight || '', id: $(optionItems).attr('title-number'), cut: { x: optionPosition.x, y: optionPosition.y, width: width, height: height } } optionInfos.push(optionInfo) }) return optionInfos }, //解答题坐标获取 //针对全学科的记忆布局不同,全学科记忆布局都是一套数据源 getAswerPositions: function (moduleItem, moduleInfo) { var self = this var answerInfos = [] var modelId = $(moduleItem).attr('data-modelid'); $(moduleItem) .find('.module') .each(function (m, moduleEl) { var marktype = 0; var modulePositon = self.getItemPosition(moduleEl, 'answer') var width = self.getElementWidth(moduleEl, 'answer') var height = self.getElementHeight(moduleEl, 'answer') var titleNumber = $(moduleEl).attr('title-number') //questionNum var isAddHalf = false self.questionMap[modelId].questions.forEach(function (item) { if (item.questionNum == titleNumber) { marktype = item.marktype ? item.marktype : 0; } }) isAddHalf = self.questionMap[modelId].dialogData.isAddHalf //分值格式 var $scoreColumn = $(moduleEl).children('.scortColumn') var scoreLimit = $(moduleEl).attr('scorelimit') || '16' var limit = $(moduleEl).attr('data-fullscore') || '16' // var isAddHalf = $(moduleEl).attr('isAddHalf') === 'true' var scorePosition = self.getItemPosition($scoreColumn) var scoreWidth = self.getElementWidth($scoreColumn, 'answer') var scoreHeight = self.getElementHeight($scoreColumn, 'answer') let noScoringWidth = $($scoreColumn).find('.no-scoring').width(); if (noScoringWidth != null) { scoreWidth = scoreWidth - noScoringWidth } /** * "scorebox":{ "type":1, "Score":[2, 3,5] limit:16 "x":1517.4015748031497, "y":20, "width":40, "height":20, } point:1 表示最后一个是0.5分 0表示没有0.5 type 1: 16 limit:12 OR 14 OR 16 type 2: 29/49 limit: 29 49 type 3:具体分值在score里面给出枚举: 2 3 5 , 2 3 4 6 limit 无效 */ //判断当前区域是否有超出的链接模块 var linkParm = +$(moduleEl).attr('data-linkparm') || 0 var cutId = $(moduleEl).attr('data-cutId') var editorId = $(moduleEl).attr('data-editorindex') var answerInfo = { type: moduleInfo.type, modelId: moduleInfo.modelId, id: titleNumber, marktype: marktype, scoreLimit: scoreLimit, editorId: editorId, contents: encodeURIComponent( self.editorArea['editor' + editorId].txt.html().replace(//gim, '') ), cut: { x: modulePositon.x, y: modulePositon.y, width: width, height: height, cutid: cutId, linkparm: linkParm }, scorebox: { type: ~'16|15'.indexOf(Number(scoreLimit)) ? '1' : '2', limit: limit, point: isAddHalf ? 1 : 2, x: scorePosition.x, y: scorePosition.y, width: scoreWidth, height: scoreHeight } } answerInfos.push(answerInfo) }) return answerInfos }, //选做题坐标获取 getChooseAswerPositions: function (moduleItem, moduleInfo) { var self = this var chooseAnswerInfos = [] var modelId = $(moduleItem).attr('data-modelid'); $(moduleItem) .find('.module') .each(function (n, moduleEl) { var modulePositon = self.getItemPosition(moduleEl, 'chooseAnswer') var width = self.getElementWidth(moduleEl, 'answer') var height = self.getElementHeight(moduleEl, 'answer') var titleNumber = $(moduleEl).attr('title-number') var scoreLimit = $(moduleEl).attr('scorelimit') || '16' var limit = $(moduleEl).attr('data-fullscore') || '16' //分值格式 var $scoreColumn = $(moduleEl).children('.scortColumn') var scoreLimit = $(moduleEl).attr('scorelimit') || '16' // var isAddHalf = $(moduleEl).attr('isAddHalf') === 'true' isAddHalf = self.questionMap[modelId].dialogData.isAddHalf var scorePosition = self.getItemPosition($scoreColumn) var scoreWidth = self.getElementWidth($scoreColumn, 'answer') var scoreHeight = self.getElementHeight($scoreColumn, 'answer') let noScoringWidth = $($scoreColumn).find('.no-scoring').width(); if (noScoringWidth != null) { scoreWidth = scoreWidth - noScoringWidth } //是否是上一题的补充区域 //判断当前区域是否有超出的链接模块 var linkParm = +$(moduleEl).attr('data-linkparm') || 0 var cutId = $(moduleEl).attr('data-cutId') var editorId = $(moduleEl).attr('data-editorindex') //选择题目数量 var selCount = 1 for (var choosePage in self.chooseAnswer) { var pageChooseAnswer = self.chooseAnswer[choosePage] if (pageChooseAnswer.length) { selCount = pageChooseAnswer[0].required break } } let bigTopicData = self.questionMap[moduleInfo.modelId] var chooseAnswerInfo = { type: moduleInfo.type, modelId: moduleInfo.modelId, id: titleNumber, ChooseNum: bigTopicData.commonFields.ChooseNum, scoreLimit: scoreLimit, editorId: editorId, select: selCount, contents: encodeURIComponent( self.editorArea['editor' + editorId].txt.html().replace(//gim, '') ), total: titleNumber.split(',').length, scorebox: { type: ~'15|16'.indexOf(Number(scoreLimit)) ? '1' : '2', limit: limit, point: isAddHalf ? 1 : 2, x: scorePosition.x, y: scorePosition.y, width: scoreWidth, height: scoreHeight }, selectqts: [ { cut: { x: modulePositon.x, y: modulePositon.y, width: width, height: height, cutid: cutId, linkparm: linkParm }, opt: [] } ] } $(moduleEl) .find('.selTopic span') .each(function (l, selItem) { var optName = $(selItem).attr('data-titleNumber') var selItemPosition = self.getItemPosition(selItem, 'selTopic') var width = self.getElementWidth(selItem) var height = self.getElementHeight(selItem) var optNameAbc = String.fromCharCode(65 + l) ////console.log(width,height) chooseAnswerInfo.selectqts[0].opt.push({ optName: optNameAbc, width: width, height: height, x: selItemPosition.x, y: selItemPosition.y }) }) chooseAnswerInfos.push(chooseAnswerInfo) }) return chooseAnswerInfos }, /** * * @param {想要定位的元素} el * @param {打印区域靠左距离} printAreaLeft * @param {打印区域靠右距离} printAreaTop * @param {是不是富文本解答题} isModule * 如果是分栏 偶数页面的X轴定位点都要 加一个固定分页的宽 */ getItemPosition: function (el, moduleType) { var self = this if (!$(el).length) return {} var curPage = $(el).closest('.pageContent') var curPageIndex = curPage.index() + 1 var positionY = $(el).offset().top - self.printAreaTop var positionX = $(el).offset().left - self.printAreaLeft //定位坐标向右偏移位置 var columnLeft = 0 //是否第一面 var isFirstPaper = curPageIndex <= self.columns //考虑分栏的定位点 //当前在第几栏 var curPageColumns = curPageIndex % self.columns ? curPageIndex % self.columns : self.columns //一栏宽度 var oneColumnsWidth = self.pageWidth / self.columns columnLeft = oneColumnsWidth * (curPageColumns - 1) //有装订线的情况需要第一页减去多余的 if (self.hasBindingLine) { positionX -= 20 } if (curPageIndex > 1) { positionY -= (curPageIndex - 1) * self.pageHeight } return { x: (positionX + columnLeft - self.pagePaddingSide) * self.dpiRadio, y: (positionY - 20) * self.dpiRadio } }, /** * * 添加题目 * 根据题目类型,重置 该题型的所有数据 */ appendSubject: function (buildQuestions, modelId) { var self = this var questionModel = buildQuestions[modelId] var modelRenderKey = self.questionTypeMapForC[questionModel.questionType] var $lastPage = $('#printcontent .pageContent:last()') var $lastPageContent = $lastPage.children('.dtk-content') var currentPage = $lastPage.index() + 1 questionModel.pages = questionModel.pages || {} questionModel.pages['page' + currentPage] = questionModel.questions //新加分页字段,重新设置 localStorage.setItem('buildQuestions', JSON.stringify(buildQuestions)) self.questionMap = buildQuestions //渲染右侧操作栏 题目列表信息 -- 可重复执行 self.renderSubjectListInfo(buildQuestions) //保存题目定位点的时候 获取 题目数量 分数 等信息 -- 可重复执行 self.getSaveSubjectInfo(buildQuestions) //模块渲染 self[modelRenderKey + 'Render'](questionModel, $lastPageContent) self.changePrintArea($lastPage) }, //编辑试题 editSubject: function (buildQuestions, modelId) { var self = this var questionModel = buildQuestions[modelId] var modelRenderKey = self.questionTypeMapForC[questionModel.questionType] var $changePage = null var $replaceEl = null $('.answerModule').each(function () { if ($(this).attr('data-modelId') === modelId) { if ($changePage) { $(this).remove() } else { $changePage = $(this).closest('.pageContent') $replaceEl = $(this) } } }) var currentPage = $changePage.index() + 1 questionModel.pages = questionModel.pages || {} questionModel.pages['page' + currentPage] = questionModel.questions //重新设置 localStorage.setItem('buildQuestions', JSON.stringify(buildQuestions)) //渲染右侧操作栏 题目列表信息 -- 可重复执行 self.renderSubjectListInfo(buildQuestions) //保存题目定位点的时候 获取 题目数量 分数 等信息 -- 可重复执行 self.getSaveSubjectInfo(buildQuestions) //模块渲染 self[modelRenderKey + 'Render'](questionModel, null, $replaceEl) // selectStyleChange: function($this, direction) // fillInBlankStyleChange: function($this, column, rowLinHeight, scoreStyle) // shortAnswerStyleChange: function($this, scoreLimitKey, isAddHalf) var $settingBtn = self.getSettingBtn(modelId) if (~modelRenderKey.indexOf('Select') || ~modelRenderKey.indexOf('uncertainOption')) { var direction = questionModel.direction ? 'vertical' : 'horizontal' self.selectStyleChange($settingBtn, direction) } else if (modelRenderKey === 'fillInBlank') { var columns = questionModel.columns var rowLineHeight = questionModel.rowLineHeight var scoreStyle = questionModel.scoreStyle self.fillInBlankStyleChange( $settingBtn, columns, rowLineHeight, scoreStyle ) } else { var isAddHalf = questionModel.isAddHalf var scoreLimit = questionModel.scoreLimit // self.shortAnswerStyleChange($settingBtn, scoreLimit, isAddHalf) } this.initPageTopic(); }, initPageTopic() { $('.h_radioItem.checked').eq(1).click(); $('.pageContent').each(function () { if ($(this).children().eq(0).children().length == 0) { $(this).remove(); } }) $(".pageContent .totalPage").html($('.pageContent').length) self.totalPage = $('.pageContent').length } } $(function () { Print.init(sizeConfig) })