// ==UserScript==
// @name minerva-online assistant
// @namespace https://space.bilibili.com/17846288
// @version 2.9.4
// @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
// @downloadURL none
// ==/UserScript==
/* VersionInfo 企业微信文档:https://doc.weixin.qq.com/doc/w2_AOMADQamAG8fAzy6aF1RWWmEc2ZhG?scode=AMwAwgcrABEDCapPcV
定制汇总:修正【选项统计】左侧无架构时无法正常生效的问题
【评论编辑】【报告存档】功能介绍说明框内添加图标
*/
/*jshint esversion: 9*/
(()=>{
'use strict';
if(document.location.href.indexOf('alias=filemanager')>0){
unsafeWindow.userIsEnterpriseAdmin=true;
return;
}
const OSM=unsafeWindow.OSM;//如存在则为v3问卷
const SET={
0:{
'id':0,
'name':'置顶置底',
'func':()=>{GOTOPBOTTOM();},
'unfunc':()=>{unGOTOPBOTTOM();},
'detail':
`在平台域名所有可滚动页面生效,页面右下方添加【∨】/【∧】按钮
【∨】/【∧】左键点击会根据页面滚动方向自动置顶或置底,按钮样式可在代码中自定义中修改
【∨】/【∧】右键点击会在左侧生成【>】按钮,再次右键点击会删除【>】图标
【>】生成时会记录当前页面位置,点击【>】将回到所记录的页面位置`,
'switch':1
},
1:{
'id':1,
'name':'菜单遮罩',
'func':()=>{COVERMENU();},
'unfunc':()=>{unCOVERMENU();},
'detail':
`在有顶端菜单栏的页面生效
让菜单栏需要点击一次后才可展开,防止鼠标经过时误触
(默认关闭)`,
'switch':0
},
2:{
'id':2,
'name':'附件下载',
'func':()=>{DOWNLOADFILE();},
'unfunc':()=>{unDOWNLOADFILE();},
'detail':
`在问卷管理页面生效,每份报告前添加【↓】按钮
【↓】点击可加载附件列表
【√】点击可下载全部附件,之后会变为【〇】
【×】点击可关闭附件列表
附件名点击可下载单个附件,鼠标悬停可预览图片
【删除全部附件】点击可将此报告全部附件标记为删除`,
'switch':1
},
3:{
'id':3,
'name':'扣分标记',
'func':()=>{if(!OSM) MARKQUESTION();},
'unfunc':()=>{if(!OSM) unMARKQUESTION();},
'detail':
`在单店报告页面生效,可醒目标记扣分或N/A的题目,方便快速检查相关题评论
将题目中勾选扣分和N/A项标色,选项更改后需保存报告才会刷新标记
可在上方设置扣分(默认为红)和N/A(默认为绿)的标记颜色,点击【√】保存更改
颜色更改后关开此功能可在报告页面即时刷新颜色
星期选项与日期不匹配时也将以扣分颜色标记`,
'switch':1
},
4:{
'id':4,
'name':'评论编辑',
'func':()=>{if(!OSM) COMMENTEDIT();},
'unfunc':()=>{if(!OSM) unCOMMENTEDIT();},
'detail':
`在单店报告页面生效,右下方【问卷图标】 按钮展开操作界面
使用前请注意阅读操作界面最上方的【点击获取提示】
【匹配/替换内容】框内输入内容将即时显示匹配的评论框数,并标灰评论框且在上方标记^^,鼠标悬停灰色评论框可预览替换后内容
【匹配内容】支持正则表达式(详见【点击获取提示】),可Ctrl+F使用浏览器自带功能搜索^^标记,以快速定位匹配到的评论框
【一键替换】点击可将所有匹配到的评论框内容修改为替换后内容,此时鼠标悬停灰色评论框可预览修改前内容
【首字母大写】点击可智能将所有句首英文字母变为大写,显示修改过的评论框数并标灰,此时鼠标悬停灰色评论框可预览修改前内容
【评论翻译】点击会调用百度翻译,在每个评论框下方输出目标语言翻译,点击↑可将下方内容添加至评论框`,
'switch':1
},
5:{
'id':5,
'name':'验证输出',
'func':()=>{VERIFYEXPORT();},
'unfunc':()=>{unVERIFYEXPORT();},
'detail':
`在问卷管理页面生效,表头上方添加【验证输出勾选的报告】按钮
【验证输出勾选的报告】点击并确认后会验证输出当前页面勾选的所有报告,成功输出的报告下方小窗口会显示绿色提示
(电脑配置较低时一次输出太多份可能导致页面卡死,请根据浏览器最多同时能开几个报告页面量力而行,默认关闭)`,
'switch':0
},
6:{
'id':6,
'name':'定制汇总',
'func':()=>{CUSTOMROLLUP();},
'unfunc':()=>{unCUSTOMROLLUP();},
'detail':
`在定制汇总页面生效,在汇总表格上方添加功能按钮
【复制表格】点击可一键复制表格全部内容,方便复制到excel等软件中编辑
【复制表格】右侧下拉框选择“分数后+%”时,仅在Pivot table界面下生效,点击【复制表格】执行复制前会为所有数据后添加%
【精确Pts%】点击可在表格右侧添加一列Pts/PtsOf的比值,并根据右侧下拉框选择的数字,进行相应小数位数的四舍五入
【精确Pts%】需要Pts和PtsOf列同时存在才能正常生效,用以避免默认Pts%的2位小数舍入可能造成的偏差
【选项统计】点击可自动统计各架构各题选项的数量与占比,并在表格下方的新增行中展示(QuestionText前[AD]标识),百分比值根据左侧下拉框数字四舍五入
【选项统计】需要QuestionText和AnswerText和#Surveys列同时存在才能正常生效,数量显示在末尾括号内,百分比值显示在#Survsys格
【选项统计】参与统计的架构仅为QuestionText/AnswerText左侧非隐藏列,可在隐藏不必要的列后重新点击按钮刷新统计`,
'switch':1
},
7:{
'id':7,
'name':'报告存档',
'func':()=>{if(!OSM) SURVEYSAVES();},
'unfunc':()=>{if(!OSM) unSURVEYSAVES();},
'detail':
`在单店报告页面生效,右下方【书本图标】 按钮展开操作界面,可查看自动/手动存档列表
【存档】点击可进行手动存档,每次对报告内容进行修改时,将在本地进行自动存档
【预览】点击可查看存档内容,并对需要读档写入的题目进行勾选
【读档】点击可将选中的存档全部内容写入到当前报告,或只写入预览界面勾选的题目
【删除】点击可删除选中的存档,自动/手动存档上限各为10个,超出时自动删除此类最早存档
(“评论编辑”功能造成的修改不会触发自动存档,可在修改后点击任意评论框触发自动存档)`,
'switch':1
},
8:{
'id':8,
'name':'PDF命名',
'func':()=>{PDFRENAME();},
'unfunc':()=>{unPDFRENAME();},
'detail':
`在“以PDF格式下载”的转化页面生效,在高级页添加【命名并下载(全部)】按钮
可在下方FIle Name处自定义命名格式,在下拉框选择需要的命名元素(无须点merge)
【命名并下载】点击可下载单个PDF,并按File Name处的自定义命名格式命名
【命名并下载全部】点击相当于一键点击了所有【命名并下载】`,
'switch':1
},
9:{
'id':9,
'name':'优化表头',
'func':()=>{BETTERTHEAD();},
'unfunc':()=>{unBETTERTHEAD();},
'detail':
`在所有含有页面滚动时自动冻结表头功能的页面生效(例:问卷管理)
点击表头上方【标题】行可显示表格所有列的表头内容,根据其勾选状态与否可显示/隐藏对应列
优化冻结表头的表现,使冻结的表头不再像原先那样闪烁,且在冻结状态下也能执行排序/筛选功能
(优化冻结表头在部分浏览器可能不支持,若无效建议使用最新版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(' ','');
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(`
`);
menu.find('li.MOassist').on('click',function(){
MOListSwitch($(this));
}).find('ul#MOoption').on('click',e=>{
e.stopPropagation();//让之后添加的功能列表不继承click事件
});
//导入所有功能列表并显示开关状态
let options='';
for(let i in SET){
menu.find('ul#MOoption').append(`
`);
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();
});
//鼠标聚焦时显示详情 【https://www.minerva-online.com/portal/menu/js/v2/menuRender.js?version=21-08 createToolOption : 】
menu.find('li.MOassist').hover(function(){
$(this).find('ul:first').stop().show(200);
},function(){
$(this).find('ul:first').stop().hide(200);
});
setMarkQuestionColor(menu);
}
}
//功能列表开关
function MOListSwitch(el){
if(el.find('ul#MOoption').css('display')==='none'){
el.find('ul#MOoption').stop().slideDown(200);
}else{
el.find('ul#MOoption').stop().slideUp(200);
}
}
//添加扣分标记颜色设置界面
function setMarkQuestionColor(menu){
menu.find('input#3.menuIconSmall').next('ul').prepend(`
扣分颜色:
N/A颜色:
`);
//颜色选项初始化
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.indexOf('#')<0){
$(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('保存成功 ');
setTimeout(()=>{
$(this).next().remove();
},3e3);
}
});
}
/*在顶端菜单栏添加MOassist设置按钮*/
/*获取app.collaboration页面Enterprise.Admin权限*/
function collaborationEnterpriseAdmin(){
if(document.location.href.indexOf('alias=app.collaboration')<0) return;
const funcName=['renderSyncLog','renderImportLog'];
for(let n of funcName) eval('unsafeWindow.'+n+'='+window[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.indexOf('alias=knowledgebase')>=0) 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.indexOf('alias=smngr.surveyexplorer')>=0&&$('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(`
↓
`);
$(this).parent().next().find('button#download').one('click',function(){
DownloadButton($(this).parent(),surveyid);//将$('div#'+surveyid)传参为df
});
});
}
//兼容inoki.va页面
if(document.location.href.indexOf('alias=inoki.va')>0){
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(`
↓
`);
$(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('...... ');
$.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(`
\t#=${fileno}
`);
if (fileno>0){
const ol=df.find('ol#filelist');
$('√ ').prependTo(ol)
.on('click',()=>{
DownloadAll(df);
});
$('删除全部附件 ').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';
$('').appendTo(tb).append(`
${filename}
${filesize}
QID:${filedata[i].ProtoQuestionID}
`);
}
df.find('a#I,a#V').mouseenter(function(){
FilePreview(1,$(this).attr('href'));
}).mouseleave(()=>{
FilePreview(0);
});
}
}else{
df.append('登录失效! ');
}
}else{
df.append('网络错误! ');
}
DownloadButton0(df,surveyid);
},'json');
}
//预览附件图片
function FilePreview(show,src){
if(show){
const imgid=src.split('=')[2];
if($('img#'+imgid+'.filepreview').length===0){
$('').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(){
$('