jiraBugTemplate

jira 提单自动填充模板

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         jiraBugTemplate
// @namespace    http://tampermonkey.net/
// @version      0.5
// @description  jira 提单自动填充模板
// @author       mocobk
// @match        https://jira.sui.work/browse/*
// @match        https://jira.sui.work/projects/*
// @require      https://greasyfork.org/scripts/390554-getdeveloper/code/getDeveloper.js
// @grant        none
// ==/UserScript==

// 测试环境
var env = '测试服';
// jira描述内容模板
var descContent = `

<p><img class="emoticon" src="/images/icons/emoticons/help_16.png" alt="" width="16" height="16" align="absmiddle" border="0" data-mce-src="/images/icons/emoticons/help_16.png"><strong>【问题描述】</strong></p>
<br>
<p><img class="emoticon" src="/images/icons/emoticons/information.png" alt="" width="16" height="16" align="absmiddle" border="0" data-mce-src="/images/icons/emoticons/information.png"><strong>【测试数据】</strong></p>
<br>
<p><img class="emoticon" src="/images/icons/emoticons/check.png" alt="" width="16" height="16" align="absmiddle" border="0" data-mce-src="/images/icons/emoticons/check.png"><strong>【预期结果】</strong></p>
<br>
<p><img class="emoticon" src="/images/icons/emoticons/error.png" alt="" width="16" height="16" align="absmiddle" border="0" data-mce-src="/images/icons/emoticons/error.png"><strong>【实际结果】</strong></p>

`;

var bugType = ['功能类', "数据类", "界面类", "环境类", "需求类", "性能类", "安全类", "自动化类"];


// 指定次数和时间间隔重复执行
function timesInterval(handler, intervalTime, times) {
    let curTimes = 0;
    let timer = setInterval(() => {
        handler();
        curTimes++;
        if (curTimes >= times) {
            clearInterval(timer);
        }
    }, intervalTime)
}

function autoFill() {
    let defaultElement = {value: '', innerHTML: ''};

    // jira 编号
    let issueKey = $('#key-val')[0].getAttribute('data-issue-key') || defaultElement;

    // huanj
    let environment = $('#environment')[0] || defaultElement;

    // 描述
    let descIframe = $('iframe')[0];
    let description = descIframe.contentWindow.document.querySelector('#tinymce');

    let relatesTo = $('#issuelinks-issues-textarea')[0] || defaultElement;

    environment.value = env;
    relatesTo.value = issueKey;
    // 因描述信息框会刷新,所以要重复填充
    timesInterval(() => {
        if (!description.innerHTML.includes('<br>')) {
            description.innerHTML = descContent + '<br>';
        }
    }, 200, 10);

    relatesTo.focus();

    $('#create-issue-dialog .form-body')[0].scrollTop = 0;
    $('#summary')[0].focus();

}

// 网上找的一份代码,试过chrome中只有enter键是生效的
function fireKeyEvent(el, evtType, keyCode) {
    var doc = el.ownerDocument,
        win = doc.defaultView || doc.parentWindow,
        evtObj;
    if (doc.createEvent) {
        if (win.KeyEvent) {
            evtObj = doc.createEvent('KeyEvents');
            evtObj.initKeyEvent(evtType, true, true, win, false, false, false, false, keyCode, 0);
        } else {
            evtObj = doc.createEvent('UIEvents');
            Object.defineProperty(evtObj, 'keyCode', {
                get: function () {
                    return this.keyCodeVal;
                }
            });
            Object.defineProperty(evtObj, 'which', {
                get: function () {
                    return this.keyCodeVal;
                }
            });
            evtObj.initUIEvent(evtType, true, true, win, 1);
            evtObj.keyCodeVal = keyCode;
            if (evtObj.keyCode !== keyCode) {
                console.log("keyCode " + evtObj.keyCode + " 和 (" + evtObj.which + ") 不匹配");
            }
        }
        el.dispatchEvent(evtObj);
    } else if (doc.createEventObject) {
        evtObj = doc.createEventObject();
        evtObj.keyCode = keyCode;
        el.fireEvent('on' + evtType, evtObj);
    }
}

// 监听有空格输入后,延时500ms后自动按 enter 确认键
function autoInputEnter(element) {
    function handleKeydown(e) {
        if (e.keyCode === 32) {
            setTimeout(() => {
                fireKeyEvent(element, 'keydown', 13);
                element.removeEventListener('keydown', handleKeydown);
            }, 500)
        }
    }

    element.addEventListener('keydown', handleKeydown);
}

// 根据匹配的开发人员姓名,自动填充经办开发
function assignDeveloper() {
    const bodyText = $('.issue-body-content')[0].innerText;
    const developer = maxTimesWord(bodyText);

    if (developer) {
        console.log('自动识别到开发', developer.name);
        let assigneeField = $('#assignee-field')[0];
        assigneeField.addEventListener(
            'click',
            () => {
                if (assigneeField.value !== developer.name) {
                    // 这里因为必须要用户主动触发按键才能选择,采用空格触发
                    assigneeField.value = developer.name + ' 按空格键确认!';
                    assigneeField.focus();
                    assigneeField.setSelectionRange(developer.name.length, -1);
                    autoInputEnter(assigneeField);
                }
            })
    }
}


// 设置问题类型
function setBugType() {
    function fillBugType(type) {
        let summary = $('#summary')[0];
        const typePattern = /^【.+?】/g;
        summary.value = summary.value.replace(typePattern, "");
        summary.value = `【${type}】` + summary.value;
    }

    let summaryField = $('#summary').parent();
    if (summaryField) {
        let aTag = [];
        for (let type of bugType) {
            const tag = `<a href='#' style="margin-right: 10px">${type}</a>`;
            aTag.push(tag)
        }
        const fieldHtml = `<div id="bug-type-field" class="field-group"><label>问题类型</label><div style="padding: 5px 0 0;">${aTag.join('')}</div></div>`;
        summaryField.before(fieldHtml);
        $('#bug-type-field a').each((index, element) => {
            console.log('添加监听')
            element.addEventListener('click', () => {
                fillBugType(element.innerText)
            })
        });
    }


}

(function () {
    let createBtn = document.getElementById('create_link');
    // 添加创建按钮监听事件
    createBtn.addEventListener(
        'click',
        function () {
            let i = 0;
            let timer = setInterval(
                function () {
                    if ($('#create-issue-dialog').length === 1 && $('iframe')[0] && $('#issuetype-field')[0].value === '故障') {
                        setBugType();
                        autoFill();
                        assignDeveloper();
                        clearInterval(timer);
                    } else {
                        i++;
                        if (i >= 100) {
                            // 100 次轮询都未找到对象则停止
                            clearInterval(timer);
                        }
                    }
                }, 500)
        }
    )
})();