// ==UserScript== // @name 点云标注-指定标签批注完整版 // @namespace http://tampermonkey.net/ // @version 4.0 // @description F2快捷键:打开弹窗→点击下拉箭头→选中属性错误→直接点确定,不操作备注 // @author You // @match *://*/* // @grant none // ==/UserScript== (function() { 'use strict'; const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); // 获取工具栏第5个按钮,数组下标4 function getTargetCommentBtn() { const toolBtns = document.querySelectorAll('div[role="toolbar"] button,.toolbar button'); const btnArr = Array.from(toolBtns); const targetBtn = btnArr[4]; if(targetBtn){ const rect = targetBtn.getBoundingClientRect(); if(rect.width>15 && rect.height>15){ return targetBtn; } } return null; } // 等待元素出现 async function waitElement(selector, timeout=4500){ const start = Date.now(); while(Date.now()-start < timeout){ const el = document.querySelector(selector); if(el) return el; await sleep(150); } return null; } // 通过文本内容查找DOM function findByText(text){ const all = document.querySelectorAll('*'); for(let el of all){ if(el.textContent && el.textContent.trim() === text){ return el; } } return null; } // 完整模拟鼠标事件 async function realClick(el){ if(!el) return; const rect = el.getBoundingClientRect(); const x = rect.left + rect.width / 2; const y = rect.top + rect.height / 2; el.dispatchEvent(new MouseEvent('mouseover', {clientX:x, clientY:y, bubbles:true})); await sleep(100); el.dispatchEvent(new MouseEvent('mousedown', {clientX:x, clientY:y, bubbles:true})); await sleep(80); el.dispatchEvent(new MouseEvent('mouseup', {clientX:x, clientY:y, bubbles:true})); await sleep(80); el.dispatchEvent(new MouseEvent('click', {clientX:x, clientY:y, bubbles:true})); if(typeof el.click === "function") el.click(); } async function runTask(){ console.log("\n=====【开始批注任务】====="); // 1、打开批注弹窗 const triggerBtn = getTargetCommentBtn(); if(!triggerBtn){ console.error("❌找不到工具栏批注按钮"); return; } await realClick(triggerBtn); await sleep(1000); const dialog = await waitElement('div[role="dialog"]'); if(!dialog){ console.error("❌批注弹窗没有弹出来"); return; } console.log("✅弹窗已打开"); // 2、点击下拉箭头展开选项,失败自动重试一次 let arrow = dialog.querySelector('.ant-select-arrow'); if(!arrow){ console.error("❌找不到下拉箭头"); return; } console.log("✅点击下拉箭头"); await realClick(arrow); await sleep(1100); let listBox = document.querySelector('div[role="listbox"]'); if(!listBox){ console.log("🔄下拉未弹出,进行重试"); await realClick(arrow); await sleep(1100); listBox = await waitElement('div[role="listbox"]',2000); } if(!listBox){ console.error("❌两次尝试,下拉列表依然打不开"); return; } // 3、选中属性错误 const attrErrItem = findByText("属性错误"); if(!attrErrItem){ console.error("❌找不到【属性错误】选项"); return; } console.log("✅选中属性错误"); await realClick(attrErrItem); await sleep(900); // 4、直接点击确定提交,跳过备注 const okBtn = findByText("确定"); if(!okBtn){ console.error("❌找不到确定按钮"); return; } console.log("✅点击确定提交"); await realClick(okBtn); console.log("=====✅整套流程执行完毕====="); } // F2快捷键绑定 document.addEventListener('keydown', async function(e){ if(e.key === 'F2'){ e.preventDefault(); await runTask(); } }); console.log("✅脚本已加载完成,选中目标框按下F2执行"); })();