您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
此脚本能更方便使用minerva-online平台,可在顶端菜单栏右下角的按钮处设置功能开关,并查看功能详情
当前为
// ==UserScript== // @name minerva-online assistant // @namespace https://space.bilibili.com/17846288 // @version 3.0.9 // @license MIT // @description 此脚本能更方便使用minerva-online平台,可在顶端菜单栏右下角的按钮处设置功能开关,并查看功能详情 // @author inoki // @match https://www.minerva-online.com/* // @grant GM_setValue // @grant GM_getValue // @grant GM_addStyle // @grant GM_xmlhttpRequest // @connect fanyi.baidu.com // @run-at document-start // @noframes // ==/UserScript== /* VersionInfo 企业微信文档:https://doc.weixin.qq.com/doc/w2_AOMADQamAG8fAzy6aF1RWWmEc2ZhG?scode=AMwAwgcrABEDCapPcV 扣分标记,现在将额外显示每题的【选项分值,题目得分,计算规则】信息,且能根据选项变化即时更新(但日期与星期的判断标记不会即时更新) */ /*jshint esversion: 9*/ (()=>{ 'use strict'; const SET={ 0:{ 'id':0, 'name':'置顶置底', 'func':()=>{GOTOPBOTTOM();}, 'unfunc':()=>{unGOTOPBOTTOM();}, 'detail': `在平台域名所有可滚动页面生效,可快速滚动页面,或记录页面位置<br> 页面右下方添加【∨】/【∧】按钮<br> 【∨】/【∧】左键点击会根据页面滚动方向自动置顶或置底,按钮样式可在代码中自定义中修改<br> 【∨】/【∧】右键点击会在左侧生成【>】按钮,再次右键点击会删除【>】图标<br> 【>】生成时会记录当前页面位置,点击【>】将回到所记录的页面位置`, 'switch':1 }, 1:{ 'id':1, 'name':'菜单遮罩', 'func':()=>{COVERMENU();}, 'unfunc':()=>{unCOVERMENU();}, 'detail': `在有顶端菜单栏的页面生效,可优化菜单栏展开逻辑<br> 让菜单栏需要点击一次后才可展开,防止鼠标经过时误触<br> (默认关闭)`, 'switch':0 }, 2:{ 'id':2, 'name':'附件下载', 'func':()=>{DOWNLOADFILE();}, 'unfunc':()=>{unDOWNLOADFILE();}, 'detail': `在问卷管理页面(alias=smngr.surveyexplorer)生效,可一键下载/预览/删除报告的附件<br> 每份报告前添加【↓】按钮<br> 【↓】点击可加载附件列表<br> 【√】点击可下载全部附件,之后会变为【〇】<br> 【×】点击可关闭附件列表<br> 附件名点击可下载单个附件,鼠标悬停可预览图片<br> 【删除全部附件】点击可将此报告全部附件标记为删除`, 'switch':1 }, 3:{ 'id':3, 'name':'扣分标记', 'func':()=>{MARKQUESTION();}, 'unfunc':()=>{unMARKQUESTION();}, 'detail': `在单店报告页面(alias=survey.view,v3问卷除外)生效,可即时观察选项改动后的分数变化,也方便快速检查相关题<br> 将报告中题目的每个选项后方显示其分值(如有),在每题右上角显示当前具体分数,并对扣分题和N/A题标记相应颜色<br> 选项发生变化时,右上角分数会即时更新,并更新颜色标记<br> 鼠标悬停于每题右上角的分数时,会显示后台设置的得分计算规则<br> 可在上方设置扣分(默认为红)和N/A(默认为绿)的标记颜色,点击【√】保存更改<br> 颜色更改后关闭再开启此功能可在报告页面即时刷新颜色<br> 星期选项与日期不匹配时也将以扣分颜色标记(非即时更新),匹配时将在后方显示绿色√`, 'switch':1 }, 4:{ 'id':4, 'name':'评论编辑', 'func':()=>{COMMENTEDIT();}, 'unfunc':()=>{unCOMMENTEDIT();}, 'detail': `在单店报告页面(alias=survey.view,v3问卷除外)生效,可对整体评论进行替换/首字大写/翻译等操作<br> 右下方【问卷图标】<img src=https://www.minerva-online.com/images/icons/menu/x16/survet.png>按钮展开操作界面<br> 使用前请注意阅读操作界面最上方的【点击获取提示】<br> 【匹配/替换内容】框内输入内容将即时显示匹配的评论框数,并标灰评论框且在上方标记^^,鼠标悬停灰色评论框可预览替换后内容<br> 【匹配内容】支持正则表达式(详见【点击获取提示】),可Ctrl+F使用浏览器自带功能搜索^^标记,以快速定位匹配到的评论框<br> 【一键替换】点击可将所有匹配到的评论框内容修改为替换后内容,此时鼠标悬停灰色评论框可预览修改前内容<br> 【首字母大写】点击可智能将所有句首英文字母变为大写,显示修改过的评论框数并标灰,此时鼠标悬停灰色评论框可预览修改前内容<br> 【评论翻译】点击会调用百度翻译,在每个评论框下方输出目标语言翻译,点击↑可将下方内容添加至评论框`, 'switch':1 }, 5:{ 'id':5, 'name':'验证输出', 'func':()=>{VERIFYEXPORT();}, 'unfunc':()=>{unVERIFYEXPORT();}, 'detail': `在问卷管理页面(alias=smngr.surveyexplorer)生效,可一键验证输出所有勾选的报告<br> 在页面内显示报告时,表头上方会添加【验证输出勾选的报告】按钮<br> 【验证输出勾选的报告】点击并确认后会验证输出当前页面勾选的所有报告,成功输出的报告下方小窗口会显示绿色提示<br> (电脑配置较低时一次输出太多份可能导致页面卡死,请根据浏览器最多同时能开几个报告页面量力而行,默认关闭)`, 'switch':0 }, 6:{ 'id':6, 'name':'定制汇总', 'func':()=>{CUSTOMROLLUP();}, 'unfunc':()=>{unCUSTOMROLLUP();}, 'detail': `在定制汇总页面(alias=clientaccess.customrollups)生效,可对数据表格执行一些便捷功能<br> 在汇总表格上方添加功能按钮<br> 【复制表格】点击可一键复制表格全部内容,方便复制到excel等软件中编辑<br> 【复制表格】右侧下拉框选择“分数后+%”时,仅在Pivot table界面下生效,点击【复制表格】执行复制前会为所有数据后添加%<br> 【精确Pts%】点击可在表格右侧添加一列Pts/PtsOf的比值,并根据右侧下拉框选择的数字,进行相应小数位数的四舍五入<br> 【精确Pts%】需要Pts和PtsOf列同时存在才能正常生效,用以避免默认Pts%的2位小数舍入可能造成的偏差<br> 【选项统计】点击可自动统计各架构各题选项的数量与占比,并在表格下方的新增行中展示(QuestionText前[AD]标识),百分比值根据左侧下拉框数字四舍五入<br> 【选项统计】需要QuestionText和AnswerText和#Surveys列同时存在才能正常生效,数量显示在末尾括号内,百分比值显示在#Survsys格<br> 【选项统计】参与统计的仅为QuestionText/AnswerText左侧非隐藏列和非隐藏行,可在隐藏不必要的列或行后重新点击按钮刷新统计<br> 【选项统计】在点击问题选项最右侧按钮<img src=https://www.minerva-online.com/images/icons/filtersv2/answers.png style="object-position:-16px 0;object-fit:none;width:16px;height:16px">加载选项后,可在统计中显示数量为0的选项`, 'switch':1 }, 7:{ 'id':7, 'name':'报告存档', 'func':()=>{SURVEYSAVES();}, 'unfunc':()=>{unSURVEYSAVES();}, 'detail': `在单店报告页面(alias=survey.view,v3问卷除外)生效,可为报告内容实时进行本地存档防止意外丢失<br> 右下方【书本图标】<img src=https://www.minerva-online.com/images/icons/menu/x16/KB-icon.png>按钮展开操作界面,可查看自动/手动存档列表<br> 【存档】点击可进行手动存档,每次对报告内容进行修改时,将在本地进行自动存档<br> 【预览】点击可查看存档内容,并对需要读档写入的题目进行勾选<br> 【读档】点击可将选中的存档全部内容写入到当前报告,或只写入预览界面勾选的题目<br> 【删除】点击可删除选中的存档,自动/手动存档上限各为10个,超出时自动删除此类最早存档<br> (“评论编辑”功能造成的修改不会触发自动存档,可在修改后点击任意评论框触发自动存档)`, 'switch':1 }, /* 8:{ 'id':8, 'name':'PDF命名', 'func':()=>{PDFRENAME();}, 'unfunc':()=>{unPDFRENAME();}, 'detail': `在“以PDF格式下载”的转化页面生效,在高级页添加【命名并下载(全部)】按钮<br> 可在下方FIle Name处自定义命名格式,在下拉框选择需要的命名元素(无须点merge)<br> 【命名并下载】点击可下载单个PDF,并按File Name处的自定义命名格式命名<br> 【命名并下载全部】点击相当于一键点击了所有【命名并下载】<br> (默认关闭,因为平台已于<a target=_blank href=https://www.minerva-online.com/document.asp?alias=knowledgebase#/article/005bcf16-8530-4437-b4a4-b671ad3db56f>2022.10更新</a>中支持了中文命名)`, 'switch':0 }, */ 9:{ 'id':9, 'name':'优化表头', 'func':()=>{BETTERTHEAD();}, 'unfunc':()=>{unBETTERTHEAD();}, 'detail': `在所有含有页面滚动时自动冻结表头功能的页面生效(例:问卷管理),可优化表头功能<br> 点击表头上方【标题】行可显示表格所有列的表头内容,根据其勾选状态与否可显示/隐藏对应列<br> 优化冻结表头的表现,使冻结的表头不再像原先那样闪烁,且在冻结状态下也能执行排序/筛选功能<br> (优化冻结表头在部分浏览器可能不支持,若无效建议使用最新版chrome/edge浏览器体验)`, 'switch':1 }, 10:{ 'id':10, 'name':'外观效果', 'func':()=>{CSSEFFECT();}, 'unfunc':()=>{unCSSEFFECT();}, 'detail': `对所有网页外观效果进行调整<br> 【夜间模式】开启后整体页面主色调变为黑色,在某些场景下更护眼<br> (目前夜间模式为较粗略的反色处理,如有视觉效果差的地方请反馈,后续将调整)<br> 【隐藏logo】开启后隐藏左上角Minerva&Co的logo区域,节省页面空间`, 'switch':1 }, 11:{ 'id':11, 'name':'图片编辑', 'func':()=>{IMAGEEDIT();}, 'unfunc':()=>{unIMAGEEDIT();}, 'detail': `在附件图片的编辑页面(/mystservices/MystImageUpload/upload_modify.asp)生效,可扩展功能<br> 在点击【shape】→【color】为添加的图形选择颜色时,颜色从原本的2种增加至63种`, 'switch':1 },/* 12:{ 'id':12, 'name':'预览报告', 'func':()=>{REPORTCONTENT();}, 'unfunc':()=>{unREPORTCONTENT();}, 'detail': `在执行管理页面(alias=smngr.opermgmt)生效,可批量预览报告内容,方便未上线报告批量复查<br> 在此页面点击【问卷】→【显示问卷】后,页面内有报告时,右侧会添加一页【报告内容】<br> 【报告内容】→【显示内容】点击后将自动加载对应报告的内容,并显示在表格中<br> 如对报告进行了修改,要刷新当前显示的报告内容,再次点击【显示内容】即可<br> 如要更换显示的报告,需先更新【问卷】内显示的报告,再点击【报告内容】→【显示内容】即可`, 'switch':1 },*/ }; unsafeWindow.MA_SET=SET; //先执行外观效果功能 let style; if(GM_getValue(SET[10].name,SET[10].switch)) SET[10].func(); //DOM加载后开始执行其余功能 let $; document.addEventListener('DOMContentLoaded',()=>{ //filemanager页面不执行 if(document.location.href.includes('alias=filemanager')){ unsafeWindow.userIsEnterpriseAdmin=true; return; } //如网页无jQuery或版本低于1.7则引入1.8.2 $=unsafeWindow.jQuery; try{ console.log($.fn.jquery); $().on();//jQuery 1.7版本后才有$().on() init(); }catch(e){ const jq=document.createElement('script'); jq.src='/lib/jquery/jquery-1.8.2.min.js';//'https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js'; document.head.appendChild(jq); jq.onload=()=>{ $=unsafeWindow.jQuery; init(); }; } collaborationEnterpriseAdmin(); }); //用于打印脚本简介 unsafeWindow.MA_logInfo=()=>{ let info='',i=0; for(let s in SET){ info+=++i+' '+SET[s].name+':\n'; info+=SET[s].detail.replaceAll(/ {2,}/g,'').replaceAll('<br>',''); info+='\n\n'; } console.log(info); return info; }; /*在顶端菜单栏添加MOassist设置按钮*/ function init(){ console.log('jQuery',$.fn.jquery); for(let i in SET) if(GM_getValue(SET[i].name,SET[i].switch)) SET[i].func();//执行开启的功能 const menu=$('div#menu'); if(menu.length){ menu.find('ul.tools').append( `<li class="MOassist"> <a class="toolsLink"> <div class="iconTools" style="background: url('/images/icons/menu/x16/tools-settings.png')"></div> <ul class="textArea" style="visibility:visible; display:none"> <li>MO助手设置</li> </ul> <ul id="MOoption" class="innerItemFirst" style="z-index: 11; display:none; top:25px; right:0px"></ul> </a> </li>` ); menu.find('li.MOassist').on('click',function(){ MOListSwitch($(this).find('ul#MOoption')); }).find('ul#MOoption').on('click',e=>{ e.stopPropagation();//让之后添加的功能列表不继承click事件 }); mouseHover(menu.find('li.MOassist')); } } //功能列表开关 function MOListSwitch(ul){ if(ul.css('display')==='none'){ if(!ul.children().length) initOptions($('div#menu')); ul.stop().slideDown(200); }else{ ul.stop().slideUp(200); } } //导入所有功能列表并显示开关状态 function initOptions(menu){ for(let i in SET){ menu.find('ul#MOoption').append( `<li id="MOoptions" class="MOassist" style="width:100%"> <div class="menuItemText" style="color:#4C5057">${SET[i].name}</div> <input type=checkbox id=${SET[i].id} class=menuIconSmall> <ul class="textArea" style="visibility:visible; display: none; margin-top:0px; right:120px"> <li style="padding:0px 5px !important">${SET[i].detail}</li> </ul> </li>` ); if(GM_getValue(SET[i].name,SET[i].switch)) menu.find('input#'+SET[i].id).prop('checked',true);//打勾开启状态的功能 } //根据是否选中即时启用或卸载功能并记录开关状态 menu.find('li#MOoptions').on('click',function(e){ const checkbox=$(this).children('input:checkbox'); const id=$(checkbox).attr('id'); if(GM_getValue(SET[id].name,SET[id].switch)){ SET[id].unfunc(); $(checkbox).prop('checked',false); GM_setValue(SET[id].name,0); }else{ SET[id].func(); $(checkbox).prop('checked',true); GM_setValue(SET[id].name,1); } }).children('ul.textArea').on('click',e=>{ e.stopPropagation(); }); mouseHover(menu.find('li#MOoptions')); setMarkQuestionColor(menu); setCSSEffectOption(menu); } //鼠标聚焦时显示详情 【https://www.minerva-online.com/portal/menu/js/v2/menuRender.js?version=21-08 createToolOption : 】 function mouseHover(ele){ ele.hover(function(){ $(this).find('ul:first').stop().show(200); },function(){ $(this).find('ul:first').stop().hide(200); }); } //添加扣分标记颜色设置界面 function setMarkQuestionColor(menu){ menu.find('input#3.menuIconSmall').next('ul').prepend(`<div style="padding:0px 5px"> <b id=de>扣分颜色:</b> <form id=de> <input type=radio name=de value=red>红 <input type=radio name=de value=orange>橙 <input type=radio name=de value=yellow>黄 <input type=radio name=de value=green>绿 <input type=radio name=de value=blue>蓝 <input type=radio name=de value=purple>紫 <input type=radio name=de value=custom>自定义 <input type=color class=selectedColor> <input type=button class=rm-btn value=√ title=保存 style="padding:1px 6px"> </form> <b id=na>N/A颜色:</b> <form id=na> <input type=radio name=na value=red>红 <input type=radio name=na value=orange>橙 <input type=radio name=na value=yellow>黄 <input type=radio name=na value=green>绿 <input type=radio name=na value=blue>蓝 <input type=radio name=na value=purple>紫 <input type=radio name=na value=custom>自定义 <input type=color class=selectedColor> <input type=button class=rm-btn value=√ title=保存 style="padding:1px 6px"> </form> </div>`); //颜色选项初始化 menu.find('form#de,form#na').each(function(){ const curColor= $(this).attr('id')==='de'? GM_getValue($(this).prev().text(),'red') : GM_getValue($(this).prev().text(),'green'); $(this).prev().css('color',curColor); $(this).children('.selectedColor').attr('id',curColor); if(!curColor.includes('#')){ $(this).children('input[value='+curColor+']').attr('checked',true); $(this).children('.selectedColor').hide(); }else{ $(this).children('input[value=custom]').attr('checked',true); $(this).children('.selectedColor').val(curColor); } }); //点击选项颜色改变 menu.find('form#de,form#na').children(':radio').on('click',function(){ if($(this).val()==='custom'){ $(this).next().show(); $(this).next().attr('id',$(this).next().val()); }else{ $(this).nextAll('.selectedColor').hide(); $(this).nextAll('.selectedColor').attr('id',$(this).val()); } $(this).parent().prev().css('color',$(this).nextAll('.selectedColor').attr('id')); }); //自定义颜色改变 menu.find('form#de,form#na').children('.selectedColor').on('input',function(){ $(this).attr('id',$(this).val()); $(this).parent().prev().css('color',$(this).val()); }); //确认更改 menu.find('form#de,form#na').children(':button').on('click',function(){ GM_setValue($(this).parent().prev().text(),$(this).prev().attr('id')); if(!$(this).next().is('b')){ $(this).after('<b>保存成功</b>'); setTimeout(()=>{ $(this).next().remove(); },3e3); } }); } //添加扣分标记颜色设置界面 function setCSSEffectOption(menu){ menu.find('input#10.menuIconSmall').next('ul').prepend(`<div id=CSSEffectOption> <input type=checkbox value=夜间模式>夜间模式 <input type=checkbox value=隐藏logo>隐藏logo </div>`); const oCE=SET[10]; const name_=oCE.name+'_'; menu.find('div#CSSEffectOption input').each(function(){ const value=this.value; if(GM_getValue(name_+value,0)) $(this).prop('checked',true);//初始化勾选状态 $(this).on('click',function(){ if(GM_getValue(name_+value,0)){ $(this).prop('checked',false); GM_setValue(name_+value,0); }else{ $(this).prop('checked',true); GM_setValue(name_+value,1); } if(GM_getValue(oCE.name,oCE.switch)) oCE.func(); }); }); } /*在顶端菜单栏添加MOassist设置按钮*/ /*获取app.collaboration页面Enterprise.Admin权限*/ function collaborationEnterpriseAdmin(){ if(!document.location.href.includes('alias=app.collaboration')) return; const funcName=['renderSyncLog','renderImportLog']; for(let n of funcName) eval('unsafeWindow.'+n+'='+unsafeWindow[n].toString().replace('if (isEnterpriseAdmin)','').replace('function '+n,'function')); } /*获取app.collaboration页面Enterprise.Admin权限*/ /*0:置顶置底*/ function GOTOPBOTTOM(){ $(window).on('scroll.gotopbottom',()=>{//如页面后续因为内容增加而能滚动的场合触发 if($('div#goTopBottom').length===0) GOTOPBOTTOM(); }); const scrollBar=$(document).height()>(window.innerHeight+1||document.documentElement.clientHeight);//如有滚动条 if(!scrollBar||document.location.href.includes('alias=knowledgebase')) return;//knowledgebase页面自带置顶按钮,不启用 const goTopBottomButton=document.createElement('div'); const toggleButton=document.createElement('img'); $(toggleButton).appendTo(goTopBottomButton); $(goTopBottomButton).appendTo('body'); $(goTopBottomButton).css({position:'fixed',zIndex:1e4}).attr('id','goTopBottom'); $(toggleButton).css({display:'block',cursor:'pointer'}).attr('src','/knowledgebase/images/arrow_back_to_top.svg');//按钮显示图片(向下箭头) $(goTopBottomButton).attr('title','置顶置底'); //以下按钮参数可自定义修改 goTopBottomButton.style.bottom='50px';//按钮距离网页底部50px goTopBottomButton.style.right='30px';//按钮距离网页右边30px toggleButton.style.width='25px';//按钮图片宽25px toggleButton.style.height='25px';//按钮图片高25px toggleButton.style.opacity=0.5;//按钮不透明度,0.0(完全透明)到1.0(完全不透明) toggleButton.style.backgroundColor='grey';//按钮背景颜色,也可使用在excel等软件的自定义颜色界面的16进制代码 const clickScrollTime=500;//点击按钮时,网页滚动到顶部或底部需要的时间,500毫秒 //点击按钮时网页滚动到顶部或底部 let scrollDirection='down'; toggleButton.addEventListener('click',()=>{ if(scrollDirection==='up'){ $('html,body').animate({scrollTop:0},clickScrollTime); }else{ $('html,body').animate({scrollTop:$(document).height()},clickScrollTime); } }); //右键按钮记录页面位置 const lock=$(goTopBottomButton).clone().attr({id:'goTopBottomLock',title:'回到记录位置'}).css({right:'60px',display:'none'}).appendTo('body'); lock.children('img').css('transform','rotate(270deg)'); goTopBottomButton.onmouseup=function(e){ if(e.button===2){ if(lock.css('display')==='none'){ const x=window.pageXOffset; const y=window.pageYOffset; lock[0].onclick=()=>{scrollTo(x,y);}; lock.show(); }else{ lock.hide(); } } }; goTopBottomButton.oncontextmenu=()=>{return false;}; //页面滚动监听 let scrollAction=window.pageYOffset; $(window).scroll(()=>{ const diffY=scrollAction-window.pageYOffset; scrollAction=window.pageYOffset; scrollDirection= diffY<0? 'down' : 'up'; toggleButton.style.transform= diffY<0? 'rotate(0deg)' : 'rotate(180deg)'; if(getScrollTop()===0){ scrollDirection='down'; toggleButton.style.transform='rotate(0deg)'; } if(getScrollTop()+window.innerHeight+20>=$(document).height()){ scrollDirection='up'; toggleButton.style.transform='rotate(180deg)'; } }); } //获取垂直方向滑动距离 function getScrollTop(){ let scrollTop=0; if(document.documentElement&&document.documentElement.scrollTop){ scrollTop=document.documentElement.scrollTop; }else if(document.body){ scrollTop=document.body.scrollTop; } return scrollTop; } //卸载置顶置底 function unGOTOPBOTTOM(){ $(window).off('scroll.gotopbottom'); if($('div#goTopBottom,div#goTopBottomLock').length) $('div#goTopBottom,div#goTopBottomLock').remove(); } /*置顶置底*/ /*1:菜单遮罩*/ function COVERMENU(){ if($('div#menu').length){ //若存在menu则添加cover层 const menu=$('div#menu')[0]; const zidx=getComputedStyle(menu).zIndex; const cover = document.createElement('div'); cover.className = 'layout'; cover.style = 'top:'+menu.style.top+';opacity:0.3;z-index:'+zidx+';right:10%'; //点击时将cover层下置 cover.addEventListener('click',()=>{ cover.style.zIndex = -1; }); //离开menu时cover层还原 menu.addEventListener('mouseleave',()=>{ cover.style.zIndex = zidx; }); //cover层位置跟随menu 【https://www.minerva-online.com/portal/menu/js/v2/menuRender.js?version=21-08 onScrollEventHandler : 】 $(window).on('scroll.covermenu',function(){ const SM=unsafeWindow.SM; if(!SM) return; SM.ui.parentContainer=cover; SM.ui.onScrollEventHandler(); SM.ui.parentContainer=menu; }); $(cover).appendTo($('body')[0]).attr('id','cover'); } } //卸载菜单遮罩 function unCOVERMENU(){ if($('div#cover').length){ $('div#cover').remove(); $(window).off('scroll.covermenu'); } } /*菜单遮罩*/ /*2:附件下载*/ function DOWNLOADFILE(){ if(document.location.href.includes('alias=smngr.surveyexplorer')&&$('tr.persist-header').length){ $('tr.persist-header').each(function(){ $(this).children().first().after($(this).children().first().clone(true).attr('class','downloadFile')); }); $('table#reporttable').find(':checkbox').each(function(){//checkbox后添加下载按钮 const surveyid=$(this).val(); $(this).parent().after( `<td> <div id=${surveyid} class=downloadFile> <button type=button id=download class=rm-btn title=加载附件列表>↓</button> </div> </td>` ); $(this).parent().next().find('button#download').one('click',function(){ DownloadButton($(this).parent(),surveyid);//将$('div.downloadFile')传参为df }); }); } //兼容inoki.va页面 if(document.location.href.includes('alias=inoki.va')){ if($('table#reporttable tr').length){ $('table#reporttable>thead>tr').each(function(){ $(this).children().first().before($(this).children().first().clone(true).attr('class','downloadFile')); $(this).children().first().text('附件下载'); }); $('table#reporttable').find('tbody>tr').each(function(){ const surveyid=$(this).attr('id'); $(this).prepend( `<td> <div class=downloadFile> <button type=button id=download class=rm-btn title=加载附件列表>↓</button> </div> </td>` ); $(this).find('button#download').one('click',function(){ DownloadButton($(this).parent(),surveyid); }); }); } } } //获取附件列表 function DownloadButton(df,surveyid){ //if(!surveyid) surveyid=df.parents('tr').attr('id'); df.find('button#download').hide(); df.append('<b id=loading>......</b>'); $.get( `/open/data.asp?post={ "action":"exec", "JSONPath":"dataset.data.3", "dataset":{"datasetname":"/Apps/SM/Survey/SurveyInstanceGetData"}, "parameters":[{"name":"SurveyInstanceID","value":"${surveyid}"}] }`,(data,status)=>{//调用API获取当前survey数据[SurveyInstanceGetData] if(status==='success'){ if(Array.isArray(data)){ const filedata=data; const fileno=filedata.length; df.append( `<ol id=filelist> <b>\t#=${fileno}</b> <table></table> </ol>` ); if(fileno>0){ const ol=df.find('ol#filelist'); $('<button type=button id=downloadAll class="rm-btn rm-btn-default" title=下载全部>√</button>').prependTo(ol) .on('click',()=>{ DownloadAll(df); }); $('<button type=button id=deleteAll class="rm-btn rm-btn-default">删除全部附件</button>').appendTo(ol) .on('click',()=>{ DeleteAll(df,surveyid); }); const tb=ol.children('table'); for(let i in filedata){ const filename=filedata[i].FileName+'.'+filedata[i].FileExtension; const fileid=filedata[i].AttachmentID; const fileurl='/mystservices/Attachments/getAttachment.asp?Attachment='+fileid+'&Password='+filedata[i].Password+''; let filesize=Number(filedata[i].FileSizeInBytes)/1024; filesize= (filesize>1024)? (filesize/1024).toFixed(2)+' MB' : filesize.toFixed(2)+' KB'; $('<tr id='+fileid+'>').appendTo(tb).append( `<td> <li><a id=${filedata[i].AttachmentType} class=mailboxlink href=${fileurl}>${filename}</a></li> </td> <td>${filesize}</td> <td>QID:${filedata[i].ProtoQuestionID}</td>` ); } df.find('a#I,a#V').mouseenter(function(){ FilePreview(1,$(this).attr('href')); }).mouseleave(()=>{ FilePreview(0); }); } }else{ df.append('<b>登录(不可用)失效!</b>'); } }else{ df.append('<b>网络错误!</b>'); } DownloadButton0(df,surveyid); },'json'); } //预览附件图片 function FilePreview(show,src){ if(show){ const imgid=src.split('=')[2]; if($('img#'+imgid+'.filepreview').length===0){ $('<div><img id='+imgid+' class=filepreview></img></div>').appendTo('body'); $('img#'+imgid+'.filepreview').attr('src',src+'&getThumbnail=1').css('height','200px')//视频附件预览图u&getThumbnail=1 .parent().css({position:'fixed',zIndex:1e4,height:'200px',background:'url(/images/icons/filtersv2/loading06.gif)'}); } $('img#'+imgid+'.filepreview').parent().css({top:event.clientY-200,left:event.clientX+100}); $('img#'+imgid+'.filepreview').show(); }else{ $('img.filepreview').hide(); } } //按钮变为关闭 function DownloadButton0(df,surveyid){ df.find('b#loading').remove(); df.find('button#download').text('×').attr('title','关闭附件列表').show().one('click',()=>{ DownloadButton1(df,surveyid); }); } //按钮重置为初始 function DownloadButton1(df,surveyid){ const passid=[]; df.find('a#I,a#V').each(function(){ passid.push($(this).attr('href').split('=')[2]); }); for(let id of passid) $('img#'+id).parent().remove(); df.find('ol,b').remove(); df.find('button#download').text('↓').attr('title','加载附件列表').one('click',()=>{ DownloadButton(df,surveyid); }); } //下载全部 function DownloadAll(df){ df.find('button#downloadAll').text('〇').hide(); const iframe=df.find('ol#filelist iframe'); const a=df.find('ol#filelist a'); if(iframe.length) iframe.remove(); setTimeout(()=>{ df.find('button#downloadAll').show(); },1e3*a.length);//有几个附件就隐藏按钮几秒 a.each(function(){ $('<iframe src='+$(this).attr('href')+'>').appendTo(this).hide(); }); } /* //不知是不是因为下载地址有重定向的关系,GM_download效率低下,弃用 function DownloadAll(df){ const a=df.find('ol#filelist a'); let loaded=0; df.find('button#downloadAll').text('〇').hide(); df.find('ol#filelist>p,ol#filelist>br').remove(); df.find('ol#filelist>b').text(`\t#=${loaded}/${a.length}\t下载中...`); a.each(function(){ GM_download({ 'url':$(this).attr('href'), 'name':df.parent().nextAll().eq(3)[0].innerText+'—'+df.parent().nextAll().eq(7)[0].innerText.replace('\n',' ')+'—'+$(this).text(), 'onload':()=>{ loaded++; if(loaded===a.length){ df.find('ol#filelist>b').text(`\t#=${loaded}/${a.length}\t下载完成!`); df.find('button#downloadAll').show(); }else{ df.find('ol#filelist>b').text(`\t#=${loaded}/${a.length}\t下载中...`); } }, 'onerror':()=>{ df.find('ol#filelist>b').after('<br><p>'+$(this).text()+'\t下载错误!</p>'); df.find('button#downloadAll').show(); }, 'ontimeout':()=>{ df.find('ol#filelist>b').after('<br><p>'+$(this).text()+'\t下载超时!</p>'); df.find('button#downloadAll').show(); } }); }); } */ function DeleteAll(df,surveyid){ const attid=[]; df.find('a').each(function(){ attid.push(this.href.match(/(?<=\=)\d+/)[0]); }); console.log(attid,surveyid); const apply=confirm('请确认是否将此报告所有附件标记为删除\n(可在more中恢复,确认后可刷新页面或再次加载附件列表查看)'); if(apply){ //模拟手动禁用单个附件发送post请求,但请求数量较多 for(let i of attid){ $.post(`/document.asp?alias=survey.disableimage&ImageID=${i}&InstanceID=${surveyid}`,'ref=&step=2&comment='); } df.children('button#download').click(); } } /* //以API实现,缺点是不会在more中留下用以恢复的记录,优点是请求数量较少 function DeleteAll(df){ let csv=''; df.find('a').each(function(){ csv+=this.href.match(/(?<=\=)\d+/)[0]+','; }); csv=csv.slice(0,-1); console.log(csv); const apply=confirm('请确认是否要删除此报告所有附件\n(无法恢复注意备份,确认后可刷新页面或再次加载附件列表查看)'); if(apply){ //调用API将当前survey的所有附件标记为删除[SurveyAttachmentsMarkAttachmentsForDelete] $.get(` /open/data.asp?post={ "action":"exec", "dataset":{"datasetname":"/Apps/SM/Media Hub/SurveyAttachmentsMarkAttachmentsForDelete"}, "parameters":[{"name":"CsvList","value":"${csv}"}] }`); df.children('button#download').click(); } } */ //卸载附件下载 function unDOWNLOADFILE(){ if ($('div.downloadFile').length&&$('td.downloadFile').length){ $('td.downloadFile').remove(); $('div.downloadFile').each(function(){ $(this).parent().remove(); }); } } /*附件下载*/ /*3:扣分标记*/ function MARKQUESTION(){ if(unsafeWindow.OSM||!$('form#frmSurvey').length) return;//如v3问卷或预览等界面不运行 if(document.location.href.includes('alias=survey.view')){ getScoreData([$('input[name=PROTO]').val()],scoreData=>{ markScore(scoreData); }); /* $('span.surveyansweroption').each(function(){ if($(this).prev('input').is(':checked')){ if($(this).prev('input').val()==='__na__'){ $(this).css('color',GM_getValue('N/A颜色:','green'));//默认标绿N/A项 } } }); */ //获取所有扣分的题目 const qidmark=[]; const check=checkDayofWeek(); if(check.isWrong) qidmark.push('Q'+check.qid+'ANS'); markDayofWeek(check.isWrong,check.ele); /* //v3问卷/mystservices/v2new/getSurvey.asp?InstanceID=请求后获取数据:unsafeWindow.Open.stringToObject(OSMRenderingInit.toString().match(/(?<=OSMRendering_SurveyInstance_Preview\(){.+}(?=, document)/)[0]) $.get('/mystservices/v2new/getSurvey.asp?InstanceID='+$('input#instanceID').val(),(data,status)=>{ if (status==='success'){ $(data).find('nobr').each(function(){ const score=$(this).text(); if(score!=''&&!score.includes('%')){//排除空值与section总分 const pts=score.split('/'); if(Number(pts[0])<Number(pts[1])){ const QidANS=$(this).parents('td.surveyquestioncell').prev().find('div').attr('id'); qidmark.push(QidANS); } } }); */ for(let q of qidmark){ $('div#'+q).find('span.surveyansweroption').css('color',GM_getValue('扣分颜色:','red'));//默认标红扣分项 } //} //}); } } //检查所选星期和日期是否不一致 function checkDayofWeek(){ const qtx=['星期','Day of the week','Day of the Week','Day of week','Day 星期','周几',' 星期'];//lee问卷[ID:1316]的星期题前有空格 const atx=['星期一','Monday']; let isWrong,ele,qid,start; $('span.surveyquestion').each(function(){ for(let q of qtx) if($(this).text().startsWith(q)) ele=$(this); }); if(ele) qid=ele.parents('a.surveyquestionnobreak').attr('name').replace('qstn',''); if(qid){ const t=$('input[name=HEAD_DATE]').val().split('-'); if(t.length===3){ const day=new Date(t[0],t[1]-1,t[2]).getDay(); const ans=unsafeWindow.sm_getmultipleanswer(qid); for(let a of atx) if($('input#'+qid+'R1').next('span').text().startsWith(a)) start=1; if(start&&!day&&day+7!=ans) isWrong=1;//如星期一开头&&应为星期日&&0+7!=7 if(start&&day&&day!=ans) isWrong=1; if(!start&&day+1!=ans) isWrong=1; } } return {isWrong:isWrong,qid:qid,ele:ele}; } //标记星期是否正确 function markDayofWeek(isWrong,ele){ if(!ele) return; if(isWrong){ ele.after('<b id=dayofweek style=color:red>×</b>'); }else{ ele.after('<b id=dayofweek style=color:green>√</b>'); } } //标记每题分数且动态更新 function markScore(scoreData){ const colorDe=GM_getValue('扣分颜色:','red'); const colorNa=GM_getValue('N/A颜色:','green'); const Q2A=handleScoreData(scoreData); const getmultipleanswer=unsafeWindow.sm_getmultipleanswer; for(let qid in Q2A){ const a=$(`a[name=qstn${qid}]`); const arrSelPos=getmultipleanswer(qid).split(','); if(arrSelPos[0]==='__na__') arrSelPos[0]='0'; const score=caculateScore(arrSelPos,Q2A[qid]); const title= 'StartingPoints: '+Q2A[qid].StartingPoints+ '\nMeasureMin: '+Q2A[qid].LimitMeasureMinimum+ '\nMeasureMax: '+Q2A[qid].LimitMeasureMaximum+ '\nPointsPossible: '+Q2A[qid].CustomPointsPossible; const bCss={position:'absolute',top:0,right:0}; if(score[0]<score[1]) bCss.color=colorDe; else if(arrSelPos[0]==='0') bCss.color=colorNa; a.find('span.surveyansweroption').css('color',bCss.color); $(`<b id=pts>${score[0]}/${score[1]}</b>`).css(bCss).attr('title',title) .appendTo(a).parent('a').css('position','relative'); for(let pos in Q2A[qid].Answer){ const ans=Q2A[qid].Answer[pos]; if(ans.Measure!==null&&!Q2A[qid].IsShowMeasure) a.find(`label[for=${qid}R${pos}]`).append(`<span id=pts> (${ans.Measure} pts)</span>`); } a.find('label').on('click.updatePts',()=>{ const arrSelPos=getmultipleanswer(qid).split(','); if(arrSelPos[0]==='__na__') arrSelPos[0]='0'; const score=caculateScore(arrSelPos,Q2A[qid]); const css={color:''}; if(score[0]<score[1]) css.color=colorDe; else if(arrSelPos[0]==='0') css.color=colorNa; a.find('span.surveyansweroption').css(css); a.children('b#pts').text(score[0]+'/'+score[1]).css(css); }); } } //卸载扣分标记 function unMARKQUESTION(){ if(unsafeWindow.OSM||!$('form#frmSurvey').length) return; if(document.location.href.includes('alias=survey.view')){ $('span.surveyansweroption').css('color',''); $('b#dayofweek,#pts').remove(); $('label').off('click.updatePts'); } } /*扣分标记*/ /*4:评论编辑*/ function COMMENTEDIT(){ if(unsafeWindow.OSM||!$('form#frmSurvey').length) return;//如v3问卷或预览等界面不运行 if(document.location.href.includes('alias=survey.view')){ if(unsafeWindow.updrowH) $('textarea.surveycomment').each(function(){unsafeWindow.updrowH(this);});//等页面自身执行到调整评论框高度过于缓慢 $('<div id=commentEdit title=评论编辑>').appendTo($('body')[0]) .css({position:'fixed',zIndex:1e4+1, right:'30px',bottom:'80px',height:'25px',width:'25px', background:'#808080'}); //插入图标 $('<img src=/images/icons/menu/x32/survet.png>').appendTo('div#commentEdit').css({width:'inherit',transform:'scale(0.8)'}); //插入操作界面并赋值为ce $('<div id=commentFunc title>').appendTo('div#commentEdit') .css({position:'fixed',right:'60px',bottom:'50px'}).hide() .on('click',e=>{ e.stopPropagation();//阻止子元素执行父元素click事件 }); const ce=$('div#commentFunc'); $('div#commentEdit').on('click',function(){ commentEditSwitch(ce); }); //提示开关 $('<b id=hint style=cursor:pointer>【点击获取提示】</b>').appendTo(ce) .on('click',function(){ hintSwitch($(this)); }); //评论匹配与替换 $('<button type=button id=replaceAll class=surveyBottomButton>一键替换</button>').appendTo(ce) .before('<textarea id=find placeholder=匹配内容></textarea><b id=commentMark style=cursor:pointer title=切换所有评论框标红状态>↓↓↓</b><textarea id=replace placeholder=替换内容></textarea>') .before('<b id=findNum>#</b>'); $('textarea#find,textarea#replace').on('keydown',e=>{ e.stopPropagation();//阻止页面自带keydown事件修改textarea的class值 }).on('input',function(){ commentMatch(ce); }); $('b#commentMark').on('click',()=>{ commentMark(ce); }); $('button#replaceAll').on('click',()=>{ execReplace(ce); }); //首字母大写 $('<button type=button id=initialUpper class=surveyBottomButton>首字母大写</button>').appendTo(ce) .on('click',()=>{ initialUpper(ce); }); //评论翻译 $( `<button type=button id=commentTrans class=surveyBottomButton>评论翻译</button> <select id=toLang> <option value=en>→英文</option> <option value=jp>→日文</option> <option value=zh>→中文(简体)</option> <option value=cht>→中文(繁体)</option> <option value=yue>→中文(粤语)</option> <option value=f→j>繁体→简体</option> </select>` ).appendTo(ce); ce.find('button#commentTrans').on('click',()=>{ commentTranslate($('select#toLang option:selected').val()); }); ce.children().css({display:'block',textAlign:'center',margin:'5px auto'}); } } //评论替换开关 function commentEditSwitch(ce){ if(ce.css('display')==='none'){ ce.show(); commentMatch(ce); }else{ ce.hide(); markMatchComment(0,$('textarea.surveycomment,textarea.active')); } } //插入或移除提示 function hintSwitch(hs){ if(hs.children().length){ hs.text('【点击获取提示】').children().remove(); }else{ hs.text('【点击关闭提示】') .append('<a class=mailboxlink target=_blank href=https://tool.oschina.net/uploads/apidocs/jquery/regexp.html>匹配支持正则表达式</a>') .append('<a class=mailboxlink target=_blank href=https://c.runoob.com/front-end/854>正则表达式测试</a>') .append( `<ol> <li>正则实例:[。|.]$ 可匹配末尾处中英文句号;^[a-z] 可匹配开头处小写字母;甲|乙|丙 可匹配甲或乙或丙</li> <li>可当作一般替换使用,如需替换一些特殊字符(\^$*+?.等,参照第一个链接中所列字符),请在前面使用\\标记转义,避免识别为正则表达</li> <li>评论框激活后按Ctrl可切换评论框是否标红,标红的评论框将被排除在修改范围之外,点击两框间的↓↓↓可快速切换全部评论框标红与否</li> </ol> `); hs.children().css('display','block').on('click',e=>{ e.stopPropagation(); }); hs.find('li').css({textAlign:'left',width:'200px'}); } } //判断此评论框是否隐藏 function isHide(ele){ const qvState=unsafeWindow.sm_questionvisibility_state; if(qvState&&qvState[ele.name.replaceAll('C','')]==='hide'||ele.style.display==='none'){ return 1; }else{ return 0; } } //切换所有评论框标记与否 function commentMark(ce){ $('textarea.surveycomment,textarea.active').each(function(){ if(isHide(this)) return; if($(this).attr('class')==='active'){ $(this).attr('class','surveycomment'); }else{ $(this).attr('class','active'); } }); commentMatch(ce); } //即时标记匹配到的评论框,预览替换后内容 function commentMatch(ce){ const f=getFind(ce); let n=0; markMatchComment(0,$('textarea.active')); $('textarea.surveycomment').each(function(){ if(isHide(this)) return; const rc=getReplacedComment(ce,f,$(this).val()); if(rc!==false){ markMatchComment(1,$(this),rc); n++; }else{ markMatchComment(0,$(this)); } }); ce.find('b#findNum').text('#='+n); } //匹配评论框标记处理 function markMatchComment(hasText,ele,text,isBefore){ ele.each(function(){ if(hasText){ text= isBefore? '之前为:\n'+text : '替换为:\n'+text; $(this).css('background','lightgrey').attr('title',text); if($(this).prev().attr('id')){ $(this).prev('div#mark').show(); }else{ $(this).before('<div id=mark>^^</div>'); } }else{ $(this).css('background','').attr('title',''); $(this).prev('div#mark').hide(); } }); } //判断并返回匹配值与类型 function getFind(ce){ let find,isRE; try{//若不是正则表达式,按普通字符处理 find=new RegExp(ce.find('textarea#find').val(),'gm'); isRE=1; }catch(e){ find=ce.find('textarea#find').val(); } return [find,isRE]; } //判断并返回替换后评论或空 function getReplacedComment(ce,f,text){ const index= f[1]? text.search(f[0]) : text.indexOf(f[0]);//search只接受正则 : indexOf只接受字符 if(index>=0){ return text.replaceAll(f[0],ce.find('textarea#replace').val()); }else{ return false; } } //进行评论替换 function execReplace(ce){ const f=getFind(ce); $('textarea.surveycomment').each(function(){ if(isHide(this)) return; const text=$(this).val(); const rc=getReplacedComment(ce,f,text); if(rc!==false){ markMatchComment(1,$(this),text,1);//记录修改前内容 $(this).val(rc); unsafeWindow.updrowH(this);//调用页面自带函数来调整评论框高度 } }); } //首字母大写 function initialUpper(ce){ let n=0; $('textarea.surveycomment').each(function(){ if(isHide(this)) return; const match=new Set($(this).val().match(/(^|\.|\?|!)("|'|) *[a-z]/gm)); if(match.size){ let text=$(this).val(); markMatchComment(1,$(this),text,1);//记录大写前内容 for(let m of match){ const r=new RegExp(`(^|\\.|\\?|!)("|'|) *`+m,'gm'); text=text.replaceAll(r,m.toUpperCase()); } $(this).val(text); n++; }else{ markMatchComment(0,$(this)); } }); ce.find('b#findNum').text('#='+n); } //调用百度翻译进行评论翻译 async function commentTranslate(toLang){ await translate_baidu_startup(); $('textarea.surveycomment').each(async function(){ if(isHide(this)) return; if($(this).val()&&$(this).next().is('input:hidden')){ $(this).after('<textarea id=trans style=overflow:hidden rows='+$(this).attr('rows')+' cols='+$(this).attr('cols')+'>') .after('<button type=button class=attachmentBtn style="display:block;height:1.5em;width:1.5em;margin:5px 0">↑</button>'); $(this).next('button').on('click',function(){ const prev=$(this).prev().val(); const next=$(this).next().val(); $(this).prev().val(prev+'\n\n'+next); unsafeWindow.updrowH($(this).prev()[0]); $(this).next().remove(); $(this).remove(); }); } if($(this).val()){ const fromLang= toLang==='f→j'? 'cht' : null; toLang= toLang==='f→j'? 'zh' : toLang; const translated=await translate_baidu(toLang,$(this).val(),fromLang); $(this).next().next('textarea').val(translated); unsafeWindow.updrowH($(this).next().next('textarea')[0]);//调用页面自带函数来调整评论框高度 } }); $('textarea#trans').on('keydown',e=>{ e.stopPropagation();//阻止页面自带keydown事件修改textarea的class值 }); } //百度翻译 参考https://gf.qytechs.cn/scripts/378277 async function translate_baidu_startup(){ if(window.sessionStorage.getItem('baidu_gtk')&&window.sessionStorage.getItem('baidu_token')) return; const options={ method:'GET', url:'https://fanyi.baidu.com', }; const res=await Request(options); window.sessionStorage.setItem('baidu_gtk',/window\.gtk = "(.*?)"/.exec(res.responseText)[1]); window.sessionStorage.setItem('baidu_token',/token: '(.*?)'/.exec(res.responseText)[1]); } async function translate_baidu(toLang,raw,fromLang){ if(!fromLang){ fromLang=await check_lang(raw); } const proc_raw= raw.length>30? (raw.substr(0,10)+raw.substr(~~(raw.length/2)-5,10)+raw.substr(-10)) : raw;//process const tk_key=window.sessionStorage.getItem('baidu_gtk'); const token=window.sessionStorage.getItem('baidu_token');//get token const options={ method:"POST", url:'https://fanyi.baidu.com/v2transapi', data:`from=${fromLang}&to=${toLang}&query=${encodeURIComponent(raw)}&transtype=translang&simple_means_flag=3&sign=${tk(proc_raw,tk_key)}&token=${token}&domain=common`, headers:{ "referer":'https://fanyi.baidu.com', 'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8', }, }; return await BaseTranslate('百度翻译',raw,options,res=>JSON.parse(res).trans_result.data.map(item=>item.dst).join('\n')); } async function check_lang(raw){ const options={ method:"POST", url:'https://fanyi.baidu.com/langdetect', data:'query='+encodeURIComponent(raw.replace(/[\uD800-\uDBFF]$/,'').slice(0,50)), headers:{ 'Content-Type':'application/x-www-form-urlencoded', } }; const res=await Request(options); try{ return JSON.parse(res.responseText).lan; }catch(e){ console.log(e); return; } } //根据翻译字符获取sign值 function tk(a,b){ var d=b.split('.'); b=Number(d[0]) || 0; for(var e=[],f=0,g=0;g<a.length;g++){ var k=a.charCodeAt(g); 128>k? e[f++]=k : ( 2048>k? e[f++]=k>>6|192 : ( 55296==(k&64512)&&g+1<a.length&&56320==(a.charCodeAt(g+1)&64512)? ( k=65536+((k&1023)<<10)+(a.charCodeAt(++g)&1023), e[f++]=k>>18|240, e[f++]=k>>12&63|128 ) : e[f++]=k>>12|224, e[f++]=k>>6&63|128 ), e[f++]=k&63|128 ); } a=b; for(f=0;f<e.length;f++) a=Fo(a+e[f],'+-a^+6'); a=Fo(a,'+-3^+b+-f'); a^=Number(d[1])||0; 0>a&&(a=(a&2147483647)+2147483648); a%=1E6; return a.toString()+'.'+(a^b); } function Fo(a,b){ for(var c=0;c<b.length-2;c+=3){ var d=b.charAt(c+2); d= "a"<=d? d.charCodeAt(0)-87 : Number(d); d= "+"==b.charAt(c + 1)? a>>>d : a<<d; a= "+"==b.charAt(c)? a+d&4294967295 : a^d; } return a; } //异步请求包装工具 async function PromiseRetryWrap(task,options,...values){ const {RetryTimes,ErrProcesser}=options||{}; let retryTimes=RetryTimes||5; const usedErrProcesser=ErrProcesser||(err=>{throw err;}); if(!task)return; while(true){ try{ return await task(...values); }catch(e){ if(!--retryTimes){ console.log(e); return usedErrProcesser(e); } } } } async function BaseTranslate(name,raw,options,processer){ const toDo=async ()=>{ let tmp; try{ const data=await Request(options); tmp=data.responseText; const result=await processer(tmp); if(result) window.sessionStorage.setItem(name+'-'+raw,result); return result; }catch(e){ throw { responseText: tmp, err: e }; } }; return await PromiseRetryWrap(toDo,{RetryTimes:3,ErrProcesser:()=>"翻译出错"}); } function Request(options){ return new Promise((reslove,reject)=>GM_xmlhttpRequest({...options,onload:reslove,onerror:reject})); } /*评论编辑*/ //卸载评论编辑 function unCOMMENTEDIT(){ if(unsafeWindow.OSM) return; if($('div#commentEdit').length) $('div#commentEdit').remove(); } /*评论编辑*/ /*5:验证输出*/ function VERIFYEXPORT(){ if (document.location.href.includes('alias=smngr.surveyexplorer')&&$('div#filterdiv').length){ $('div#filterdiv').before('<button type=button id=verifyExport class="rm-btn rm-btn-default">验证输出勾选的报告</button>'); $('button#verifyExport').css({margin:'10px 0px',display:'block'}).on('click',()=>{ verifyExportAll(); }); } } //验证输出全部报告 function verifyExportAll(){ const apply=confirm('请确认是否要验证输出当前页面勾选的所有报告\n(电脑配置低请勿一次性输出过多报告)'); if(apply){ $('table#reporttable>tbody>tr').each(function(){ if($(this).css('display')!='none'&&$(this).find('input:checkbox').eq(0).is(':checked')){ const a=$(this).find('td>a.mailboxlink').eq(0); const src=a.attr('href').replace('document.asp?alias=survey.view&','importmngr/ImportSurveys/ImportSurveysFrame.asp?'); const iframe=document.createElement('iframe'); iframe.src=src; iframe.style='height:80px;width:250px'; a.after(iframe); iframe.onload=function(){ if(this.src.includes('ImportSurveysFrame.asp')){ const doc=$(this).contents(); doc.find('div#addInfo,div#menu,div#pathContainer').remove(); if(doc.find('input#scrverN').is(':checked')&&doc.find('input#questVerN').is(':checked')){//前2点均为否时才进行操作 doc.find('input#scrverY').click(); doc.find('input#questVerY').click(); doc.find('button#save').click(); }else if(this.contentWindow.surveyImportSurveySubmitted){ $(this).before('<div style=background:green;width:250px;color:black><img src=/images/icons/xp16/accept-hover.png>报告已成功执行上线</div>'); $(this).remove(); }else{ $(this).before('<div style=width:250px>报告原本已处于上线状态</div>'); } } }; } }); alert('请耐心等待所有小窗口加载完成,显示绿色保存成功提示后,再刷新页面检查是否全部验证输出成功'); } } //卸载验证输出 function unVERIFYEXPORT(){ if($('button#verifyExport').length) $('button#verifyExport').remove(); } /*验证输出*/ /*6:定制汇总*/ function CUSTOMROLLUP(){ if(document.location.href.includes('alias=clientaccess.customrollups')){ if($('table.reporttable,table.incCrossTabTableClass').length){ const cr=document.createElement('div'); cr.id='CRfunction'; $('div.q2r_tableCaptionDiv,table.incCrossTabTableClass').before(cr); //复制表格 $('<button type=button id=copyBtn>复制表格</button>').appendTo(cr) .on('click',function(){ if($(this).next('select#percentSign').val()==='+%'){//给Pivot table形式的数据后添加% $('table.incCrossTabTableClass td.incCrossTabTableBodyValuesClass').each(function(){ if(!$(this).attr('rowspan')) $(this).text($(this).text().replace('%','')+'%'); }); }else{ $('table.incCrossTabTableClass td.incCrossTabTableBodyValuesClass').each(function(){ if(!$(this).attr('rowspan')) $(this).text($(this).text().replace('%','')); }); } window.getSelection().removeAllRanges(); const content=$(cr).parent().find('table#reporttable,table.incCrossTabTableClass').children('tbody')[0].innerText; if($(this).prevAll('textarea').length===0) $(this).before('<textarea>'); $(this).prev('textarea').show(); $(this).prev('textarea').val(content).select(); document.execCommand('copy')? $(this).text('复制成功!') : $(this).text('复制失败...'); $(this).prev('textarea').hide(); window.getSelection().removeAllRanges(); setTimeout(()=>{ $(this).text('复制表格'); },3e3); }); $(`<select id=percentSign title="此选项仅针对Pivot table(自定义表格)界面下,复制时为分数后添加%,在Tabular(默认表格)界面下无效"> <option value=+%>分数后+%</option> <option value=无>无</option> </select><br>`).appendTo(cr); //精确pts% $('<button type=button id=ptsPercPlus title=根据Pts和PtsOf列精确计算pts%值>精确pts%</button>').appendTo(cr) .on('click',function(){ const td=$(cr).parent().find('table#reporttable>thead>tr>td'); let pts,ptsOf; for(let i=0;i<td.length;i++){ if(td.eq(i).text()==='Pts') pts=i; if(td.eq(i).text()==='Pts Of') ptsOf=i; } if(pts&&ptsOf){ $('#reporttable tr').each(function(){ const last=$(this).children('td:last-child'); if(last.attr('class')!=='ptsPercPlus') last.after(last.clone(true).attr('class','ptsPercPlus')); const tar=$(this).children('td.ptsPercPlus'); if($(this).attr('class')==='persist-header'){ tar.text('Pts%+'); }else{ const score=$(this).children().eq(pts).children().text()/$(this).children().eq(ptsOf).children().text();//只取<span>中的数据 tar.text((score*100).toFixed($(cr).children('select#toFixed').val())+'%'); } }); $(this).text('计算成功!'); }else{ $(this).text('缺少关键列!'); } setTimeout(()=>{ $(this).text('精确pts%'); },3e3); }); $('<select id=toFixed title=此选项对【精确pts%】和【选项统计】同时生效>').appendTo(cr); const sel=$(cr).children('select#toFixed'); for(let i=0;i<6;i++) sel.append(`<option value=${i}>保留${i}位小数</option>`); sel.children().eq(1).prop('selected',true); //选项统计 $('<button type=button id=answerDistribution title=根据QuestionText和AnswerText和#Surveys列统计各架构各题各选项数量和占比>选项统计</button>').appendTo(cr) .on('click',function(){ $(cr).parent().find('table#reporttable>tbody>tr.ad').remove(); //获取各关键列位置及隐藏情况 const thtd=$(cr).parent().find('table#reporttable>thead>tr>td'); let QText,AText,surveyNum; const hideCol=[],colIndex=[];//QuestionText/AnswerText列中靠左的所有左侧的未隐藏列都将记录至colIndex并参与统计 for(let i=0;i<thtd.length;i++){ if(thtd.eq(i).text()==='Question Text') QText=i; else if(thtd.eq(i).text()==='Answer Text') AText=i; else if(thtd.eq(i).text()==='# Surveys') surveyNum=i; else if(QText===undefined&&AText===undefined&&thtd.eq(i).css('display')!='none') colIndex.push(i); else if(thtd.eq(i).css('display')==='none') hideCol.push(i); } if(QText>=0&&AText>=0&&surveyNum>=0){ //先显示可能被隐藏的关键列 const input=$('div#hideOption input'); if(input.length) for(let i of [QText,AText,surveyNum]) if(!input.eq(i).is(':checked')) toggleCol(input.eq(i).prop('checked',true)[0]); //开始统计 const AD={}; $('table#reporttable>tbody>tr').each(function(){ if(this.style.display==='none') return; const tbtd=$(this).children(); const Q=checkKey(AD,tbtd.eq(QText).text().trim()); let BUText=''; for(let c of colIndex) BUText+=tbtd.eq(c).text()+';'; const BU=checkKey(Q,BUText); const num=Number(tbtd.eq(surveyNum).children('span').text()); if(!BU.num) Object.defineProperty(BU,'num',{value:0,enumerable:false,writable:true});//将作为分母的num设为不可枚举 BU.num+=num; for(let a of tbtd.eq(AText).text().split(';')){ if(!BU[a]) BU[a]=0; BU[a]+=num; } }); //检测是否已加载选项并补充样本量为0的选项 const selectedQ=$('input[name=fieldForCheckingFilter]').val().match(/(?<=4:).+(?= 5:)/),QnA={}; let selectedArr=[]; const PCmsFilterQuestion=$('select#PCmsFilterQuestionsSelectQuestion'); if(selectedQ) selectedArr=selectedQ[0].split('%2C'); else{ PCmsFilterQuestion.find('optgroup>option').filter(function(){return !this.value.includes(',');}).each(function(){ selectedArr.push(this.value); }); } for(let s of selectedArr){ const Q=PCmsFilterQuestion.find(`[value=${s}]`).text().trim(); QnA[Q]=[]; PCmsFilterQuestion.find(`[value*=_${s}_]`).each(function(){ QnA[Q].push(this.innerText.trim().substr(1));//去除多余空格和前面的'-' }); const QnA_Q=QnA[Q],AD_Q=AD[Q];//将缺少的选项赋值为0 for(let a in QnA_Q) for(let bu in AD_Q) if(!Object.keys(AD_Q[bu]).includes(QnA_Q[a])) AD_Q[bu][QnA_Q[a]]=0; } //输出统计结果 for(let q in AD){ for(let bu in AD[q]){ const buArr=bu.split(';'); for(let a in AD[q][bu]){ let tr='<tr class=ad>',n=0; for(let i=0;i<thtd.length;i++){ if(hideCol.includes(i)) tr+='<td style=display:none></td>'; else if(colIndex.includes(i)) tr+=`<td>${buArr[n++]}</td>`; else if(QText===i) tr+=`<td>[AD] ${q} (${AD[q][bu].num})</td>`; else if(AText===i) tr+=`<td>${a} (${AD[q][bu][a]})</td>`; else if(surveyNum===i) tr+=`<td>${(AD[q][bu][a]/AD[q][bu].num*100).toFixed($(cr).children('select#toFixed').val())}%</td>`; else tr+='<td></td>'; } tr+='</tr>'; $('table#reporttable>tbody').append(tr); } } } $(this).text('统计成功!'); }else{ $(this).text('缺少关键列!'); } setTimeout(()=>{ $(this).text('选项统计'); },3e3); }); //整体css调整 $(cr).children('button').css({margin:'5px',font:'inherit'}); } } } function checkKey(obj,key){ if(!obj[key]) obj[key]={}; return obj[key]; } //卸载定制汇总 function unCUSTOMROLLUP(){ if($('div#CRfunction').length) $('div#CRfunction').remove(); } /*定制汇总*/ /*7:报告存档*/ function SURVEYSAVES(){ if(unsafeWindow.OSM||!$('form#frmSurvey').length) return; if(document.location.href.includes('alias=survey.view')){ //插入操作界面并赋值为ssl $('<div id=surveySaves title=报告存档>').appendTo($('body')[0]) .css({position:'fixed','zIndex':1e4, right:'30px',bottom:'110px',height:'25px',width:'25px', background:'#808080'}); $('<img src=/images/icons/menu/x16/KB-icon.png>').appendTo('div#surveySaves').css({width:'inherit',transform:'scale(0.8)'}); $('<div id=surveySavesList title>').appendTo('div#surveySaves') .css({position:'fixed',right:'60px',bottom:'50px',background:'lightgrey'}).hide() .on('click',e=>{ e.stopPropagation();//阻止子元素执行父元素click事件 }); const ssl=$('div#surveySavesList'); ssl.append(` <div style=margin:5px> <button type=button id=Show class=rm-btn>预览</button> <button type=button id=Load class=rm-btn>读档</button> <button type=button id=Save class=rm-btn>存档</button> <button type=button id=Dele class=rm-btn>删除</button> </div> <div id=tab style=margin:5px> <label><input type=radio name=tab value=autosaves checked>自动存档</label> <label><input type=radio name=tab value=selfsaves>手动存档</label> </div> <table cellpadding=5 style=margin:5px> <thead id=saves> <tr> <td></td> <td>保存时间</td> <td>问卷标题</td> <td>店铺ID</td> <td>报告ID</td> </tr> </thead> <thead id=questions> <tr> <td><input type=checkbox name=questions checked></td> <td>QID</td> <td>题目</td> <td>选项</td> <td>评论</td> </tr> </thead> <tbody id=autosaves></tbody> <tbody id=selfsaves></tbody> <tbody id=questions style=height:300px;overflow:scroll></tbody> </table> `); ssl.find('thead,tbody').css('display','block'); ssl.find('#selfsaves,#questions').hide(); //存档列表开关 $('div#surveySaves').on('click',function(){ if(ssl.css('display')==='none'){ ssl.show(); refreshList(ssl); }else{ ssl.hide(); } }); //按钮功能 ssl.find('button#Show').on('click',()=>{ showData(ssl); }); ssl.find('button#Load').on('click',()=>{ loadData(ssl); }); ssl.find('button#Save').on('click',()=>{ saveData(ssl,'selfsaves'); }); ssl.find('button#Dele').on('click',()=>{ deleteData(ssl); }); //切换存档列表页 ssl.find('div#tab').on('click',function(){ ssl.find('input[name=saves]:checked').prop('checked',false);//将存档的选中状态重置 const checked=$(this).find('input:checked').val(); const unchecked= checked==='autosaves'? 'selfsaves' : 'autosaves'; $(this).parent().find('tbody#'+unchecked).hide(); $(this).parent().find('tbody#'+checked).show(); refreshList(ssl,checked); theadWidth(ssl.find('thead#saves'),ssl.find('tbody#'+checked)); }); //预览界面一键勾选与取消 ssl.find('thead#questions input').on('click',function(){ if($(this).is(':checked')){ $(this).parents('table').find('input[name=questions]').prop('checked',true); }else{ $(this).parents('table').find('input[name=questions]').prop('checked',false); } }); //监听表单内点击和评论失焦触发存档事件 let Form=$('form#frmSurvey').serialize(); $('form#frmSurvey').on('click.autosave',()=>{ Form=autoSave(ssl,Form); }); $('textarea.surveycomment,textarea.active').on('blur.autosave',()=>{ Form=autoSave(ssl,Form); }); } } //表单变化时自动存档 function autoSave(ssl,prvForm){ const curForm=$('form#frmSurvey').serialize(); if(prvForm!=curForm){//如表单数据改变 saveData(ssl,'autosaves'); } return curForm; } //刷新存档列表 function refreshList(ssl,fromSave){ if(ssl.css('display')==='none') return;//界面隐藏时不刷新 if(!fromSave) fromSave=ssl.find('input[name=tab]:checked').val();//无参数自动判断当前页 const curChecked=ssl.find('input[name=saves]:checked').parent('td').next().text();//记录当前选中存档 ssl.find('tbody#'+fromSave).empty(); const saves=GM_getValue(fromSave,{}); const k=Object.keys(saves); if(k.length){ for(let i in k){ const line= i%2===1? 'reporttable_odd' : 'reporttable_even'; ssl.find('tbody#'+fromSave).prepend( `<tr class=${line}> <td><input type=radio name=saves></td> <td>${k[i]}</td> <td>${saves[k[i]].surveytitle}</td> <td>${saves[k[i]].formhead.LOCATION}</td> <td>${saves[k[i]].surveyid}</td> </tr>` ); if(curChecked===k[i]) ssl.find('tbody#'+fromSave).children('tr:first').find('input').prop('checked',true);//还原存档选中状态 } //如为当前存档页则同步表头宽度 if(ssl.find('input[name=tab]:checked').val()===fromSave){ theadWidth(ssl.find('thead#saves'),ssl.find('tbody#'+fromSave)); } }else{ const w=getComputedStyle(ssl.find('tbody#'+fromSave)[0]).width; ssl.find('tbody#'+fromSave).append('<td style=width:'+w+';text-align:center>无数据!</td>'); } } //预览 function showData(ssl){ if(ssl.find('thead#questions').css('display')==='none'){ const [save]=checkSave(ssl); if(!save) return; const head=save.formhead; for(let h in head){ const line='reporttable_odd'; ssl.find('tbody#questions').append( `<tr class=${line}> <td><input type=checkbox name=questions></td> <td colspan=2>${h}</td> <td colspan=2>${head[h]}</td> </tr>` ); } const body=save.formbody; for(let b of body){ if(!Object.keys(b).includes('ans')) b.ans='×'; if(!Object.keys(b).includes('cmt')) b.cmt='×'; const line='reporttable_even'; ssl.find('tbody#questions').append( `<tr class=${line}> <td><input type=checkbox name=questions></td> <td>${b.qid}</td> <td>${b.qtx}</td> <td>${b.ans}</td> <td>${b.cmt}</td> </tr>` ); } if(ssl.find('thead#questions input').is(':checked')){ ssl.find('tbody#questions input').prop('checked',true); }else{ ssl.find('tbody#questions input').prop('checked',false); } ssl.find('button#Show').text('←'); ssl.find('button#Save,button#Dele,div#tab,[id$=saves]').hide(); ssl.find('table #questions').show(); theadWidth(ssl.find('thead#questions'),ssl.find('tbody#questions'));//在显示后同步宽度,隐藏时会默认为auto }else{ ssl.find('tbody#questions').empty(); ssl.find('button#Show').text('预览'); ssl.find('table #questions').hide(); ssl.find('button#Save,button#Dele,div#tab,#saves,tbody#'+$('input[name=tab]:checked').val()).show(); } } //读档 function loadData(ssl){ const [save]=checkSave(ssl); if(!save) return; //如当前报告id与存档报告id不相等,询问是否执行 if(save.surveyid!=$('input#instanceID').val()){ //将文本,是否确认,确认后执行的方法传给feedback(ssl,text,ifConfirm,yesFunc)生成确认提示 feedback( ssl, '报告ID不同,仅会修改当前报告中和存档中相匹配的题目,是否继续?', 1, ()=>{execLoadData(ssl,save);} ); }else{ execLoadData(ssl,save); } } //执行读档 function execLoadData(ssl,save){ const qidArr=[]; if(ssl.find('thead#questions').css('display')!='none'){ if(ssl.find('input[name=questions]:checked').length===0){ feedback(ssl,'请勾选题目!'); return; } ssl.find('input[name=questions]:checked').each(function(){ qidArr.push($(this).parent().next().text()); }); } const setAnswer=unsafeWindow.sm_setmultipleanswer; const setComment=unsafeWindow.sm_setcomment; const head=save.formhead; let count=0; for(let h in head){ if(qidArr.length&&!qidArr.includes(h)) continue; if(h==='DATE'){ if(head[h]===''){ $('select#dsYear').children(':first').prop('selected',true); $('select#dsMonth').children(':first').prop('selected',true); $('select#dsDay').children(':first').prop('selected',true); }else{ const date=head[h].split('-'); $('select#dsYear').children('[value='+date[0]+']').prop('selected',true); $('select#dsMonth').children('[value='+date[1]+']').prev().prop('selected',true); $('select#dsDay').children('[value='+date[2]+']').prev().prop('selected',true); } } if(h==='TIME'){ if(head[h]===''){ $('select#tsHoursHEAD_TIME').children(':first').prop('selected',true); $('select#tsMinutesHEAD_TIME').children(':first').prop('selected',true); }else{ const time=head[h].split(':'); $('select#tsHoursHEAD_TIME').children('[value='+time[0]+']').prop('selected',true); $('select#tsMinutesHEAD_TIME').children('[value='+time[1]+']').prop('selected',true); } } if(h==='TIMEOUT'){ if(head[h]===''){ $('select#tsHoursHEAD_TIMEOUT').children(':first').prop('selected',true); $('select#tsMinutesHEAD_TIMEOUT').children(':first').prop('selected',true); }else{ const time=head[h].split(':'); $('select#tsHoursHEAD_TIMEOUT').children('[value='+time[0]+']').prop('selected',true); $('select#tsMinutesHEAD_TIMEOUT').children('[value='+time[1]+']').prop('selected',true); } } if($('input[name=HEAD_'+h+']').length){ $('input[name=HEAD_'+h+']').val(head[h]); count++; } } const body=save.formbody; for(let b of body){ if(qidArr.length&&!qidArr.includes(b.qid)||$('textarea#C'+b.qid+'C').length===0) continue;//跨问卷读档时跳过没有的题防止updrowH()报错 const key=Object.keys(b); if(key.includes('ans')) setAnswer(b.qid,b.ans); if(key.includes('cmt')){ setComment(b.qid,b.cmt); unsafeWindow.updrowH(document.querySelector('textarea#C'+b.qid+'C'));//调整评论框高度 } count++; } feedback(ssl,'读档成功。(共修改'+count+'题)'); } //存档 function saveData(ssl,toSave){ const save={ 'surveytitle':$('h1.surveytitle').text(), 'surveyid':$('input#instanceID').val(), 'formhead':{ 'LOCATION':$('input[name=HEAD_LOCATION]').val()||$('table.visualization_HEAD_LOCATION').find('lookup').text().split(' - ')[0], 'SHOPPER':$('input[name=HEAD_SHOPPER]').val(), 'DATE':$('input[name=HEAD_DATE]').val(), 'TIME':$('input[name=HEAD_TIME]').val(), 'TIMEOUT':$('input[name=HEAD_TIMEOUT]').val() }, 'formbody':[] }; const getAnswer=unsafeWindow.sm_getmultipleanswer; const getComment=unsafeWindow.sm_getcomment; $('a.surveyquestionnobreak').each(function(){ const qtx=$(this).find('span.surveyquestion').text(); const qid=$(this).attr('name').replace('qstn',''); const ans= $('input[name=Q'+qid+'Q]').length? getAnswer(qid) : undefined; //ans 已填写:'1,2'||'__na__';未填写:'';无选项列:undefined const cmt= getComment(qid); //cmt 已填写:'xxx';未填写:'';无评论框:undefined save.formbody.push({ 'qtx':qtx, 'qid':qid, 'ans':ans, 'cmt':cmt }); }); const saves=GM_getValue(toSave,{}); saves[new Date().toLocaleString()]=save; //存档超过10个覆盖最早存档 if(Object.keys(saves).length>10) delete saves[Object.keys(saves)[0]]; GM_setValue(toSave,saves); refreshList(ssl,toSave); if(toSave==='autosaves') feedback(ssl,'自动存档成功。'); if(toSave==='selfsaves') feedback(ssl,'手动存档成功。'); } //删除 function deleteData(ssl){ const [save,time,saves,fromSave]=checkSave(ssl); if(!save) return; delete saves[time]; GM_setValue(fromSave,saves); refreshList(ssl); feedback(ssl,'删除成功。'); } //检查存档有效性 function checkSave(ssl){ if(ssl.find('input[name=saves]:checked').length===0){ feedback(ssl,'请选择存档!'); return []; } const fromSave=ssl.find('input[name=saves]:checked').parents('tbody').attr('id'); const saves=GM_getValue(fromSave,{}); const time=ssl.find('input[name=saves]:checked').parent().next().text(); if(!Object.keys(saves).includes(time)){ feedback(ssl,'无此存档!(可能已被覆盖)'); return []; } return [saves[time],time,saves,fromSave]; } //操作反馈提示 function feedback(ssl,text,ifConfirm,yesFunc){ if(ssl.css('display')==='none') return;//界面隐藏时不提示 if(ssl.find('b#feedback').length===0){ ssl.find('div#tab').before('<b id=feedback style=margin:5px></b>'); } const b=ssl.find('b#feedback'); b.text(text).append('<br>'); if(ifConfirm){ $('<input type=button value=√ class="rm-btn rm-btn-default">').appendTo(b) .on('click',function(){ $(this).parents('b#feedback').remove(); yesFunc(); }); $('<input type=button value=× class="rm-btn rm-btn-default">').appendTo(b) .on('click',function(){ $(this).parents('b#feedback').remove(); }); b.children('input:button').css('margin','5px'); }else{ setTimeout(()=>{ b.remove(); },3e3); } } //将表头宽度同步为表身 function theadWidth(thead,tbody){ if(tbody.find('td').text()==='无数据!') return; thead.find('tr td').each(function(){ const i=$(this).index(); const w=getComputedStyle(tbody.children('tr:last').children()[i]).width; $(this).css('width',w); }); } //卸载报告存档 function unSURVEYSAVES(){ if(unsafeWindow.OSM||!$('form#frmSurvey').length) return; if($('div#surveySaves').length) $('div#surveySaves').remove(); if(document.location.href.includes('alias=survey.view')){ $('form#frmSurvey').off('click.autosave'); $('textarea.surveycomment,textarea.active').off('blur.autosave'); } } /*报告存档*/ /*8:PDF命名 function PDFRENAME(){ if(!document.location.href.includes('exportMultiplePDF.asp')) return; $('table#pdfconvertProcessTableAdv tr.reporttable_thead').append('<th id=downloadAll>'); $('<button style=font-size:10px;width:100px>命名并下载全部</button>').appendTo('table#pdfconvertProcessTableAdv th#downloadAll') .on('click',function(){ $(this).parent().parent().nextAll('tr').find('button').click(); }); $('table#pdfconvertProcessTableAdv a[id^=dlLinkAdv]').each(function(){ const a=$(this); const surveyid=a.attr('id').replace('dlLinkAdv',''); a.parent().after('<td id=download>'); const td=a.parent().next('td#download'); $('<button style=font-size:10px;width:100px>命名并下载</button>').appendTo(td) .on('click',function(){ if(a.attr('href')==='/surveyexport_pdf/done.asp?docID='){ $(this).text('请等待转化完成'); setTimeout(()=>{ $(this).text('命名并下载'); },1e3); }else{ $(this).text('下载中...'); fetchName(a,surveyid,$(this),0); } }); }); } function fetchName(a,surveyid,self,isInternal){ let name=$('textarea#naming_convention').val(); const field=new Set(name.match(/(?<=#\$FIELD\[)[A-Za-z0-9\._]+(?=\]\$#)/g)); if(field.size){ const fieldDict= isInternal? { 'DateSubmitted':'SurveyDateOrDueDate', 'TimeSubmitted':'SurveyDateOrDueDate', 'Campaign':'CampaignName', 'CustomProperty001':'LocationCustomPropertyValue001', 'CustomProperty002':'LocationCustomPropertyValue002', 'CustomProperty003':'LocationCustomPropertyValue003', 'CustomProperty004':'LocationCustomPropertyValue004', 'CustomProperty005':'LocationCustomPropertyValue005', 'CustomProperty006':'LocationCustomPropertyValue006', 'CustomProperty007':'LocationCustomPropertyValue007', 'CustomProperty008':'LocationCustomPropertyValue008', 'CustomProperty009':'LocationCustomPropertyValue009', 'CustomProperty010':'LocationCustomPropertyValue010', 'ExportServicePointsScored':'PrecalcScore', 'ExportServicePointsPossible':'PrecalcScoreOutOf' } : { 'SurveyInstanceID':'InstanceID', 'DateSubmitted':'Date', 'TimeSubmitted':'Time', 'LocationId':'Loc ID', 'LocationName':'Location Name', 'LocationAddress':'Location Address 1', 'LocationCity':'Location City', 'LocationCounty':'Location County', 'LocationState_Region':'Location State/Region', 'LocationPostalCode':'Location Postal Code', 'LocationCountry':'Location Country', 'SurveyTitle':'Title', 'CustomProperty001':'CustLocationProperty001', 'CustomProperty002':'CustLocationProperty002', 'CustomProperty003':'CustLocationProperty003', 'CustomProperty004':'CustLocationProperty004', 'CustomProperty005':'CustLocationProperty005', 'CustomProperty006':'CustLocationProperty006', 'CustomProperty007':'CustLocationProperty007', 'CustomProperty008':'CustLocationProperty008', 'CustomProperty009':'CustLocationProperty009', 'CustomProperty010':'CustLocationProperty010', 'ExportServicePointsScored':'PrecalcPts', 'ExportServicePointsPossible':'PrecalcPtsOf', 'ExportServiceScorePercentXX':'PrecalcScorePctXX', 'ExportServiceScorePercentXX.X':'PrecalcScorePctXX.X', 'ExportServiceScorePercentXX.XX':'PrecalcScorePctXX.XX' }; const qSet=new Set(); for(let i of field){ if(isInternal){ if(i.includes('ServiceScorePercentXX')){ qSet.add('PrecalcScore'); qSet.add('PrecalcScoreOutOf'); continue; } } if(fieldDict[i]) i=fieldDict[i]; qSet.add(i); } let query=''; for(let i of qSet) query+='['+i+'],'; query=query.slice(0,-1); const api= isInternal? '/Apps/SM/APIv2/Query/Operations/Operations' : '/Apps/SM/APIv2/Query/ClientAnalytics/ClientAnalytics'; $.get(` /open/data.asp?post={ "action":"exec", "dataset":{"datasetname":"${api}"}, "parameters":[ {"name":"QuerySpecification","value":"${query}"}, {"name":"SurveyInstanceIDs","value":"${surveyid}"} ] }`,data=>{//调用API获取当前survey数据(客户端和内部端由于权限不同需要使用不同api) if(!isInternal&&data.dataset.data[0].length===0){//如客户端api返回无数据则用内部端再尝试 fetchName(a,surveyid,self,1); }else if(isInternal&&data.dataset.data[0].length===0){//如内部端api返回无数据则报错 download(a.attr('href'),name+'.pdf',()=>{self.text('无法获取命名数据');}); return; } const info=data.dataset.data[0][0]; for(let i of field){ const tmp=i; if(fieldDict[i]) i=fieldDict[i]; let r; if(isInternal&&tmp.includes('Submitted')){ if(tmp==='DateSubmitted') r=info[i].split(' ')[0]; if(tmp==='TimeSubmitted') r=info[i].split(' ')[1]; }else if(tmp.includes('ServiceScorePercentXX')){ if(isInternal){ r=Number(info.PrecalcScore)/Number(info.PrecalcScoreOutOf)*100; if(tmp==='ExportServiceScorePercentXX') r=r.toFixed(0)+'%'; if(tmp==='ExportServiceScorePercentXX.X') r=r.toFixed(1)+'%'; if(tmp==='ExportServiceScorePercentXX.XX') r=r.toFixed(2)+'%'; }else{ r=info[i]+'%'; } }else{ r=info[i]; } name=name.replaceAll(`#$FIELD[${tmp}]$#`,r); } download(a.attr('href'),name+'.pdf',()=>{self.text('命名并下载〇');}); },'json'); }else{ download(a.attr('href'),name+'.pdf',()=>{self.text('命名并下载〇');}); } } function download(url,filename,done){//done()为执行完毕后执行的函数 getBlob(url,function(blob){ saveAs(blob,filename,done); }); } function getBlob(url,cb){ const xhr=new XMLHttpRequest(); xhr.open('GET',url,true); xhr.responseType='blob'; xhr.onload=function(){ if (xhr.status === 200){ cb(xhr.response); } }; xhr.send(); } function saveAs(blob,filename,done){ if (window.navigator.msSaveOrOpenBlob){//Firefox&IE navigator.msSaveBlob(blob,filename); }else{ const link=document.createElement('a'); const body=document.querySelector('body'); link.href=window.URL.createObjectURL(blob); link.download=filename; link.style.display='none'; body.appendChild(link); link.click(); body.removeChild(link); window.URL.revokeObjectURL(link.href); } done(); } //卸载PDF命名 function unPDFRENAME(){ if(!document.location.href.includes('exportMultiplePDF.asp')) return; $('table#pdfconvertProcessTableAdv th#downloadAll').remove(); $('table#pdfconvertProcessTableAdv td#download').remove(); } /*PDF命名*/ /*9:优化表头*/ function BETTERTHEAD(){ if($('table.sticky-thead,#rollupTable').length){ $('table.sticky-thead,#rollupTable').each(function(){ execBetterThead(this); }); } if(!$('table.persist-area').length&&!document.location.href.includes('alias=client.analysiscustomrollups.3.0')) return; unsafeWindow.betterThead_observer=new MutationObserver(function(mutationsList){ for(let m of mutationsList) execBetterThead(m.target); }); unsafeWindow.betterThead_observer.observe(document.body, {childList: true, subtree: true}); } //根据情况执行优化表头 function execBetterThead(ele){ let oTable,oDiv; if(ele.className==='sticky-thead'){ oTable=$(ele).prev('table.sticky-enabled'); oTable.children('thead').css({position:'sticky',top:$('#menu').height()||0}); $(ele).hide(); oDiv=oTable.parents('div.q2r_tableHolder').children('[class^=q2r_tableCaptionDiv]'); if(oDiv.attr('class')==='q2r_tableCaptionDiv_without_text') oDiv.attr('class','q2r_tableCaptionDiv'); } if(ele.id==='rollupTable'){ oTable=$(ele).find('table#smReporttableTable'); oDiv=oTable.prev(); } if(!oTable||!oTable.length||!oDiv||!oDiv.length) return; if(oDiv[0].settle) return; oDiv[0].settle=1; oDiv.css('cursor','pointer').attr('title','显示/隐藏列').on('click.tableCaptionDivFunc',function(){ tableCaptionDivFunc(this,oTable); }); } //表头标题点击功能 function tableCaptionDivFunc(oDiv,oTable){ const next=$(oDiv).next(); if(next.attr('id')==='hideOption'){ if(next.css('display')==='none'){ if(oTable.find('thead>tr>td').length+1===next.find('tr').length) next.show(); else{ next.remove(); tableCaptionDivFunc(oDiv,oTable); } }else{ next.hide(); } }else{ let hideOption='<div id=hideOption><table><thead class=persist-header>',i=0; const show=[]; oTable.find('thead>tr>td').each(function(){ if(this.style.display!='none') show.push(i); hideOption+= `<tr> <td><input type=checkbox value=${i++}></td> <td>${this.textContent}</td> </tr>`; }); next.before(hideOption); const inputs=next.prev('div#hideOption').css({position:'absolute',/*top:tableCaptioDiv.clientHeight,*/zIndex:1,overflow:'scroll',maxHeight:'300px',background:'white'}) .find('input').on('click',function(){ toggleCol(this,oTable); }); next.prev('div#hideOption').find('thead').prepend( `<tr> <td><input type=checkbox checked></td> <td><b>全选/取消全选</b></td> </tr>`) .find('input').eq(0).on('click',function(){ if($(this).is(':checked')){ inputs.each(function(){ if(!$(this).is(':checked')) this.click(); }); }else{ inputs.each(function(){ if($(this).is(':checked')) this.click(); }); } }); for(let s of show) next.prev('div#hideOption').find('input').eq(s+1).prop('checked',true); } } //显示隐藏列 function toggleCol(checkbox,oTable){ if($(checkbox).is(':checked')){ oTable.find('tr').each(function(){ $(this).children().eq(checkbox.value).show(); }); }else{ oTable.find('tr').each(function(){ $(this).children().eq(checkbox.value).hide(); }); } } //卸载优化表头 function unBETTERTHEAD(){ $('table.sticky-enabled>thead').css({position:'',top:''}); $('table.sticky-thead').show(); if($('div#hideOption').length){ $('div#hideOption').find('input').each(function(){ if(!$(this).is(':checked')) this.click(); }); $('div#hideOption').remove(); } const oDiv1=$('table.sticky-enabled').parents('div.q2r_tableHolder').children('[class^=q2r_tableCaptionDiv]').css('cursor','').attr('title',null).off('click.tableCaptionDivFunc'); const oDiv2=$('table#smReporttableTable').parent('div#resultsTable').children('div#smAnalysisCustomRollupsTableDiv').css('cursor','').attr('title',null).off('click.tableCaptionDivFunc'); $(oDiv1,oDiv2).each(function(){delete this.settle;}); if(unsafeWindow.betterThead_observer) unsafeWindow.betterThead_observer.disconnect(); } /*优化表头*/ /*10:外观效果*/ function CSSEFFECT(){ iframeInject(); let css=''; if(GM_getValue('外观效果_夜间模式',0)){ const darkExclEle=[ 'img', 'video', 'option', 'canvas', 'div#menu', 'div#cover', 'ul.innerItemFirst', 'ul.textArea', 'code>iframe', '#ResourceSectionDiv>iframe', 'div#graphicPlaceHolder', 'div.picker', 'div.swatch', 'div.shape', ]; const darkExtraCSS='ul.textArea img{filter:none}option{background:black !important;color:white}'; css+='html,'+darkExclEle.toString()+'{filter:invert(1) hue-rotate(180deg)}'+darkExtraCSS; if(document.location.href.includes('surveyexport_pdf/exportMultiplePDF.asp')) css+='body{background:white}'; } if(GM_getValue('外观效果_隐藏logo',0)) css+='#sm_headerLogoTable{display:none}#addInfo{height:0 !important}#menu,#cover{top:0 !important}'; if(style&&$('#'+style.id).length&&css===style.textContent) return; if(style) style.remove(); style=GM_addStyle(css); } //为特定iframe注入css function iframeInject(){ const list={ 'iframe#id_iframe_select_language':'img{filter:invert(1) hue-rotate(180deg)}', }; for(let selector in list){ const iframe=document.querySelector(selector); if(!iframe) continue; if(iframe.darkCSS) continue; iframe.addEventListener('load',()=>{ const style=document.createElement('style'); style.textContent=list[selector]; iframe.contentDocument.head.append(style); }); iframe.darkCSS=true; } } //卸载外观效果 function unCSSEFFECT(){ if(style) style.remove(); } /*外观效果*/ /*11:图片编辑*/ function IMAGEEDIT(){ if(!document.location.href.includes('MystImageUpload/upload_modify.asp')) return; $('div#shape-controls').on('click.shapeControls',function(e){ if(e.target.className!=='picker') return; $(this).off('click.shapeControls'); $('div#colorPicker_palette-2').append($('div#colorPicker_palette-0').children()); $('div#colorPicker_palette-0').append($('div#colorPicker_palette-2').children(':nth-child(-n+2)')); }); } //卸载图片编辑 function unIMAGEEDIT(){ if(!document.location.href.includes('MystImageUpload/upload_modify.asp')) return; $('div#shape-controls').off('click.shapeControls'); $('div#colorPicker_palette-0').append($('div#colorPicker_palette-2').children()); $('div#colorPicker_palette-2').append($('div#colorPicker_palette-0').children(':nth-child(-n+2)')); } /*图片编辑*/ /*12:预览报告*/ function REPORTCONTENT(){ if(!document.location.href.includes('alias=smngr.opermgmt')) return; if($('table#reporttable>tbody>tr').length&&!$('table#reporttable>tbody>tr>td.q2r_NoEntriesFound').length){ const li=$('<li style=cursor:pointer id=tabButton3><a>报告内容</a></li>'); $('li#tabButton2').after(li); li.on('click',function(){ let tabPage3Div=$('div#tabPage3Div'); if(!tabPage3Div.length){ tabPage3Div=$( `<div id=tabPage3Div style=display:none> <button type=button id=reportContent class="rm-btn rm-display-block rm-btn-default rm-btn-success">显示内容</button> </div>` ); $('div#tabPage2Div').before(tabPage3Div); tabPage3Div.children('button#reportContent').on('click',function(){ showReportContent($(this),tabPage3Div); }); $('li#tabButton1,li#tabButton2').on('click',()=>{ this.className=''; tabPage3Div.hide(); }); } $('li#tabButton1,li#tabButton2').attr('class',''); this.className='active'; $('div#tabPage1Div,div#tabPage2Div').hide(); tabPage3Div.show(); }); } } //显示内容 function showReportContent(reportContentBtn,tabPage3Div){ reportContentBtn.attr('disabled',1).text('......'); //记录并监听请求数和是否正在渲染表格 tabPage3Div.tmp={ request:$('table#reporttable>tbody>tr').length, rendering:0, renderList:[], scoreData:null }; let tmp=tabPage3Div.tmp; Object.defineProperty(tabPage3Div,'tmp',{ get(){ return tmp; }, set(newValue){ tmp=newValue; if(!newValue.rendering&&newValue.renderList.length){ const toRender=newValue.renderList.shift(); handleSurveyData(toRender.data,toRender.surveyInsID,tabPage3Div); } if(!newValue.request&&newValue.scoreData){ outputScoreData(handleScoreData(newValue.scoreData)); reportContentBtn.attr('disabled',null).text('显示内容'); tabPage3Div.find('#currnumofrecs').text($('table#reporttable>tbody>tr').length); downloadBtn(); initReportTable(document.querySelector('#reporttable_rc')); execBetterThead(tabPage3Div.find('table.sticky-thead')[0]); } } }); //首次执行先添加必要组件 if(tabPage3Div.children().length<2){ tabPage3Div.append( `<div class=rm-margin-bottom-xlarge></div> <span id=recordsnum style=font:Icon;font-size:11px>Number of Records: <span id=currnumofrecs></span></span> <a target=_blank id=download_rc> <img class=download_excel_button style=width:16px;height:16px;border:0px title=下载表格 src=/images/icons/q2r/blank.png> </a> <div style="z-index:999;padding-top:4px;border:1px solid;background:ButtonFace;border-color:#AFAFAF #666666 #666666 #AFAFAF;position:absolute;layer-background-color:#C0C0C0;visibility:hidden;width:438px" name=filterdiv id=filterdiv></div> <div class="q2r_tableHolder reporttable" style=position:relative;display:table> <div class=q2r_tableCaptionDiv style=text-align:left>报告内容</div> <div> <table width=100% class="reporttable persist-area sticky-enabled" id=reporttable_rc cellspacing=0 style=margin:0px;width:100%> <table class=sticky-thead></table> <style> #reporttable_rc>tbody td>table td{white-space:nowrap} #reporttable_rc>tbody div{min-width:200px;max-height:140px;overflow:scroll} </style> </div> </div>` ); } //复制表格隐藏若干列后匹配报告id并发送请求 const surveyInsIDArr=[]; tabPage3Div.find('table#reporttable_rc').empty().append($('table#reporttable').html()).find('tr').each(function(){ if($(this).find('a').attr('href')){//tbody>tr const match=$(this).find('a').attr('href').match(/(?<=InstanceID=)\d+/); $.get( `/open/data.asp?post={ "action":"exec", "JSONPath":"dataset.data", "dataset":{"datasetname":"/Apps/SM/Survey/SurveyInstanceGetData"}, "parameters":[{"name":"SurveyInstanceID","value":"${match[0]}"}] }`,data=>{ if(!tabPage3Div.tmp.rendering&&!tabPage3Div.tmp.renderList.length){ handleSurveyData(data,match[0],tabPage3Div); }else{ tabPage3Div.tmp.renderList.push({ data:data, surveyInsID:match[0] });//若正在渲染或队列不为空则加入队列 } },'json'); this.id='surveyInsID'+match[0]; surveyInsIDArr.push(match[0]); $(this).children('td').eq(0).css({position:'sticky',left:0,background:'#E4E4E4'});//冻结tbody第一列 $(this).append('<td id=totalScore></td>'); }else{//thead>tr $(this).children('td').each(function(){ $(this).text(this.textContent); }); $(this).append(`<td id=totalScore onMouseover=addClassName(this,'reporttable_headerhover'); onMouseout=removeClassName(this,'reporttable_headerhover'); style=text-transform:none;>总分</td>`); } $(this).children('td').each(function(){ if(![0,1,2,19,20].includes(this.cellIndex)) $(this).hide();//隐藏4-19列 }); }); tabPage3Div.find('table#reporttable_rc>thead').css('zIndex',1);//置于冻结的第一列之上 $.get( `/open/data.asp?post={ "action":"exec", "JSONPath":"dataset.data.0", "dataset":{"datasetname":"/Apps/SM/APIv2/Query/Operations/Operations"}, "parameters":[ {"name":"QuerySpecification","value":"[ProtoSurveyID]"}, {"name":"SurveyInstanceIDs","value":"${surveyInsIDArr.toString()}"} ] }`,data=>{ const surveyIDArr=[]; for(let i of data) if(!surveyIDArr.includes(i.ProtoSurveyID)) surveyIDArr.push(i.ProtoSurveyID); getScoreData(surveyIDArr,scoreData=>{ tabPage3Div.tmp={ request:tabPage3Div.tmp.request, rendering:tabPage3Div.tmp.rendering, renderList:tabPage3Div.tmp.renderList, scoreData:scoreData }; }); },'json'); } //处理返回的报告数据 function handleSurveyData(data,surveyInsID,tabPage3Div){ tabPage3Div.tmp={ request:tabPage3Div.tmp.request, rendering:1, renderList:tabPage3Div.tmp.renderList, scoreData:tabPage3Div.tmp.scoreData }; const table=tabPage3Div.find('table#reporttable_rc'); const theadAttr=`onMouseover=addClassName(this,'reporttable_headerhover'); onMouseout=removeClassName(this,'reporttable_headerhover'); style=text-transform:none;`; //处理问题内容和模块分割 for(let q of data[0]){ if(!table.find(`td[id="SEC_${q.SectionLevel1Title}"]`).length){ table.find('thead>tr').append(`<td id="SEC_${q.SectionLevel1Title}" ${theadAttr}>${q.SectionLevel1Title}<br>(模块)</td>`); table.find('tbody>tr[id^=surveyInsID]').append(`<td id="SEC_${q.SectionLevel1Title}"></td>`); } if(!table.find(`td[id^=QID${q.QuestionID}][section="${q.SectionLevel1Title}"]`).length){ const headAtd=`<td id=QID${q.QuestionID}ANS section="${q.SectionLevel1Title}" ${theadAttr}display:none>${q.Text}<br>(选项)</td>`; const bodyAtd=`<td id=QID${q.QuestionID}ANS section="${q.SectionLevel1Title}" style=display:none></td>`; const headCtd=`<td id=QID${q.QuestionID}CMT section="${q.SectionLevel1Title}" ${theadAttr}display:none>${q.Text}<br>(评论)</td>`; const bodyCtd=`<td id=QID${q.QuestionID}CMT section="${q.SectionLevel1Title}" style=display:none></td>`; const sectionTD=table.find(`thead td[section="${q.SectionLevel1Title}"]`); /*按模块内文本排序插入 if(tabPage3Div.tmp.request<$('table#reporttable>tbody>tr').length&§ionTD.length){ let cellIndex; for(let i=sectionTD.length-1;i>=0;i--){ if(q.Text>sectionTD.eq(i).text()){ cellIndex=sectionTD[i].cellIndex; break; }else if(!i){ cellIndex=sectionTD[i].cellIndex-1; } } */ if(sectionTD.length){ const cellIndex=sectionTD.last()[0].cellIndex; //在模块后方直接插入↑ table.find('thead td').eq(cellIndex).after(headCtd).after(headAtd); table.find(`tbody>tr[id^=surveyInsID]>td:nth-child(${cellIndex+1})`).after(bodyCtd).after(bodyAtd); }else{ table.find('thead>tr').append(headAtd).append(headCtd); table.find('tbody>tr[id^=surveyInsID]').append(bodyAtd).append(bodyCtd); } } } //处理问题选项 for(let a of data[1]){ table.find('td#QID'+a.ProtoQuestionID+'ANS').show(); const atd=table.find('tbody>tr#surveyInsID'+surveyInsID+'>td#QID'+a.ProtoQuestionID+'ANS'); if(atd.text()){ const tds=atd.find('td'); tds[0].textContent+=','+a.AnswerPosID; tds[1].textContent+=','+a.Description; tds[2].textContent+=','+a.Measure; }else{ atd.html(`<table><tbody> <tr><td>位置:${a.AnswerPosID}</td></tr> <tr><td>内容:${a.Description}</td></tr> <tr><td>分值:${a.Measure}</td></tr> </tbody></table>`); } } //处理问题评论 for(let c of data[2]){ table.find('td#QID'+c.ProtoQuestionID+'CMT').show(); table.find('tbody>tr#surveyInsID'+surveyInsID+'>td#QID'+c.ProtoQuestionID+'CMT').html(`<div>${c.CommentField}</div>`); } //处理附件 /*for(let f of data[3]){ }*/ tabPage3Div.tmp={ request:tabPage3Div.tmp.request-1, rendering:0, renderList:tabPage3Div.tmp.renderList, scoreData:tabPage3Div.tmp.scoreData }; } //表头筛选排序 function initReportTable(tableEle){ const [SortableTable,getCheckBoxValue,removeClassName,addClassName]=[unsafeWindow.SortableTable,unsafeWindow.getCheckBoxValue,unsafeWindow.removeClassName,unsafeWindow.addClassName]; /*修改筛选逻辑 let getDistinct=SortableTable.prototype.getDistinct.toString(); getDistinct=getDistinct.replace('//\t\twindow.alert("row "+i+ " display: "+rows[i].style.display)','if(rows[i].style.display==="none"&&!String(rows[i].getAttribute("filtered")).includes(nColumn)) continue'); eval('SortableTable.prototype.getDistinct='+getDistinct); let doFilter=SortableTable.prototype.doFilter.toString(); doFilter=doFilter.replace(/rowsToKeepVisible.indexOf\(":"\+i\+":"\) =/g,'rowsToHide.indexOf(":"+i+":") !'); doFilter=doFilter.replace(/rowsToKeepVisible.indexOf\(":"\+i\+":"\) !/g,'rowsToHide.indexOf(":"+i+":") ='); eval('SortableTable.prototype.doFilter='+doFilter); */ //初始化 var h=tableEle; var st1=new SortableTable(h,1,"True","true",new Array($(h).find('thead td').length).fill('String')); // restore the class names st1.addSortType("CheckBox", null, null, getCheckBoxValue); if (/MSIE/.test(navigator.userAgent)) { st1.onbeforesort = function () { var table = st1.element; var inputs = table.getElementsByTagName("INPUT"); var l = inputs.length; for (var i = 0; i < l; i++) inputs[i].parentNode.parentNode._checked = inputs[i].checked; }; st1.onsort = function () { var rows = st1.tBody.rows; var table = st1.element; var inputs = table.getElementsByTagName("INPUT"); var l = inputs.length; for (var i = 0; i < rows.length; i++) { removeClassName(rows[i], i % 2 ? "filter_odd" : "filter_even"); addClassName(rows[i], i % 2 ? "filter_even" : "filter_odd"); } for (var j = 0; j < l; j++) inputs[j].checked = inputs[j].parentNode.parentNode._checked; }; } else { st1.onsort = function () { var rows = this.tBody.rows; var l = rows.length; var cnt = 0; for (var i = 0; i < l; i++) { if(rows[i].style.display != "none") { cnt++; removeClassName(rows[i], cnt % 2 ? "reporttable_even" : "reporttable_odd"); addClassName(rows[i], cnt % 2 ? "reporttable_odd" : "reporttable_even"); } } }; } } //下载表格 function downloadBtn(){ const table=$('table#reporttable_rc').clone(); table.attr('border',1); table.find('br').before('\n').remove(); table.find('td').each(function(){ if($(this).find('a').length) return; this.setAttribute('style','mso-number-format:"\@";height:40px;vertical-align:top'); this.textContent=this.textContent; }); table.find('thead td').css('fontWeight','bold'); table.find('a').each(function(){ this.href=this.href; }); //'<html><head><meta charset=utf-8></head><body>'+'</body></html>'; const blob=new Blob([table[0].outerHTML],{type:"application/vnd.ms-excel"}); const aBtn=document.querySelector('a#download_rc'); aBtn.href=URL.createObjectURL(blob); aBtn.download=new Date().toLocaleString()+'.xls'; } function getScoreData(surveyIDArr,func){ const postJSON={//超过get上限 action: "exec", JSONPath:"dataset.data", dataset : {datasetname : "/Apps/SM/APIv2/Query/Projects/FormElements"}, parameters: [ {name: "FormIDs",value: surveyIDArr.toString()}, {name: "IsIncludeForms",value: 0}, {name: "IsIncludeFormElements",value: 0}, {name: "IsIncludeFormElementTypes",value: 0}, {name: "IsIncludeFormQuestionAnswers",value: 1}, {name: "IsIncludeQuestionProperties",value: 0}, {name: "IsIncludeQuestionAnswerSetsProperties",value: 1}, {name: "IsIncludeGridProperties",value: 0}, {name: "IsIncludeLoopProperties",value: 0}, {name: "IsIncludeFormQuestionCategories",value: 0}, {name: "IsIncludeFormQuestionProperties",value: 0}, {name: "IsIncludeFormElementsParentSections",value: 0}, {name: "IsIncludeFormVisibility",value: 0}, {name: "IsIncludeFormQuestionVisibility",value: 0} ] }; $.post('/open/data.asp','post='+JSON.stringify(postJSON),data=>{ func(data); },'json'); } //处理分数信息 function handleScoreData(data){ const QAInfo={A2Q:{},Q2A:{}}; const Q2A=QAInfo.Q2A; for(let i in data[3]){ const a=data[3][i]; QAInfo.A2Q[a.AnswerSetID]=a.QuestionID; if(!Q2A[a.QuestionID]) Q2A[a.QuestionID]={}; Q2A[a.QuestionID].AnswerSetID=a.AnswerSetID; if(!Q2A[a.QuestionID].Answer) Q2A[a.QuestionID].Answer={}; if(!Q2A[a.QuestionID].Answer[a.Position]) Q2A[a.QuestionID].Answer[a.Position]={}; Q2A[a.QuestionID].Answer[a.Position].Measure=a.Measure; Q2A[a.QuestionID].Answer[a.Position].Text=a.Text; //Q2A[a.QuestionID].Answer[a.Position].ObjectName=a.ObjectName; //Q2A[a.QuestionID].Answer[a.Position].FormID=a.FormID; } for(let j in data[5]){ const s=data[5][j]; const qid=QAInfo.A2Q[s.AnswerSetID]; if(!qid) continue; Q2A[qid].IsMultipleSelection=s.IsMultipleSelection; Q2A[qid].IsBonusPenalty=s.IsBonusPenalty; Q2A[qid].CustomPointsPossible=s.CustomPointsPossible; Q2A[qid].IsLimitedMeasure=s.IsLimitedMeasure; Q2A[qid].LimitMeasureMinimum=s.LimitMeasureMinimum; Q2A[qid].LimitMeasureMaximum=s.LimitMeasureMaximum; Q2A[qid].StartingPoints=s.StartingPoints; Q2A[qid].IsShowMeasure=s.IsShowMeasure; } return Q2A; } //将分数信息写入表格 function outputScoreData(Q2A){ const table=$('table#reporttable_rc'); table.children('tbody').children('tr').each(function(){ const totalScore={ total:{pts:0,ptsOf:0}, section:{} }; $(this).children('td[id$=ANS]').each(function(){ if(!this.textContent) return; const arrSelPos=$(this).find('td').eq(0).text().replace('位置:','').split(','); const score=caculateScore(arrSelPos,Q2A[this.id.replace(/^QID|ANS$/g,'')]); $(this).find('tbody').append(`<tr><td>分数:${score[0]}/${score[1]}</td></tr>`); totalScore.total.pts+=score[0]; totalScore.total.ptsOf+=score[1]; const section=this.getAttribute('section'); if(!totalScore.section[section]) totalScore.section[section]={pts:0,ptsOf:0}; totalScore.section[section].pts+=score[0]; totalScore.section[section].ptsOf+=score[1]; }); $(this).children('td#totalScore').text(`${(totalScore.total.pts/totalScore.total.ptsOf*100).toFixed(1)}%(${totalScore.total.pts}/${totalScore.total.ptsOf})`); for(let s in totalScore.section){ $(this).children(`td[id="SEC_${s}"]`).text(`${(totalScore.section[s].pts/totalScore.section[s].ptsOf*100).toFixed(1)}%(${totalScore.section[s].pts}/${totalScore.section[s].ptsOf})`); } }); } //计算pts和ptsOf function caculateScore(arrSelPos,oQid){ if(arrSelPos[0]==='') return [null,null]; if(arrSelPos.includes('0')) return [0,0]; let [pts,ptsOf]=[0,0]; if(oQid.StartingPoints) pts=oQid.StartingPoints; if(oQid.IsMultipleSelection){ for(let s of arrSelPos) pts+=oQid.Answer[s].Measure; for(let a in oQid.Answer) ptsOf+=oQid.Answer[a].Measure; }else{ pts=oQid.Answer[arrSelPos[0]].Measure||0; for(let a in oQid.Answer) if(oQid.Answer[a].Measure>ptsOf) ptsOf=oQid.Answer[a].Measure; } if(oQid.IsLimitedMeasure&&oQid.LimitMeasureMinimum>pts) pts=oQid.LimitMeasureMinimum; if(oQid.IsLimitedMeasure&&oQid.LimitMeasureMaximum<pts) pts=oQid.LimitMeasureMaximum; if(oQid.IsBonusPenalty) ptsOf=oQid.CustomPointsPossible; return [pts,ptsOf]; } //卸载预览报告 function unREPORTCONTENT(){ if($('div#tabPage3Div,li#tabButton3').length) $('div#tabPage3Div,li#tabButton3').remove(); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址