以下适用物润船联的网货平台系统
1.网页指定元素内,鼠标右键菜单选项并填入指定元素事件
// ==UserScript==
// @name 快速审核插件
// @namespace http://*
// @version 1.0
// @description try to take over the world!
// @author Jagyl
// @match https://admin.jagyl.top/*
// @icon https://*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 预定义的文本内容,包括二级菜单项
const predefinedMenu = [
{
text: '证件缺失 >>',
subItems: [' 上传身份证!',' 上传车辆协议,没协议用身份证人像正面!', ' 上传电子版道路运输证!', ' 上传对应驾驶证证和副本!', ' 上传对应行驶证和副本!', ' 上传道路运输证!',' 上传从业资格证',' 上传人车合照,要求人站车前,车头车牌全部拍到!', ' 上传最新的车辆年检记录!']
},
{
text: '证件质量 >>',
subItems: [' 身份证模糊!', ' 驾驶证模糊!',' 行驶证模糊!',' 从业资格证模糊!',' 道路运输证模糊!']
},
{
text: ' 证件逾期 >>',
subItems: [' 身份证逾期!', ' 驾驶证逾期!',' 行驶证年检逾期!',' 从业资格证逾期!',' 道路运输证逾期!']
},
{
text: 'A------ >>',
subItems: ['A-1', 'A-2', 'A-3']
},
{
text: 'B------ >>',
subItems: ['B-1', 'B-2', 'B-3']
}
];
// 监听右键点击事件
document.addEventListener('contextmenu', function(e) {
// 找到目标 textarea
let textareaElement = e.target.closest('textarea.ivu-input');
// 检查是否点击在指定的 textarea 上
if (textareaElement) {
e.preventDefault(); // 阻止默认右键菜单
// 移除已存在的自定义菜单,避免重复
removeExistingMenu();
// 显示自定义菜单
showCustomMenu(e.pageX, e.pageY, textareaElement);
}
});
// 显示自定义菜单并提供预定义的主菜单和子菜单
function showCustomMenu(x, y, textareaElement) {
let customMenu = document.createElement('div');
customMenu.id = 'customMenu'; // 给菜单一个ID,方便删除
customMenu.style.position = 'absolute';
customMenu.style.backgroundColor = 'white';
customMenu.style.padding = '5px';
customMenu.style.border = '1px solid #ccc';
customMenu.style.zIndex = '10000';
customMenu.style.whiteSpace = 'nowrap'; // 避免文本换行
customMenu.style.minWidth = '100px'; // 设置最小宽度
customMenu.style.maxWidth = '300px'; // 限制最大宽度,防止过长文本撑开页面
customMenu.style.boxShadow = '0px 0px 10px rgba(0, 0, 0, 0.1)'; // 添加阴影以美化
// 动态调整菜单位置,防止超出屏幕
document.body.appendChild(customMenu); // 先添加到body中,再调整位置
adjustMenuPosition(customMenu, x, y);
// 创建主菜单项
predefinedMenu.forEach(function(menuItem) {
let mainMenuItem = document.createElement('div');
mainMenuItem.textContent = menuItem.text;
mainMenuItem.style.padding = '5px';
mainMenuItem.style.cursor = 'pointer';
mainMenuItem.style.position = 'relative';
// 创建子菜单容器
let subMenu = document.createElement('div');
subMenu.style.position = 'absolute';
subMenu.style.left = '100%';
subMenu.style.top = '0';
subMenu.style.backgroundColor = 'white';
subMenu.style.padding = '5px';
subMenu.style.border = '1px solid #ccc';
subMenu.style.whiteSpace = 'nowrap'; // 避免文本换行
subMenu.style.minWidth = '100px'; // 设置最小宽度
subMenu.style.maxWidth = '300px'; // 限制最大宽度
subMenu.style.display = 'none'; // 初始时隐藏
subMenu.style.zIndex = '10001';
subMenu.style.boxShadow = '0px 0px 10px rgba(0, 0, 0, 0.1)'; // 添加阴影
// 为每个主菜单项创建对应的子菜单项
menuItem.subItems.forEach(function(subItemText) {
let subMenuItem = document.createElement('div');
subMenuItem.textContent = subItemText;
subMenuItem.style.padding = '5px';
subMenuItem.style.cursor = 'pointer';
// 当点击子菜单时,将其内容追加到 textarea
subMenuItem.onclick = function() {
// 在现有内容后追加文本
textareaElement.value += subItemText;
removeExistingMenu(); // 填充后隐藏菜单
};
subMenu.appendChild(subMenuItem);
});
// 鼠标悬停时显示子菜单
mainMenuItem.addEventListener('mouseover', function() {
subMenu.style.display = 'block';
});
// 鼠标移出时隐藏子菜单
mainMenuItem.addEventListener('mouseout', function() {
subMenu.style.display = 'none';
});
mainMenuItem.appendChild(subMenu);
customMenu.appendChild(mainMenuItem);
});
// 点击其他地方时移除菜单
document.addEventListener('click', function removeMenu(event) {
if (!customMenu.contains(event.target)) {
removeExistingMenu();
document.removeEventListener('click', removeMenu);
}
});
}
// 调整菜单位置,防止被浏览器窗口遮挡,左下角为基准弹出
function adjustMenuPosition(menu, x, y) {
// 获取窗口的宽度和高度
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
// 获取菜单的尺寸
const menuRect = menu.getBoundingClientRect();
// 如果菜单超出右边界,则向左调整
if ((x + menuRect.width) > windowWidth) {
menu.style.left = `${x - menuRect.width}px`;
} else {
menu.style.left = `${x}px`;
}
// 菜单左下角对齐:如果菜单超出底部,则向上调整
if ((y + menuRect.height) > windowHeight) {
menu.style.top = `${y - menuRect.height}px`;
} else {
menu.style.top = `${y - menuRect.height}px`; // 左下角对齐鼠标位置
}
}
// 移除现有的自定义菜单(如果有)
function removeExistingMenu() {
let existingMenu = document.getElementById('customMenu');
if (existingMenu) {
document.body.removeChild(existingMenu);
}
}
})();
2.其他表单内的自动化:
// ==UserScript==
// @name 车辆审核综合插件2
// @namespace http://*
// @version 1.2
// @description 提供多种便捷操作,如更改textarea高度、同步年检日期、同步车辆所有人信息以及复制VIN码和车牌号到剪贴板。
// @author Jagyl
// @match https://admin.jagyl.top/*
// @icon https://*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Function to change the height of textarea elements
function changeTextareaHeight() {
const textareas = document.querySelectorAll('textarea');
textareas.forEach(textarea => {
textarea.style.height = '200px';
});
}
// Function to copy and update the date
function copyAndUpdateDate() {
const currentDate = new Date();
const nextYear = (currentDate.getFullYear() + 1).toString();
const sourceXPath = "//label[contains(text(), '车辆行驶证注册日期')]/..//input";
const sourceNode = document.evaluate(sourceXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (sourceNode) {
let sourceText = sourceNode.value;
const updatedText = sourceText.replace(/(\d{4})/, nextYear);
const targetXPath = "//label[contains(text(), '行驶证到期日期')]/..//input";
const targetNode = document.evaluate(targetXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (targetNode) {
targetNode.value = updatedText;
} else {
console.error('Target <input> element not found.');
}
} else {
console.error('Source <input> element not found.');
}
}
// Function to copy vehicle owner information
function copyVehicleOwnerInfo() {
const sourceXPath = "//label[contains(text(), '车辆所有人')]/..//input";
const sourceNode = document.evaluate(sourceXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (sourceNode) {
const sourceText = sourceNode.value;
const targetXPath = "//label[contains(text(), '业户名称')]/..//input";
const targetNode = document.evaluate(targetXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (targetNode) {
targetNode.value = sourceText;
} else {
console.error('Target <input> element for vehicle owner not found.');
}
} else {
console.error('Source <input> element for vehicle owner not found.');
}
}
// Function to copy VIN and another value to clipboard
function copyVINAndAnotherValueToClipboard() {
const vinXPath = "//label[contains(text(), '道路运输证字号')]/..//input";
const vinNode = document.evaluate(vinXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
const anotherValueXPath = "//label[contains(text(), '车牌号')]/..//input";
const anotherValueNode = document.evaluate(anotherValueXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (vinNode && anotherValueNode) {
const valuesList = [vinNode.value, anotherValueNode.value].join('\n');
navigator.clipboard.writeText(valuesList)
.then(() => {
alert('VIN码和车牌号已复制到剪切板');
})
.catch(err => {
console.error('获取失败: ', err);
});
} else {
console.error('识别码异常');
}
}
// Function to fill input from clipboard
async function fillInputFromClipboard() {
try {
const clipText = await navigator.clipboard.readText();
const xpathExpression = "//label[contains(text(), '道路运输证到期日期')]/..//input"; // 修改为实际的XPath
const targetNode = document.evaluate(xpathExpression, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (targetNode) {
targetNode.value = clipText.trim();
alert('从剪贴板填充输入成功!');
} else {
console.error('目标 <input> 元素未找到。');
alert('目标 <input> 元素未找到。');
}
} catch (err) {
console.error('无法从剪贴板读取数据: ', err);
alert('无法从剪贴板读取数据,请检查权限设置。');
}
}
// 创建第一个按钮元素 - 更改textarea高度
const button1 = createButton('审核意见插件', 10, 10, changeTextareaHeight);
// 创建第二个按钮元素 - 复制并更新日期
const button2 = createButton('同步年检日期', 110, 10, copyAndUpdateDate);
// 创建第三个按钮元素 - 同步车辆所有人
const button3 = createButton('同步业户名称', 10, 55, copyVehicleOwnerInfo);
// 创建第四个按钮元素 - 复制VIN码和车牌号
const button4 = createButton('<运输证>车牌', 110, 55, copyVINAndAnotherValueToClipboard);
// 创建第五个按钮元素 - 从剪贴板填充输入
const button5 = createButton('运输证有效期', 10, 100, fillInputFromClipboard);
// 将五个按钮添加到文档中
[button1, button2, button3, button4, button5].forEach(button => document.body.appendChild(button));
// Helper function to create a button
function createButton(text, left, bottom, clickHandler) {
const button = document.createElement('button');
button.textContent = text;
button.style.position = 'fixed';
button.style.bottom = `${bottom}px`;
button.style.padding = '9px';
button.style.left = `${left}px`;
button.style.zIndex = '1000';
button.addEventListener('click', clickHandler);
return button;
}
})();
交通部网页查询
// ==UserScript==
// @name 交通运输部运输证信息插件
// @namespace http://tampermonkey.net/
// @version 2024-09-28
// @description 运输证查询信息插件
// @author JAGYL
// @match https://ysfw.mot.gov.cn/NetRoadCGSS-web/information/query?searchType=owner
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Function to read clipboard and fill input elements
function fillInputsFromClipboard() {
navigator.clipboard.readText()
.then(clipText => {
const values = clipText.split('\n').map(value => value.trim());
if (values.length === 2) {
const [vin, anotherValue] = values;
const vehicleNoNode = document.evaluate("//*[@id='transCertificateCode']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
const transCertificateCodeNode = document.evaluate("//*[@name='vehicleNo']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (vehicleNoNode && transCertificateCodeNode) {
vehicleNoNode.value = vin;
transCertificateCodeNode.value = anotherValue;
alert('输入框已成功填充!');
} else {
console.error('One or both of the <input> elements not found.');
}
} else {
console.error('Clipboard does not contain exactly two values.');
}
})
.catch(err => {
console.error('Failed to read from clipboard: ', err);
});
}
// Function to get information from a specific location using XPath and copy to clipboard
async function getInfoAndCopyToClipboard() {
const xpathExpression = "//*[@id='search-2']/table[2]/tbody/tr[3]/td[4]";
const result = document.evaluate(xpathExpression, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
if (result) {
try {
await navigator.clipboard.writeText(result.innerText);
alert('指定位置的信息已复制到剪贴板: ' + result.innerText);
} catch (err) {
console.error('Failed to write to clipboard: ', err);
alert('无法将信息复制到剪贴板,请检查权限设置。');
}
} else {
console.error('无法找到指定位置的元素。');
alert('无法找到指定位置的元素。');
}
}
// 创建第一个按钮 - 从剪贴板填充输入
const buttonFill = document.createElement('button');
buttonFill.textContent = '运输证车号';
buttonFill.style.position = 'fixed';
buttonFill.style.bottom = '10px';
buttonFill.style.padding = '10px';
buttonFill.style.left = '10px';
buttonFill.style.zIndex = '1000';
buttonFill.addEventListener('click', fillInputsFromClipboard);
// 创建第二个按钮 - 获取指定位置的信息并复制到剪贴板
const buttonGetInfo = document.createElement('button');
buttonGetInfo.textContent = '获取日期';
buttonGetInfo.style.position = 'fixed';
buttonGetInfo.style.bottom = '10px';
buttonGetInfo.style.padding = '10px';
buttonGetInfo.style.left = '140px'; // 放置在第一个按钮旁边
buttonGetInfo.style.zIndex = '1000';
buttonGetInfo.addEventListener('click', getInfoAndCopyToClipboard);
// 将两个按钮添加到文档中
document.body.appendChild(buttonFill);
document.body.appendChild(buttonGetInfo);
})();