Zentao Utils

7/27/2021, 4:53:18 PM

Du musst eine Erweiterung wie Tampermonkey, Greasemonkey oder Violentmonkey installieren, um dieses Skript zu installieren.

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 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.

Sie müssten eine Skript Manager Erweiterung installieren damit sie dieses Skript installieren können

(Ich habe schon ein Skript Manager, Lass mich es installieren!)

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        Zentao Utils
// @namespace   Violentmonkey Scripts
// @match       http://zentao.inovance.com/pro/*
// @match       http://10.44.244.63/pro/*
// @icon        https://blog.sbw.so/favicon.ico
// @grant       GM_getValue
// @grant       GM_setValue
// @version     1.10
// @license     MIT
// @author      sbw <[email protected]>
// @description 7/27/2021, 4:53:18 PM
// ==/UserScript==


(function() {
  
  // 显示 alert 对话框
  function show_alert(message)
  {
    bootAlert(message);
  }
  
  // 显示对话框
  function update_dialog(title, content)
  {
    $('#dialog .modal-title').html(title);
    $('#dialog .modal-body').html(content);
  }
  
  // 获取当前项目中的模块分类
  function update_module_on_dialog()
  {
    var url = "/tree-ajaxGetOptionMenu-149-bug-0-0-html--true.html";
    $.get(url, function(data, status){
      update_dialog('更新模块', data);
      
      // 清除事件
      $('.form-control').off('change');
      $('.form-control').removeAttr('onchange');
    });
  }
  
  // 更新任务所属模块
  function update_jobs_module(e)
  {
    // 禁止默认的响应
    e.preventDefault();
    
    update_module_on_dialog();
    
    // 绑定对话框确定按钮的事件
    $('#dialog .btn-primary').off('click');
    var basicInfoPanel = $('#legendBasicInfo');
    if (basicInfoPanel.length > 0) {
      $('#dialog .btn-primary').click(submit_jobs_module_inline);
    } else {
      $('#dialog .btn-primary').click(submit_jobs_module);
    }
  }
  
  function submit_modify_job(jobId, fun)
  {
    // 修改任务的地址
    var url = '/pro/bug-edit-' + jobId + '.html';
    $.get(url, function(data, status) {
      // 从任务修改界面获取初始数据集
      var resData = $.parseHTML(data, true);
      var formData = new FormData($(resData).find('form')[0]);
      fun(resData, formData);

      // 发送数据
      $.ajax({
        type: 'post',
        url: url, 
        data: formData, 
        contentType: false,
        processData: false,
        success: function(data, status) { 
          /*$('html').html(data);*/
          new $.zui.Messager('任务 ' + jobId + ' 更新完成', { icon: 'bell' }).show();
          
          // // 刷新当前页面
          // location.reload();
        }
      });
    });
  }
  
  function submit_jobs_module()
  {
    // 获取选择的数据
    var choose = $('#module').find(":selected").val();
    
    // 隐藏对话框
    $('#dialog').modal('hide');
    
    // 获取选中的任务列表
    $('#bugList tr').filter('.checked').each(function () {
      var id = $(this).find('.c-id input').val();
      var title = $(this).find('.text-left').attr('title');
      if (typeof(title) === "undefined") {
        title = $(this).find('.text-left > a').attr('title');
      }
      
      submit_modify_job(id, function(resData, formData) {
        // 修改所属模块
        formData.set('module', choose);
      });
    });
  }
  
  function submit_jobs_module_inline()
  {
    // 获取选择的数据
    var choose = $('#module').find(":selected").val();
    
    // 隐藏对话框
    $('#dialog').modal('hide');
    
    // 当前任务 id
    var id = $('.label-id').text();
    submit_modify_job(id, function(resData, formData) {
      // 修改所属模块
      formData.set('module', choose);
    });
  }
  
  // 从 bug 页面获取关键词列表
  function get_keywords_from_bug_page()
  {
    var keywords = $('#legendBasicInfo tr:nth-child(25) td:first')[0].childNodes[0].nodeValue;
    keywords = split_keywords(keywords);
    
    return keywords;
  }
  
  // 从 GM 中获取存储的最近使用的关键词列表
  function get_last_recent_used_keywords()
  {
    var default_keywords = ["待评审", "无效", "延期处理", "不复现"]
    var keywords = GM_getValue('last_recent_used_keywords', default_keywords);
    if (!Array.isArray(keywords))
      return default_keywords;
    
    return keywords;
  }
  
  // 更新最近使用的关键词列表
  function update_last_recent_used_keywords(keywords)
  {
    // bug 中的关键词列表
    var bugKeywords = get_keywords_from_bug_page();
    // 上次的关键字列表
    var lastKeywords = get_last_recent_used_keywords();
    // 提交的关键词中去掉 bug 中的
    var newKeywords = keywords.filter(x => !bugKeywords.includes(x));
    
    // 最后的列表中移除新的,并把新的添加到前面
    lastKeywords = lastKeywords.filter(x => !newKeywords.includes(x));
    lastKeywords = newKeywords.concat(lastKeywords);
    if (lastKeywords.length > 10)
      lastKeywords.length = 10;
    
    GM_setValue('last_recent_used_keywords', lastKeywords);
  }
  
  // 分隔关键词列表
  function split_keywords(keywords)
  {
    if (!keywords || keywords.trim().length === 0)
      return [];

    // 分隔已有的关键词列表
    var re = /\s+|,|,|;|;/;
    var keywords = keywords.split(re).map(x => x.trim()).filter(x => x && x.length > 0);
    
    return keywords;
  }
  
  // 更新输入框元素列表
  function update_keywords_input()
  {
    // 是否自定义
    var custom = $('.custom-keywords').is(":checked");
    $('#keywords-input').prop('disabled', !custom);
    
    // 非自定义,由用户输入决定结果
    if (!custom) {
      // 非自定义,由标签决定结果,遍历所有标签
      var keywords = [];
      $('.checkbox input:checked').each(function() {
        keywords.push($(this)[0].nextSibling.nodeValue.trim());
      });
      
      // 输入框数据
      $('#keywords-input').val(keywords.join(", "));
    }
  }
  
  // 用户提交编辑后的关键字列表
  function submit_keywords()
  {    
    var keywords = $('#keywords-input').val();
    keywords = split_keywords(keywords);
    
    // 隐藏对话框
    $('#dialog').modal('hide');
    
    // 关键词列表提交保存
    update_last_recent_used_keywords(keywords);
    
    // 提交修改
    var keywords = keywords.join(", ");
    
    // 当前任务 id
    var id = $('.label-id').text();
    submit_modify_job(id, function(resData, formData) {
      // 修改关键字数据
      formData.set('keywords', keywords);
    });
  }
  
  function assign_back(e) {
    // 禁止默认的响应
    e.preventDefault();
    
    // 获取选中的任务列表
    $('#bugList tr').filter('.checked').each(function () {
      var id = $(this).find('.c-id input').val();
      
      submit_modify_job(id, function(resData, formData) {
        // 找到创建者名字和 id
        var creater = $(resData).find('.detail:nth-child(3) > .table-form td:first').text();
        var creater_id = '';
        
        var options = $(resData).find('#assignedTo > option');
        for (var i = 0; i != options.length; ++i) {
          if (options[i].title == creater) {
            creater_id = options[i].value;
            break;
          }
        }
        
        formData.set('assignedTo', creater_id);
      });
    });
  }
  
  function update_jobs_keywords(e)
  {
    // 禁止默认的响应
    e.preventDefault();
    
    // 获取当前关键词列表
    var keywords = get_keywords_from_bug_page();
    
    // 最后使用的 keywords
    var last_keywords = get_last_recent_used_keywords();
    
    // 合并去重后的选项列表
    var options = keywords.filter(x => !last_keywords.includes(x)).concat(last_keywords);
    // 创建选项组
    var divBox = $("<div></div>");
    options.forEach(x => {
      var select = $("<div class='checkbox'><label><input type='checkbox'>" + x + "</label></div>");
      
      // 勾选事件
      $(select).find('input').change(update_keywords_input);
      if (keywords.includes(x)) {
        $(select).find('input').prop('checked', true);
      }
      
      $(divBox).append(select);
    });
    // 输入框
    var inputGroup = $("<div class='checkbox'><label><input class='custom-keywords' type='checkbox'>自定义</label>&nbsp;<div class='input-control'><input id='keywords-input' type='text' class='form-control'></div></div>");
    // 标签和输入框居中
    $(inputGroup).css({"display": "flex", "align-items": "center"});
    // 输入框伸长
    $(inputGroup).find('.input-control').css({"flex-grow": "1"});
    // 输入框勾选自定义
    $(inputGroup).find('.custom-keywords').change(update_keywords_input);
    $(divBox).append(inputGroup);
    
    // 更新对话框
    update_dialog('更新关键词', divBox);  
    // 更新对话框的提交事件
    $('#dialog .btn-primary').off('click');
    $('#dialog .btn-primary').click(submit_keywords);
    // 更新元素状态
    update_keywords_input();
  }
  
  // 添加对话框
  $("body").append("<div class='modal fade' id='dialog'><div class='modal-dialog modal-sm'><div class='modal-content'><div class='modal-header'><h4 class='modal-title'></h4></div><div class='modal-body'></div><div class='modal-footer'><button type='button' class='btn btn-default' data-dismiss='modal'>关闭</button><button type='button' class='btn btn-primary'>保存</button></div></div></div></div>");

  // 添加模块修改按钮
  $('.table-actions').append('<button class="btn" id="update-module" data-toggle="modal" data-target="#dialog">修改所属模块</button>');
  // 更新模块点击的事件
  $('#update-module').click(update_jobs_module);
  
  // 添加一键指回 bug 提出人按钮
  $('.table-actions').append('<button class="btn" id="assign-back">指派给提出人</button>');
  // 事件
  $('#assign-back').click(assign_back);

  // 如果在 bug view 界面,增加快速修改按钮
  var basicInfoPanel = $('#legendBasicInfo');
  if (basicInfoPanel.length > 0)
  {
    // 更新模块
    var btn = '<button class="btn" id="update-module-x" data-toggle="modal" data-target="#dialog">更新模块</button>';
    $('#legendBasicInfo tr:nth-child(2) td:first').append(btn);
    $('#update-module-x').click(update_jobs_module);
    
    // 更新关键词
    var btn = '<button class="btn" id="update-keywords-x" data-toggle="modal" data-target="#dialog">更新关键词</button>';
    $('#legendBasicInfo tr:nth-child(25) td:first').append(btn);
    $('#update-keywords-x').click(update_jobs_keywords);
  }
  
  // 如果在 bug 列表界面,计算 bug 解决率
  if ($('.table-footer > .text').length > 0) 
  {
    var items = $('.table-footer > .text > strong');
    var total = parseInt($(items[0]).text(), 10);
    var unresolved = parseInt($(items[1]).text(), 10);
    
    $('.table-footer > .text > strong:last-child').after(',解决率 <strong>' + (100.0 * (total - unresolved) / total).toFixed(2) + '%</strong>');
  }
})();