// ==UserScript== // @name 腾讯文档 - 快递工具合集(优化版) // @namespace http://tampermonkey.net/ // @version 3.5 // @description 快递CSV单号匹配 + 智能文本解析 + 格式化填入 + 数量拆分 // @author Codex // @match https://docs.qq.com/sheet/* // @icon https://docs.qq.com/favicon.ico // @grant GM_notification // @license MIT // ==/UserScript== (function(){"use strict"; var D=document; // CSS注入 (function(){var s=D.createElement("style");s.textContent=".co{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.35);z-index:999999;display:flex;align-items:center;justify-content:center;font-family:Microsoft YaHei,sans-serif}.cd{background:#fff;border-radius:12px;padding:0;width:760px;max-width:92vw;max-height:88vh;box-shadow:0 8px 32px rgba(0,0,0,.2);display:flex;flex-direction:column;font-size:14px;color:#1d2129;overflow:hidden}.ct{display:flex;background:#f7f8fa;border-bottom:1px solid #e5e6e8}.ct button{padding:12px 24px;border:none;background:transparent;font-size:14px;cursor:pointer;color:#4e5969;border-bottom:2px solid transparent}.ct button:hover{background:#eef0f4}.ct button.on{color:#2468f2;border-bottom-color:#2468f2;background:#fff;font-weight:600}.cb{padding:20px 24px 16px;overflow-y:auto;flex:1}.cb .hint{color:#86909c;font-size:13px;margin-bottom:8px}.cb textarea{width:100%;height:130px;padding:10px 12px;border:1px solid #e5e6e8;border-radius:6px;font-size:13px;font-family:Consolas,monospace;resize:vertical;box-sizing:border-box;outline:none;margin-bottom:8px}.cb textarea:focus{border-color:#2468f2}.cb label{font-size:13px;color:#4e5969;display:inline-flex;align-items:center;gap:4px;margin-right:10px}.cb label input[type=text]{width:50px;padding:4px 6px;border:1px solid #e5e6e8;border-radius:4px;font-size:13px;text-align:center;outline:none}.cb label input[type=text]:focus{border-color:#2468f2}.cb .br{display:flex;gap:10px;justify-content:flex-end;margin-top:8px;flex-wrap:wrap}.cb .br button{padding:8px 20px;border-radius:6px;border:none;font-size:14px;cursor:pointer}.cb .br button:hover{opacity:.85}.bp{background:#2468f2;color:#fff}.bs{background:#f2f3f5;color:#4e5969}.bp:disabled{opacity:.5;cursor:not-allowed}.cl{background:#f7f8fa;border-radius:6px;padding:10px 12px;margin-top:8px;max-height:200px;overflow:auto;font-size:12px;font-family:Consolas,monospace;line-height:1.6;white-space:pre-wrap}.cl .ok{color:#00b42a}.cl .skip{color:#86909c}.cl .err{color:#f53f3f}.cr{border:1px solid #e5e6e8;border-radius:6px;margin-top:8px;max-height:200px;overflow:auto;font-size:12px}.cr table{width:100%;border-collapse:collapse}.cr th{background:#f7f8fa;padding:5px 7px;text-align:left;font-weight:600;border-bottom:1px solid #e5e6e8;font-size:11px}.cr td{padding:4px 7px;border-bottom:1px solid #f2f3f5;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11px}.cf,.cm{position:fixed;right:32px;z-index:999999;width:48px;height:48px;border-radius:50%;color:#fff;border:none;box-shadow:0 4px 12px rgba(36,104,242,.4);font-size:22px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:.2s}.cf:hover,.cm:hover{transform:scale(1.08)}.cf{bottom:32px;background:#2468f2}.cm{bottom:92px;background:#00b42a}";D.head.appendChild(s)})(); // 按钮 D.body.appendChild(function(b){b.className="cf";b.textContent="CSV";b.title="CSV单号匹配";b.onclick=function(){showDialog("csv")};return b}(D.createElement("button"))); D.body.appendChild(function(b){b.className="cm";b.textContent="AI";b.title="智能解析文本";b.onclick=function(){showDialog("parse")};return b}(D.createElement("button"))); function sl(t){return new Promise(function(r){setTimeout(r,t)})} function L(el,t,c){var d=D.createElement("div");d.textContent=t;if(c)d.className=c;el.appendChild(d);el.scrollTop=el.scrollHeight} async function wc(cell,val){ var lb=D.querySelector(".bar-label"),ed=D.querySelector("#alloy-simple-text-editor"); if(!lb||!ed)return false; var v=String(val||"");lb.focus();lb.value=cell; lb.dispatchEvent(new Event("input",{bubbles:true})); ["keydown","keypress","keyup"].forEach(function(t){lb.dispatchEvent(new KeyboardEvent(t,{key:"Enter",keyCode:13,bubbles:true}))}); lb.dispatchEvent(new Event("change",{bubbles:true}));await sl(200); ed.focus();window.getSelection().selectAllChildren(ed);document.execCommand("delete",false); await sl(30);document.execCommand("insertText",false,v);await sl(30); ed.dispatchEvent(new Event("input",{bubbles:true}));ed.dispatchEvent(new Event("change",{bubbles:true})); await sl(50);ed.blur();await sl(100);return true } async function rc(cell){var lb=D.querySelector(".bar-label"),ed=D.querySelector("#alloy-simple-text-editor");if(!lb||!ed)return"";lb.focus();lb.value=cell;lb.dispatchEvent(new Event("input",{bubbles:true}));["keydown","keypress","keyup"].forEach(function(t){lb.dispatchEvent(new KeyboardEvent(t,{key:"Enter",keyCode:13,bubbles:true}))});lb.dispatchEvent(new Event("change",{bubbles:true}));await sl(250);return(ed.textContent||"").trim()} async function fr(f){for(var r=f||2;r<=Math.min((f||2)+20,500);r++){var v=await rc("A"+r);if(!v)return r}return f||2} async function fill(r,s,cl){var o=0,f=0;for(var i=0;i=0&&ti>=0){for(var i=1;i=0&&r.address.indexOf(addrPart.slice(0,4))>=0){t=t.replace(addrMatch[0],"");continue} r.address=(r.address||"")+addrPart; t=t.replace(addrMatch[0],"") } var nameMatch=t.match(/(?:姓名|收件人|收货人|联系人|名字)[::]\s*(.+?)(?:\n|$)/); if(nameMatch&&!r.name){r.name=nameMatch[1].trim().replace(/(?:先生|女士|小姐|师傅|小哥|同学|老师|收)\s*$/,"");t=t.replace(nameMatch[0],"")} var itemMatch=t.match(/(?:物品|商品|货品|产品|内容)[::]\s*(.+?)(?:\n|$)/); if(itemMatch){r.items=splItems(itemMatch[1]);t=t.replace(itemMatch[0],"")} t=t.replace(/(?:收件人|收货人|联系人|姓名|手机号码|手机|电话|固话|地址|详细地址|所在地区|省市区|物品|商品|产品|内容)[::]/gi,""); t=t.replace(/,+\s*,+/g,",").replace(/^[,\s]+/,"").replace(/[,\s]+$/,""); t=t.replace(/[。,]/g," "); var segs=t.split(/[\s,;;\n\r]+/).map(function(s){return s.trim()}).filter(Boolean); if(!r.name&&r.phone){ var searchText=text.replace(/^\d+[、...]\s*/,""); var pi=searchText.indexOf(r.phone); if(pi<0){var cp=t.indexOf(r.phone);pi=cp>=0?cp:0} var bp=searchText.substring(0,pi).split(/[\s,,、;;:\n\r]+/).filter(Boolean); for(var i=bp.length-1;i>=0;i--){if(bp[i].trim().length>=1&&!/^\d+$/.test(bp[i].trim())&&!/^1[3-9]/.test(bp[i].trim())&&!/电话|手机|固话/.test(bp[i].trim())){r.name=bp[i].trim();break}} } var pRe=/^(?:北京|天津|上海|重庆|河北|山西|辽宁|吉林|黑龙江|江苏|浙江|安徽|福建|江西|山东|河南|湖北|湖南|广东|海南|四川|贵州|云南|陕西|甘肃|青海|台湾|内蒙古|广西|西藏|宁夏|新疆)/; if(r.name){var ni=-1;for(var i=0;i=0){r.address=(r.address||"")+segs.slice(0,ni).join("");segs=segs.slice(ni+1)}} if(!r.address){var aS=[],oS=[];for(var i=0;i=1){var ss=splItems(segs[i]);for(var j=0;j1?[""]:[]); // 用末尾数量标记覆盖物品数量 if(r._qty>1&&r.items.length===0){r.items=[""]} return r; function filterUnique(a){var seen={};return a.filter(function(x){if(seen[x])return false;seen[x]=true;return true})} } function parseMultipleOrders(text,startLine){ if(startLine>1){var _ls=text.split("\n");text=_ls.slice(startLine-1).join("\n")} // 自动分行:遇到"手机号(数量)→ 下条地址开头"插入空行 var _ln=text.split("\n");var _nf=[]; for(var _i=0;_i<_ln.length;_i++){ _nf.push(_ln[_i]); if(_i<_ln.length-1){ var _cu=_ln[_i].trim(),_nx=_ln[_i+1].trim(); // 手机号后跟商品名 if(_cu&&_nx&&/1[3-9]\d{9}$/.test(_cu.replace(/\s+/g,""))&&/^[一二两三四五六七八九十\d]+(?:箱|盒|包|袋|条|罐|瓶|桶|个|份|块|卷|对|双|套|打|件|捆|提)/.test(_nx)){ _nf.push(""); } // 序号开头 if(_cu&&_nx&&/^\d+[、..]/.test(_nx)){ _nf.push(""); } // 手机号+(数量)结尾 → 下一行非空且不以序号/空白开头 if(_cu&&_nx&&/1[3-9]\d{9}(\d+[箱盒包袋条罐瓶桶个份块卷对双套打件捆提])$/.test(_cu)&&!/^\d+[、..]/.test(_nx)){ _nf.push(""); } } } text=_nf.join("\n"); // 预处理手机号空格 text=text.replace(/1\s*[3-9]\s*\d\s*\d\s*\d\s*\d\s*\d\s*\d\s*\d\s*\d\s*\d/g,function(m){return m.replace(/\s+/g,"")}); var _pc=(text.match(/1[3-9]\d{9}/g)||[]); if(_pc.length<=1){ var _single=parseOrder(text); if(_single&&_single.name&&_single.phone){ var _si=_single.items.length?_single.items:[""];var _sr=[]; for(var _j=0;_j<_si.length;_j++){for(var _k=0;_k<_single._qty;_k++){_sr.push({name:_single.name,phone:_single.phone,landline:_single.landline,address:_single.address,item:_si[_j]})}} return{rows:_sr,errors:[]} } } var blocks=text.split(/\n\s*\n/).map(function(b){return b.trim()}).filter(Boolean); var allRows=[],errs=[]; for(var i=0;i=0||nc.indexOf(k)>=0){fk=k;break}}} if(!fk||!used[fk]||!used[fk].length){L(log,"第"+rw.row+"行"+c+"→CSV未匹配","err");fail++;continue} var tn=used[fk].shift(); if(!tn){L(log,"第"+rw.row+"行"+c+"→无单号","err");fail++;continue} (await wc("G"+rw.row,tn))?L(log,"第"+rw.row+"行"+c+" → "+tn,"ok"):L(log,"第"+rw.row+"行写入失败","err"); await sl(30) } L(log,"\n完成:填充"+fill+"行,跳过"+skip+"行,失败"+fail+"行"); }catch(e){L(log,"错误:"+e.message,"err")} btn.textContent="完成";btn.disabled=false; GM_notification({text:"单号匹配完成:"+fill+"行",timeout:3000}) } } function buildParse(ov){ var t=ov.querySelector("#tab-parse"); t.innerHTML='
粘贴快递文本,自动解析。支持多行/多单/数量标记如(5箱)
'; var ta=t.querySelector("textarea"),pv=t.querySelector("#ppv"),pl=t.querySelector("#ppl"),pb=t.querySelector("#ppb"),cur=[]; t.querySelector("#ppc").onclick=function(){ov.remove()}; t.querySelector("#ppp").onclick=function(){ var text=ta.value.trim();if(!text){alert("请先粘贴快递文本");return} var r=parseMultipleOrders(text,1);cur=r.rows; if(!cur.length){alert("未解析到有效信息");return} pv.style.display="block"; var h='
'; for(var i=0;i"} pv.innerHTML=h+"
姓名手机固话地址格式化合并
"+x.name+""+x.phone+""+(x.landline||"")+""+x.address+""+formatOrderLine(x)+"
"; pl.style.display="block";pl.innerHTML="";L(pl,"解析"+cur.length+"条,失败"+r.errors.length+"条");r.errors.forEach(function(e){L(pl,"!"+e,"err")}); pb.style.display="flex" }; t.querySelector("#ppfill").onclick=async function(){ if(!cur.length)return; var sr=parseInt(t.querySelector(".prn").value)||1; if(t.querySelector(".auto-row").checked)sr=await fr(sr); var fm=t.querySelector("#fmtMerge").checked,btn=t.querySelector("#ppfill"); btn.disabled=true;btn.textContent="写入中…"; var ok=0,fail=0; if(fm){ for(var i=0;i