265 lines
13 KiB
JavaScript
265 lines
13 KiB
JavaScript
// ==UserScript==
|
||
// @name AliExpress-Order-List-Modifier
|
||
// @namespace http://tampermonkey.net/
|
||
// @version 2024-08-28
|
||
// @description Скрипт, который модифицирует список заказов на странице AliExpress: добавляет таблицу с номерами заказов, отслеживает изменения URL, извлекает данные по каждому заказу и добавляет ссылки на трекинг посылок.
|
||
// @author You
|
||
// @match https://aliexpress.ru/order-list?*
|
||
// @icon https://www.google.com/s2/favicons?sz=64&domain=aliexpress.ru
|
||
// @grant none
|
||
// ==/UserScript==
|
||
|
||
(function() {
|
||
'use strict';
|
||
|
||
// Запускать скрипт только после полной загрузки страницы
|
||
window.addEventListener('load', function() {
|
||
modifyOrderList();
|
||
setupURLObserver();
|
||
});
|
||
|
||
function modifyOrderList() {
|
||
// Получаем контейнер с заказами
|
||
const container = document.querySelector('.RedOrderList_RedOrderList__container__eukpr');
|
||
if (!container) return;
|
||
|
||
// Создаем новую таблицу
|
||
const table = document.createElement('table');
|
||
table.style.width = '100%';
|
||
table.style.borderSpacing = '0 6px'; // Добавляем расстояние между строками
|
||
|
||
// Проходим по каждому элементу с классом "RedOrderList_OrderList__item__1utr0 RedOrderList_OrderList__withBackground__1utr0"
|
||
const items = Array.from(container.querySelectorAll('.RedOrderList_OrderList__item__1utr0.RedOrderList_OrderList__withBackground__1utr0'));
|
||
const spm = extractSPMParameter(); // Извлекаем параметр SPM из текущего URL
|
||
|
||
items.forEach(item => {
|
||
const orderLink = item.querySelector('a');
|
||
if (!orderLink) return;
|
||
|
||
// Извлекаем номер заказа из href
|
||
const orderNumberMatch = orderLink.href.match(/order-list\/(\d+)\?/);
|
||
if (!orderNumberMatch) return;
|
||
const orderNumber = orderNumberMatch[1];
|
||
|
||
// Меняем класс элемента
|
||
const originalClass = item.className;
|
||
item.className = 'BlueOrderList_OrderList__item__' + orderNumber;
|
||
|
||
// Создаем строку таблицы
|
||
const row = document.createElement('tr');
|
||
|
||
// Первая колонка (оригинальный элемент)
|
||
const cell1 = document.createElement('td');
|
||
cell1.style.width = '80%';
|
||
cell1.style.padding = '5px';
|
||
cell1.appendChild(item);
|
||
|
||
// Вторая колонка (новый элемент с div)
|
||
const cell2 = document.createElement('td');
|
||
cell2.style.width = '20%';
|
||
cell2.style.padding = '5px';
|
||
cell2.style.position = 'relative';
|
||
|
||
const div = document.createElement('div');
|
||
div.className = 'BlueOrderList_OrderList__item__' + orderNumber;
|
||
div.style.position = 'absolute';
|
||
div.style.top = '0';
|
||
div.style.left = '0';
|
||
div.style.right = '0';
|
||
div.style.bottom = '0';
|
||
div.style.padding = '5px';
|
||
div.style.width = '100%';
|
||
div.style.height = '100%';
|
||
div.style.border = '1px solid #e6eaf0';
|
||
div.style.borderRadius = '6px';
|
||
div.style.padding = '3px';
|
||
|
||
// Создаем и добавляем элементы <p> с помощью функции
|
||
const pID = createParagraph('ID', orderNumber);
|
||
const pDate = createParagraph('Date', 'Дата'); // Замените на актуальную дату
|
||
const pPosilka = createParagraph('Posilka', 'Посылка'); // Placeholder, будет обновлено позже
|
||
|
||
div.appendChild(pID);
|
||
div.appendChild(pDate);
|
||
div.appendChild(pPosilka);
|
||
|
||
// Вызов функции для получения данных заказа и обновления pPosilka.textContent
|
||
fetchOrderDetails(orderNumber, pPosilka, pDate, spm);
|
||
|
||
// Создаем и добавляем ссылки под pPosilka
|
||
const pLinks = createTrackingLinks(pPosilka);
|
||
div.appendChild(pLinks);
|
||
|
||
// Добавляем <div> в ячейку таблицы
|
||
cell2.appendChild(div);
|
||
|
||
// Добавляем колонки в строку
|
||
row.appendChild(cell1);
|
||
row.appendChild(cell2);
|
||
|
||
// Добавляем строку в таблицу
|
||
table.appendChild(row);
|
||
|
||
// Восстанавливаем оригинальный класс после добавления
|
||
item.className = originalClass;
|
||
});
|
||
|
||
// Заменяем содержимое контейнера новой таблицей
|
||
container.innerHTML = '';
|
||
container.appendChild(table);
|
||
}
|
||
|
||
// Функция для создания элемента <p>
|
||
function createParagraph(className, textContent) {
|
||
const p = document.createElement('p');
|
||
p.className = className;
|
||
p.textContent = textContent;
|
||
p.style.margin = '3px 0px';
|
||
return p;
|
||
}
|
||
|
||
// Функция для создания ссылок на "Казпочта" и "Где посылка"
|
||
function createTrackingLinks(pPosilka) {
|
||
const container = document.createElement('div');
|
||
container.style.marginTop = '5px';
|
||
|
||
// Создаем ссылку для "Казпочта"
|
||
const kazPostLink = document.createElement('a');
|
||
kazPostLink.href = `https://qazpost.kz/ru/tracking?trackNumber=${pPosilka.textContent}`;
|
||
kazPostLink.target = '_blank';
|
||
kazPostLink.style.padding = '5px 0px 6px 0px';
|
||
|
||
// Создаем изображение для "Казпочта"
|
||
const kazPostImg = document.createElement('img');
|
||
kazPostImg.src = 'https://qazpost.kz/favicon/favicon-16x16.png';
|
||
kazPostImg.alt = 'Казпочта';
|
||
kazPostImg.style.verticalAlign = 'middle';
|
||
kazPostImg.style.marginRight = '5px';
|
||
|
||
kazPostLink.appendChild(kazPostImg); // Добавляем изображение в ссылку
|
||
kazPostLink.appendChild(document.createTextNode('Казпочта')); // Добавляем текст
|
||
|
||
const br = document.createElement('br'); // Создаем элемент <br> для разрыва строки
|
||
|
||
// Создаем ссылку для "Где посылка"
|
||
const gdePosylkaLink = document.createElement('a');
|
||
gdePosylkaLink.href = `https://gdeposylka.ru/detect/${pPosilka.textContent}`;
|
||
gdePosylkaLink.target = '_blank';
|
||
gdePosylkaLink.style.padding = '5px 0px 6px 0px';
|
||
|
||
// Создаем изображение для "Где посылка"
|
||
const gdePosylkaImg = document.createElement('img');
|
||
gdePosylkaImg.src = 'https://gdeposylka.ru/favicon.ico';
|
||
gdePosylkaImg.alt = 'Где посылка';
|
||
gdePosylkaImg.style.verticalAlign = 'middle';
|
||
gdePosylkaImg.style.marginRight = '5px';
|
||
|
||
gdePosylkaLink.appendChild(gdePosylkaImg); // Добавляем изображение в ссылку
|
||
gdePosylkaLink.appendChild(document.createTextNode('Где посылка')); // Добавляем текст
|
||
|
||
container.appendChild(kazPostLink);
|
||
container.appendChild(br); // Добавляем разрыв строки между ссылками
|
||
container.appendChild(gdePosylkaLink);
|
||
|
||
return container;
|
||
}
|
||
|
||
// Функция для получения данных заказа по order_id с учетом параметра spm
|
||
function fetchOrderDetails(p_order_id, pPosilka, pDate, pSpm) {
|
||
const url = `https://aliexpress.ru/order-list/${p_order_id}${pSpm ? pSpm : ''}`;
|
||
|
||
fetch(url)
|
||
.then(response => response.text())
|
||
.then(html => {
|
||
// Создаем DOMParser для анализа полученной HTML страницы
|
||
const parser = new DOMParser();
|
||
const doc = parser.parseFromString(html, 'text/html');
|
||
|
||
// Извлекаем содержимое скрипта с id "__AER_DATA__"
|
||
const scriptTag = doc.querySelector('#__AER_DATA__');
|
||
if (scriptTag) {
|
||
const jsonData = scriptTag.textContent;
|
||
|
||
// Поиск значения originalTrackNumber и обновление текста в pPosilka
|
||
const originalTrackNumber = findOriginalTrackNumber(jsonData);
|
||
if (originalTrackNumber) {
|
||
pPosilka.textContent = originalTrackNumber;
|
||
pPosilka.style.backgroundColor = "#90ee90";
|
||
} else {
|
||
pPosilka.textContent = 'Информация недоступна';
|
||
pPosilka.style.backgroundColor = "#f08080"; // Добавляем цвет для недоступной информации
|
||
}
|
||
|
||
// Обновление ссылок в pLinks
|
||
const pLinks = pPosilka.nextElementSibling;
|
||
if (pLinks) {
|
||
pLinks.querySelector('a[href^="https://qazpost.kz"]').href = `https://qazpost.kz/ru/tracking?trackNumber=${originalTrackNumber}`;
|
||
pLinks.querySelector('a[href^="https://gdeposylka.ru"]').href = `https://gdeposylka.ru/detect/${originalTrackNumber}`;
|
||
}
|
||
|
||
// Поиск значения даты и обновление текста в pDate
|
||
const orderDate = findOrderDate(jsonData);
|
||
if (orderDate) {
|
||
pDate.textContent = orderDate;
|
||
} else {
|
||
pDate.textContent = 'Дата недоступна';
|
||
}
|
||
} else {
|
||
console.error(`JSON данные для заказа ${p_order_id} не найдены.`);
|
||
pPosilka.textContent = 'Ошибка загрузки';
|
||
pDate.textContent = 'Ошибка загрузки';
|
||
pPosilka.style.backgroundColor = "#f08080"; // Добавляем цвет для ошибки
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Ошибка при запросе данных:', error);
|
||
pPosilka.textContent = 'Ошибка запроса';
|
||
pDate.textContent = 'Ошибка запроса';
|
||
pPosilka.style.backgroundColor = "#f08080"; // Добавляем цвет для ошибки
|
||
});
|
||
}
|
||
|
||
// Функция для поиска originalTrackNumber в текстовом представлении JSON
|
||
function findOriginalTrackNumber(jsonText) {
|
||
const match = jsonText.match(/"originalTrackNumber":"(.*?)"/);
|
||
if (match && match[1]) {
|
||
return match[1];
|
||
} else {
|
||
console.error('originalTrackNumber не найден в JSON');
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// Функция для поиска даты заказа в текстовом представлении JSON
|
||
function findOrderDate(jsonText) {
|
||
const match = jsonText.match(/"header":\{"ordersTitle":"Заказы","date":"от\s(.*?)"/);
|
||
if (match && match[1]) {
|
||
return match[1];
|
||
} else {
|
||
console.error('Дата заказа не найдена в JSON');
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// Функция для извлечения параметра SPM из текущего URL
|
||
function extractSPMParameter() {
|
||
const urlParams = new URLSearchParams(window.location.search);
|
||
const spm = urlParams.get('spm');
|
||
return spm ? `?spm=${spm}` : '';
|
||
}
|
||
|
||
function setupURLObserver() {
|
||
// Наблюдаем за изменением URL и обновляем страницу, если она не совпадает с текущей
|
||
let lastUrl = location.href;
|
||
new MutationObserver(() => {
|
||
const currentUrl = location.href;
|
||
if (currentUrl !== lastUrl) {
|
||
lastUrl = currentUrl;
|
||
if (currentUrl.startsWith('https://aliexpress.ru/order-list')) {
|
||
location.reload();
|
||
}
|
||
}
|
||
}).observe(document, { subtree: true, childList: true });
|
||
}
|
||
})();
|