您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
try to take over the node server!
当前为
// ==UserScript== // @name 生成上线周知 // @namespace http://tampermonkey.net/ // @version 0.7 // @description try to take over the node server! // @author pujiaxun // @match https://km.sankuai.com/* // @grant GM_setClipboard // ==/UserScript== const BUTTON_ID = "SXZZ-GenDeployNoticeButton"; const PLUGIN_NAME = "[生成上线周知插件]"; (function() { "use strict"; window.addEventListener( "load", function(e) { setTimeout(init, 2000); }, true ); })(); /** * 监视内容DOM子元素的变化,主要用来判断是否切换页面 */ function observeIt() { const targetNode = document.getElementById("page-wrapper"); const config = { childList: true, characterData: true }; const observer = new MutationObserver(mutationList => { refresh(); }); observer.observe(targetNode, config); } /** * 初始化,添加页面切换的observer,并refresh按钮 */ function init() { observeIt(); refresh(); } /** * 清除按钮,并判断是否需要添加按钮 */ function refresh() { flush(); if (hasDeployPlan()) { create(); } } /** * 清除按钮 */ function flush() { const existBtn = document.getElementById(BUTTON_ID); if (existBtn) { existBtn.parentNode.removeChild(existBtn); } } /** * 插入一个按钮,用来一键生成上线周知 */ function create() { const d = document.createElement("div"); d.innerHTML = `<button style="position: fixed; right: 40px; bottom: 150px" class="ant-btn ant-btn-primary" id="${BUTTON_ID}" title="点击自动复制"><span>生成上线周知</span></button>`; d.addEventListener("click", genDeployNotice); document.body.appendChild(d); } /** * 生成上线周知,并复制到系统剪贴板 */ function genDeployNotice() { try { const textList = getValidLineDatas(); const noticeItems = [ `【上线项目】:${textList[1]}`, `【上线内容】:${textList[0]}`, `【上线时间】:${textList[6]}`, `【影响范围】:${textList[2]}`, `【上线计划】:${location.href}` ]; const result = noticeItems.join("\n"); GM_setClipboard(result, { type: "text" }); message("上线周知已成功复制到剪贴板", "success"); } catch (e) { message("Something Wrong", "error"); console.info(PLUGIN_NAME, "报错了,我也不知道咋处理,欢迎帮忙debug"); console.error(PLUGIN_NAME, e); } } /** * 判断是否为上线方案页面 */ function hasDeployPlan() { return !!document.querySelector('a[title="境外度假终端上线流程规范"]'); } /** * 解析HTML,获取表格最后n行的所有单元格 */ function parseHtml(lastIndex = 0) { const trs = document.querySelectorAll("table tbody tr"); const tds = trs[trs.length - 1 - lastIndex].querySelectorAll("td"); const tdContentList = Array.map(tds, td => td.textContent); return tdContentList; } /** * 循环遍历列表,找到最后一条有效数据 */ function getValidLineDatas() { const trs = document.querySelectorAll("table tbody tr"); let textList = []; let lastIndex = 0; do { textList = parseHtml(lastIndex); lastIndex += 1; // 数据列表未定义或者仅包含空格则寻找上一条 } while ((!textList || !textList.join('').trim()) && lastIndex < trs.length); return textList; } /** * 弹出消息提示框 * @param {string} msg 提示信息内容 * @param {string} type 提示样式类型:success|warning|error */ function message(msg = "", type = "success") { const msgEl = document.createElement("div"); msgEl.innerHTML = `<div data-reactroot="" class="ant-message"><span><div class="ant-message-notice"><div class="ant-message-notice-content"><div class="ant-message-custom-content ant-message-${type}"><i class="anticon anticon-check-circle"></i><span>${msg}</span></div></div></div></span></div>`; document.body.appendChild(msgEl); setTimeout(() => { msgEl.remove(); }, 3000); }