您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Display items in Cardtrader Zero orders grouped by processing/shipment status
// ==UserScript== // @name CardtraderZero Detailed Displayer // @namespace https://www.cardtrader.com // @version 2025-08-02 // @description Display items in Cardtrader Zero orders grouped by processing/shipment status // @author Sibbob // @match https://www.cardtrader.com/* // @icon https://www.cardtrader.com/assets/favicon/favicon-32x32-a5e0283790f269dc65e3d5d886d9ec2ac290bf407249b2c124e7baff5c10080d.png // @grant window.onurlchange // @license MIT // ==/UserScript== const TEXT_HEADER_CLASS = "bg-tertiary"; const TEXT_INFO_CLASS = "text-info"; // Event listener to URL changes, to allow the script to be run if you land to the page navigating throug CT. if (window.onurlchange === null) { window.addEventListener('urlchange', (info) => {if(info.url.includes("orders/buyer_future_order")) main()}); } // Run the script if landing directly to the page. if (window.location.href.indexOf("orders/buyer_future_order") > -1) main(); function main() { const trs = document.getElementsByTagName('tr'); let futureOrderLineIds = []; let textInfo; let textInfoIndex = 0; let textHeader; //get the list of all cards ordered, and the template for headers for (let tr of trs) { if (tr.classList.length > 0 ){ if (tr.classList.contains(TEXT_HEADER_CLASS)) { textHeader = tr; } else if(tr.classList.contains(TEXT_INFO_CLASS)){ if (textInfoIndex == 1) { textInfo = tr; } textInfoIndex ++ ; } } else { if (tr.dataset.testId.endsWith("pending")){ futureOrderLineIds.push(tr.dataset.futureOrderLineId); } } } console.debug('OriginalTextHeader',textHeader); console.debug('OriginalTextInfo',textInfo); // creating new sections of the table const tbody = document.getElementsByTagName('tbody')[0]; const sec_ids = ["arrived-final","shipped-final","arrived-local","shipped-local","processed","purchased"]; const sec_descs = ["arrived in main warehouse", "shipped to main warehouse", "arrived in local hub","shipped to local hub","processed", "purchased"]; const sec_icon_classes = ["fa-truck-loading","fa-truck","fa-truck-loading","fa-truck","fa-cogs","fa-shopping-cart"] for (let i = 0; i < sec_ids.length; i++){ //modify the header, including id to the text box to ease changing its text let textHeaderModified = textHeader.cloneNode(true); let textBox = textHeaderModified.children[0].children[0]; let textIcon = textBox.children[0]; setNewText(textBox,`0 cards ${sec_descs[i]}`); textBox.id = `header-${sec_ids[i]}`; // change icon textIcon.classList.remove("fa-truck"); textIcon.classList.add(sec_icon_classes[i]); //add id to info - to ease append after it let textInfoModified = textInfo.cloneNode(true); textInfoModified.id = `info-${sec_ids[i]}` console.debug('ModifiedTextHeader',textHeaderModified); console.debug('ModifiedTextInfo',textInfoModified); tbody.insertAdjacentElement('beforeend', textHeaderModified); tbody.insertAdjacentElement('beforeend', textInfoModified); } // fetch status and move the line accordingly for (let lineId of futureOrderLineIds){ fetch(`https://www.cardtrader.com/orders/${lineId}/where_is_my_card.json?state=pending`) .then(res => res.json()) .then(data => { console.debug('FetchedData',lineId,data); let orderInfo = data[0].data; if (orderInfo.repurchase){ orderInfo = orderInfo.repurchase; } console.debug('ProcessedData',lineId,orderInfo); let orderStatus = determineStatus(orderInfo); // Purchased insertRowInSection(lineId,orderStatus); }) }; //delete the original header and info textInfo.remove(); textHeader.remove(); }; function setNewText(node, newText) { const children = Array.from(node.childNodes); children.forEach(child => { if (child.nodeType === Node.TEXT_NODE) { child.textContent = newText; return; } }); } function determineStatus(orderInfo) { if (orderInfo.has_mini_hub){ if (orderInfo.last_delivered_at){ // Arrived to final return "arrived-final"; } if (orderInfo.mini_hub_shipped_at ){ // Shipped to final return "shipped-final"; } if (orderInfo.mini_hub_accepted_at){ // Arrived to local return "arrived-local"; } if (orderInfo.shipped_at) { // Shipped to local return "shipped-local"; } }else{ if (orderInfo.first_delivered_at){ //Arrived to final return "arrived-final" } if (orderInfo.shipped_at) { // Shipped to final return "shipped-final"; } } if (orderInfo.closed_at){ // Processed return "processed"; } return "purchased" } function insertRowInSection(lineId,sectionId){ let info = document.getElementById(`info-${sectionId}`) let tableRow = document.querySelector(`tr[data-future-order-line-id="${lineId}"]`); info.parentNode.insertBefore(tableRow,info.nextSibling); increaseCardCount(document.getElementById(`header-${sectionId}`)); } function increaseCardCount(node) { const children = Array.from(node.childNodes); children.forEach(child => { if (child.nodeType === Node.TEXT_NODE) { let n = parseInt(child.textContent.split(" ")[0]); child.textContent=child.textContent.replace(/\d+/,n+1); return; } }); };