Greasy Fork

Greasy Fork is available in English.

TAPD 修改“基本信息”显示

用于在 TAPD 需求详情页面高亮关键字、重排字段展示顺序,便于快速定位自己关心的字段

当前为 2022-08-30 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         TAPD 修改“基本信息”显示
// @namespace    [email protected]
// @version      0.1.4
// @description  用于在 TAPD 需求详情页面高亮关键字、重排字段展示顺序,便于快速定位自己关心的字段
// @author       qiuhongliang
// @icon         https://www.google.com/s2/favicons?sz=64&domain=tapd.cn
// @match        https://www.tapd.cn/*/prong/stories/view/*
// @grant        none
// @license      GPL
// ==/UserScript==

(function () {
  "use strict";
  
  changeFieldOrder();
  highlightKeyWord();

  /**
   * 修改字段展示顺序,关心的字段靠前面排
   */
  function changeFieldOrder() {
    let baseInfo = document.querySelector("#base_information > div.content");
    if (baseInfo == null || baseInfo == undefined) {
      // 只修改需求详情页面的数据
      console.log("未找到需求详情页面数据");
      return;
    }

    // 将处理人作为基点元素,对关心的元素进行重排
    let statusOwner = baseInfo.querySelector("#ContentStatusOwner").parentNode; // 处理人
    let needAddElementList = [
      // 开发阶段关注内容
      baseInfo.querySelector("#Content卖家账号").parentNode,
      baseInfo.querySelector("#ContentIteration").parentNode, // 迭代
      baseInfo.querySelector("#ContentPriority").parentNode, // 优先级
      baseInfo.querySelector("#ContentDeveloper").parentNode, // 开发人员
      baseInfo.querySelector("#ContentBegin").parentNode,
      // 兼容一个多个预计结束时间的 id
      document.querySelector("#ContentDue") ? document.querySelector("#ContentDue").parentNode : baseInfo.querySelector("#ContentEst\\.End").parentNode,

      // 线上测试阶段关注内容
      baseInfo.querySelector("#Content产品经理").parentNode,
      baseInfo.querySelector("#Content评审人").parentNode,
      baseInfo.querySelector("#Content是否需要灰测(WMS接口用)").parentNode,
      baseInfo.querySelector("#Content预计完成时间(WMS接口用)").parentNode,
      baseInfo.querySelector("#Content线上跟进情况(WMS接口用)").parentNode,
      baseInfo.querySelector("#Content接口线上测试").parentNode,

      // 接口上线关注内容
      baseInfo.querySelector("#ContentReleasePlan").parentNode, // 发布计划

      // 代码审核阶段——接口还未启用该流程,故往后放
      baseInfo.querySelector("#Content代码核查人员").parentNode,
      baseInfo.querySelector("#Content代码核查状态").parentNode,

      // 目前接口不关注,但是挺重要的字段
      baseInfo.querySelector("#ContentProgress").parentNode, // 进度
      baseInfo.querySelector("#ContentEffort").parentNode, // 预估工时
      baseInfo.querySelector("#ContentCompletedEffort").parentNode, // 完成工时
      baseInfo.querySelector("#ContentRemainingEffort").parentNode, // 剩余工时
      baseInfo.querySelector("#ContentExceededEffort").parentNode, // 超出工时

      // 其他不重要内容
      document.querySelector("#ContentModule").parentNode, // 模块
      baseInfo.querySelector("#Content加急处理").parentNode,
    ];
    sortNodeList(statusOwner, needAddElementList);

    // 不关心的元素移动到最底部
    let baseInfoLastChild = baseInfo.lastChild;
    baseInfoLastChild.after(
      baseInfo.querySelector("#ContentCategory").parentNode
    ); // 需求分类
    baseInfoLastChild.after(
      baseInfo.querySelector("#Content需求反馈人").parentNode
    );
    baseInfoLastChild.after(baseInfo.querySelector("#Content区域").parentNode);
    baseInfoLastChild.after(baseInfo.querySelector("#Content类目").parentNode);
  }

  /**
   * 按照 needAddElementList 传入顺序向基点元素后增加元素
   *
   * @param {Element} baseNode 基点元素, 将 needAddElementList 放到这个节点后
   * @param {Element[]} needAddElementList
   * @returns
   */
  function sortNodeList(baseNode, needAddElementList) {
    if (baseNode == null || baseNode == undefined) {
      console.log("排序失败,基点元素为空");
      return;
    }
    if (needAddElementList == null || needAddElementList == undefined) {
      console.log("排序失败,基点元素为空");
      return;
    }

    // 先倒序,再增加
    let newNeedAddElementList = needAddElementList.reverse();
    for (const node of newNeedAddElementList) {
      baseNode.after(node);
    }
  }

  /**
   * 高亮关键字
   */
  function highlightKeyWord() {
    let baseInfo = document.querySelector("#base_information > div.content");
    if (baseInfo == null || baseInfo == undefined) {
      // 只修改需求详情页面的数据
      console.log("未找到需求详情页面数据");
      return;
    }

    let elementList = [
      baseInfo.querySelector("#ContentDeveloper").parentNode.firstElementChild, // 开发人员
      baseInfo.querySelector("#ContentReleasePlan").parentNode
        .firstElementChild, // 发布计划
      baseInfo.querySelector("#Content接口线上测试").parentNode
        .firstElementChild, // 接口线上测试
      baseInfo.querySelector("#Content是否需要灰测(WMS接口用)").parentNode
        .firstElementChild,
      baseInfo.querySelector("#Content预计完成时间(WMS接口用)").parentNode
        .firstElementChild,
    ];

    let targetColor = "red";
    for (const element of elementList) {
      element.style.color = targetColor;
    }
  }
})();