您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
jiar工具箱
// ==UserScript== // @name jira工具箱 // @namespace qigege // @version 1.1.0 // @description jiar工具箱 // @author qgg // @match http://172.19.5.17:8888/browse/* // @match http://jira.xquant.com:8888/browse/* // @icon https://www.google.com/s2/favicons?sz=64&domain=5.17 // @grant none // @license MIT // ==/UserScript== (function () { 'use strict'; function copyLog() { const version = document.querySelector("#fixVersions-field")?.innerText || ""; const lis = document.querySelector(".aui-nav-breadcrumbs").children; const isBug = document.querySelector("#type-val").innerText.includes("缺陷"); let jiraId = "", summary = "", bugId = "", problem = ""; if (isBug) { if (lis.length === 2) { bugId = lis[1].innerText; problem = document.querySelector("#summary-val").innerText; } else { const [id, ...rest] = lis[1].innerText.split(' '); jiraId = id; summary = rest.join(' '); bugId = lis[2].innerText; problem = document.querySelector("#summary-val").innerText; } } else { jiraId = lis[1].innerText; summary = document.querySelector("#summary-val").innerText; } const content = `版本:${version} \n需求编号:${jiraId} \n内容概要:${summary} \n缺陷编号:${bugId} \n问题描述:${problem} `; addClipboard(content); } function copyFileName() { const user = document.querySelector("#header-details-user-fullname").getAttribute("data-displayname"); const jiraId = document.querySelector(".aui-nav-breadcrumbs").children[1].innerText; const summary = document.querySelector("#summary-val").innerText; const client = document.querySelector("#customfield_10503-val").innerText; const content = client.includes("中信") ? `【${jiraId}】需求:${summary} ` : `${jiraId}_${user}_${summary} `; addClipboard(content); } function calculateRows(content) { const lines = content.split('\n'); return lines.length + 1; } function createDoc() { backboard.hidden = false; const user = document.querySelector("#header-details-user-fullname").getAttribute("data-displayname"); const jiraId = document.querySelector(".aui-nav-breadcrumbs").children[1].innerText; const summary = document.querySelector("#summary-val").innerText; const client = document.querySelector("#customfield_10503-val").innerText; if (client.includes("中信")) { showFloatingMessage("抱歉,暂不支持中信!"); backboard.hidden = true; return; } const fileName = `${jiraId}_${user}_${summary} ` const analysis = document.querySelector(".user-content-block") ? document.querySelector(".user-content-block").innerText.trimStart() : "无"; const sln = document.querySelector("#customfield_10910-val") ? document.querySelector("#customfield_10910-val").innerText.trimStart() : "无"; const sugg = document.querySelector("#customfield_11700-val") ? document.querySelector("#customfield_11700-val").innerText.trimStart() : "无"; const dialog = createDialog("Auto Create Doc", [ createNewDocField('文件名称', "x-file-name", fileName, 1), createNewDocField('需求描述', "x-desc", "无", 1), createNewDocField('需求分析', "x-analyes", analysis, calculateRows(analysis)), createNewDocField('解决方案', "x-sln", sln, calculateRows(sln)), createNewDocField('测试建议', "x-sugg", sugg, calculateRows(sugg)), createNewDocField('自测场景', "x-self-text", "无", 1), createNewDocField('相关脚本', "x-script", "无", 1) ], () => { const content = `【需求描述】\n${document.querySelector("#x-desc").value} \n 【需求分析】\n${document.querySelector("#x-analyes").value} \n 【解决方案】\n${document.querySelector("#x-sln").value} \n 【测试建议】\n${document.querySelector("#x-sugg").value} \n 【自测场景】\n${document.querySelector("#x-self-text").value} \n 【相关脚本】\n${document.querySelector("#x-script").value} `; downloadFile(`${fileName}.txt`, content); backboard.hidden = true; document.body.removeChild(dialog); }); document.body.appendChild(dialog); } function createNewDocField(label, id, content, rows = 3) { const field = document.createElement('div'); field.className = "field-group"; field.style.marginBottom = "20px"; const labelElement = document.createElement('label'); labelElement.innerHTML = label; labelElement.style.display = "inline-block"; labelElement.style.width = "100px"; labelElement.style.verticalAlign = "top"; // 修改为top,使label和输入框平齐 field.appendChild(labelElement); const textBox = document.createElement('textarea'); textBox.id = id; textBox.className = "textarea long-field"; textBox.rows = rows; textBox.cols = 95; textBox.style.border = "2px solid var(--aui-form-field-border-color)"; textBox.style.transition = "background-color 0.2s ease-in-out, border-color 0.2s ease-in-out"; textBox.style.resize = "vertical"; textBox.style.verticalAlign = "top"; // 修改为top,使label和输入框平齐 textBox.style.fontFamily = "inherit"; textBox.style.boxSizing = "border-box"; textBox.style.borderRadius = "3.01px"; textBox.textContent = content; textBox.addEventListener('mouseover', () => textBox.style.backgroundColor = "var(--aui-form-field-hover-bg-color)"); textBox.addEventListener('mouseout', () => textBox.style.backgroundColor = ""); textBox.addEventListener('mousedown', () => textBox.style.backgroundColor = ""); field.appendChild(textBox); return field; } function closeRightPanel() { const sidebar = document.querySelector("#viewissuesidebar"); sidebar.style.display = sidebar.style.display === 'none' ? "" : 'none'; } function setting() { backboard.hidden = false; const dialog = createDialog("Jira Tool Box Settings", [ createSettingField('Copy Log', 'addCopyLog', true), createSettingField('Copy FileName', 'addCopyFileName'), createSettingField('Create Doc', 'addCreateDoc', true), createSettingField('Close Right Panel', 'addCloseRightPanel'), createSettingField('Setting(reset need clear cache)', 'addSetting', true) ], () => { localStorage.setItem('addCopyLog', document.querySelector('#addCopyLog').checked); localStorage.setItem('addCopyFileName', document.querySelector('#addCopyFileName').checked); localStorage.setItem('addCreateDoc', document.querySelector('#addCreateDoc').checked); localStorage.setItem('addCloseRightPanel', document.querySelector('#addCloseRightPanel').checked); localStorage.setItem('addSetting', document.querySelector('#addSetting').checked); addCopyLog = localStorage.getItem('addCopyLog') === "true"; addCopyFileName = localStorage.getItem('addCopyFileName') === "true"; addCreateDoc = localStorage.getItem('addCreateDoc') === "true"; addCloseRightPanel = localStorage.getItem('addCloseRightPanel') === "true"; addSetting = localStorage.getItem('addSetting') === "true"; backboard.hidden = true; document.body.removeChild(dialog); init(); }); document.body.appendChild(dialog); } function createSettingField(label, id, defaultCheck = false) { const field = document.createElement('div'); field.className = "field-group"; field.style.marginBottom = "20px"; const labelElement = document.createElement('label'); labelElement.innerHTML = label; labelElement.style.display = "inline-block"; labelElement.style.width = "220px"; labelElement.style.verticalAlign = "middle"; field.appendChild(labelElement); const checkbox = document.createElement('input'); checkbox.type = "checkbox"; checkbox.id = id; if (localStorage.getItem(id) === 'true') { checkbox.checked = true; } else { checkbox.checked = defaultCheck; } checkbox.style.verticalAlign = "middle"; field.appendChild(checkbox); return field; } function createDialog(title, fields, onSave) { const dialog = document.createElement('div'); dialog.className = "jira-dialog jira-dialog-core box-shadow jira-dialog-open popup-width-large jira-dialog-content-ready"; dialog.style = ` position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); max-height: 80%; overflow: hidden; display: flex; flex-direction: column; `; const header = document.createElement('div'); header.className = "jira-dialog-heading jira-dialog-core-heading"; header.innerHTML = `<h2> ${title}</h2> `; header.style.flexShrink = '0'; dialog.appendChild(header); const content = document.createElement('div'); content.className = "jira-dialog-content jira-dialog-core-content"; content.style.flexGrow = '1'; content.style.overflowY = 'auto'; dialog.appendChild(content); const form = document.createElement('div'); form.className = "form-body"; fields.forEach(field => form.appendChild(field)); content.appendChild(form); const btnContainer = document.createElement('div'); btnContainer.className = "buttons-container form-footer"; btnContainer.style.flexShrink = '0'; const btns = document.createElement('div'); btns.className = "buttons"; btnContainer.appendChild(btns); const okBtn = document.createElement('a'); okBtn.className = "aui-button toolbar-trigger issueaction-workflow-transition"; okBtn.innerHTML = "保存"; okBtn.addEventListener('click', onSave); btns.appendChild(okBtn); const cancelBtn = document.createElement('a'); cancelBtn.innerHTML = "取消"; cancelBtn.className = "aui-button aui-button-link cancel"; cancelBtn.addEventListener('click', () => { backboard.hidden = true; document.body.removeChild(dialog); }); btns.appendChild(cancelBtn); dialog.appendChild(btnContainer); // 添加Esc键关闭功能 document.addEventListener('keydown', function (event) { if (event.key === 'Escape') { backboard.hidden = true; document.body.removeChild(dialog); } }); return dialog; } function downloadFile(filename, content) { const element = document.createElement('a'); element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(content)); element.setAttribute('download', filename); element.style.display = 'none'; document.body.appendChild(element); element.click(); document.body.removeChild(element); } function addClipboard(content) { const textarea = document.createElement('textarea'); textarea.value = content; document.body.appendChild(textarea); textarea.select(); document.execCommand('copy'); document.body.removeChild(textarea); showFloatingMessage("已将以下内容增加到剪切板\n\n" + content); } function addOpsbarButton(needAdd, label, action, tooltip) { const id = label.replaceAll(' ', ''); const existingButton = document.querySelector('#' + id); if (needAdd && !existingButton) { document.querySelector("#opsbar-opsbar-transitions").appendChild(createButton(label, action, tooltip)); } else if (!needAdd && existingButton) { existingButton.remove(); } } function createButton(label, clickHandler, tooltip) { const btn = document.createElement('a'); btn.className = "aui-button toolbar-trigger issueaction-workflow-transition"; btn.href = "#"; btn.id = label.replaceAll(' ', ''); btn.title = tooltip; const span = document.createElement('span'); span.className = "trigger-label"; span.innerHTML = label; btn.appendChild(span); btn.addEventListener('click', clickHandler); return btn; } function showFloatingMessage(message) { const floatingDiv = document.createElement('div'); floatingDiv.style.position = 'fixed'; floatingDiv.style.top = '20px'; floatingDiv.style.left = '50%'; floatingDiv.style.transform = 'translateX(-50%)'; floatingDiv.style.padding = '10px 20px'; floatingDiv.style.backgroundColor = 'rgba(0, 0, 0, 0.7)'; floatingDiv.style.color = 'white'; floatingDiv.style.borderRadius = '5px'; floatingDiv.style.zIndex = '9999'; floatingDiv.style.opacity = '0'; floatingDiv.style.transition = 'opacity 0.5s ease-in-out'; floatingDiv.innerHTML = message.replace(/\n/g, '<br>'); document.body.appendChild(floatingDiv); // 渐入动画 setTimeout(() => { floatingDiv.style.opacity = '1'; }, 10); // 渐出动画 setTimeout(() => { floatingDiv.style.opacity = '0'; floatingDiv.addEventListener('transitionend', () => { document.body.removeChild(floatingDiv); }); }, 4500); } function init() { addOpsbarButton(addCopyLog, 'Copy Log', copyLog, "快捷复制svn提交log"); if (document.querySelector("#type-val").innerText.includes("需求")) { addOpsbarButton(addCopyFileName, 'Copy FileName', copyFileName, "快捷复制文档名称"); addOpsbarButton(addCreateDoc, 'Create Doc', createDoc, "快捷创建文档,支持jira维护后一键生成文档"); } addOpsbarButton(addCloseRightPanel, 'Close Right Panel', closeRightPanel, "关闭右侧栏"); addOpsbarButton(addSetting, 'Setting', setting, "设置"); } let addCopyLog = false; let addCopyFileName = false; let addCreateDoc = false; let addCloseRightPanel = false; let addSetting = false; const backboard = document.createElement('div'); backboard.className = "aui-blanket"; backboard.hidden = true; document.body.appendChild(backboard); if (localStorage.getItem('addCopyLog') === null) { setting(); } else { addCopyLog = localStorage.getItem('addCopyLog') === "true"; addCopyFileName = localStorage.getItem('addCopyFileName') === "true"; addCreateDoc = localStorage.getItem('addCreateDoc') === "true"; addCloseRightPanel = localStorage.getItem('addCloseRightPanel') === "true"; addSetting = localStorage.getItem('addSetting') === "true"; } init(); setInterval(init, 2000); })();