var env = (function (defaultEnv) { var isProduction = ~location.href.indexOf('schcur.com') var isLocal = ~location.href.indexOf('localhost') || ~location.href.indexOf('192.168') || ~location.href.indexOf('xg.xueping.com') 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 //当前环境转pdf所需css 相对路径 var printCssPath = envConfig.printCssPath //当前环境转pdf所要请求的域 var printPdfIp = envConfig.printPdfIp //试题编辑区域高度 var oldModH =0 var ueEditor = null var topicEl = null var 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', getOnlinePdfApi: domain + '/third/getOnlinePdf' + loginStatus, delPdfApi: '//' + printPdfIp + '/delPdf', batchGeneratePdfApi: '//' + printPdfIp + '/batchGeneratePdf', //latex 转 公式图片 getMathtexApi: domain + '/print/ajaxGetMathtex' + loginStatus, // php生成pdf generatePhpPdf:domain +'/print/sendCreateOnlineAllStudents'+ loginStatus }, init: function (config) { this.modal = hgc_modal //需要同时保存用来记忆布局的有:纸张规格,纸张方向,是否有装订线,考号配置(填涂考号or条形码,是否使用二维码) this.paper = 'A3' this.direction = 'horizontal' //装订线 this.hasBindingLine = false //信息栏 this.hasPaperMsg = true //考号配置 this.examInfoConfig = { //时间 wpTimes: true, //满分 fullScore: true, //命卷人 wpAuthor: true, //审核人 wpReviewer: true } this.examInfoConfigText = { //时间 wpTimes: '', //满分 fullScore: '', //命卷人 wpAuthor: '', //审核人 wpReviewer: '' } //考号配置 this.examNumberConfig = { //条形码 barCode: true, //准考证号 ticketNumber: true } //是否使用二维码 this.useQrCode = false // 是否是学校答题卡 0 系统 1学校 this.cardStatus = 0 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', 'formula' ] this.UEditorConfig = { toolbars: [[ 'formatmatch','undo', 'redo','fontsize', 'bold','italic', 'underline','subscript','superscript', 'removeformat', 'lineheight', 'justifyleft','justifycenter', 'justifyright', 'justifyjustify', 'insertimage','imagenone', 'imageleft', 'imageright', 'horizontal', 'spechars', 'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells','kityformula','chineselattice','horizontalline' ]], enableAutoSave:false, imagePopup:false, focus:true, allHtmlEnabled:true, initialFrameHeight: 140, UEDITOR_HOME_URL: '/js/ueditor/', } //题型配置 this.questionTypeMapForPhp = { //0单选 singleSelect: 0, //8多选 moreSelect: 8, //填空 fillInBlank: 3, //解答 answer: 1, //选做 chooseAnswer: 2, //必做题 mustAnswer: 27 } //类型 1 单选 2 多选 5 填空 7 解答 17 选做 this.questionTypeMapForC = { 1: 'singleSelect', 2: 'moreSelect', 5: 'fillInBlank', 7: 'shortAnswer', 27: 'mustAnswer', 17: 'chooseAnswer' } //题型名称映射 this.questionNameMap = { singleSelect: '单选题', moreSelect: '多选题', fillInBlank: '填空题', shortAnswer: '解答题', chooseAnswer: '选做题', mustAnswer: '必做题' } //题型数据存储 this.questionMap = [] //全局groupId this.examGroupId = examGroupId this.examIds = examIds this.schoolId = schoolId //当前区域定位信息,用来简单判断两次保存是否有改动,来防止重复提交数据 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] //下载PDFUrl this.downPdfUrl = '' this.examQuestions = [] this.initDom() //初始化打印面积 this.initPageStyle() //初始化页面渲染 this.initPage() //解答题图片移动 this.shortAnswerImgPositionChange() //显示编辑器 this.showUeditor() }, 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 //纸张方向,纸张大小,纸张分栏 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 $('#hgc_print').height($(window).height()) self.getTopicDetails() }, getTopicDetails: function () { var self = this //如果之前保存过,则需要记忆之前的答题卡排版 $.post( self.apis.getTopicsDetailAPi, { examGroupId: self.examGroupId }, function (res) { res = JSON.parse(res) if (res.success) { self.downPdfUrl = res.online_card_pdf self.examQuestions = res.object.questions //判断是否已经保存过,如果已经保存过,需要记忆布局 self.alreadySave = res.position ? true : false //判断是否题卡合一 self.isSubjectInfoToCard = res.paperTplType == self.subjectCardToOneType if (self.alreadySave) { var memoryPosition = JSON.parse(res.position) //之前题文信息存放直接单独存放stemInfo字段,现在直接放在position里面,做一个容错处理的判断 if(res.stem_info){ memoryPosition.stemInfo = res.stem_info } 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() } let arr = $('#printcontent').find('img'); let imgLoadNumber = 0; if(self.isCanEditCard){ for (let i=0;i9){ return false } let dom = $(this).parents('.pageContent') $(this).parents('.editorContent').height('auto'); self.changePrintArea(dom) }) }) } } self.cardStatus = res.card_status; self.editNoticeDetail(self.useQrCode,res.card_status) } else { hgc_layer.msg('获取试卷题目信息失败') } } ) }, 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) } }, /* -------------------------------------------------------------------------------------------------------------------- 初始页面布局功能开始 --------------------------------------------------------------------------------------------------------------------- */ renderPage: function (renderJSON, memoryPosition) { var self = this memoryPosition = memoryPosition || null self.renderExamBaseInfo(renderJSON.object) self.renderSubjectInfo(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 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 //题型 /** * "questionTypeId": 1, "fullScore": 5, "optionCount": 4, "questionNum": "1", "answer": "D" */ var questionClassify = (self.questionMap = questions.reduce( function (questionMap, item) { var questionMapKey = self.questionTypeMapForC[item.questionTypeId] var questionMapItem = questionMap[questionMapKey] if (questionMapItem) { questionMapItem.push(item) } else { questionMap[questionMapKey] = [item] } return questionMap }, { singleSelect: [], moreSelect: [], fillInBlank: [], shortAnswer: [], chooseAnswer: [], mustAnswer: [] } )) var titleTPls = { singleSelect: '、选择题(本大题共{subjectCount}小题,{subjectPointText}共{totalPoint}分。在每小题给出的四个选项中,只有一项是符合题目要求的。把答案填涂在答题卡上。)', moreSelect: '、多选题(本大题共{subjectCount}小题,{subjectPointText}共{totalPoint}分。在每小题给出的四个选项中,有两项及以上是符合题目要求的。把答案填涂在答题卡上。)', fillInBlank: '、填空题(本大题共{subjectCount}小题,{subjectPointText}共{totalPoint}分。把答案填写在答题卡相应的题号后的横线上。)', shortAnswer: '、解答题(本大题共{subjectCount}小题,{subjectPointText}共{totalPoint}分。解答写出相应的文字说明、证明过程或演算步骤。)', chooseAnswer: '、选做题(本题包括{chooseOption}{chooseOptionLength}小题,请选定其中{chooseCount}小题,并在相应的答题区域内作答,请用2B铅笔涂黑(示例:■)。若多做,则按作答的前一小题评分。解答应写出文字说明、证明过程或演算步骤。)', mustAnswer: '、必做题(本大题共{subjectCount}小题,{subjectPointText}共{totalPoint}分。解答写出相应的文字说明、证明过程或演算步骤。)' } var objectiveTitleTpl = { singleSelect: '、选择题题文', moreSelect: '、多选题题文', fillInBlank: '、填空题题文' } //填空题,选择题超出控制数据 var numberIndex = 0 for (var type in questionClassify) { //当前分类 var questionClassifyItem = questionClassify[type] if (!questionClassifyItem.length) continue numberIndex++ var titleFormatData = {} var isChooseAnswer = type === 'chooseAnswer' var isMoreSelect = type === 'moreSelect' //选做题题干信息 var chooseSubjectContent = '' //选做题标题特殊对待 if (isChooseAnswer) { var chooseOptionLength = SectionToChinese(questionClassifyItem.length) var chooseOption = questionClassifyItem .map(function (questionItem, index) { let isP = questionItem.queBody.search('1 || isP==-1){ queBody = '

' + questionItem.queBody +'

' } else { queBody = questionItem.queBody } chooseSubjectContent += '
' + questionItem.questionNum + '、' + queBody + '
' return String.fromCharCode(65 + index) }, []) .join(',') var chooseCount = SectionToChinese(questionClassifyItem[0].required) titleFormatData = { chooseOption: chooseOption, chooseCount: chooseCount === '二' ? '两' : chooseCount, chooseOptionLength: chooseOptionLength === '二' ? '两' : chooseOptionLength } } else { var subjectCount = questionClassifyItem.length var subjectPoint = questionClassifyItem[0].fullScore var totalPoint = 0 var isSameScore = questionClassifyItem.every(function (item) { return item.fullScore === subjectPoint }) var subjectPointText = '' if (isSameScore) { subjectPointText = '每小题{subjectPoint}分,'.substitute({ subjectPoint: subjectPoint }) totalPoint = subjectPoint * subjectCount } else { subjectPointText = questionClassifyItem.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) { self.chooseAnswerObjective = '
' + chooseSubjectContent + '
' } //试卷大题默认title self[type + '-title'] = SectionToChinese(numberIndex) + titleTPls[type].substitute(titleFormatData) //题干信息title---只针对客观题 if (objectiveTitleTpl[type]) { self[type + 'ObjectiveTitle'] = '

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

' } self[type] = self[type] || { page2: [], page1: simpleCopy(questionClassifyItem) } } return questionClassify }, titleHtml: function (title) { var self = this return title ? self.tpls.moduleTitleTpl.substitute({ title: title }) : '' }, //渲染答题卡题目题型信息 renderSubjectInfo: function (questions, memoryPosition) { var self = this //格式化题型题号信息 var questionClassify = self.renderSubjectDataFormat(questions) //渲染右侧操作栏 题目列表信息 self.renderSubjectListInfo(questionClassify) //保存题目定位点的时候 获取 题目数量 分数 等信息 self.getSaveSubjectInfo(questionClassify) //批量渲染所有题干信息模块 var dtkContentEl = $('.dtk-content') for (var subjectType in questionClassify) { if (subjectType === 'shortAnswer') { //或者一开始进来就是题卡合一 if (!self.alreadySave && self.isSubjectInfoToCard) { self.renderObjective() //有记忆的时候先渲染题卡合一,主要是缓存原题干信息内容 } else if ( memoryPosition && memoryPosition.stemInfo && memoryPosition.stemInfo.length ) { self.renderObjective() } } if (!questionClassify[subjectType].length) continue self[subjectType + 'Render'](questionClassify[subjectType], dtkContentEl) } }, //右侧题目列表模块-布局 renderSubjectListInfo: function (questionClassify) { var self = this var nameMap = { singleSelect: '单选题', moreSelect: '多选题', fillInBlank: '填空题', shortAnswer: '解答题', chooseAnswer: '选做题', mustAnswer: '必做题' } var listItemTpl = '
{name}
{quantityStart}~{quantityEnd}
' var listHtml = '' for (var name in questionClassify) { if (!questionClassify[name][0]) continue var quantityStart = +questionClassify[name][0].questionNum var quantityEnd = quantityStart + questionClassify[name].length - 1 listHtml += listItemTpl.substitute({ name: nameMap[name], quantityStart: quantityStart, quantityEnd: quantityEnd }) } $('#subjectList').html(listHtml) }, /** ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— 客观题题干内容渲染 开始 ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— */ renderObjective: function (cb) { var self = this questionClassify = self.questionMap self.originStemInfos = [] //,'shortAnswer','chooseAnswer','mustAnswer' var quesTypeOrder = ['fillInBlank', 'moreSelect', 'singleSelect'] //判断第一次出现的分页 var lastPageIndex var lastPageType quesTypeOrder.forEach(function (type) { if (lastPageType) return if (self[type]) { var pageIndex = Object.keys(self[type]).length function getLastPageIndex() { var pageData = self[type]['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 = questionClassify[quesType] if (quesTypeData && quesTypeData.length) { self[quesType + 'StemRender'](quesTypeData, $afterModule) } }) //图片加载时间 self.judegeImgsLoaded('.objectiveItem') cb && cb($afterPage) }, //公式自带的行内样式转换mm //type origin 原始高度 没有auto 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 /** $(this).attr('style',originStyle+';width:'+mmWidth+';height:'+(isMaxWidth?'auto':mmHeight+'mm')+';vertical-align:middle;'+(isMaxWidth?'max-width:100%;':'')) */ 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 (data, $afterModule) { var self = this var htmls = self.singleSelectObjectiveTitle 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 (data, $afterModule) { var self = this var htmls = self.moreSelectObjectiveTitle 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 (data, $afterModule) { var self = this var htmls = self.fillInBlankObjectiveTitle 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 }) 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 var titleMap = { //type singleSelect: self['singleSelect-title'], moreSelect: self['moreSelect-title'] } 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(titleMap[data.title]) : '', moduleType: data.title, selectContent: data.selectContent, direction: direction, settingBtn: data.settingBtn ? '
'.substitute({ moduleType: data.title }) : '' }) return SingleSelectModuleHtml }, //单选题--布局 singleSelectRender: function (datas, appendEl) { var self = this var singleSelectHtml = self.getSingleSelectHtml(datas, 'single') //selectContent, title, direction,hasTitle var SingleSelectModuleHtml = self.getSelectRenderContent({ selectContent: singleSelectHtml, title: 'singleSelect' }) appendEl.append(SingleSelectModuleHtml) }, //多选题--布局 moreSelectRender: function (datas, appendEl) { var self = this //获取选项html var singleSelectHtml = self.getSingleSelectHtml(datas, 'more') //获取整个选择题区域模块html //selectContent, title, direction,hasTitle var SingleSelectModuleHtml = self.getSelectRenderContent({ selectContent: singleSelectHtml, title: 'moreSelect' }) 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) { var self = this title = title || '' var fillInBlankModuleHtml = self.tpls.fillInBlankTpl.substitute({ fillInBlankContent: fillInBlankHtml, scoreStyle: scoreStyle, title: title }) return fillInBlankModuleHtml }, //填空题--布局 fillInBlankRender: function (datas, appendEl) { var self = this self.fillInBlankDatas = datas var fillInBlankHtml = self.getFillInBlankHtml(datas) var scoreStyle = datas[0].scoreStyle || '' var fillInBlankModuleHtml = self.getFillInBlankRenderContent( fillInBlankHtml, self.titleHtml(self['fillInBlank-title']), scoreStyle ) appendEl.append(fillInBlankModuleHtml) }, //重新渲染填空题 reRenderFillInBlank: function () { var self = this var pageIndex = 1 while (self.fillInBlank['page' + pageIndex]) { var pageFillInBlank = self.fillInBlank['page' + pageIndex] if (!pageFillInBlank.length) { pageIndex++ continue } var $curPage = $('#printcontent .pageContent').eq(pageIndex - 1) var $pageFillInBlank = $curPage.find('.completion-topic .subjectCol') var scoreStyle = pageFillInBlank[0].scoreStyle || '' $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 (datas, appendEl) { var self = this var shortAnswerTpl = self.tpls.shortAnswerItemTpl var shortAnswerHtml = '' datas.forEach(function (shortAnswerItem) { shortAnswerItem.editorContentHeight = shortAnswerItem.editorContentHeight ? shortAnswerItem.editorContentHeight : self.moduleDefaultHeihgt //scorelimitkey 15 16 29 49 isHalf 是否有半分的概念 var minLimit = self.getAnswerMinScoreLimit(shortAnswerItem.fullScore) shortAnswerItem.scoreColumnHtml = self.generateScoreBox(minLimit, false ,shortAnswerItem.fullScore) shortAnswerItem.scoreLimit = minLimit shortAnswerHtml += shortAnswerTpl.substitute(shortAnswerItem) //保存原题信息 self.editorAreaOriginContent[shortAnswerItem.questionNum] = shortAnswerItem.queBody }) var shortAnswerModuleHtml = self.tpls.shortAnswerTpl.substitute({ shortAnswerContent: shortAnswerHtml, title: self['shortAnswer-title'] }) appendEl.append(shortAnswerModuleHtml) //初始化解答题富文本插件 datas.forEach(function (item) { var questionNum = item.questionNum var answerContent = '' //题卡合一渲染原题信息,并且是题卡合一 if (!self.alreadySave && self.isSubjectInfoToCard) { let topicObj = self.editorAreaOriginContent[questionNum] let questionNumHtml = '
'+item.questionNum +'、
' answerContent = questionNumHtml+topicObj // answerContent = '
'+ answerContent + self.editorAreaOriginContent[questionNum] +'
' } else { answerContent = item.questionNum +'、' // $(self.editorAreaOriginContent[questionNum]).find('img').each(function () { // if(!$(this).hasClass('gsImgLatex') && $(this).attr('data-type')===undefined){ // answerContent = answerContent + $(this).context.outerHTML; // } // }) if(item.matchPicture !==null){ answerContent = answerContent +"
"+ item.matchPicture; } } answerContent = '
'+answerContent+'
'; self.createShortAnswer(questionNum, answerContent) }) }, //选做题--布局 chooseAnswerRender: function (datas, appendEl) { var self = this var chooseAnswerTpl = self.tpls.chooseAnswerItemTpl var editorCreateIds = [] //m 选 n 的n var requiredCount = datas[0].required 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.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 + ',' selOptionHtml += '[{char}]'.substitute( { char: String.fromCharCode(65 + index), titleNumber: item.questionNum } ) }) var minLimit = self.getAnswerMinScoreLimit(fullScore) var scoreColumnHtml = self.generateScoreBox(minLimit, false,fullScore) chooseAnswerHtml += chooseAnswerTpl.substitute({ questionNum: startChooseNumber, questionNumShow: questionNumShow, //4,5,6, titleNumber: titleNumber.substring(0, titleNumber.length - 1), selOptionHtml: selOptionHtml, scoreColumnHtml: scoreColumnHtml, editorContentHeight: self.moduleDefaultHeihgt, scoreLimit: minLimit, fullScore:fullScore }) } //先渲染多选题 //选做题题干信息单独处理 var chooseAddTitle = '' var hasObjective = self.chooseAnswerObjective && !self.alreadySave if (hasObjective) { chooseAddTitle = self.chooseAnswerObjective } var chooseAnswerModuleHtml = self.tpls.chooseAnswerTpl.substitute({ chooseAnswerContent: chooseAnswerHtml, title: self['chooseAnswer-title'] + chooseAddTitle }) appendEl.append(chooseAnswerModuleHtml) //如果有题干信息 if (hasObjective) { self.judegeImgsLoaded( '.answerModule[data-type="chooseAnswer"] .originSubjectInfo' ) } let chooseContent = questionNumShow+ '、' // self.questionMap[chooseAnswer].map(function (questionItem, index) { // if (questionItem.matchPicture !== null) { // chooseContent += // '

' + // questionItem.questionNum + // '、' + // questionItem.matchPicture + // '

' // } // }, []) editorCreateIds.forEach(function (editorId) { self.createShortAnswer(editorId,chooseContent) }) }, //必做题--布局 mustAnswerRender: function (datas, appendEl) { 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: self['mustAnswer-title'] }) appendEl.append(shortAnswerModuleHtml) //初始化解答题富文本插件 datas.forEach(function (item) { var questionNum = item.questionNum var answerContent = '' if (!self.alreadySave && self.isSubjectInfoToCard) { answerContent = self.editorAreaOriginContent[questionNum] }else { // $(self.editorAreaOriginContent[questionNum]).find('img').each(function () { // if(!$(this).hasClass('gsImgLatex') && $(this).attr('data-type')===undefined){ // answerContent = answerContent + $(this).context.outerHTML; // } // }) if(item.matchPicture !==null){ answerContent = answerContent +"
"+ item.matchPicture; } } self.createShortAnswer(questionNum, answerContent) }) }, /*-------------------------------------------------------------------------------------------------------------------- 初始页面布局功能结束 -----------------------------------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------------------------------------------- 记忆布局功能开始 ------------------------------------------------------------------------------------------------------------------------------------*/ memoryLayout: function (res) { var self = this var formatData = self.memoryDataFormat(res) var singleSelectData = formatData.singleSelectData var moreSelectData = formatData.moreSelectData var fillInBlankData = formatData.fillInBlankData 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 (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) } if (shortAnswerData.length) { 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; i < pageData.questions.length; i++) { 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: //非多选题 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 if(hasPaperMsgConfig.hasPaperMsg==undefined) return self.examInfoConfigText=hasPaperMsgConfig.examInfoConfigText; self.examInfoConfig=hasPaperMsgConfig.examInfoConfig; self.hasPaperMsg=hasPaperMsgConfig.hasPaperMsg; $('#examInfoConfig').find('.h_checkItem').each(function () { let type = $(this).attr('data-value'); if(hasPaperMsgConfig.examInfoConfig[type]==true){ if(!$(this).hasClass('checked')){ $(this).addClass('checked') } } else { if($(this).hasClass('checked')){ $(this).removeClass('checked') } } }) self.isShowPaperMsg(); }, memorySelectData: function (direction, type) { var self = this var $this = $('.' + type) .eq(0) .find('.settingBtn') self.selectStyleChange($this, type, direction) }, memoryFillInBlank: function (fillInBlankData) { var self = this var questionItem = fillInBlankData[0] //当前答题卡只有一大填空题大题的情况下 var $this = $('.completion-topic').eq(0).find('.settingBtn') var column = questionItem.column || 1 var rowLinHeight = questionItem.rowLinHeight || 40 var scoreStyle = questionItem.scoreStyle || '' self.fillInBlankStyleChange($this, column, rowLinHeight, scoreStyle) }, /** * * 异步图片加载完成 * 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) { //$(this)[0].outerHTML = decodeUtf8(stemInfo[index].split(',').map(function(v){return +v})) 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) { // $('.module').find('.editorContent').html(''); var self = this //2 解答题区域高度修改 //shortAnswerData 所有解答题的区域信息 通过两点确定唯一对应点关系 var checkQuestionData = {} var checkmoduleEl = {} var modules 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 var isAddHalf = questionItem.scorebox.point==1?true:false var questionItemId = questionItem.id.replace(/、/g,','); //console.log(moduleHeight) $('#printcontent .pageContent .short-answer .module').each(function ( pageIndex, moduleItem ) { var $pageItem = $(moduleItem).closest('.pageContent') var $moduleItem = $(moduleItem) var isOverPage = false var titleNumber = $moduleItem.attr('title-number') titleNumber = titleNumber.replace(/、/g,','); var dataEditorIndex = $moduleItem.attr('data-editorindex') if (self.isSurplusModule($moduleItem)) return //该题已经布局就无需重复布局--针对选择题 //多选题的 titleNumber 都相同 //确定唯一模块,模块id来确定 if ( titleNumber === questionItemId && !checkQuestionData[questionItem.editorId] && !checkQuestionData[dataEditorIndex] ) { checkQuestionData[questionItem.editorId] = true checkQuestionData[dataEditorIndex] = true //同步之前设置的内容 if (questionItem.contents) { var editorId = questionItem.editorId // self.editorArea['editor' + editorId].txt.html( // decodeURIComponent(questionItem.contents) // ) let topicHtml = decodeURIComponent(questionItem.contents) // let topicHtml = '
'+decodeURIComponent(questionItem.contents)+'
' $('#editorContent'+editorId).html(''); let isW = topicHtml.search(".w-e-text") $('#printcontent .pageContent .short-answer .module').each(function ( pageIndexs, moduleItems ) { if($(moduleItems).attr('title-number') == editorId ){ $(moduleItems).find('.editorContent').html('
'); } }) if(isW>-1){ $('#editorContent'+editorId).html(decodeURIComponent(questionItem.contents)); }else { $('#editorContent'+editorId).html('
'+decodeURIComponent(questionItem.contents)+'
'); } } var $this = $moduleItem.children('.settingBtn') self.shortAnswerStyleChange($this, scoreLimitKey, isAddHalf,questionItem.scorebox.limit) //设置大题区域高度 $moduleItem .children('.editorContent') .height(moduleHeight - self.modulePadding) curPageEl = $pageItem //如果当前有page分栏页有超出 则直接调到下一个分页 isOverPage = self.getOverModule(curPageEl) self.changePrintArea(curPageEl) } if (isOverPage) return 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) } if (clearStatus) { $shortAnswer.find('.module').each(function (){ let number = $(this).attr('title-number'); let numberArr = number.split(","); let numberHtml = numberArr[0]+'~'+numberArr[numberArr.length-1]+'、'; $(this).find('.w-e-text').html(numberHtml) }) } 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($moduleEditorContent.length===0){ $(this).find('.editorContent').html('
'); $moduleEditorContent = $(this).find('.w-e-text') } //如果是补充模块直接清空内容 if (self.isSurplusModule($(this))) { // let pageEl = $(this).parents('.pageContent') $moduleEditorContent.html('') // let modL = $(this).parents('.answerModule').find('.module'); // if(modL.length==1){ // let divL = $(this).parents('.dtk-content').children('div'); // if(divL.length==1){ // $(this).parents('.pageContent').remove(); // self.totalPage-- // self.refrushPageLabel() // }else { // $(this).parents('.answerModule').remove(); // } // // // self.changePrintArea(pageEl) // } else { // $(this).remove() // } // self.changePrintArea(pageEl) } else { var flexibleIconHtml = '
' var questionNumHtml = '
' + questionNum + '、
' // var baseContent = questionNumHtml + flexibleIconHtml var baseContent = questionNumHtml let topicImgHtml = '' // $(self.editorAreaOriginContent[questionNum]).find('img').each(function () { // if(!$(this).hasClass('gsImgLatex') && $(this).attr('data-type')===undefined){ // topicImgHtml = topicImgHtml + $(this).context.outerHTML; // } // }) if(clearStatus){ self.examQuestions.forEach(item => { if(item.questionNum == questionNum){ if(item.matchPicture !==null){ topicImgHtml = topicImgHtml +"
"+ item.matchPicture; } } }) } $moduleEditorContent.html( baseContent + (clearStatus ? topicImgHtml : self.editorAreaOriginContent[questionNum]) ) $moduleEditorContent.find('img').load(function (e) { var minHeight = self.calcEditorContentHeight($moduleEditorContent) // if ($moduleContentWrap.height() < minHeight) { // $moduleContentWrap.height(minHeight) // } if ($module.height() < minHeight) { $module.find('.editorContent').height(minHeight) let curPageEl = $module.parents('.pageContent') self.changePrintArea(curPageEl) } }) var minHeight = self.calcEditorContentHeight($moduleEditorContent) // if ($moduleContentWrap.height() < minHeight) { // $moduleContentWrap.height(minHeight) // } if ($module.height() < minHeight) { $module.find('.editorContent').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 */ 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 // minScaleHeight += $(this)[0].getBoundingClientRect().height }) return minScaleHeight }, bindEvent: function () { var self = this var base64_img = jrQrcode.getQrBase64(self.examGroupId) $('#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('mousedown', '.short-answer .dragBtn', function (e) { 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') // ) var scaleMinHeight = changeEl.children('.w-e-text').height(); if(changeEl.children('.w-e-text').length<1){ scaleMinHeight = self.calcEditorContentHeight( changeEl.children() ) } // 如果题卡合一的话,最小高度就是里面内容的高度 // 否则最小高度就是默认的高度 // if(this.isSubjectInfoToCard){ // } /** * 超过当前纸张的情况下 当鼠标松开的时候 * 1先把当前纸张放满 * 2剩余高度重新新到下个版本新建一个富文本高度一样没有内容 * 3单词拖动鼠标控制解答题区域缩放只能拖动到当前页面最底部 */ document.onmousemove = function (e) { distance = e.pageY - startPageY var newHeight = startHeight + distance if (newHeight <= scaleMinHeight) return changeEl.height(startHeight + distance) } //判断是否超过了一页 /** * 1当前模块已经缩放超过了当前页 * a>该区域后面的内容板块自动清空 * b>该区域不可再移动,自动新建一页,然后在下一页新建一个富文本默认是上一页超出的区域 * 2后面的模块超过了当前缩放页面 * a>直接把后面的题放到新排版页面 */ document.onmouseup = function () { self.changePrintArea(curPageEl) document.onmouseup = null document.onmousemove = null } }) //删除一个分页超出的部分 $('#printcontent').on('click', '.delBtn', function (e) { if (!self.isCanEditCard) return var $this = $(this) // if($this.siblings('.editorContent').find('.w-e-text').html() == ''){ // $this.closest('.module').remove(); // return // } 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 } if (self.totalPage > self.columns * 2) { hgc_layer.msg('答题卡最多支持' + self.columns * 2 + '页') return } self.judgeHasPrintClass(function () { self.savePrintPosition('printcontent') }) }) //下载pdf $('#downLoadBtn').click(function () { if (self.isCanEditCard) return var $this = $(this) if (self.totalPage > self.columns * 2) { hgc_layer.msg('答题卡最多支持' + self.columns * 2 + '页') return } //保存状态不用重新执行保存逻辑直接下载或者批量生成 if (!self.isCanEditCard) { if (self.useQrCode) { self.judgeHasPrintClass(function () { setTimeout(function () { self.modal.init({ title: '批量生成', content: '该操作会把该场考试下面的所有班级学生考试模板进行批量生成

请勿重复生成

', ensureText: '确定', cancelText: '取消', 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() // self.resetExamStudentStatus(function(){ // }) } }) }) }) } else { self.judgeHasPrintClass(function () { setTimeout(function () { self.modal.init({ title: '批量生成', content: '该操作会把该场考试下面的所有班级学生考试模板进行批量生成', sureCb: function () { // self.resetExamStudentStatus(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) { if(ueEditor!=null &&ueEditor.key!=undefined){ self.saveUeditor(ueEditor,topicEl) } var paper = $radioItem.attr('data-paper') self.paper = paper self.linkageForPaper(paper) }) //选择排版方向 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() }) //信息栏弹窗配置 new CheckBoxItem( $('#examInfoConfig'), function () { }, self.selExamInfoStyle.bind(self) ) //信息栏设置 $('#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 noticeEl = $(this).parent('.notice-item').find('.noticeContent'); $(noticeEl).hide(); }) //考号配置 new CheckBoxItem( $('#examNumberConfig'), function () {}, self.selExamNumberStyle.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') //填空 if (type === 'fillInBlank') { self.fillInBlankSet($this) //选择 单选-多选 } else if (~type.indexOf('Select')) { self.selectSetLayout($this, type) } else { self.shortAnswerSet($this) } }) // 给模块标题设置高度 $('#printcontent').on('click', '.answerModule h3', function () { $(this).css('height','auto') }) // 学校栏编辑状态 $('#printcontent').on('click', '.input-examInfo', function () { if (!self.isCanEditCard){ $('.input-examInfo').attr("readonly","readonly"); } else { $('.input-examInfo').removeAttr("readonly"); $('.input-examInfo.fraction').attr("readonly","readonly"); } }) // 图片拖拽 // $('#printcontent').on('click', 'img', function () { // if (!self.isCanEditCard) return // // }) // // $('div').mousedown(function(e) { // // e.pageX // var positionDiv = $(this).offset(); // var distenceX = e.pageX - positionDiv.left; // var distenceY = e.pageY - positionDiv.top; // //alert(distenceX) // // alert(positionDiv.left); // // $(document).mousemove(function(e) { // var x = e.pageX - distenceX; // var y = e.pageY - distenceY; // // if (x < 0) { // x = 0; // } else if (x > $(document).width() - $('div').outerWidth(true)) { // x = $(document).width() - $('div').outerWidth(true); // } // // if (y < 0) { // y = 0; // } else if (y > $(document).height() - $('div').outerHeight(true)) { // y = $(document).height() - $('div').outerHeight(true); // } // // $('div').css({ // 'left': x + 'px', // 'top': y + 'px' // }); // }); // // $(document).mouseup(function() { // $(document).off('mousemove'); // }); // }); 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 ) 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 = unescape(imgLatex) //'\left\{ {\left( {x\;,\;y} \right)\left| {y = 2x - 1} \right.} \right\}'// if (window.kfe) { window.kfe.execCommand('render', latexUse || '\\placeholder') } else { window.factory = window.kf.EditorFactory.create( $('#kfEditorContainer')[0], { render: { fontsize: 24 }, resource: { path: './js/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 = encodeURIComponent(window.kfe.execCommand('get.source')) $.post( self.apis.getMathtexApi, { mathtex: window.kfe.execCommand('get.source') }, 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 }) } }) }, changeCardEditStatus: function () { var self = this $('#dtkName textarea').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 self.$layoutItem.each(function () { var $this = $(this) var dataColumn = +$this.attr('data-column') if (~columns.indexOf(dataColumn)) { $this.removeClass('disabled') if (!isLayoutItemStop) { isLayoutItemStop = true $this.trigger('click') } } else { $this.addClass('disabled') } }) }, //选择题 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, type, tempDirection) } }) }, selectStyleChange: function ($this, type, direction) { var self = this var curPageIndex = $this.closest('.pageContent').index() + 1 var $selectModule = $this.closest('.single-select') var $curPage = $this.closest('.pageContent') self[type].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 (self[type]['page' + curPageIndex]) { var $nextPage = $('.pageContent').eq(curPageIndex - 1) var $nextPageFirstSelect = $nextPage.find('.single-select').eq(0) 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 maxScoreArr = $subjectCol .find('.subjectItem') // .attr('data-fullScore') // 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) { let isDisabled = false for( let i=0; i' + 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 } } var scoreLimit = scoreLimitMap[scoreLimitKey] var scoreModuleHtml = '' var scoreLimitArr = [] var noScoringW = 42 let pw = $('#printcontent').width(); noScoringW = pw/17 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'); } }, showExamInfoHtml: function () { var self = this if(!self.hasPaperMsg){ return false } let examInfoHtml = ''; if (self.examInfoConfig.wpTimes) { if(self.examInfoConfigText.wpTimes == undefined) { self.examInfoConfigText.wpTimes = '' } examInfoHtml += '时间:分钟' } if (self.examInfoConfig.fullScore) { if(self.examInfoConfigText.fullScore == undefined) { self.examInfoConfigText.fullScore = '' } examInfoHtml += '满分:' } if (self.examInfoConfig.wpAuthor) { if(self.examInfoConfigText.wpAuthor == undefined) { self.examInfoConfigText.wpAuthor = '' } examInfoHtml += '命卷人:' } if (self.examInfoConfig.wpReviewer) { if(self.examInfoConfigText.wpReviewer == undefined) { self.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') } }, //是否只使用条形码 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,type) { var self = this // var surplusModuleContentHeight = self.calcEditorContentHeight( // $surplusModule.find('.editorContent') // ) var surplusModuleContentHeight = $surplusModule.find('.editorContent').height(); var prevPage = $prevModule.closest('.pageContent') var prevPageContentHeight = prevPage.height() - self.pagePadding * 2 //内容区域 // var $prevContentArea = $prevModule.find('.w-e-text-container') var $prevContentArea = $($prevModule).children('.editorContent').children() if($prevContentArea==undefined || $prevContentArea.length==0){ $prevContentArea = $prevModule.find('.editorContent') } // var $prevContentArea = $prevModule.find('.editorContent') // 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, '') // ) var surplusEditorContent = $surplusModule.find('.w-e-text').html(); if(surplusEditorContent==undefined){ surplusEditorContent = $surplusModule.find('.editorContent').html(); } var prevEditorContent = $prevContentArea.html(); // if(surplusEditorContent==undefined){ // prevEditorContent = $prevModule.find('.editorContent').html(); // } let prevModuleH = $prevContentArea.height(); if($prevModule.find('.editorContent').height()>prevModuleH){ prevModuleH = $prevModule.find('.editorContent').height() } var prevCalcHeight = prevModuleH + surplusModuleContentHeight; if(type === 'surplus'){ prevCalcHeight = prevModuleH } let topicHtml = prevEditorContent +surplusEditorContent // let isW = $(topicHtml).find('.w-e-text') let isW = topicHtml.search(".w-e-text") if(isW>-1){ if(prevEditorContent==''){ topicHtml = surplusEditorContent } else { let isSurplusW = surplusEditorContent.search(".w-e-text") if(isSurplusW>-1){ surplusEditorContent = surplusEditorContent.replace(/.w-e-text/g,''); } else { prevEditorContent = prevEditorContent.replace(/.w-e-text/g,''); } // topicHtml = $(prevEditorContent).prepend(surplusEditorContent) // topicHtml = prevEditorContent+ surplusEditorContent topicHtml = '
'+prevEditorContent +surplusEditorContent+'
' } } else { topicHtml = '
'+prevEditorContent +surplusEditorContent+'
' } $prevModule.find('.editorContent').html(topicHtml) let wH = $prevModule.find('.editorContent').children().height() if(wH>prevCalcHeight){ prevCalcHeight = wH } $($prevModule).children('.editorContent').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,type) //点击删除重置上一页最后一个模块的高度 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[0].clientHeight + 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')) { 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) } }, //重新计算填空题渲染数据,改变填空题手动打分分值样式 calcFillInBlankData: function (fillInBlankData, scoreStyle, column) { //如果前一页不是column 的倍数 直接补充成column的倍数 var pageIndex = 1 while (fillInBlankData['page' + pageIndex]) { var pageKey = 'page' + pageIndex var curPageKeyIndex = pageIndex var pageLength = fillInBlankData[pageKey].length var pageNextData = fillInBlankData['page' + (curPageKeyIndex + 1)] //这里的规则是: //当前模块所有的填空题全部拿到第一次当前填空题模块出现的分页 //然后根据心规则重新渲染 //所以需要把第一次出现的填空题模块保留,其他的删除 var prevFillInBlankData = fillInBlankData['page' + (pageIndex - 1)] if (pageLength) { //如果下一页有数据 if (pageNextData && pageNextData.length) { if (pageLength % column) { var restLength = column - (pageLength % column) fillInBlankData[pageKey] = fillInBlankData[pageKey].concat( pageNextData.splice(0, restLength) ) if (!pageNextData.length) { var nextFillEl = $('#printcontent .pageContent') .eq(pageIndex) .find('.completion-topic') if (nextFillEl.length) { nextFillEl.remove() } } } } fillInBlankData[pageKey] = fillInBlankData[pageKey].map(function ( item ) { item.scoreStyle = scoreStyle return item }) } pageIndex++ } return fillInBlankData }, //题干区域超出 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) nextPageFirstAnswerModule = nextPageEl.find('.answerModule').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 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 isChooseAnswer = overAnswerModuleType === 'chooseAnswer' var isSelect = ~overAnswerModuleType.indexOf('Select') var isFillInBlank = overAnswerModuleType === 'fillInBlank' self.resetPageDataForSubject( overAnswerModule, times, resetEditorIds, nextPageEl ) if (isSelect || isFillInBlank) { moduleTitle = self.titleHtml(self[overAnswerModuleType + '-title']) 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) }, /** * 超出情况 * ** 如果下一页的模块有补充模块,最终都需要删除,增加新的补充模块 * 1 如果剩余解答区域小于默认解答区域高度--则直接全部拿到下一页,高度和下一个区域的补充模块高度累加,下一页的补充模块自动移除 * 2 如果剩余解答区域大于默认解答区域高度--则超出部分高度和之前下一区域的补充模块高度累加,下一页补充模块高度自动移除 * 缺失情况 * 1 如果剩余空间大于下一个模块 * -如果是补充模块,直接拿上来,高度累加该补充模块的高度 * -如果不是补充模块,直接拿上来,然后递归下一页的下一个模块,直到该页面没有剩余空间 * 2 如果剩余空间小于下一个模块 * a如果有标题 * - 如果小于标题加题号的空间,则不动,递归下一页的缺失情况 * - 如果大于标题加题号的空间,则直接拿上去,下一页保留多余高度的作答区域 (可以高度缩小直接拿上去,然后再补一个剩余高度的拓展模块) * b如果没有标题(小题或者补充模块) * - 如果下一页的第一个模块是补充模块,直接缩小对应的高度,上一个页面增加对应的高度 * - 如果下一个面是小题模块,则直接拿上去,下一页保留多余高度的作答区域 (可以高度缩小直接拿上去,然后再补一个剩余高度的拓展模块) */ addPrintForAnswer: function (curPageEl, overPart) { var self = this var curPageIndex = curPageEl.index() var times = curPageIndex + 1 //如果part不存在只有一种可能就是选做题只有题干信息超出 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) } let titleNumber = 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 ) let isW = overContentObj.overContent.search('.w-e-text'); if(isW>-1){ editorOverContent = overContentObj.overContent } else { editorOverContent = '
'+overContentObj.overContent+'
' } var editorOverHeight = overContentObj.overHeight titleNumber = part.attr('title-number'); subjectHtml += self.expandModule(part,editorOverContent, 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 } //超出模块 while (overAnswerModule.length) { var editModuleHtml = '' overAnswerModuleType = overAnswerModule.attr('data-type') //如果是当前超出模块,则直接用上面的多余的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 } editModuleHtml = overAnswerModule.html() //2 判断是否有需要重置的富文本 var editorEls = overAnswerModule.find('.editorContent') editorEls.length && editorEls.each(function () { resetEditorIds.push({ editorId: $(this).attr('id'), toolbarId: $(this).prev().attr('id') }) }) removeElements.push(overAnswerModule) } var formatStrData = { editModule: editModuleHtml, moduleType: overAnswerModule.attr('data-type') } overAnswerHtml += self.tpls.answerModuleTpl.substitute(formatStrData) overAnswerModule = overAnswerModule.next() } /** * 是否需要重置上一个页面的高度 * 当前缩放的模块超出,直接当前模块在当前分页高度设置到限制内最大 */ //重置上一页第一个超出模块的高度 = pageHeight - subject.offset().top - subjectModullePadding的模块高度 //上一个页面其他剩余模块的所占的高度 var preOtherModuleHeight = overPart.subjectModule.offset().top + $('#contentWrap').scrollTop() + self.pagePadding + self.modulePadding +10 //上一个页面第一个超出模块所能占用的高度 var preFirstOverModuleHeight = self.pageHeight * times - preOtherModuleHeight let isEn = overPart.subjectModule.children('.editorContent').find('.w-e-text').find('en') if(isEn.length>0){ preFirstOverModuleHeight = preFirstOverModuleHeight - 20 } // let wH = overPart.subjectModule.children('.editorContent').find('.w-e-text').height(); // // if(wH>preFirstOverModuleHeight){ // preFirstOverModuleHeight = wH // } overPart.subjectModule .children('.editorContent') .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(self.editorIndex, editorOverContent) hasNewRichText && self.createShortAnswer(titleNumber+'-'+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 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) nextPageEl.find('.completion-topic').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 nextExpendDataLength = self.fillInBlank[curModuleDataIndex].length copyFillInBlankLength = copyFillInBlankLength > nextExpendDataLength ? nextExpendDataLength : copyFillInBlankLength //原页面保留的题目 self.fillInBlank[nextExpendDataIndex] = self.fillInBlank[nextExpendDataIndex] || [] self.fillInBlank[nextExpendDataIndex] = self.fillInBlank[curModuleDataIndex] .splice(nextExpendDataLength - copyFillInBlankLength) .concat(self.fillInBlank[nextExpendDataIndex]) var originPageRetainHtml = self.getFillInBlankHtml( self.fillInBlank[curModuleDataIndex] ) var overFillInBlankItemsHtml = self.getFillInBlankHtml( self.fillInBlank[nextExpendDataIndex] ) if (!originPageRetainHtml) { removeElements.push(part.closest('.completion-topic')) } else { part.find('.subjectCol').html(originPageRetainHtml) } //超出的放在新页面上 如果原页面没有保留模块则需要加上title 并且需要setting按钮 overFillInBlankItemsHtml = self.titleHtml(!originPageRetainHtml ? self['fillInBlank-title'] : '') + self.tpls.fillInBlankContentTpl.substitute({ addFillInBlankHtml: overFillInBlankItemsHtml, columns: columns, scoreStyle: scoreStyle, rowLineHeight: rowLineHeight, settingBtn: !originPageRetainHtml ? self.tpls.fillInBlankSettingBtnTpl : '' }) //超出模块 //判断超出简答题区域 var overAnswerModule = overPart.answerModule var overModuleHasObjective = false while (overAnswerModule.length) { var editModuleHtml = '' var isCurOverAnswer = overAnswerModule === overPart.answerModule //如果有题干信息 var isObjective = overAnswerModule.attr('data-type') === 'objective' //如果是当前超出模块,则直接用上面的多余的moduleHtml来填充 //否则,直接用answerModule的内容来填充 if (isCurOverAnswer) { editModuleHtml = overFillInBlankItemsHtml } else { editModuleHtml = overAnswerModule.html() //2 判断是否有需要重置的富文本 var editorEls = overAnswerModule.find('.editorContent') editorEls.length && editorEls.each(function () { resetEditorIds.push({ editorId: $(this).attr('id'), toolbarId: $(this).prev().attr('id') }) }) removeElements.push(overAnswerModule) } overAnswerHtml += self.tpls[ isCurOverAnswer ? 'answerModulForFillInBlankTpl' : 'answerModuleTpl' ].substitute({ editModule: editModuleHtml, moduleType: overAnswerModule.attr('data-type') }) if (isObjective) { overModuleHasObjective = true } overAnswerModule = overAnswerModule.next() } /** * 【优化】 * 模块删除关系需要优化 */ 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()') } if (overModuleHasObjective) { self.judegeImgsLoaded('.objectiveItem') } //重置富文本 self.resetAddNewModuleEditor(resetEditorIds) //递归轮询判断 self.changePrintArea(nextPageEl) }, //选择题超出 /** * @param {*} curPageEl * @param {*} overPart */ addPrintForSelect: function (curPageEl, overPart, type) { var self = this //超出选择题的题目 var curPageIndex = curPageEl.index() + 1 //合并的简答题区域 var overAnswerHtml = '' //通过缩放确定每个页面需要移除的元素 var removeElements = [] //需要重置富文本编辑功能区域的id var resetEditorIds = [] //当前超出的模块height var part = overPart.subjectModule var overHeight = self.getOverHeight(part) //page data index var curModuleDataIndex = 'page' + curPageIndex var nextExpendDataIndex = 'page' + (curPageIndex + 1) //每小题的高度 var selectItemHeight = $('.single-option').eq(0).outerHeight() //针对选择题竖版一行排几个 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 = self[type][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 = self[type]['page' + curPageIndex].length //超出的放在新页面上,顺表保存一份用来给下一次使用 self[type][nextExpendDataIndex] = self[type][nextExpendDataIndex] || [] self[type][nextExpendDataIndex] = self[type][curModuleDataIndex] .splice(nextExpendDataLength - overSelectItemsLength) .concat(self[type][nextExpendDataIndex]) //是否存在下一页 var nextPageEl = curPageEl.next() //首先判断是要删除下一个分页的补充模块如果下一个分页存在的话 var nextPageFirstModule = null var nextPageFirstAnswerModule = null if (nextPageEl.length) { nextPageFirstAnswerModule = nextPageEl.find('.answerModule').eq(0) nextPageFirstModule = nextPageEl.find('.module').eq(0) } //计算留在当前页面的和下一个页面的数据 var originPageRetainHtml = self.getSingleSelectHtml( self[type][curModuleDataIndex] ) var overSelectItemsHtml = self.getSingleSelectHtml( self[type][nextExpendDataIndex] ) if (!originPageRetainHtml) { removeElements.push(part.closest('.single-select')) overSelectItemsHtml = self.tpls.settingBtnTpl.substitute({ moduleType: type }) + overSelectItemsHtml } else { //原来模块必须保留设置按钮 originPageRetainHtml = self.tpls.settingBtnTpl.substitute({ moduleType: type }) + originPageRetainHtml part.html(originPageRetainHtml) } //根据module 的data-type来确定使用的module 模板 var tplForTypeMap = { singleSelect: 'selectTpl', moreSelect: 'selectTpl', fillInBlank: 'answerModulForFillInBlankTpl', answer: 'answerModuleTpl', chooseAnswer: 'answerModuleTpl', mustAnswer: 'answerModuleTpl', objective: 'objectiveWrapTpl' } //判断超出简答题区域 var overAnswerModule = overPart.answerModule var overModuleHasObjective = false while (overAnswerModule.length) { var editModuleHtml = '' var overModuleType = overAnswerModule.attr('data-type') var direction = overAnswerModule.attr('data-direction') var moduleTitle = '' //如果是当前超出模块,则直接用上面的多余的moduleHtml来填充 //否则,直接用answerModule的内容来填充 var isCurOverAnswer = overAnswerModule === overPart.answerModule var isObjective = overModuleType === 'objective' if (isCurOverAnswer) { editModuleHtml = overSelectItemsHtml if (!originPageRetainHtml) { moduleTitle = self.titleHtml(self[type + '-title']) } if ( nextPageFirstAnswerModule && overModuleType === nextPageFirstAnswerModule.attr('data-type') ) { removeElements.push(nextPageFirstAnswerModule) } } else { var isSelect = ~overModuleType.indexOf('Select') var isFillInBlank = overModuleType === 'fillInBlank' self.resetPageDataForSubject( overAnswerModule, curPageIndex, resetEditorIds, nextPageEl ) if (isSelect || isFillInBlank) { moduleTitle = self.titleHtml(self[overModuleType + '-title']) if (isSelect) { overAnswerModule.find('.singleContent h3').remove() editModuleHtml = overAnswerModule.find('.singleContent').html() } } if (!isSelect) editModuleHtml = overAnswerModule.html() removeElements.push(overAnswerModule) } overAnswerHtml += self.tpls[tplForTypeMap[overModuleType]].substitute({ editModule: editModuleHtml, moduleType: overModuleType, selectType: overModuleType, selectContent: editModuleHtml, direction: direction, title: moduleTitle }) if (isObjective) { overModuleHasObjective = true } overAnswerModule = overAnswerModule.next() } /** * 【优化】 * 模块删除关系需要优化 */ 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') } let nextPageFirstModuleType = $(nextPageFirstModule).parents('.answerModule').attr('data-type'); if(nextPageFirstModuleType == 'fillInBlank'&&$(nextPageFirstModule).parents('.dtk-content').find('.completion-topic').length>1){ let fillInBlankItemNo = $(nextPageFirstModule).find('.subjectItem').length; if(fillInBlankItemNo>0){ $(nextPageFirstModule).parents('.dtk-content').find('.completion-topic').eq(0).find('.subjectCol').append($(nextPageFirstModule).find('.subjectCol').html()) } $(nextPageFirstModule).parents('.answerModule').remove(); } } else { self.addPage(overAnswerHtml) nextPageEl = $('#printcontent').children('.pageContent:last()') } if (overModuleHasObjective) { self.judegeImgsLoaded('.objectiveItem') } //重置富文本 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 nextHasData = false self[overModuleType][nextExpendDataIndex] = self[overModuleType][nextExpendDataIndex] || [] var nextExpendData = self[overModuleType][nextExpendDataIndex] var curModuleData = self[overModuleType][curModuleDataIndex] if (nextExpendData.length) { nextHasData = true self[overModuleType][nextExpendDataIndex] = curModuleData.concat( nextExpendData ) } else { self[overModuleType][nextExpendDataIndex] = [].concat(curModuleData) } self[overModuleType][curModuleDataIndex].length = 0 if (isSelect) { //如果下一个模块存在数据,直接合并到上一页在整体下移到下一页 if (nextHasData) { var $expendModule = overAnswerModule.find('.singleContent') var $nextRemoveModule = nextPageEl.find('.single-select').eq(0) var $expendHtml = self.tpls.settingBtnTpl.substitute({ moduleType: overModuleType }) + self.getSingleSelectHtml(self[overModuleType][nextExpendDataIndex]) $expendModule.html($expendHtml) $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( self[overModuleType][nextExpendDataIndex] ) $expendModule.html($expendHtml) $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] // $('#' + resetEditorId.toolbarId).html('') // var editor = new self.EDITOR( // '#' + resetEditorId.toolbarId, // '#' + resetEditorId.editorId // ) // editor.customConfig.menus = 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) { var self = this originContent = originContent || '' //this.createShortAnswer("#toolbar2", "#editorContent2", 2); if (!$('#toolbar' + editorIndex).length) return $('#editorContent' + editorIndex).html(originContent); $('#editorContent' + editorIndex).find('img').load(function (e) { let curPageEl = $('#editorContent' + editorIndex).parents('.pageContent') self.changePrintArea(curPageEl) }) // $('#editorContent' + editorIndex).html(originContent); // var editor = new self.EDITOR( // '#toolbar' + editorIndex, // '#editorContent' + editorIndex // ) // var ueEditor = window.UE.getEditor('toolbar' + editorIndex,); // 自定义菜单配置 // editor.customConfig.menus = 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.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, '')) // self.editorIndex = editorIndex // self.editorArea['editor' + editorIndex] = editor }, //答题区域文本图片位置更换 shortAnswerImgPositionChange: function () { var self = this var curOpratorImg = null var fa = null var imgSelector = '.editorContent .customImg' $('#hgc_print').on('mousedown', imgSelector, 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', imgSelector, 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', imgSelector, 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' //判断超出当前页面的条件 //如果是选做题并且当前有题干信息,题干信息单独提取出来,当成模块超出 var isChooseAnswer = moduleType === 'chooseAnswer' //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) { var objectiveInfo = part.siblings('h3').children('.originSubjectInfo') if (isChooseAnswer && objectiveInfo.length) { var $itemBodys = objectiveInfo.children('.questionItemBody') var overChooseObjectiveHtml = '' var removeTemp = [] for (var i = 0; i < $itemBodys.length; i++) { var $itemBody = $itemBodys.eq(i) if (self.getOverHeight($itemBody) > 0) { overChooseObjectiveHtml += $itemBody[0].outerHTML removeTemp.push($itemBody) } } if (removeTemp.length >= $itemBodys.length) { moduleTitle = modulePrev[0].outerHTML removeElements.push(modulePrev) } else if (removeTemp.length) { moduleTitle = '

' + overChooseObjectiveHtml + '

' removeElements.push(...removeTemp) } } else { 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 = modulePrev[0].outerHTML removeElements.push(modulePrev) } return moduleTitle + part[0].outerHTML }, //拿到富文本超出的内容 顺便计算一下下一个模块该有的最低高度 getOverContent: function (part, surplusHeight, removeElements) { var self = this // var editorContentEl = part.find('.w-e-text') var editorContentEl = part.find('.editorContent') let partHtml = part.html() let WETextLength =partHtml.search(".w-e-text") // let WETextLength = part.find('.w-e-text').length if(WETextLength>-1){ editorContentEl = part.find('.w-e-text') if(editorContentEl.length==0){ editorContentEl =$(part).children('.editorContent').children() } } var overContent = [] var overHeight = 0 //富文本可视化高度 // var surplusEditorViewportHeight = // editorContentEl.height() - surplusHeight - 20 var surplusEditorViewportHeight = part.find('.editorContent').height() - surplusHeight - 20 //看看当前富文本内容的高度有没有被超出的高度区域截掉 // var editorContentHeight = self.calcEditorContentHeight(editorContentEl) var editorContentHeight = editorContentEl.height(); //如果剩余高度还能装的下答题文本 直接返回空 if (surplusEditorViewportHeight > editorContentHeight) { return { overContent: overContent.reverse().join(''), overHeight: overHeight } } var paperHeight = $(part).parents('.pageContent').height() //当前超出富文本内容元素集合,倒序递归删除放到下一页 var editorContentElements = ''; if(WETextLength>-1){ editorContentElements = [].slice .call(editorContentEl.children(), 0) .reverse() } else { editorContentElements = [].slice .call(part.find('.editorContent').children(), 0) .reverse() } for (var i = 0, elItem; (elItem = editorContentElements[i++]); ) { if (editorContentHeight < surplusEditorViewportHeight) break var elItemHeight = $(elItem).height() if ($(elItem).hasClass("composition-column")){ elItemHeight = 10 } if ($(elItem).hasClass("en")){ elItemHeight = 34 } if(elItemHeight>(paperHeight-150)){ $(elItem).find('img').css('max-height',paperHeight-150) elItemHeight = paperHeight-150 } editorContentHeight -= elItemHeight overHeight += elItemHeight removeElements.push($(elItem)) overContent.push(elItem.outerHTML) } return { overContent: overContent.reverse().join(''), overHeight: overHeight } }, //上一个模块的拓展模块 expandModule: function (part,editorOverContent, nextContentMinHeight) { var self = this var titleNumber = part.attr('title-number') //当前超出的模块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 去 排列超出的顺序 ++self.editorIndex var linkparm = 1 var cutId = self.editorIndex //如果该模块是首次超出 则直接从1开始计数,否则从当前位置开始计数 if (!part.attr('data-linkparm')) { part.attr({ 'data-cutId': self.editorIndex, 'data-linkparm': linkparm }) linkparm++ } else { linkparm = +part.attr('data-linkparm') cutId = +part.attr('data-cutId') linkparm++ } return self.tpls.overModuleTpl.substitute({ overIndex: self.editorIndex, cutId: cutId, linkparm: linkparm, titleNumber: titleNumber, editorOverContent:editorOverContent, 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 $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 self.fillInBlank[curModuleDataIndex] = self.fillInBlank[ curModuleDataIndex ].concat( self.fillInBlank[nextExpendDataIndex].splice(0, copyFillInBlankLength) ) //原页面残留 var originPageRetainHtml = self.getFillInBlankHtml( self.fillInBlank[curModuleDataIndex] ) //新页面超出 var overFillInBlankItemsHtml = self.getFillInBlankHtml( self.fillInBlank[nextExpendDataIndex] ) var $overFillInBlank = part.closest('.completion-topic') var $overDtkContent = $overFillInBlank.closest('.dtk-content') $overFillInBlank.remove() if (overFillInBlankItemsHtml) { overFillInBlankItemsHtml = self.titleHtml(originPageRetainHtml ? '' : self['fillInBlank-title']) + 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' } ) $overDtkContent.prepend(overFillInBlankItemsHtml) } //老页面残留填空题模块 var $prevFillInBlank = $dtKContent.find('.completion-topic') if (!$prevFillInBlank.length) { originPageRetainHtml = self.titleHtml(self['fillInBlank-title']) + 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' }) $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() + 1 var fromPageIndex = part.closest('.pageContent').index() + 1 var type = part.closest('.answerModule').attr('data-type') var direction = part.closest('.answerModule').attr('data-direction') var prevTag = part.prev()[0] if (prevTag && prevTag.tagName === 'H3') { surplusHeight -= part.prev().height() } //每小题的高度 var selectItemHeight = $(part).find('.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 curModuleDataIndex = 'page' + curPageIndex var nextExpendDataIndex = 'page' + fromPageIndex self[type][curModuleDataIndex] = self[type][curModuleDataIndex].concat( self[type][nextExpendDataIndex].splice(0, overSelectItemsLength) ) //计算留在当前页面的和下一个页面的数据 var originPageRetainHtml = self.getSingleSelectHtml( self[type][curModuleDataIndex] ) var overSelectItemsHtml = self.getSingleSelectHtml( self[type][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, title: type, direction: direction, hasTitle: originPageRetainHtml ? false : true, settingBtn: !originPageRetainHtml }) $overDtkContent.prepend(overSelectItemsHtml) } //老页面残留填空题模块处理 var $originAnswerModule = $dtKContent.find( type === 'singleSelect' ? '.single-select' : '.moreSelect' ) if (!$originAnswerModule.length) { //获取整个选择题区域模块html originPageRetainHtml = self.getSelectRenderContent({ selectContent: originPageRetainHtml, direction: direction, title: type }) $dtKContent.append(originPageRetainHtml) } else { $originAnswerModule.find('.singleContent').html(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 nextPageAllModule = [].splice.call( canUpMovePage.find('.answerModule'), 0 ) //var objectiveModule = [].splice.call(canUpMovePage.find('.objectiveModule'), 0) //var nextPageAllModule = objectiveModule.concat(answerModule) 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') 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 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 }) $dtkContent.append(cloneHtml) modulePrev.remove() } else { cloneHtml = moduleHtml //可能中间出现真空区域 if (!$shortAnswerLast.length) { cloneHtml = self.tpls.answerModuleTpl.substitute({ editModule: cloneHtml, moduleType: moduleType }) $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) $('body').append('
关闭
') $('#closeIframeBtn').click(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() //数量 var timu = { KeGuanTi: questionClassify.singleSelect.length, TianKongTi: questionClassify.fillInBlank.length, ZhuGuanTi: questionClassify.shortAnswer.length, XuanZuoTi: questionClassify.chooseAnswer.length } //选择题答案 var sheet_answer = {} questionClassify.singleSelect.forEach(function (item) { sheet_answer[item.questionNum] = item.answer }) questionClassify.moreSelect.forEach(function (item) { sheet_answer[item.questionNum] = item.answer }) //每题对应分数 var sheet_score = {} for (var subjectType in questionClassify) { questionClassify[subjectType].forEach(function (subjectItem) { sheet_score[subjectItem.questionNum] = '' + subjectItem.fullScore }) } self.savePrintInfo = { title: title, timu: timu, sheet_answer: sheet_answer, sheet_score: sheet_score } }, //printcontent --- printPart savePrintPosition: function (printPart, cb) { var self = this // 给模块标题设置高度 $('.answerModule').find('h3').each(function (){ $(this).css('height',$(this).height()) }) var position = self.getPositions() //校验答题卡试题量与试卷题量是否相等 var cardNos = '' position.pages.forEach(paper=>{ paper.questions.forEach(topic=>{ cardNos = cardNos+topic.id+',' }) }) var cardNoArr = cardNos.split(','); var isLeak = false; self.examQuestions.forEach(paperTopic=>{ var isLeakTopic = true cardNoArr.forEach(cardTopic=>{ if(paperTopic.questionNum == cardTopic){ isLeakTopic = false } }) if(isLeakTopic){ isLeak = true } }) if(isLeak){ self.modal.init({ title: '提示', content: '答题卡题量与试卷不符,请重置', ensureText: '重置', cancelText: '取消', sureCb: function () { location.reload() } }) return false } //保存当前坐标点用于和下次一点击保存做对比,如果没有变化就可以防止重复提交 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', name: 'pdf', examGroupId: self.examGroupId, direction: self.direction, pdfHtml: pdfHtml }, function (res) { let resData = JSON.parse(res) if(resData.status==0){ hgc_layer.msg('生成pdf失败,请稍后再试!') return false } var pdfFileUrl = resData.data self.downPdfUrl = resData.data var html2canvasPromise = [] //html2canvas 返回的是一个promise ;[].slice.call(pages).forEach(function (pageItem) { html2canvasPromise.push(html2canvas(pageItem)) }) Promise.all(html2canvasPromise).then(function (res) { var imgFiles = [] res.forEach(function (canvas, index) { var img = Canvas2Image.convertToJPEG(canvas) var dataUrl = img.src imgFiles.push(dataURLtoFile(dataUrl, 'pic' + index + '.jpeg')) }) //处理模版html var pdfHtmlStream = new Blob([pdfHtml], { type: 'text/plain;charset=utf-8' }) self.savePrintInfo.pdfHtml = pdfHtml self.savePrintInfo.position = position self.savePrintInfo.examGroupId = self.examGroupId self.savePrintInfo.useQrCode = self.useQrCode ? 1 : 0 self.savePrintInfo.columns = self.columns //题干信息记忆布局 self.savePrintInfo.stemInfo = self.stemInfo var formData = new FormData() 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]) } } formData.append('pdfTemplate', pdfHtmlStream, 'pdfTepmlate.txt') //试卷原图 imgFiles.forEach(function (img, index) { formData.append('imgFiles' + index, img) }) //pdf链接 formData.append('pdf_url', pdfFileUrl) $.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 //删除node端存储pdf文件 // $.post(self.apis.delPdfApi, { // identifier: self.examGroupId // }) //如果使用二维码 //考号 和 条形码 都没有了,导致试卷内所有定位点错误,需要重新保存定位点 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) { // // }) // }, batchGeneratePdf: function () { var self = this var postData = { exam_group_id: this.examGroupId } $.ajax({ url: self.apis.generatePhpPdf, method: 'POST', data: postData, success: function (res) { hgc_layer.closeAll() var resData = JSON.parse(res); if(resData.status==1){ hgc_layer.msg('发送成功!后台处理中。') }else if(resData.status==0){ var layerMsg = resData.msg || '发送生成失败!' hgc_layer.msg(layerMsg) } } }) }, downLoadPdf: function () { var self = this if (!self.alreadySave || self.downPdfUrl=='') { hgc_layer.msg('请先保存答题卡') return } var downloadUrl = // self.apis.downPdfApi + '?exam_group_id=' + self.examGroupId self.apis.downOnlinePdfApi + '?url=' + self.downPdfUrl + '&title=pdf-'+self.examGroupId+'.pdf' 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 textareaContent = $(elm).find('.editorContent').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 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 }) } //清空 $('#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 chooseAnswerStemInfo = '' if (isConcat) { $('.originSubjectInfo').each(function () { chooseAnswerStemInfo += $(this).html() }) chooseAnswerStemInfo = '
' + chooseAnswerStemInfo + '
' } var printPositionInfo = { totalPage: 2, stemInfo:self.getStemInfo(), //准考证类型 school_card_status: self.school_card_status, //需要记录本次的paperTplType 是否为题卡合一 isSubjectInfoToCard: self.isSubjectInfoToCard, //选做题题干信息单独保存 chooseAnswerStemInfo: encodeURIComponent(chooseAnswerStemInfo), //纸张大小、方向、分栏、装订线、考号配置等,需要记忆布局 columns: self.columns, hasBindingLine: self.hasBindingLine, paper: self.paper, direction: self.direction, examNumberConfig: self.examNumberConfig, useQrCode: self.useQrCode, width: self.config.width, height: self.config.height, examInfoConfigText:self.examInfoConfigText, examInfoConfig:self.examInfoConfig, hasPaperMsg:self.hasPaperMsg, 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 moduleInfo = { type: self.questionTypeMapForPhp[type] } var positionInfos = [] switch (type) { case 'singleSelect': case 'moreSelect': 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) }) }) for (var paperKey in paperPosition) { printPositionInfo.pages.push(paperPosition[paperKey]) } //console.log(JSON.parse(JSON.stringify(printPositionInfo))) return printPositionInfo }, //获取填空题获取选择题的题干信息 getStemInfo: function () { var self = this var memoryObjectiveHtmls = '' $('.objectiveItem').each(function () { //memoryObjectiveHtmls += encodeUtf8($(this)[0].outerHTML).toString() + '|end|' 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, 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, 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 = [] $(moduleItem) .find('.module') .each(function (m, moduleEl) { var modulePositon = self.getItemPosition(moduleEl, 'answer') 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 fullScore = $(moduleEl).attr('data-fullscore') || '16' //分值格式 var $scoreColumn = $(moduleEl).children('.scortColumn') 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') let TopicHtml = $(moduleEl).find('.w-e-text').html() if(TopicHtml==undefined){ TopicHtml = $(moduleEl).find('.editorContent').html() } var answerInfo = { type: moduleInfo.type, id: titleNumber, scoreLimit: scoreLimit, editorId: editorId, contents: encodeURIComponent(TopicHtml), cut: { x: modulePositon.x, y: modulePositon.y, width: width, height: height, cutid: cutId, linkparm: linkParm }, scorebox: { type: ~'16|15'.indexOf(scoreLimit) ? '1' : '2', limit: fullScore, 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 = [] $(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 fullScore = $(moduleEl).attr('data-fullscore') || '16' //分值格式 var $scoreColumn = $(moduleEl).children('.scortColumn') 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 } //是否是上一题的补充区域 //判断当前区域是否有超出的链接模块 var linkParm = +$(moduleEl).attr('data-linkparm') || 0 var cutId = $(moduleEl).attr('data-cutId') var editorId = $(moduleEl).attr('data-editorindex') //选择题目数量 var selCount = 1 let TopicHtml = $(moduleEl).find('.editorContent').html() for (var choosePage in self.chooseAnswer) { var pageChooseAnswer = self.chooseAnswer[choosePage] if (pageChooseAnswer.length) { selCount = pageChooseAnswer[0].required break } } var chooseAnswerInfo = { type: moduleInfo.type, id: titleNumber, scoreLimit: scoreLimit, editorId: editorId, select: selCount, contents: encodeURIComponent(TopicHtml), total: titleNumber.split(',').length, scorebox: { type: ~'15|16'.indexOf(scoreLimit) ? '1' : '2', limit: fullScore, 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) chooseAnswerInfo.selectqts[0].opt.push({ optName: optName, 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 (~'select|fillInBlank|examNumber'.indexOf(moduleType)) { // positionY += 3 // } //有装订线的情况需要第一页减去多余的 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 } }, showUeditor:function (){ let self = this // var ueEditor = null // var topicEl = null $('.printcontent').on('click','.editorContent',function (event){ event.stopPropagation(); if (!self.isCanEditCard) return let _this = this; let ueHeidht = $(this).height(); self.UEditorConfig.initialFrameHeight = Number(ueHeidht); // let ueId = $(this).parents('.module').attr('title-number'); // let dataEditorindex = $(this).parents('.module').attr('data-editorindex'); // if(dataEditorindex!=undefined){ // ueId = ueId+'-'+dataEditorindex // } let modId = $(this).attr('id'); let ueId = modId.replace(/editorContent/i,"toolbar"); let domHtml = $(this).find('.w-e-text').html(); if(domHtml===undefined){ domHtml = $(this).html(); } // $(_this).find('.w-e-text').html(''); // $(_this).html('
') $(_this).html('') if(ueEditor!==null &&ueEditor.key!==undefined &&ueEditor.key!==ueId){ let ueShow = $('#'+ueEditor.key).find('.edui-editor').css('display'); if(ueShow!='none'){ self.saveUeditor(ueEditor,topicEl) } } topicEl = this; oldModH = ueHeidht; let top = $('#contentWrap').scrollTop(); ueEditor = UE.getEditor(ueId,self.UEditorConfig); $('.edui-for-chineselattice div').hide(); $('#contentWrap').scrollTop(top); ueEditor.ready(function() { let html = ueEditor.getContent(); if(html.length<1){ ueEditor.setContent(domHtml); } else { ueEditor.setShow(); let isShow = $('#'+ueId).children('.edui-editor').css('display'); if(isShow=='none'){ $('#'+ueId).children('.edui-editor').css('display','block'); } if(domHtml.length>0){ ueEditor.setContent(domHtml); } ueEditor.setHeight(ueHeidht); } $(_this).find('.w-e-text').html(''); $(_this).height('auto'); ueEditor.body.addEventListener('click', function (event) { let target = event.target || event.srcElement; let k = target.getAttribute('data-latex'); if (target.className.indexOf('mathType') !== -1 ) { let text = target.src.substring(target.src.indexOf("?")+1); editKityFormula(ueEditor,'chineselattice',text) } if(k==null){ return false } if(k.length>0){ editKityFormula(ueEditor,'chineselattice',k); } }) }); }); $('body').on('click',function (event){ if(ueEditor==null) return if(ueEditor.key==undefined) return let ueDisplay = $(ueEditor.container).css('display'); if(ueDisplay=='none') return let isUe = $(event.toElement).parents('.edui-default'); if(isUe.length>0){ event.stopPropagation(); event.preventDefault(); return false } self.saveUeditor(ueEditor,topicEl) }) }, saveUeditor:function (ueEditor,dom){ let _this = this; let html = ueEditor.getContent(); html = html.replace(/\u200B/g,'') // html = html.replace(/ /g,' ') if($(dom).find('.w-e-text').length>0){ $(dom).find('.w-e-text').html(html); } else { let isW = html.search('.w-e-text'); if(isW>-1){ $(dom).html(html); } else { let domHtml = '
'+ html +'
' $(dom).html(domHtml); } } // $(dom).find('.w-e-text').html(html); // if(oldModH>10){ // $(dom).find('.w-e-text').find('img').css('max-height',oldModH) // } else { // $(dom).find('.w-e-text').find('img').css('height',14) // } let imgBoxHeight = JSON.parse(JSON.stringify(oldModH)); $(dom).find('.w-e-text').find('img').load(function (e) { // let paperHeight = $(dom).parents('.pageContent').height() let elItemHeight = $(this).height(); if(imgBoxHeight>10){ if(elItemHeight>(imgBoxHeight-10)){ $(this).height(imgBoxHeight-10) } }else { $(this).height(14) } // _this.changePrintArea(curPageEl) }) $(dom).css('height','auto'); let newH = $(dom).height(); if(newH') // // ('').replaceAll('#'+ueBoxId); // $('#'+ueBoxId).css('height',0) ueEditor = null; let curPageEl = $(dom).parents('.pageContent') if(newH>oldModH){ this.changePrintArea(curPageEl) } } } $(function () { Print.init(sizeConfig) })