// ==UserScript==
// @name 德鲁伊被强化了
// @namespace http://tampermonkey.net/
// @version 0.1.3
// @description 提供运营与开发界面的互跳功能
// @author 燕修
// @match http://insiopweb.stable.alipay.net/*
// @match https://insiopweb.alipay.com/*
// @icon https://www.google.com/s2/favicons?domain=alipay.net
// @require https://greasyfork.org/scripts/415581-jquery%E5%BA%93/code/jquery%E5%BA%93.js?version=866373
// @grant GM_setValue
// @grant GM_getValue
// @license GNU AGPLv3
// ==/UserScript==
// 公用数据
//js模拟触发React DOM点击
function simulateReactClick(element) {
['mousedown', 'click', 'mouseup'].forEach(mouseEventType=>element.dispatchEvent(new MouseEvent(mouseEventType,{
view: window,
bubbles: true,
cancelable: true,
buttons: 1
})));
}
var url = document.location.href;
var modeMap = {
scene: '运营场景管理',
sceneEdit: '运营场景配置',
// queryCode 有意义
adminScene: '开发场景管理',
template: '开发模板管理',
// sceneCode sceneName
templateEdit: '开发模板配置',
// templateCode edit sceneCode sceneName
sceneModule: '运营场景模块管理',
// sceneCode sceneName keyword
sceneModuleEdit: '运营场景模块配置',
// queryCode 数字串
unsupport: '暂不支持',
}
var envMap = {
stable: '开发环境',
prod: '线上环境',
change: '修改地址',
}
var urlEnvMap = {
stable: 'http://insiopweb.stable.alipay.net',
prod: 'https://insiopweb.alipay.com'
}
var urlModeMap = {
sceneModuleEdit: '/scene/module/edit',
sceneModule: '/scene/module',
templateEdit: '/admin/template/edit',
template: '/admin/template',
adminScene: '/admin/scene',
sceneEdit: '/scene/edit',
scene: '/scene',
unsupport: '/'
}
var getStorage = () =>{
let _storage;
try {
_storage = JSON.parse(GM_getValue('$_POWER_DRUID_DATA','{}'));
} catch(e){}
return _storage;
}
var data = getStorage();
const moduleEditURLMap = data && data.moduleEditURLMap || {};
let logedVersion = data && data.logedVersion || 0 ;
var setStorage = () =>{
var data = {
moduleEditURLMap,
logedVersion
};
GM_setValue('$_POWER_DRUID_DATA',JSON.stringify(data));
}
var jumpAndSave = (url)=>{
setStorage();
url && (location.href = url);
}
var getMode = (url)=>{
for (let name of Object.keys(urlModeMap)) {
if (url.includes(urlModeMap[name]))
return name;
}
}
var mode, env, param;
var updateEnvModeParam = ()=>{
url = location.href;
mode = getMode(url);
env = url.includes('.stable.') ? 'stable' : 'prod';
}
updateEnvModeParam();
cc(mode, env, param)
// 公用数据结束
// 处理更新日志
const upgradeLog = [
{
version: 1,
log: '增加了跳转地址记录功能,现在输入一次可以记录模块编辑线上环境与线下环境跳转的地址,以解决他们querycode不相同的问题',
}
];
if( logedVersion < upgradeLog[0].version ){
alert(upgradeLog[0].log);
logedVersion = upgradeLog[0].version;
setStorage();
}
// 处理待发布
var dealPublic = (param)=>{
if (!param || !param.insiopPlusInfoModuleName)
return;
const _list = $(".ant-table-tbody tr");
for (let row in _list) {
const list = $(_list[row]).children();
for (let col in list) {
if (list[col].innerText === param.insiopPlusInfoModuleName) {
for (let col in list) {
if (list[col].innerText === '发布') {
simulateReactClick(list[col].firstChild.firstChild.firstChild);
}
}
}
}
}
}
// 注入逻辑
var injectPlugin = ()=>{
$("#insiop-plus-panel").remove();
$("#insiop-plus-css").length || loadCss();
loadPanel();
//给所有Dom提供触发方法
document.__proto__.__proto__.__proto__.reactClick = function() {
simulateReactClick(this);
}
}
var doAfterLoad = (fn,condition)=>{
var inject = setInterval(()=>{
if (condition ? condition() : $('[class^=contentRight]').length) {
fn();
clearInterval(inject);
}
}
, 100);
}
doAfterLoad(()=>{
injectPlugin()
}
)
if (mode === 'sceneModule') {
doAfterLoad(()=>{
var param = getQuery(url);
dealPublic(param);
}
, ()=>{
if ($('.ant-table-tbody tr').length > 1)
return true;
return false;
}
)
}
$(window).on('hashchange', ()=>{
updateEnvModeParam();
injectPlugin();
}
);
$(window).on('popstate', ()=>{
updateEnvModeParam();
injectPlugin();
}
);
// 注入逻辑结束
// 公用函数
function cc(...arg) {
console.log(' ========= ');
console.log('德鲁伊Plus[日志]:', ...arg);
console.log(' ========= ');
}
function getQuery(url) {
if (!url)
url = document.location.href + '';
let query = {};
if (url.indexOf("?") != -1) {
url = url.split("?")[1];
let str = decodeURI(url);
// 获取url中"?"符后的字串(包括问号)
const pairs = str.split("&");
for (let i = 0; i < pairs.length; i++) {
const pair = pairs[i].split("=");
query[pair[0]] = pair[1];
}
}
return query;
// 返回对象
}
function getPureUrl(url) {
url += '';
if (url.indexOf("?") != -1) {
return url.split("?")[0];
}
return url
}
function getUrlWithParam(url, param) {
let result = getPureUrl(url);
result += '?'
for (let name in param) {
result += `${name}=${param[name]}&`
}
result = result.substring(0, result.length - 1);
cc('result', result);
return result;
}
var urlReplace = (find,target)=>{
return document.location.href.replace(find, target)
}
var getUrlWithoutQueryCode = (url,param)=>{
url = getPureUrl(url);
delete param.queryCode;
url = getUrlWithParam(url, param);
return url;
}
var itemFn = {
switchEnv: (targetEnv)=>{
const ismoduleEdit = mode === 'sceneModuleEdit';
if(ismoduleEdit){
if(targetEnv == 'change'|| !moduleEditURLMap[url]){
const targetUrl = prompt('请输入要切换对应环境的地址,只需设置一次即可存储双向跳转');
moduleEditURLMap[url] = targetUrl;
moduleEditURLMap[targetUrl] = url;
}
jumpAndSave(moduleEditURLMap[url]);
return;
}
let targetUrl;
var param = getQuery(url);
if (targetEnv == 'stable') {
targetUrl = url.replace(urlEnvMap.prod, urlEnvMap.stable)
}
if (targetEnv == 'prod') {
targetUrl = url.replace(urlEnvMap.stable, urlEnvMap.prod)
}
jumpAndSave(targetUrl);
}
,
switchMode: (targetMode)=>{
var param = getQuery(url);
const targetUrl = getUrlWithParam(location.origin + urlModeMap[targetMode], param);
cc(targetUrl);
jumpAndSave(targetUrl);
}
,
handlePublish: ()=>{
var param = getQuery($('.ant-breadcrumb > span:nth-child(2) a').attr('href'));
param.insiopPlusInfoModuleName = $('.ant-breadcrumb > span:last-child>span>span').text();
const targetUrl = getUrlWithParam(location.origin + urlModeMap['sceneModule'], param);
cc(targetUrl);
jumpAndSave(targetUrl);
}
}
var itemBuild = (type,options)=>{
var temp;
if (!options.id) {
options.id = options.fnName
}
switch (type) {
case 'btn':
temp = `<button ##ID## ##CLASS##>${options.content}</button>`;
temp = temp.replace('##ID##', `id="${options.id}"`).replace('##CLASS##', 'class="ant-btn ant-btn-primary insiop-plus-middle"');
break;
case 'state':
temp = `<span class="ant-tag insiop-plus-tag ${options.color ? options.color : 'ant-tag-blue'}">${options.content}</span>${options.break ? '<br/>' : ''}`
break;
default:
case 'select':
temp = `<select ##ID## ##CLASS## > ${options.options.map(item=>`<option value="${item.value}" ${item.value === options.default ? 'selected' : ''}>${item.label}</option>`).join('')}
</select>`;
temp = temp.replace('##ID##', `id="${options.id}"`).replace('##CLASS##', 'class="ant-select-selection ant-select-selection--single insiop-plus-select"');
break;
}
return [temp, {
...options,
type
}];
}
// 公用函数 结束
// 业务逻辑
var loadCss = ()=>{
$('body').append(`<style id="insiop-plus-css">
#insiop-plus-panel{
height: 64px;
width: 400px;
background: #ffffff;
border: #e4e3e3 solid 1px;
padding: 13px;
border-radius: 0 0 10px 10px;
position: absolute;
top: 0;
right: 600px;
z-index: 9999;
display: flex;
justify-content: center;
flex-direction: row;
}
#insiop-plus-panel.stable{
width: 500px;
}
#insiop-plus-entry{
height: 20px;
width: 20px;
background: #ffffff;
border: #f1a700 solid 1px;
color: #f1a700;
position: absolute;
top: 0;
right: 593px;
text-align: center;
line-height: 15px;
z-index: 99999;
cursor: pointer;
}
.insiop-plus-tag {
height:20px;
}
.insiop-plus-select{
margin-right:20px;
min-width: 130px;
align-self: center;
}
#insiop-plus-close{
color: #333333;
position: absolute;
top: 0;
right: 10px;
cursor: pointer;
}
.insiop-plus-middle{
align-self: center;
}
</style>`);
}
var loadPanel = ()=>{
$('#insiop-plus-entry').remove();
const ismoduleEdit = mode === 'sceneModuleEdit';
const modeList = Object.keys(modeMap);
const modeOptions = modeList.map(item=>{
return {
value: item,
label: modeMap[item]
}
}
);
const envList = ismoduleEdit?['stable', 'prod','change']:['stable', 'prod'];
const envOptions = envList.map(item=>{
return {
value: item,
label: envMap[item]
}
}
);
const hasModuleEditMap = ismoduleEdit && url && !!moduleEditURLMap[url];
const panelItems = [// itemBuild('state',{content:modeMap[mode],color:'ant-tag-green'}),
// itemBuild('state',{content:envMap[env],break:true}),
itemBuild('select', {
fnName: 'switchMode',
id: 'switchMode',
options: modeOptions,
default: mode
}), itemBuild('select', {
fnName: 'switchEnv',
id: 'switchEnv',
options: envOptions,
default: env
}),hasModuleEditMap? itemBuild('state',{
content: '可切换',
color:'ant-tag-green insiop-plus-middle',
}) : ['', ''],
env === 'stable' && ismoduleEdit ? itemBuild('btn', {
content: '一键发布',
fnName: 'handlePublish'
}) : ['', ''], // itemBuild('btn',{content:'切换模式',fnName:'switchMode'}),
]
const panelEl = panelItems.map(item=>item[0]);
const isStable = env === 'stable';
$('body').append(`<div id="insiop-plus-panel" class="${isStable ? 'stable' : ''}">${panelEl.join('')}<div id="insiop-plus-close">X</div></div>`)
panelItems.map(item=>{
let {id, fnName, type} = item[1];
if (['btn'].includes(type)) {
$('#' + id).click(itemFn[fnName])
}
;if (['select'].includes(type)) {
$('#' + id).change(function() {
var value = $(this).children('option:selected').val();
itemFn[fnName](value);
});
}
}
);
$('#insiop-plus-close').click(()=>{
$('#insiop-plus-panel').remove();
$('body').append(`<div id="insiop-plus-entry">+</div>`);
$('#insiop-plus-entry').click(loadPanel);
}
)
}
// 业务逻辑结束