// ==UserScript==
// @name minerva-online assistant
// @namespace https://space.bilibili.com/17846288
// @version 2.9.6
// @license MIT
// @description 此脚本能更方便使用minerva-online平台,可在顶端菜单栏右下角的按钮处设置功能开关,并查看功能详情
// @author inoki
// @match https://www.minerva-online.com/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// @connect fanyi.baidu.com
// @noframes
// ==/UserScript==
/* VersionInfo 企业微信文档:https://doc.weixin.qq.com/doc/w2_AOMADQamAG8fAzy6aF1RWWmEc2ZhG?scode=AMwAwgcrABEDCapPcV
优化表头:在页面中有多个表格的情况下现在将正确处理
定制汇总:【选项统计】修正样本量由于隐藏的span标签造成叠加的问题
*/
/*jshint esversion: 9*/
(()=>{
'use strict';
if(document.location.href.includes('alias=filemanager')){
unsafeWindow.userIsEnterpriseAdmin=true;
return;
}
const OSM=unsafeWindow.OSM;//如存在则为v3问卷
const SET={
0:{
'id':0,
'name':'置顶置底',
'func':()=>{GOTOPBOTTOM();},
'unfunc':()=>{unGOTOPBOTTOM();},
'detail':
`在平台域名所有可滚动页面生效,页面右下方添加【∨】/【∧】按钮<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':
`在问卷管理页面生效,每份报告前添加【↓】按钮<br>
【↓】点击可加载附件列表<br>
【√】点击可下载全部附件,之后会变为【〇】<br>
【×】点击可关闭附件列表<br>
附件名点击可下载单个附件,鼠标悬停可预览图片<br>
【删除全部附件】点击可将此报告全部附件标记为删除`,
'switch':1
},
3:{
'id':3,
'name':'扣分标记',
'func':()=>{if(!OSM) MARKQUESTION();},
'unfunc':()=>{if(!OSM) unMARKQUESTION();},
'detail':
`在单店报告页面生效,可醒目标记扣分或N/A的题目,方便快速检查相关题评论<br>
将题目中勾选扣分和N/A项标色,选项更改后需保存报告才会刷新标记<br>
可在上方设置扣分(默认为红)和N/A(默认为绿)的标记颜色,点击【√】保存更改<br>
颜色更改后关闭再开启此功能可在报告页面即时刷新颜色<br>
星期选项与日期不匹配时也将以扣分颜色标记,匹配时将在后方显示绿色√`,
'switch':1
},
4:{
'id':4,
'name':'评论编辑',
'func':()=>{if(!OSM) COMMENTEDIT();},
'unfunc':()=>{if(!OSM) unCOMMENTEDIT();},
'detail':
`在单店报告页面生效,右下方【问卷图标】<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':
`在问卷管理页面生效,表头上方添加【验证输出勾选的报告】按钮<br>
【验证输出勾选的报告】点击并确认后会验证输出当前页面勾选的所有报告,成功输出的报告下方小窗口会显示绿色提示<br>
(电脑配置较低时一次输出太多份可能导致页面卡死,请根据浏览器最多同时能开几个报告页面量力而行,默认关闭)`,
'switch':0
},
6:{
'id':6,
'name':'定制汇总',
'func':()=>{CUSTOMROLLUP();},
'unfunc':()=>{unCUSTOMROLLUP();},
'detail':
`在定制汇总页面生效,在汇总表格上方添加功能按钮<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>加载选项后,可在统计中显示数量为0的选项`,
'switch':1
},
7:{
'id':7,
'name':'报告存档',
'func':()=>{if(!OSM) SURVEYSAVES();},
'unfunc':()=>{if(!OSM) unSURVEYSAVES();},
'detail':
`在单店报告页面生效,右下方【书本图标】<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>
【命名并下载全部】点击相当于一键点击了所有【命名并下载】`,
'switch':1
},
9:{
'id':9,
'name':'优化表头',
'func':()=>{BETTERTHEAD();},
'unfunc':()=>{unBETTERTHEAD();},
'detail':
`在所有含有页面滚动时自动冻结表头功能的页面生效(例:问卷管理)<br>
点击表头上方【标题】行可显示表格所有列的表头内容,根据其勾选状态与否可显示/隐藏对应列<br>
优化冻结表头的表现,使冻结的表头不再像原先那样闪烁,且在冻结状态下也能执行排序/筛选功能<br>
(优化冻结表头在部分浏览器可能不支持,若无效建议使用最新版chrome/edge浏览器体验)`,
'switch':1
},
};
//用于打印脚本简介
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;
};
//如网页无jQuery或版本低于1.7则引入1.8.2
var $=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();
/*在顶端菜单栏添加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);
}
//鼠标聚焦时显示详情 【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=√ 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=√ 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);
}
});
}
/*在顶端菜单栏添加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权限*/
/*置顶置底*/
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.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:'0px'},clickScrollTime);
}else{
$('html,body').animate({scrollTop:$(document).height()},clickScrollTime);
}
});
//右键按钮记录页面位置
const lock=$(goTopBottomButton).clone().attr('id','goTopBottomLock').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();
}
/*置顶置底*/
/*菜单遮罩*/
function COVERMENU(){
if($('div#menu').length){
//若存在menu则添加cover层
const menu=$('div#menu')[0];
const zidx=parseInt(getComputedStyle(menu).zIndex)+1;
const cover = document.createElement('div');
cover.className = 'layout';
cover.style = 'top:'+menu.style.top+';opacity:0.3;z-index:'+zidx+';right:10%';
$(cover).appendTo($('body')[0]).attr('id','cover');
//点击时将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).scroll(()=>{
const SM=unsafeWindow.SM;
const ind = SM.ui.headerHeight - SM.ui.getScrollTop();
cover.style.top= ind>0? ind+'px' : '0px';
});
}
}
//卸载菜单遮罩
function unCOVERMENU(){
if($('div#cover').length) $('div#cover').remove();
}
/*菜单遮罩*/
/*附件下载*/
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));
});
$('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>↓</button>
</div>
</td>`);
$(this).parent().next().find('button#download').one('click',function(){
DownloadButton($(this).parent(),surveyid);//将$('div#'+surveyid)传参为df
});
});
}
//兼容inoki.va页面
if(document.location.href.includes('alias=inoki.va')){
let t=0;
const settle=setInterval(()=>{
if($('table#reporttable button#download').length||t++>9){
clearInterval(settle);
return;
}
if($('table#reporttable tr').length){
$('table#reporttable>thead>tr').each(function(){
$(this).children().first().before($(this).children().first().clone(true));
$(this).children().first().text('DownloadFile');
});
$('table#reporttable').find('tbody>tr').each(function(){//checkbox后添加下载按钮
const surveyid=$(this).attr('id');
$(this).prepend(`
<td>
<div id=${surveyid} class=downloadFile>
<button type=button id=download class=rm-btn>↓</button>
</div>
</td>`);
$(this).find('button#download').one('click',function(){
DownloadButton($(this).parent(),surveyid);//将$('div#'+surveyid)传参为df
});
});
}
},2e3);
}
}
//获取附件列表
function DownloadButton(df,surveyid){
df.find('button#download').hide();
df.append('<b id=loading>......</b>');
$.get(`
/open/data.asp?post={
"action":"exec",
"dataset":{"datasetname":"/Apps/SM/Survey/SurveyInstanceGetData"},
"parameters":[{"name":"SurveyInstanceID","value":"${surveyid}"}]
}`,(data,status)=>{//调用API获取当前survey数据[SurveyInstanceGetData]
if (status==='success'){
if(data?.dataset){
const filedata=data.dataset.data[3];
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">√</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+'px','left':event.clientX+100+'px'});
$('img#'+imgid+'.filepreview').show();
}else{
$('img.filepreview').hide();
}
}
//按钮变为关闭
function DownloadButton0(df,surveyid){
df.find('b#loading').remove();
df.find('button#download').text('×').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('↓').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){
const surveyid=df.attr('id');
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 (document.location.href.includes('alias=smngr.surveyexplorer')&&$('tr.persist-header').length){
$('tr.persist-header').each(function(){
$(this).children().first().remove();
});
$('div.downloadFile').each(function(){
$(this).parent().remove();
});
}
}
/*附件下载*/
/*扣分标记*/
function MARKQUESTION(){
if(document.location.href.includes('alias=survey.view')){
$('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(pts[0]<pts[1]){
const QidANS=$(this).parents('td.surveyquestioncell').prev().find('div').attr('id');
qidmark.push(QidANS);
}
}
});
for(let i in qidmark){
$('div#'+qidmark[i]).find('span.surveyansweroption').css('color',GM_getValue('扣分颜色:','red'));//默认标红扣分项
}
}
});
}
}
//检查所选星期和日期是否不一致
function checkDayofWeek(){
const qtx=['星期','Day of the week','Day of the Week','Day of week','Day 星期','周几'];
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!=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 unMARKQUESTION(){
if(document.location.href.includes('alias=survey.view')){
$('span.surveyansweroption').css('color','');
$('b#dayofweek').remove();
}
}
/*扣分标记*/
/*评论编辑*/
function COMMENTEDIT(){
if(document.location.href.includes('alias=survey.view')){
if(unsafeWindow.updrowH) $('textarea.surveycomment').each(function(){unsafeWindow.updrowH(this);});//等页面自身执行到调整评论框高度过于缓慢
$('<div id=commentEdit>').appendTo($('body')[0])
.css({'position':'fixed','zIndex':1e4+1,
'right':'30px','bottom':'80px','height':'25px','width':'25px',
'background':'url("/images/icons/menu/x32/survet.png") 50%/80% no-repeat #4C5157'});
//插入操作界面并赋值为ce
$('<div id=commentFunc>').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>↓↓↓</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','text-align':'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({'text-align':'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){
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($('div#commentEdit').length) $('div#commentEdit').remove();
}
/*评论编辑*/
/*验证输出*/
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('请确认是否要验证输出当前页面勾选的所有报告(电脑配置低请勿一次性输出过多报告)');
if(apply){
$('table#reporttable tbody').find('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><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();
}
/*验证输出*/
/*定制汇总*/
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).prev('textarea').hide();
window.getSelection().removeAllRanges();
document.execCommand('copy')?
$(this).text('复制成功!') : $(this).text('复制失败...');
setTimeout(()=>{
$(this).text('复制表格');
},3e3);
});
$(`<select id=percentSign>
<option value=+%>分数后+%</option>
<option value=无>无</option>
</select>`).appendTo(cr);
//精确pts%
$('<button type=button id=ptsPercPlus>精确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(!$('#reporttable>thead>tr>td.ptsPercPlus').length) 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()[pts].innerText/$(this).children()[ptsOf].innerText;//$.text()会包含<span>中的多余数据
tar.text((score*100).toFixed($(cr).children('select#toFixed').val())+'%');
}
});
$(this).text('计算成功!');
}else{
$(this).text('缺少Pts或PtsOf列!');
}
setTimeout(()=>{
$(this).text('精确pts%');
},3e3);
});
$('<select id=toFixed>').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>选项统计</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(){
const tbtd=$(this).children();
const Q=checkKey(AD,tbtd.eq(QText).text());
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('缺少QuestionText或AnswerText或#Surveys列!');
}
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();
}
/*定制汇总*/
/*报告存档*/
function SURVEYSAVES(){
if(document.location.href.includes('alias=survey.view')){
//插入操作界面并赋值为ssl
$('<div id=surveySaves>').appendTo($('body')[0])
.css({'position':'fixed','zIndex':1e4,
'right':'30px','bottom':'110px','height':'25px','width':'25px',
'background':'url("/images/icons/menu/x16/KB-icon.png") 50%/80% no-repeat #4C5157'});
$('<div id=surveySavesList>').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($('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');
}
}
/*报告存档*/
/*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命名*/
/*优化表头*/
function BETTERTHEAD(){
if($('table.sticky-thead').length){
$('table.sticky-enabled>thead').css({'position':'sticky','top':($('#menu').height()||0)+'px'});
$('table.sticky-thead').hide();
$('table.sticky-enabled').each(function(){
const prev=$(this).parent().prev();
if(prev.attr('class')==='q2r_tableCaptionDiv_without_text') prev.attr('class','q2r_tableCaptionDiv');
prev.css('cursor','pointer').on('click.tableCaptionDivFunc',function(){
tableCaptionDivFunc(this);
});
});
}
}
//表头标题点击功能
function tableCaptionDivFunc(tableCaptioDiv){
const next=$(tableCaptioDiv).next();
if(next.attr('id')==='hideOption'){
if(next.css('display')==='none'){
if($('table.sticky-enabled>thead>tr>td').length===next.find('tr').length) next.show();
else{
next.remove();
tableCaptionDivFunc(tableCaptioDiv);
}
}else{
next.hide();
}
}else{
let hideOption='<div id=hideOption><table><thead class=persist-header>',i=0;
const show=[];
next.find('table.sticky-enabled>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);
next.prev('div#hideOption').css({'position':'absolute','top':'0','z-index':'1','overflow':'scroll','max-height':'300px','background':'white'})
.find('input').on('click',function(){
toggleCol(this,next);
});
for(let s of show) next.prev('div#hideOption').find('input').eq(s).prop('checked',true);
}
}
//显示隐藏列
function toggleCol(checkbox,table){
if($(checkbox).is(':checked')){
table.find('tr').each(function(){
$(this).children().eq(checkbox.value).show();
});
}else{
table.find('tr').each(function(){
$(this).children().eq(checkbox.value).hide();
});
}
}
//卸载优化表头
function unBETTERTHEAD(){
if($('table.sticky-thead').length){
$('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();
}
$('table.sticky-enabled').parent().prev()
.css('cursor','')
.off('click.tableCaptionDivFunc');
}
}
/*优化表头*/
})();