// ==UserScript== // @name TAPD 修改“基本信息”显示 // @namespace hl_qiu163@163.com // @version 0.1.6 // @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 // @downloadURL none // ==/UserScript== (function () { "use strict"; highlightKeyWord(); changeFieldOrder(); /** * 修改字段展示顺序,关心的字段靠前面排 */ 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 baseInfo.querySelector("#ContentDue") ? baseInfo.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") ? baseInfo.querySelector("#ContentEffort").parentNode : baseInfo.querySelector("#ContentEst\\.Effort").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) { if (!node) { continue; } 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; } } })();