// ==UserScript== // @name pingCode-思必驰 // @namespace http://tampermonkey.net/ // @version 2026-1-6 // @description try to take over the world! // @author You // @match https://pms.aispeech.com.cn/* // @icon https://www.google.com/s2/favicons?sz=64&domain=pingcode.com // @grant GM_xmlhttpRequest // @grant unsafeWindow // @require https://cdn.tailwindcss.com // @connect example.com // ==/UserScript== (function () { // 输出环境信息 "use strict"; // Your code here... window.addEventListener("load", function () { //请求后台接口的ip const requireIp = "https://pms.aispeech.com.cn/bpi"; // const requireIp = "https://172.16.2.201/bpi"; // const requireIp = "http://172.16.2.144:8999"; // const requireIp = "https://10.12.4.189/bpi"; const requireApi = "/api"; //需要预览的环境 const devUrl = ""; // 转发规则配置xqs https://mexy20221018025038583.pingcode.com/api/ladon/workload/review/quick-instances let redirectRules = [ //批量登记工时 { from: "/api/ladon/workload/register/batch?only_audit=1", to: requireIp + "/pingcode/configReviewPerson", method: "POST", uuidIndex: 4, replaceKey: "{projectId}", }, //工时日志 提交评审 { from: "/api/ladon/workload/review/stages-by-pilots", to: requireIp + "/pingcode/confirmApproval", method: "POST", uuidIndex: 4, replaceKey: "{projectId}", }, { from: "/api/agile/work-items/state ", to: requireIp + "/external/agile/work-items/state", method: "POST", uuidIndex: 4, replaceKey: "{projectId}", }, { from: "/api/agile/work-items/*/property ", to: requireIp + "/external/agile/work-items/{workItemId}/property", method: "PUT", uuidIndex: 4, replaceKey: "{workItemId}", }, ]; let existTeamList = []; //存储当前登录人都在哪个团队中存在 let projectIds = []; //RD项目列表 //发送请求 function setRequest(data, carBack) { //创建xhr对象 let xhr = new XMLHttpRequest(); //设置xhr请求的超时时间 xhr.timeout = 3000; //设置响应返回的数据格式 xhr.responseType = "text"; //创建一个 post 请求,采用异步 xhr.open(data.methods, data.url, true); xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8"); //注册相关事件回调处理函数 xhr.onload = function (e) { if (xhr.status == 200 || xhr.status == 304) { let res = JSON.parse(this.responseText); if (res.code == "200") { carBack(res); } else { console.log(res.msg || res.message); } if (data.url.indexOf("/pingcode/getSpecialProject") > -1) { carBack(res); } } }; //发送数据 xhr.send(JSON.stringify(data.data)); } const observer = new MutationObserver(function (mutations) { // 监听首页右上角的添加工时 let wordHourBtn = document.querySelectorAll(".dropdown-menu-item.ng-star-inserted"); wordHourBtn.forEach(item => { if (item.innerText == "工时") { item.style.display = "none"; } else if (item.innerText == "登记工时") { item.style.display = "none"; } }); // 监听工作项菜单里的登记工时按钮 // 监听工作项中的添加工时的小按钮 let addBtn = document.querySelectorAll( ".thy-btn.btn.btn-outline-default.btn-xs.ng-star-inserted.thy-btn-icon-only", ); if (addBtn && addBtn.length > 0) { addBtn.forEach(item => { if (item.children && item.children.length == 1) { if (item.children[0].className == "thy-icon thy-icon-plus") { item.style.display = "none"; } } }); } // 监听工时日志的页面 let registerWorkingBtn = document.querySelectorAll( ".btn-group.btn-group-primary.btn-group-md", ); //创建button按钮 let button = document.createElement("button"); button.className = "thy-btn btn word-btn btn-primary ng-star-inserted"; button.thybutton = "primary"; button.innerHTML = "RD&SC工时日志审批"; button.style.fontSize = "0.875rem"; button.style.padding = "0.25rem 20px"; button.style.marginRight = "0.25rem"; if (registerWorkingBtn && registerWorkingBtn.length > 0) { // 找到登记工时按钮后,再去找工时日志的tab切换 let workloadLogTab = document.querySelector( 'a[href="/workspace/workload/log"].active', ); if (workloadLogTab && workloadLogTab.innerText == "工时日志") { // 找到工时日志的页面后,添加RD工时日志审批按钮 //isAddBtn判断是否已经添加了按钮,如果添加了就不再添加 let workloadLogBtn = document.querySelector(".thy-btn.btn.word-btn"); if (!workloadLogBtn) { //registerWorkingBtn[0].before(button) registerWorkingBtn.forEach(item => { // if(item.innerText == '登记工时'){ // item.before(button) item.style.display = "none"; button.onclick = function () { window.open( requireIp + "/static/dist/workHourLogApproval/index.html", "newWindowName", ); }; // } }); } } else { let workloadLogBtn = document.querySelector(".thy-btn.btn.word-btn"); // 方法A:通过父节点删除(兼容性最好,支持所有浏览器) if (workloadLogBtn && workloadLogBtn.parentElement) { workloadLogBtn.parentElement.removeChild(workloadLogBtn); } } } else { let workloadLogBtn = document.querySelector(".thy-btn.btn.word-btn"); // 方法A:通过父节点删除(兼容性最好,支持所有浏览器) if (workloadLogBtn && workloadLogBtn.parentElement) { workloadLogBtn.parentElement.removeChild(workloadLogBtn); } } //监听工时日历的页面 let workloadLogBtn = document.querySelector(".thy-btn.btn.working-reporting"); if (window.location.pathname == "/workspace/workload/insight") { let workloadReviewsTab = document.querySelector( 'a[href="/workspace/workload/insight"].active', ); if (workloadReviewsTab && workloadReviewsTab.innerText == "工时日历") { // 获取新建按钮 let btnPrimary = document.querySelectorAll( ".btn-group.btn-group-primary.btn-group-md", ); // 获取是否已经存在批量工时审批按钮 if (!workloadLogBtn) { button.className = "thy-btn btn working-reporting btn-primary ng-star-inserted"; button.innerHTML = "工时填报"; btnPrimary.forEach(item => { // if(item.innerText == '登记工时'){ item.before(button); item.style.display = "none"; button.onclick = function () { window.open( requireIp + "/static/dist/workload/index.html", "newWindowName", ); }; // } }); } } } else { // 方法A:通过父节点删除(兼容性最好,支持所有浏览器) if (workloadLogBtn && workloadLogBtn.parentElement) { workloadLogBtn.parentElement.removeChild(workloadLogBtn); } } // 监听工时审批 if (window.location.pathname == "/workspace/workload/reviews") { let workloadReviewsTab = document.querySelector( 'a[href="/workspace/workload/reviews"].active', ); if (workloadReviewsTab && workloadReviewsTab.innerText == "工时评审") { // 获取新建按钮 let btnPrimary = document.querySelectorAll(".thy-btn.btn.btn-primary.btn-md"); // 获取是否已经存在批量工时审批按钮 let workloadLogBtn = document.querySelector(".thy-btn.btn.approval"); if (!workloadLogBtn) { button.className = "thy-btn btn approval btn-primary ng-star-inserted"; button.innerHTML = "工时批量审批"; btnPrimary.forEach(item => { if (item.innerText == "新建") { item.before(button); button.onclick = function () { window.open( requireIp + "/static/dist/batchApproval/index.html", "newWindowName", ); // window.location.href="http://localhost:3000/batchApproval/index.html" }; } }); } } } else { let workloadLogBtn = document.querySelector(".thy-btn.btn.approval"); // 方法A:通过父节点删除(兼容性最好,支持所有浏览器) if (workloadLogBtn && workloadLogBtn.parentElement) { workloadLogBtn.parentElement.removeChild(workloadLogBtn); } } //监听是否是设置评审人的弹框 let dialogContainer = document.querySelectorAll( 'thy-dialog-container[aria-labelledby="设置评审人"]', ); //判断是设置评审人弹框的操作 if (dialogContainer.length > 0) { console.log("点击了========"); // 禁用点击事件 const approvalDom = document.getElementsByClassName( "form-group row-fill ng-star-inserted", ); for (let i = 0; i < approvalDom.length; i++) { const item = approvalDom[i]; item.style.pointerEvents = "none"; } // 修改文字:请配置负责人 setTimeout(() => { Array.from(approvalDom).forEach(element => { // 查找包含“选择评审人”文本的元素 const elementsContainingText = element.querySelectorAll("*"); elementsContainingText.forEach(el => { if (el.textContent && el.textContent.trim() == "选择评审人") { // 修改文字颜色为红色 el.style.color = "red"; // 替换文本内容 el.textContent = el.textContent.replace( "选择评审人", "请配置负责人", ); } }); }); }, 1000); } //监听登记工时弹框 隐藏提交审批按钮 let RegisterWorkingHoursPop = document.querySelectorAll( 'thy-dialog-container[aria-labelledby="登记工时"]', ); if (RegisterWorkingHoursPop[0]) { Array.from(RegisterWorkingHoursPop).forEach(element => { // 查找包含“提交评审”文本的元素 const elementsContainingText = element.querySelectorAll("*"); elementsContainingText.forEach(el => { if (el.textContent && el.textContent.trim() == "提交评审") { // 隐藏 “提交评审” 按钮 el.style.display = "none"; } }); }); } //监听修改实际工时弹框 隐藏提交审批按钮 let modifyActualWorkHours = document.querySelectorAll( 'thy-dialog-container[aria-labelledby="修改实际工时"]', ); if (modifyActualWorkHours[0]) { Array.from(modifyActualWorkHours).forEach(element => { // 查找包含“提交评审”文本的元素 const elementsContainingText = element.querySelectorAll("*"); elementsContainingText.forEach(el => { if (el.textContent && el.textContent.trim() == "提交评审") { // 隐藏 “提交评审” 按钮 el.style.display = "none"; } }); }); } //监听批量登记工时弹框 隐藏提交审批按钮 let batchRegisterWorkHours = document.querySelectorAll( 'thy-dialog-container[aria-labelledby="批量登记工时"]', ); if (batchRegisterWorkHours[0]) { Array.from(batchRegisterWorkHours).forEach(element => { // 查找包含“提交评审”文本的元素 const elementsContainingText = element.querySelectorAll("*"); elementsContainingText.forEach(el => { if (el.textContent && el.textContent.trim() == "提交评审") { // 隐藏 “提交评审” 按钮 el.style.display = "none"; } }); }); } //监听是否已经打开自建应用 let applicationsBodyMenu = document.querySelectorAll( ".applications-menu-body .thy-menu", ); if (applicationsBodyMenu && applicationsBodyMenu[0]) { //判断当前用户是否在工时报表团队中,如果不在就隐藏 政府项目工时规划、工时报表-财务 let findInfo = existTeamList.find(good => good._id == "690dad545b9ece25c6e8ed09"); //判断当前用户是否在成员及日志管理团队中,如果不在就隐藏 部门和负责人设置、新增的日志功能 let findInfo2 = existTeamList.find(good => good._id == "6939435bb15a92c49628a55e"); for (let index = 0; index < applicationsBodyMenu[0].children.length; index++) { let item = applicationsBodyMenu[0].children[index]; //如果不在工时报表团队中,就隐藏 政府项目工时规划、工时报表-财务 if (!findInfo) { if ( item.innerText == "工时报表-财务合并" || item.innerText == "政府项目工时规划" || item.innerText == "工时报表-财务" ) { item.style.display = "none"; } } if (!findInfo2) { if (item.innerText == "日志查询" || item.innerText == "部门和负责人设置") { item.style.display = "none"; } } } } }); const observer2 = new MutationObserver(function (mutations) { // 1. 右上角菜单:隐藏「工时/登记工时」 document.querySelectorAll(".dropdown-menu-item.ng-star-inserted").forEach(item => { if (item.innerText === "工时" || item.innerText === "登记工时") { item.style.display = "none"; } }); // 2. 工作项里:隐藏小「+」添加工时按钮 document .querySelectorAll( ".thy-btn.btn.btn-outline-default.btn-xs.ng-star-inserted.thy-btn-icon-only", ) .forEach(item => { const icon = item.children?.[0]; if (icon?.className === "thy-icon thy-icon-plus") { item.style.display = "none"; } }); // 3. 设置评审人弹框:禁用选择、改文字 const setReviewDlg = document.querySelector( 'thy-dialog-container[aria-labelledby="设置评审人"]', ); if (setReviewDlg) { const rows = document.getElementsByClassName( "form-group row-fill ng-star-inserted", ); for (let el of rows) el.style.pointerEvents = "none"; setTimeout(() => { setReviewDlg.querySelectorAll("*").forEach(el => { if (el.textContent?.trim() === "选择评审人") { el.style.color = "red"; el.textContent = "请配置负责人"; } }); }, 1000); } // 4. 登记工时/修改实际工时/批量登记工时:隐藏「提交评审」按钮 ["登记工时", "修改实际工时", "批量登记工时"].forEach(title => { const dlg = document.querySelector( `thy-dialog-container[aria-labelledby="${title}"]`, ); if (!dlg) return; dlg.querySelectorAll("*").forEach(el => { if (el.textContent?.trim() === "提交评审") { el.style.display = "none"; } }); }); // 5. 工时日历页面:显示「工时填报」按钮(仅依赖全局 button、requireIp) const workloadLogBtn = document.querySelector(".thy-btn.btn.working-reporting"); if (window.location.pathname === "/workspace/workload/insight") { const tab = document.querySelector('a[href="/workspace/workload/insight"].active'); if (tab?.innerText === "工时日历" && !workloadLogBtn) { const btnPrimary = document.querySelectorAll( ".btn-group.btn-group-primary.btn-group-md", ); const button = document.createElement("button"); button.className = "thy-btn btn working-reporting btn-primary ng-star-inserted"; button.innerHTML = "工时填报"; button.style.fontSize = "0.875rem"; button.style.padding = "0.25rem 20px"; button.style.marginRight = "0.25rem"; button.onclick = () => { window.open( requireIp + "/static/dist/workload/index.html", "newWindowName", ); }; btnPrimary.forEach(item => { item.before(button); item.style.display = "none"; }); } } else { if (workloadLogBtn?.parentElement) { workloadLogBtn.parentElement.removeChild(workloadLogBtn); } } // 隐藏工时评审 let reviewsPage = document.querySelector('a[href="/workspace/workload/reviews"]') if(reviewsPage){ reviewsPage.style.display = 'none' } // 隐藏EPIC(客户项目) // 判断是否在项目、工作项列表页面 const EPICReg = /^\/pjm\/projects\/[a-zA-Z0-9_-]+\/[a-zA-Z0-9_-]+\/[a-zA-Z0-9_-]+$/ if(EPICReg.test(window.location.pathname)){ let dropdownMenu = document.querySelectorAll(".dropdown-menu-item.ng-star-inserted"); console.log(dropdownMenu) dropdownMenu.forEach(item => { if( item.innerText == "EPIC(客户项目)"){ item.style.display = 'none' } }) // 新建工作项弹框中的 let optionList = document.querySelectorAll(".thy-option-item.ng-star-inserted") optionList.forEach(item => { if(item.innerText == "EPIC(客户项目)"){ item.style.display = 'none' } }) } // 工作项详情 const EPICReg2 = /^\/pjm\/workitems\/[a-zA-Z0-9_-]+$/; if(EPICReg2.test(window.location.pathname)){ let dropdownMenu = document.querySelectorAll(".dropdown-menu-item.ng-star-inserted"); console.log(dropdownMenu) dropdownMenu.forEach(item => { if(item.innerText == "EPIC(客户项目)"){ item.style.display = 'none' } }) } }); const config = { attributes: true, childList: true, subtree: true, attributeOldValue: true, }; observer2.observe(document.body, config); // 纯前端:不需要任何接口数据,页面加载后可立即执行 function runPureDOM() { // 1. 右上角菜单:隐藏「工时/登记工时」 document.querySelectorAll(".dropdown-menu-item.ng-star-inserted").forEach(item => { if (item.innerText === "工时" || item.innerText === "登记工时") { item.style.display = "none"; } }); // 2. 工作项里:隐藏小「+」添加工时按钮 document .querySelectorAll( ".thy-btn.btn.btn-outline-default.btn-xs.ng-star-inserted.thy-btn-icon-only", ) .forEach(item => { const icon = item.children?.[0]; if (icon?.className === "thy-icon thy-icon-plus") { item.style.display = "none"; } }); // 3. 设置评审人弹框:禁用选择、改文字 const setReviewDlg = document.querySelector( 'thy-dialog-container[aria-labelledby="设置评审人"]', ); if (setReviewDlg) { const rows = document.getElementsByClassName( "form-group row-fill ng-star-inserted", ); for (let el of rows) el.style.pointerEvents = "none"; setTimeout(() => { setReviewDlg.querySelectorAll("*").forEach(el => { if (el.textContent?.trim() === "选择评审人") { el.style.color = "red"; el.textContent = "请配置负责人"; } }); }, 1000); } // 4. 登记工时/修改实际工时/批量登记工时:隐藏「提交评审」按钮 ["登记工时", "修改实际工时", "批量登记工时"].forEach(title => { const dlg = document.querySelector( `thy-dialog-container[aria-labelledby="${title}"]`, ); if (!dlg) return; dlg.querySelectorAll("*").forEach(el => { if (el.textContent?.trim() === "提交评审") { el.style.display = "none"; } }); }); // 5. 工时日历页面:显示「工时填报」按钮(仅依赖全局 button、requireIp) const workloadLogBtn = document.querySelector(".thy-btn.btn.working-reporting"); if (window.location.pathname === "/workspace/workload/insight") { const tab = document.querySelector('a[href="/workspace/workload/insight"].active'); if (tab?.innerText === "工时日历" && !workloadLogBtn) { const btnPrimary = document.querySelectorAll( ".btn-group.btn-group-primary.btn-group-md", ); const button = document.createElement("button"); button.className = "thy-btn btn working-reporting btn-primary ng-star-inserted"; button.innerHTML = "工时填报"; button.style.fontSize = "0.875rem"; button.style.padding = "0.25rem 20px"; button.style.marginRight = "0.25rem"; button.onclick = () => { window.open( requireIp + "/static/dist/workload/index.html", "newWindowName", ); }; btnPrimary.forEach(item => { item.before(button); item.style.display = "none"; }); } } else { if (workloadLogBtn?.parentElement) { workloadLogBtn.parentElement.removeChild(workloadLogBtn); } } } //获取团队列表 function getTeamList() { //获取用户信息 setRequest( { methods: "get", url: devUrl + "/api/typhon/account/profile", }, userRes => { //获取团队信息 setRequest( { methods: "get", url: requireIp + "/pingcode/getTeams", }, async res => { let teamList = res.data.references.categories; // 等待Promise完成,拿到结果(暂停1秒后执行下一行) const result = await fetchData(teamList, userRes.data.value.uid); console.log(result, "result"); // 获取RD项目列表的id setRequest( { methods: "get", url: requireIp + "/pingcode/getSpecialProject", }, projectRes => { console.log(projectRes, "projectRes"); projectIds = projectRes; // 配置并启动观察器 const config = { attributes: true, childList: true, subtree: true, attributeOldValue: true, }; observer.observe(document.body, config); }, ); }, ); }, ); } getTeamList(); function fetchData(teamList, uid) { return new Promise(resolve => { for (let i = 0; i < teamList.length; i++) { let item = teamList[i]; if ( item._id == "690dad545b9ece25c6e8ed09" || item._id == "6939435bb15a92c49628a55e" ) { //获取团队的成员 setRequest( { methods: "get", url: requireIp + "/pingcode/getTeamsUser?teamId=" + item._id, }, itemRes => { //对比看看团队成员中是否有当前登录人 itemRes.data.value.forEach(good => { if (good.uid == uid) { existTeamList.push(item); } }); }, ); } } resolve(existTeamList); }); } //获取Url上的?参数 function getQueryString(url) { // 找到?的位置 const queryStart = url.indexOf("?"); // 如果存在?,则提取从?开始的部分,否则返回空字符串 return queryStart !== -1 ? url.substring(queryStart) : ""; } //比较拦截路径与设置的路径是否匹配 function isPathMatch(actualPath, patternPath) { // 是为了只匹配固定的路径,携带only_audit=1参数的路径 if (actualPath.indexOf("/api/ladon/workload/register/batch?only_audit=1") > -1) { return actualPath == patternPath; } // 创建 URL 对象(假设使用当前域名) const actualUrl = new URL(actualPath, "http://localhost"); const patternUrl = new URL(patternPath, "http://localhost"); // 提取路径名部分 const actualParts = actualUrl.pathname.split("/"); const patternParts = patternUrl.pathname.split("/"); if (actualParts.length !== patternParts.length) { return false; } // 逐个比较路径段 for (let i = 0; i < actualParts.length; i++) { if (actualParts[i] === "*") { continue; // * 匹配任意内容,跳过比较 } if (actualParts[i] !== patternParts[i]) { return false; // 不匹配 } } return true; // 所有段都匹配 } function getUUidByOriginalUrl(url, uuidIndex) { const actualUrl = new URL(url, "http://localhost"); const actualParts = actualUrl.pathname.split("/"); return actualParts[uuidIndex]; } // 自定义Toast函数 function showToast(message, duration = 3000) { // 创建Toast元素(避免重复创建) let toast = document.querySelector(".toast"); if (!toast) { toast = document.createElement("div"); toast.className = "toast"; toast.style.minWidth = "380px"; toast.style.position = "fixed"; toast.style.top = "20px"; toast.style.left = "50%"; toast.style.transform = "translate(-50%)"; toast.style.padding = "15px"; toast.style.border = "1px solid #fde2e2"; toast.style.color = "#F56C6C"; toast.style.borderRadius = "4px"; toast.style.fontSize = "14px"; toast.style.zIndex = 9999; toast.style.opacity = 0; toast.style.transition = "opacity 0.3s, transform 0.4s, top 0.4s, -webkit-transform 0.4s;"; toast.style.backgroundColor = "#fef0f0"; document.body.appendChild(toast); } // 设置提示文本 toast.innerHTML = message; // 显示Toast toast.classList.add("show"); toast.style.opacity = 1; // 自动隐藏 setTimeout(() => { toast.classList.remove("show"); toast.style.opacity = 0; }, duration); } setTimeout(async () => { console.log("---加载"); // 拦截 XMLHttpRequest xqs const originalXHROpen = XMLHttpRequest.prototype.open; const originalSend = XMLHttpRequest.prototype.send; let currentUrl = ""; XMLHttpRequest.prototype.send = function (body) { // 工时日志 查询是否有RD项目阻断请求 let isSend = true; if (currentUrl.indexOf("/api/ladon/workload/review/check-review-permission") > -1) { const sendBody = JSON.parse(body); sendBody.data.map(item => { if (projectIds.indexOf(item.pilot_id) > -1) { isSend = false; } }); } if (window.location.pathname == "/workspace/workload/log" && !isSend) { showToast("RD项目请点击右上角【RD&SC工时日志审批】"); return; } // 项目概览 修改项目负责人 let isOverview = false; if (currentUrl.startsWith("/api/agile/projects/")) { const sendBody = JSON.parse(body); if (sendBody && sendBody.assignee) { isOverview = true; } } this.addEventListener("load", function () { // rd项目 深聪项目 修改项目负责人的处理 const reg = /^\/external\/agile\/work-items\/[0-9a-fA-F]{24}\/property$/; let urlList = this.responseURL.split("bpi"); // let urlList = this.responseURL.split('8999') const isMatch = urlList && reg.test(urlList[urlList.length - 1]); if (isMatch) { const sendBody = JSON.parse(body); console.log(sendBody); if ( sendBody.key != "yanfabuziyanxiangmu" && sendBody.key != "yanfabuziyanxiangmufuzeren" && sendBody.key != "renwubao" ) return; const path = window.location.pathname; const pathList = path.split("/"); const projectCode = pathList[pathList.length - 1]; setTimeout(() => { setRequest( { methods: "get", url: requireApi + "/agile/work-items/" + projectCode, }, res => { let properties = res.data.value.properties; let data = { headId: properties.yanfabuziyanxiangmufuzeren, workingHoursTask: properties.yanfabuziyanxiangmu || properties.renwubao, taskId: res.data.value._id, type: sendBody.key, }; setRequest( { methods: "put", url: requireIp + "/workInfo/editRDProjectManager", data, }, resData => { console.log(resData, "resData"); }, ); }, ); }, 3000); } // 其他项目 修改项目负责人 // 判断是否在当前项目概览 // 正则:以 /pjm/projects 开头,且包含 /overview const reg1 = /^\/pjm\/projects.*\/overview/; const path = window.location.pathname; if (reg1.test(path) && isOverview) { const sendBody = JSON.parse(body); // 判断是否修改负责人 if (!sendBody.assignee) return; const projectsCode = path.split("/")[3]; let urlList = this.responseURL.split("/"); const projectId = urlList[urlList.length - 1]; let data = { projectCode: projectsCode, projectId: projectId, assignee: sendBody.assignee, }; setRequest( { methods: "put", url: requireIp + "/workInfo/editProjectManager?projectCode=" + projectsCode + "&projectId=" + projectId, data, }, resData => { console.log(resData, "resData"); }, ); } }); // 调用原生的 send 方法,发送请求(如果修改了 body,会发送修改后的参数) return originalSend.apply(this, [body]); }; XMLHttpRequest.prototype.open = function (method, url) { // ✅ 关键:强制开启携带 Cookie(必须在 send() 之前设置) this.withCredentials = true; currentUrl = url; const rule = redirectRules.find(r => { if (isPathMatch(r.from, url) && r.method == method) { return r; } }); if (rule && rule.method == method) { console.log("拦截 XHR 请求:", method, url); let newUrl = rule.to; //拼接参数,为与原接口保持一致 const ignone = ["/api/ladon/workload/register/batch?only_audit=1"]; // 为了解决,路径不需要only_audit=1参数的问题 if (ignone.indexOf(url) == -1) { newUrl += getQueryString(url); } newUrl = newUrl.replaceAll( rule.replaceKey, getUUidByOriginalUrl(url, rule.uuidIndex), ); if (rule.replaceKey2) { newUrl = newUrl.replaceAll( rule.replaceKey2, getUUidByOriginalUrl(url, rule.uuidIndex2), ); } if (rule.replaceKey3) { newUrl = newUrl.replaceAll( rule.replaceKey3, getUUidByOriginalUrl(url, rule.uuidIndex3), ); } //增加判断 ,如果有afterNewRequest 属性,则依旧转发原请求,并在原请求响应后调用afterNewRequest的路径 if (rule.afterNewRequest) { //console.log(rule) //todo } else { url = newUrl; } // 全部请求相关信息 var self = this; // 监听readystatechange事件 this.onreadystatechange = function () { // 当readyState变为4时获取响应 pingcode/configReviewPerson if ( self.readyState == 4 && self.responseURL.indexOf("pingcode/configReviewPerson") != -1 ) { let res = JSON.parse(self.response); if (res.code == 500) { let msg = res.msg; let message = ""; if (msg.project && msg.project.length > 0) { message = `请配置以下RD项目负责人:${msg.project.join(",")}`; } if (msg.dept) { if (message == "") { message = `
${msg.dept}
`; } else { message += `
${msg.dept}
`; } } showToast(message); } } }; return originalXHROpen.call(this, method, url); } // 可以在这里修改请求参数 return originalXHROpen.apply(this, arguments); }; }, 500); }); })();