麦芽田备注图片下载器
// ==UserScript==
// @name 麦芽田备注图片下载器
// @namespace http://tampermonkey.net/
// @version 0.2
// @description 一键下载麦芽田订单备注中的所有图片
// @author @Cland
// @match *://*.maiyatian.com/*
// @grant GM_download
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// ==/UserScript==
(function() {
'use strict';
// 添加油猴脚本设置
let isWidthAdjustEnabled = GM_getValue('isWidthAdjustEnabled', true); // 默认开启
// 注册菜单命令
GM_registerMenuCommand('✅ 开启宽度调节', () => {
isWidthAdjustEnabled = true;
GM_setValue('isWidthAdjustEnabled', true);
location.reload(); // 刷新页面使设置生效
});
GM_registerMenuCommand('❌ 关闭宽度调节', () => {
isWidthAdjustEnabled = false;
GM_setValue('isWidthAdjustEnabled', false);
location.reload(); // 刷新页面使设置生效
});
// 修改宽度调节滑块功能
function addWidthAdjustSlider() {
if (!isWidthAdjustEnabled) return;
// 获取保存的宽度设置
const savedWidth = GM_getValue('savedWidth', 25);
// 创建滑块容器
const sliderContainer = document.createElement('div');
sliderContainer.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
transform: none;
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
z-index: 10000;
width: 300px;
`;
// 创建标题
const title = document.createElement('div');
title.textContent = '调整区域宽度';
title.style.cssText = `
font-weight: bold;
margin-bottom: 15px;
text-align: center;
`;
// 创建滑块
const slider = document.createElement('input');
slider.type = 'range';
slider.min = '20';
slider.max = '80';
slider.value = savedWidth;
slider.style.cssText = `
width: 100%;
margin: 10px 0;
`;
// 创建数值显示
const valueDisplay = document.createElement('div');
valueDisplay.style.cssText = `
text-align: center;
margin: 10px 0;
color: #666;
`;
// 更新显示的数值和实际宽度
function updateWidth(value) {
const rightArea = document.querySelector('.main-small.fn-right');
const leftArea = document.querySelector('.main-big.main-position-left.block-order.page-order');
if (rightArea && leftArea) {
rightArea.style.width = `${value}%`;
leftArea.style.width = `${100 - value}%`;
valueDisplay.textContent = `右侧宽度: ${value}% / 左侧宽度: ${100 - value}%`;
}
}
// 使用防抖函数优化事件处理
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// 优化 MutationObserver
const observer = new MutationObserver(
debounce((mutations, obs) => {
checkAndAddButton();
}, 100)
);
// 优化滑块事件监听
slider.addEventListener('input', debounce((e) => {
updateWidth(e.target.value);
}, 16)); // 约60fps
// 创建最小化按钮
const minimizeBtn = document.createElement('button');
minimizeBtn.textContent = '最小化';
minimizeBtn.style.cssText = `
position: absolute;
top: 10px;
right: 10px;
padding: 2px 8px;
background: none;
border: none;
color: #666;
cursor: pointer;
font-size: 12px;
`;
// 创建最小化后的按钮
const expandBtn = document.createElement('button');
expandBtn.textContent = '📐 调整宽度';
expandBtn.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
padding: 8px 16px;
background: #2DAED6;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
z-index: 10000;
display: none;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
`;
// 添加最小化/展开功能
minimizeBtn.addEventListener('click', () => {
sliderContainer.style.display = 'none';
expandBtn.style.display = 'block';
});
expandBtn.addEventListener('click', () => {
sliderContainer.style.display = 'block';
expandBtn.style.display = 'none';
});
// 创建保存按钮
const saveBtn = document.createElement('button');
saveBtn.textContent = '保存设置';
saveBtn.style.cssText = `
display: block;
margin: 15px auto 0;
padding: 6px 20px;
background: #2DAED6;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background 0.2s;
`;
// 添加保存按钮的悬停效果
saveBtn.addEventListener('mouseenter', () => {
saveBtn.style.background = '#249cc0';
});
saveBtn.addEventListener('mouseleave', () => {
saveBtn.style.background = '#2DAED6';
});
// 添加保存功能
saveBtn.addEventListener('click', () => {
const currentValue = slider.value;
GM_setValue('savedWidth', currentValue);
// 显示保存成功提示
const toast = document.createElement('div');
toast.textContent = '✅ 宽度设置已保存';
toast.style.cssText = `
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.7);
color: white;
padding: 8px 16px;
border-radius: 4px;
font-size: 14px;
z-index: 10001;
`;
document.body.appendChild(toast);
// 2秒后移除提示
setTimeout(() => {
toast.remove();
}, 2000);
});
// 组装滑块窗口
sliderContainer.appendChild(title);
sliderContainer.appendChild(slider);
sliderContainer.appendChild(valueDisplay);
sliderContainer.appendChild(saveBtn); // 添加保存按钮
sliderContainer.appendChild(minimizeBtn);
// 添加到页面
document.body.appendChild(sliderContainer);
document.body.appendChild(expandBtn);
// 添加样式以确保区域平滑过渡
const style = document.createElement('style');
style.textContent = `
.main-small.fn-right,
.main-big.main-position-left.block-order.page-order {
transition: width 0.3s ease-in-out;
}
`;
document.head.appendChild(style);
// 初始化显示时使用保存的宽度
updateWidth(savedWidth);
}
// 修改监听逻辑,不再在找到元素后立即断开观察
const observer = new MutationObserver((mutations, obs) => {
checkAndAddButton();
});
// 开始观察
observer.observe(document.body, {
childList: true,
subtree: true
});
function checkAndAddButton() {
// 缓存 DOM 查询结果
const remarkElements = document.querySelectorAll('.order-goods .order-remark');
if (!remarkElements.length) return; // 提前返回
remarkElements.forEach(remarkElement => {
const titleElement = remarkElement.querySelector('.order-remark-title');
if (!titleElement || titleElement.textContent.trim() !== '用户备注') return; // 提前返回
const contentElement = remarkElement.querySelector('.order-remark-content');
if (!contentElement) return; // 提前返回
// 使用 dataset 标记已处理过的元素
if (!remarkElement.dataset.processed) {
if (!titleElement.querySelector('.download-remark-images')) {
addDownloadButton(titleElement);
}
if (!remarkElement.querySelector('.remark-preview-container')) {
addImagePreviewArea(remarkElement, contentElement);
}
colorizeRemarkText(contentElement);
updateFloatingPreview(contentElement);
remarkElement.dataset.processed = 'true';
}
});
// 添加隐藏打印贺卡按钮的功能
hideCardPrintButton();
}
function addDownloadButton(titleElement) {
// 创建下载按钮
const downloadBtn = document.createElement('button');
downloadBtn.innerHTML = '下载所有备注图片';
downloadBtn.className = 'download-remark-images';
downloadBtn.style.cssText = `
margin-left: 10px;
padding: 2px 8px;
color: #2DAED6;
border: 1px solid #2DAED6;
border-radius: 3px;
background: white;
cursor: pointer;
`;
// 添加点击事件
downloadBtn.addEventListener('click', function() {
const remarkElement = titleElement.closest('.order-remark');
downloadAllImages(remarkElement);
});
// 将按钮添加到标题元素后面
titleElement.appendChild(downloadBtn);
}
function addImagePreviewArea(remarkElement, contentElement) {
// 创建整个预览区域的容器
const previewContainer = document.createElement('div');
previewContainer.className = 'remark-preview-container';
previewContainer.style.cssText = `
margin: 10px 0;
background-color: #fff;
border-radius: 4px;
padding: 15px;
`;
// 创建图片预览区域
const previewArea = document.createElement('div');
previewArea.className = 'remark-images-preview';
previewArea.style.cssText = `
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
margin-bottom: 15px;
`;
// 解析备注内容
const text = contentElement.textContent;
const imageMatches = text.matchAll(/\[(.*?)\](https?:\/\/[^\s]+?\.(jpg|jpeg|png|gif))/g);
// 处理图片
const images = Array.from(imageMatches);
images.forEach(([_, label, url]) => {
const imageContainer = document.createElement('div');
imageContainer.style.cssText = `
aspect-ratio: 1;
position: relative;
`;
const image = document.createElement('img');
image.src = url;
image.style.cssText = `
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 4px;
cursor: pointer;
border: 1px solid #E7E7E7;
`;
const labelDiv = document.createElement('div');
labelDiv.textContent = label;
labelDiv.style.cssText = `
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: rgba(0,0,0,0.6);
color: white;
font-size: 12px;
padding: 4px;
text-align: center;
border-radius: 0 0 4px 4px;
`;
// 为定制花束图片和其他定制要求图片添加下载按钮
if (label.includes('定制花束图片') || label.includes('其他定制要求图片')) {
const downloadBtn = document.createElement('button');
downloadBtn.textContent = '⬇️';
downloadBtn.style.cssText = `
position: absolute;
top: 8px;
right: 8px;
padding: 4px 8px;
background: rgba(45, 174, 214, 0.9);
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
z-index: 2;
transition: background 0.2s;
`;
// 悬停效果
downloadBtn.addEventListener('mouseenter', () => {
downloadBtn.style.background = 'rgba(45, 174, 214, 1)';
});
downloadBtn.addEventListener('mouseleave', () => {
downloadBtn.style.background = 'rgba(45, 174, 214, 0.9)';
});
// 添加点击事件
downloadBtn.addEventListener('click', (e) => {
e.stopPropagation(); // 防止触发图片预览
const filename = `${label}.${url.split('.').pop()}`;
GM_download({
url: url,
name: filename,
saveAs: false,
onerror: (error) => console.error('下载失败:', error)
});
});
imageContainer.appendChild(downloadBtn);
}
imageContainer.appendChild(image);
imageContainer.appendChild(labelDiv);
previewArea.appendChild(imageContainer);
// 点击图片放大预览
image.addEventListener('click', () => {
const modal = createImageModal(url, label);
document.body.appendChild(modal);
});
});
// 组装所有元素
previewContainer.appendChild(previewArea);
contentElement.parentNode.insertBefore(previewContainer, contentElement.nextSibling);
}
function createImageModal(url, label) {
const modal = document.createElement('div');
modal.style.cssText = `
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.8);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 9999;
cursor: pointer;
`;
const img = document.createElement('img');
img.src = url;
img.style.cssText = `
max-width: 90vw;
max-height: 80vh;
object-fit: contain;
margin-bottom: 15px;
`;
const downloadBtn = document.createElement('button');
downloadBtn.textContent = '下载图片';
downloadBtn.style.cssText = `
padding: 8px 16px;
background: #2DAED6;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
margin-top: 10px;
`;
downloadBtn.addEventListener('click', (e) => {
e.stopPropagation();
const filename = `${label}.${url.split('.').pop()}`;
GM_download({
url: url,
name: filename,
saveAs: false,
onerror: (error) => console.error('下载失败:', error)
});
});
modal.appendChild(img);
modal.appendChild(downloadBtn);
modal.addEventListener('click', () => modal.remove());
return modal;
}
function downloadAllImages(remarkElement) {
if (!remarkElement) return;
const remarkContent = remarkElement.querySelector('.order-remark-content');
if (!remarkContent) return;
// 使用新的正则表达式匹配带标签的图片URL
const text = remarkContent.textContent;
const matches = text.matchAll(/\[(.*?)\](https?:\/\/[^\s]+?\.(jpg|jpeg|png|gif))/g);
const urlsWithLabels = Array.from(matches, match => ({
label: match[1],
url: match[2]
}));
if (!urlsWithLabels.length) {
alert('未找到可下载的图片链接');
return;
}
// 下载所有找到的图片
urlsWithLabels.forEach(({label, url}, index) => {
const filename = `${label}_${index + 1}.${url.split('.').pop()}`;
GM_download({
url: url,
name: filename,
saveAs: false,
onerror: (error) => console.error('下载失败:', error)
});
});
}
// 修改文本着色函数
function colorizeRemarkText(contentElement) {
let text = contentElement.textContent;
// 保存原始文本
contentElement.setAttribute('data-original-text', text);
// 创建一个总容器
const mainContainer = document.createElement('div');
mainContainer.style.cssText = `
display: flex;
flex-direction: column;
gap: 12px;
`;
// 创建格式化备注容器
const formattedContainer = document.createElement('div');
formattedContainer.style.cssText = `
display: flex;
flex-direction: column;
gap: 8px;
`;
// 解析备注内容
const parsedNote = parseNote(text);
// 遍历所有标签(包括无标签)
for (const [tag, contents] of Object.entries(parsedNote)) {
contents.forEach(content => {
if (content) {
// 创建每行的容器
const lineContainer = document.createElement('div');
lineContainer.style.cssText = `
display: flex;
align-items: flex-start;
gap: 8px;
`;
// 创建标签元素(不可复制)
const labelElement = document.createElement('div');
labelElement.style.cssText = `
user-select: none;
background: #f5f5f5;
padding: 2px 8px;
border-radius: 4px;
font-size: 13px;
white-space: nowrap;
width: 120px;
text-align: center;
flex-shrink: 0;
`;
// 根据标签类型设置颜色
if (tag.includes('图片') || tag.includes('定制花束') || tag.includes('其他定制要求')) {
labelElement.style.color = '#999999';
} else if (tag.includes('其他定制备注') || tag.includes('贺卡') || tag === '无标签') {
labelElement.style.color = '#000000';
}
labelElement.textContent = `[${tag}]`;
// 创建内容元素
const contentElement = document.createElement('div');
contentElement.style.cssText = `
flex: 1;
word-break: break-all;
`;
contentElement.textContent = content.trim();
// 根据标签类型设置内容颜色
if (tag.includes('图片') || tag.includes('定制花束') || tag.includes('其他定制要求')) {
contentElement.style.color = '#999999';
} else if (tag.includes('其他定制备注') || tag.includes('贺卡') || tag === '无标签') {
contentElement.style.color = '#000000';
}
// 组装每行的元素
lineContainer.appendChild(labelElement);
lineContainer.appendChild(contentElement);
formattedContainer.appendChild(lineContainer);
}
});
}
// 添加原始备注显示
const originalNoteContainer = document.createElement('div');
originalNoteContainer.style.cssText = `
margin-top: 12px;
padding: 8px 12px;
background-color: #f8f8f8;
border-radius: 4px;
color: #999;
font-size: 12px;
line-height: 1.4;
`;
// 添加标题
const originalNoteTitle = document.createElement('div');
originalNoteTitle.style.cssText = `
font-weight: bold;
margin-bottom: 4px;
color: #666;
`;
originalNoteTitle.textContent = '原始备注:';
// 添加内容
const originalNoteContent = document.createElement('div');
originalNoteContent.textContent = text;
// 组装原始备注
originalNoteContainer.appendChild(originalNoteTitle);
originalNoteContainer.appendChild(originalNoteContent);
// 组装所有内容
mainContainer.appendChild(formattedContainer);
mainContainer.appendChild(originalNoteContainer);
// 清空原有内容并添加新的格式化内容
contentElement.textContent = '';
contentElement.appendChild(mainContainer);
}
// 添加解析备注的函数
function parseNote(noteText) {
const PATTERNS = {
'定制花束图片': /\[定制花束图片\](https?:\/\/[^\s\[]+?\.(jpg|jpeg|png|gif)|[^\[]*?)(?=\[|$)/g,
'其他定制要求图片': /\[其他定制要求图片\](https?:\/\/[^\s\[]+?\.(jpg|jpeg|png|gif)|[^\[]*?)(?=\[|$)/g,
'贺卡内容': /\[贺卡内容\]([^\[]*?)(?=\[|$)/g,
'其他定制备注': /\[其他定制备注\]([^\[]*?)(?=\[|$)/g
};
let remainingText = noteText;
const result = {};
// 解析所有标签内容
for (const [key, pattern] of Object.entries(PATTERNS)) {
result[key] = [];
remainingText = remainingText.replace(pattern, (match, content) => {
if (content && content.trim()) {
result[key].push(content.trim());
}
return ''; // 移除已匹配的内容
});
}
// 处理剩余的无标签文本
remainingText = remainingText.trim();
if (remainingText) {
// 检查是否已经存在相同的无标签内容
if (!result['无标签']) {
result['无标签'] = [];
}
if (!result['无标签'].includes(remainingText)) {
result['无标签'].push(remainingText);
}
}
return result;
}
// 新增更新预览内容的函数
function updateFloatingPreview(contentElement) {
let floatingWindow = document.querySelector('.floating-remark-preview');
let toggleBtn = document.querySelector('.floating-preview-toggle');
// 如果预览窗口不存在,则创建
if (!floatingWindow) {
const { window: newWindow, button: newButton } = createFloatingPreview();
floatingWindow = newWindow;
toggleBtn = newButton;
}
// 获取原始文本内容,而不是处理后的内容
const originalText = contentElement.getAttribute('data-original-text') || contentElement.textContent;
// 更新预览内容
const content = floatingWindow.querySelector('.preview-content');
if (content) {
updatePreviewContent(content, originalText);
}
}
// 修改创建预览窗口的函数
function createFloatingPreview() {
// 创建悬浮窗触发按钮
const toggleBtn = document.createElement('button');
toggleBtn.className = 'floating-preview-toggle';
toggleBtn.innerHTML = '📝 备注预览';
toggleBtn.style.cssText = `
position: fixed;
right: 20px;
top: 80px;
z-index: 9998;
padding: 8px 16px;
background: #2DAED6;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
user-select: none;
`;
// 创建悬浮预览窗口
const floatingWindow = document.createElement('div');
floatingWindow.className = 'floating-remark-preview';
floatingWindow.style.cssText = `
position: fixed;
right: 20px;
top: 130px;
width: 400px;
max-height: 70vh;
background: white;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
z-index: 9997;
overflow: hidden;
display: none;
transition: all 0.3s ease;
`;
// 创建预览窗口头部
const header = document.createElement('div');
header.style.cssText = `
padding: 12px 16px;
background: #f5f5f5;
border-bottom: 1px solid #e8e8e8;
font-weight: bold;
display: flex;
justify-content: space-between;
align-items: center;
cursor: move;
user-select: none;
`;
header.innerHTML = '<span>备注预览</span>';
// 修改内容容器,添加类名以便后续更新
const content = document.createElement('div');
content.className = 'preview-content';
content.style.cssText = `
padding: 16px;
overflow-y: auto;
max-height: calc(70vh - 45px);
`;
// 组装窗口
floatingWindow.appendChild(header);
floatingWindow.appendChild(content);
// 添加展开/折叠功能
let isExpanded = false;
toggleBtn.addEventListener('click', () => {
isExpanded = !isExpanded;
floatingWindow.style.display = isExpanded ? 'block' : 'none';
toggleBtn.innerHTML = isExpanded ? '📝 关闭预览' : '📝 备注预览';
});
// 添加到页面
document.body.appendChild(toggleBtn);
document.body.appendChild(floatingWindow);
// 添加拖拽功能(同时支持按钮和窗口的拖拽)
let isDragging = false;
let currentX;
let currentY;
let initialX;
let initialY;
let xOffset = 0;
let yOffset = 0;
let dragTarget = null;
function dragStart(e, target) {
initialX = e.clientX - xOffset;
initialY = e.clientY - yOffset;
dragTarget = target;
isDragging = true;
}
function drag(e) {
if (isDragging) {
e.preventDefault();
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
xOffset = currentX;
yOffset = currentY;
setTranslate(currentX, currentY, dragTarget);
// 如果拖动的是按钮,同时更新窗口位置
if (dragTarget === toggleBtn) {
const windowX = currentX + (parseFloat(floatingWindow.style.right) || 20);
const windowY = currentY + (parseFloat(floatingWindow.style.top) || 130);
setTranslate(windowX, windowY, floatingWindow);
}
}
}
function dragEnd() {
initialX = currentX;
initialY = currentY;
isDragging = false;
dragTarget = null;
}
function setTranslate(xPos, yPos, el) {
el.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`;
}
// 为按钮添加拖拽事件
toggleBtn.addEventListener('mousedown', (e) => dragStart(e, toggleBtn));
// 为窗口头部添加拖拽事件
header.addEventListener('mousedown', (e) => dragStart(e, floatingWindow));
// 添加全局拖拽事件监听
document.addEventListener('mousemove', drag);
document.addEventListener('mouseup', dragEnd);
// 返回窗口和按钮引用
return { window: floatingWindow, button: toggleBtn };
}
// 修改更新预览内容的函数
function updatePreviewContent(previewContent, originalText) {
// 清空现有内容
previewContent.textContent = '';
// 创建预览容器
const previewContainer = document.createElement('div');
previewContainer.className = 'remark-preview-container';
previewContainer.style.cssText = `
background-color: #fff;
border-radius: 4px;
`;
// 使用原始文本进行解析
const text = originalText;
// 创建图片预览区域
const previewArea = document.createElement('div');
previewArea.className = 'remark-images-preview';
previewArea.style.cssText = `
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
margin-bottom: 12px;
`;
// 处理图片显示
const imageMatches = text.matchAll(/\[(.*?(?:图片|定制花束|其他定制要求).*?)\](https?:\/\/[^\s]+?\.(jpg|jpeg|png|gif))/g);
const images = Array.from(imageMatches);
if (images.length > 0) {
images.forEach(([_, label, url]) => {
const imageContainer = document.createElement('div');
imageContainer.style.cssText = `
aspect-ratio: 1;
position: relative;
`;
const image = document.createElement('img');
image.src = url;
image.style.cssText = `
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 4px;
cursor: pointer;
border: 1px solid #E7E7E7;
`;
const labelDiv = document.createElement('div');
labelDiv.textContent = label;
labelDiv.style.cssText = `
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: rgba(0,0,0,0.6);
color: white;
font-size: 12px;
padding: 4px;
text-align: center;
border-radius: 0 0 4px 4px;
`;
// 为定制花束图片和其他定制要求图片添加下载按钮
if (label.includes('定制花束图片') || label.includes('其他定制要求图片')) {
const downloadBtn = document.createElement('button');
downloadBtn.textContent = '⬇️';
downloadBtn.style.cssText = `
position: absolute;
top: 8px;
right: 8px;
padding: 4px 8px;
background: rgba(45, 174, 214, 0.9);
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
z-index: 2;
transition: background 0.2s;
`;
// 悬停效果
downloadBtn.addEventListener('mouseenter', () => {
downloadBtn.style.background = 'rgba(45, 174, 214, 1)';
});
downloadBtn.addEventListener('mouseleave', () => {
downloadBtn.style.background = 'rgba(45, 174, 214, 0.9)';
});
// 添加点击事件
downloadBtn.addEventListener('click', (e) => {
e.stopPropagation(); // 防止触发图片预览
const filename = `${label}.${url.split('.').pop()}`;
GM_download({
url: url,
name: filename,
saveAs: false,
onerror: (error) => console.error('下载失败:', error)
});
});
imageContainer.appendChild(downloadBtn);
}
imageContainer.appendChild(image);
imageContainer.appendChild(labelDiv);
previewArea.appendChild(imageContainer);
// 点击图片放大预览
image.addEventListener('click', () => {
const modal = createImageModal(url, label);
document.body.appendChild(modal);
});
});
previewContainer.appendChild(previewArea);
}
// 创建文本内容容器
const mainContainer = document.createElement('div');
mainContainer.style.cssText = `
display: flex;
flex-direction: column;
gap: 12px;
`;
// 解析备注内容
const parsedNote = parseNote(text);
// 创建格式化备注容器
const formattedContainer = document.createElement('div');
formattedContainer.style.cssText = `
display: flex;
flex-direction: column;
gap: 8px;
`;
// 遍历所有标签(包括无标签)
for (const [tag, contents] of Object.entries(parsedNote)) {
contents.forEach(content => {
if (content) {
const lineContainer = document.createElement('div');
lineContainer.style.cssText = `
display: flex;
align-items: flex-start;
gap: 8px;
`;
const labelElement = document.createElement('div');
labelElement.style.cssText = `
user-select: none;
background: #f5f5f5;
padding: 2px 8px;
border-radius: 4px;
font-size: 13px;
white-space: nowrap;
width: 120px;
text-align: center;
flex-shrink: 0;
`;
if (tag.includes('图片') || tag.includes('定制花束') || tag.includes('其他定制要求')) {
labelElement.style.color = '#999999';
} else if (tag.includes('其他定制备注') || tag.includes('贺卡') || tag === '无标签') {
labelElement.style.color = '#000000';
}
labelElement.textContent = `[${tag}]`;
const contentElement = document.createElement('div');
contentElement.style.cssText = `
flex: 1;
word-break: break-all;
`;
contentElement.textContent = content.trim();
if (tag.includes('图片') || tag.includes('定制花束') || tag.includes('其他定制要求')) {
contentElement.style.color = '#999999';
} else if (tag.includes('其他定制备注') || tag.includes('贺卡') || tag === '无标签') {
contentElement.style.color = '#000000';
}
lineContainer.appendChild(labelElement);
lineContainer.appendChild(contentElement);
formattedContainer.appendChild(lineContainer);
}
});
}
// 添加原始备注显示
const originalNoteContainer = document.createElement('div');
originalNoteContainer.style.cssText = `
margin-top: 12px;
padding: 8px 12px;
background-color: #f8f8f8;
border-radius: 4px;
color: #999;
font-size: 12px;
line-height: 1.4;
`;
// 添加标题
const originalNoteTitle = document.createElement('div');
originalNoteTitle.style.cssText = `
font-weight: bold;
margin-bottom: 4px;
color: #666;
`;
originalNoteTitle.textContent = '原始备注:';
// 添加内容
const originalNoteContent = document.createElement('div');
originalNoteContent.textContent = text;
// 组装原始备注
originalNoteContainer.appendChild(originalNoteTitle);
originalNoteContainer.appendChild(originalNoteContent);
// 组装所有内容
mainContainer.appendChild(formattedContainer);
mainContainer.appendChild(originalNoteContainer);
previewContainer.appendChild(mainContainer);
previewContent.appendChild(previewContainer);
}
// 新增隐藏打印贺卡按钮的函数
function hideCardPrintButton() {
// 添加样式到页面
const style = document.createElement('style');
style.textContent = `
.order-remark-print {
display: none !important;
}
`;
// 避免重复添加样式
if (!document.querySelector('#hide-print-button-style')) {
style.id = 'hide-print-button-style';
document.head.appendChild(style);
}
}
// 修改页面加载时的宽度设置
function initSavedWidth() {
const savedWidth = GM_getValue('savedWidth', 25);
const rightArea = document.querySelector('.main-small.fn-right');
const leftArea = document.querySelector('.main-big.main-position-left.block-order.page-order');
if (rightArea && leftArea) {
rightArea.style.width = `${savedWidth}%`;
leftArea.style.width = `${100 - savedWidth}%`;
}
}
// 初始检查
checkAndAddButton();
// 监听 PJAX 件
document.addEventListener('pjax:complete', checkAndAddButton);
window.addEventListener('popstate', checkAndAddButton);
window.addEventListener('load', checkAndAddButton);
// 初始化宽度调节功能
addWidthAdjustSlider();
// 脚本初始化时调用
window.addEventListener('load', () => {
initSavedWidth();
});
// 统一管理样式
const STYLES = {
container: `
display: flex;
flex-direction: column;
gap: 8px;
`,
button: `
margin-left: 10px;
padding: 2px 8px;
color: #2DAED6;
border: 1px solid #2DAED6;
border-radius: 3px;
background: white;
cursor: pointer;
`,
// ... 其他样式
};
// 使用样式
element.style.cssText = STYLES.container;
// 添加全局错误处理
window.addEventListener('error', (error) => {
console.error('脚本运行错误:', error);
});
// 添加函数错误处理
function safeExecute(fn, ...args) {
try {
return fn(...args);
} catch (error) {
console.error('函数执行错误:', error);
return null;
}
}
// 延迟加载非关键功能
window.addEventListener('load', () => {
setTimeout(() => {
initSavedWidth();
addWidthAdjustSlider();
}, 0);
});
// 添加清理函数
function cleanup() {
observer.disconnect();
// 移除所有事件监听器
// 移除所有创建的DOM元素
}
// 在页面卸载时清理
window.addEventListener('unload', cleanup);
// 批量处理存储操作
const storage = {
get(key, defaultValue) {
try {
return GM_getValue(key, defaultValue);
} catch (error) {
console.error('获取存储值失败:', error);
return defaultValue;
}
},
set(key, value) {
try {
GM_setValue(key, value);
return true;
} catch (error) {
console.error('设置存储值失败:', error);
return false;
}
}
};
})();