您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在阿里物流页面集成箱规合箱计算表单
// ==UserScript== // @name 箱规合箱计算器-树洞先生 // @namespace http://tampermonkey.net/ // @version 1.3 // @description 在阿里物流页面集成箱规合箱计算表单 // @author 树洞先生 // @license MIT // @match *://*/* // @grant none // ==/UserScript== (function() { 'use strict'; // 创建触发按钮 const showBtn = document.createElement('button'); showBtn.textContent = '📦'; showBtn.style.position = 'fixed'; showBtn.style.top = '80px'; showBtn.style.right = '20px'; showBtn.style.zIndex = 9999; showBtn.style.background = '#1890ff'; showBtn.style.color = '#fff'; showBtn.style.border = 'none'; showBtn.style.padding = '10px 20px'; showBtn.style.borderRadius = '6px'; showBtn.style.cursor = 'pointer'; document.body.appendChild(showBtn); // 创建表单容器(初始隐藏) const container = document.createElement('div'); container.style.position = 'fixed'; container.style.top = '130px'; container.style.right = '20px'; container.style.zIndex = 10000; container.style.background = '#e6f0ff'; // 蓝色背景 container.style.border = '1px solid #1890ff'; container.style.padding = '16px'; container.style.borderRadius = '8px'; container.style.boxShadow = '0 2px 8px rgba(0,0,0,0.1)'; container.style.fontSize = '14px'; container.style.display = 'none'; // 表单内容 container.innerHTML = ` <div style="font-weight:bold;margin-bottom:8px;">箱规合箱计算器</div> <div style="margin-bottom:8px;"> <label>产品尺寸(cm): <input id="product-l" type="number" style="width:50px" placeholder="长"> × <input id="product-w" type="number" style="width:50px" placeholder="宽"> × <input id="product-h" type="number" style="width:50px" placeholder="高"> </label> </div> <div style="margin-bottom:8px;"> <label>箱规尺寸(cm):(选填) <input id="maxbox-l" type="number" style="width:50px" placeholder="长"> × <input id="maxbox-w" type="number" style="width:50px" placeholder="宽"> × <input id="maxbox-h" type="number" style="width:50px" placeholder="高"> </label> </div> <div style="margin-bottom:8px;"> <label>最大装箱数:(选填) <input id="max-per-box" type="number" style="width:60px" placeholder=""></label> </div> <div style="margin-bottom:8px;"> <label>实际装箱数量: <input id="box-count" type="number" style="width:60px" placeholder=""></label> </div> <div style="margin-bottom:8px;"> <label>空隙率(%): <input id="gap-rate" type="number" style="width:60px" placeholder="如5" value="5"></label> </div> <button id="box-calc-btn" style="margin-top:10px;background:#1890ff;color:#fff;border:none;padding:6px 16px;border-radius:4px;cursor:pointer;">计算</button> <button id="box-close-btn" style="margin-top:10px;margin-left:10px;background:#fff;color:#1890ff;border:1px solid #1890ff;padding:6px 16px;border-radius:4px;cursor:pointer;">关闭</button> <div id="box-result" style="margin-top:10px;color:#333;"></div> `; document.body.appendChild(container); // 紧凑排列算法:允许空位,体积最小且三边差最小 function getBestLooseArrangement(n) { let best = [n, 1, 1]; let minVol = Infinity; let minDiff = Infinity; const maxSide = Math.ceil(Math.pow(n, 1/3)) * 3; for (let a = 1; a <= maxSide; a++) { for (let b = 1; b <= maxSide; b++) { for (let c = 1; c <= maxSide; c++) { if (a * b * c < n) continue; let arr = [a, b, c]; let vol = a * b * c; let diff = Math.max(...arr) - Math.min(...arr); if ( vol < minVol || (vol === minVol && diff < minDiff) ) { minVol = vol; minDiff = diff; best = arr; } } } } return best; } // 显示弹窗 showBtn.onclick = function() { container.style.display = 'block'; }; // 关闭弹窗 container.querySelector('#box-close-btn').onclick = function() { container.style.display = 'none'; }; // 事件 container.querySelector('#box-calc-btn').onclick = function() { const productL = parseFloat(document.getElementById('product-l').value); const productW = parseFloat(document.getElementById('product-w').value); const productH = parseFloat(document.getElementById('product-h').value); const maxBoxL = parseFloat(document.getElementById('maxbox-l').value); const maxBoxW = parseFloat(document.getElementById('maxbox-w').value); const maxBoxH = parseFloat(document.getElementById('maxbox-h').value); const maxPerBox = parseInt(document.getElementById('max-per-box').value, 10); const count = parseInt(document.getElementById('box-count').value, 10); const gapRate = parseFloat(document.getElementById('gap-rate').value) || 0; let resultDiv = document.getElementById('box-result'); // 只校验产品尺寸和装箱数量 if ([productL, productW, productH, count].some(x => isNaN(x) || x <= 0)) { resultDiv.textContent = '请正确填写产品尺寸和装箱数量!'; return; } // 判断是否有限制 const hasBoxLimit = !isNaN(maxBoxL) && !isNaN(maxBoxW) && !isNaN(maxBoxH) && maxBoxL > 0 && maxBoxW > 0 && maxBoxH > 0; const hasCountLimit = !isNaN(maxPerBox) && maxPerBox > 0; if (hasCountLimit && count > maxPerBox) { resultDiv.textContent = '实际装箱数量不能大于单箱最大装箱数!'; return; } // 使用紧凑排列算法 const [numL, numW, numH] = getBestLooseArrangement(count); // 生成所有排列组合(6种) function getAllPermutations(arr) { return [ [arr[0], arr[1], arr[2]], [arr[0], arr[2], arr[1]], [arr[1], arr[0], arr[2]], [arr[1], arr[2], arr[0]], [arr[2], arr[0], arr[1]], [arr[2], arr[1], arr[0]], ]; } const boxDims = hasBoxLimit ? [maxBoxL, maxBoxW, maxBoxH].sort((a, b) => b - a) : null; const factor = 1 + gapRate / 100; let bestOpt = null, minVol = Infinity; for (const nArr of getAllPermutations([numL, numW, numH])) { for (const pArr of getAllPermutations([productL, productW, productH])) { const dims = [nArr[0] * pArr[0], nArr[1] * pArr[1], nArr[2] * pArr[2]]; const dimsWithGap = dims.map(x => x * factor).sort((a, b) => b - a); if (hasBoxLimit) { if (dimsWithGap[0] > boxDims[0] || dimsWithGap[1] > boxDims[1] || dimsWithGap[2] > boxDims[2]) continue; } const vol = dimsWithGap[0] * dimsWithGap[1] * dimsWithGap[2]; if (vol < minVol) { minVol = vol; bestOpt = dimsWithGap; } } } if (bestOpt) { const l = bestOpt[0], w = bestOpt[1], h = bestOpt[2]; const cbm = (l * w * h) / 1e6; const volWeightExpress = (l * w * h) / 5000; const volWeightSea = (l * w * h) / 6000; resultDiv.innerHTML = ` 排列:${numL} × ${numW} × ${numH}(共${numL * numW * numH}格,实际装${count}个)<br> 合箱尺寸(含空隙):<b>${l.toFixed(1)} × ${w.toFixed(1)} × ${h.toFixed(1)} cm</b><br> CBM:<b>${cbm.toFixed(4)}</b> 立方米<br> 体积重(快递):<b>${volWeightExpress.toFixed(2)}</b> kg<br> 体积重(海运):<b>${volWeightSea.toFixed(2)}</b> kg `; } else { resultDiv.innerHTML = '该数量无法在最大箱规内装下!'; } }; })();