// ==UserScript== // @name Temu 商品图片批量上传工具6.0 // @namespace http://tampermonkey.net/ // @version 5.1 // @description 货号不补0,上传最多6张,中文标题≤250字,英文≤500字,错误红色提示+禁止上传 // @author You // @match https://agentseller.temu.com/* // @icon https://www.temu.com/favicon.ico // @grant none // ==/UserScript== (function() { 'use strict'; // 1. 样式:完全保留你提供的“高度修复对齐版”样式 + 新增错误提示样式 const style = document.createElement('style'); style.textContent = ` .upload-mask { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 9999; display: flex; justify-content: center; align-items: start; padding-top:10px } .upload-container { background: white; padding: 25px; border-radius: 8px; box-shadow: 0 2px 20px rgba(0,0,0,0.3); max-height: 85vh; overflow-y: auto; width: 95%; } .upload-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid #eee; } .upload-title { margin: 0; font-size: 20px; color: #333; } .close-btn { background: none; border: none; font-size: 24px; color: #999; cursor: pointer; padding: 5px 10px; } .batch-spu-container { display: flex; gap: 15px; align-items: center; margin-bottom: 20px; padding: 15px; background-color: #f5fafe; border-radius: 6px; } .batch-spu-input { width: 100%; padding: 8px 10px; border: 1px solid #ddd; border-radius: 4px; } /* 复选框本身放大 */ .color-checkbox-item input[type="checkbox"] { width: 14px; /* 复选框宽度 */ height: 14px; /* 复选框高度 */ transform: scale(1.2); /* 额外放大 */ } /* --- 修复单元格高度一致性的关键 CSS --- */ .data-table { width: 100%; border-collapse: collapse; margin-bottom: 20px; table-layout: fixed; } .data-table th, .data-table td { border: 1px solid #ddd; padding: 12px; vertical-align: top; height: 100%; } .input-field { width: 100%; padding: 8px 10px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box; } /* 新增:输入框错误样式 */ .input-field.error { border: 2px solid #ff4444; background-color: #fff5f5; } /* 错误提示文字样式 */ .error-tip { font-size: 12px; color: #ff4444; margin-top: 4px; display: flex; align-items: center; gap: 4px; } .error-tip::before { content: "❗"; font-size: 14px; } .color-select-cell { font-size:19px; align-content: flex-start; min-height: 40px; } .color-checkbox-item { display: flex; align-items: center; gap: 4px; padding: 4px 8px; border-radius: 4px; background-color: #f5f5f5; font-size: 16px; white-space: nowrap; } .color-image-group { border: 1px solid #eee; border-radius: 6px; padding: 10px; margin-bottom: 10px; } .color-group-header { display: flex; justify-content:start; align-items: center; margin-bottom: 8px; } .color-label { font-size: 13px; font-weight: bold; color: #333; } .image-upload-btn { padding: 10px 10px; background-color: #4299e1; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; margin-left:20px} .image-preview-container { display: flex; flex-wrap: wrap; gap: 8px; min-height: 55px; padding: 8px; background: #fafafa; border-radius: 4px; } .image-preview-remove { position: relative; display: inline-block; transition: all 0.2s; border: 2px solid transparent; border-radius: 4px; cursor: grab; } .image-preview { width: 80px; height: 80px; object-fit: cover; border-radius: 4px; border: 1px solid #ddd; display: block; background: white; } /* 拖放提速核心:取消延迟 + 缩小动画幅度 */ .image-preview-remove { transition: transform 0.1s ease, opacity 0.1s ease; /* 超级快 */ } .image-preview-remove.dragging { opacity: 0.5; transform: scale(0.95); /* 只缩一点点,不卡 */ border: 2px dashed #4299e1; } .image-preview-remove.drag-over { border: 2px solid #48bb78; transform: scale(1); /* 不放大,零延迟 */ } .image-preview-remove::after { content: '×'; position: absolute; top: -6px; right: -6px; background: #e53935; color: white; width: 16px; height: 16px; border-radius: 50%; font-size: 10px; text-align: center; line-height: 16px; cursor: pointer; } .button-group { display: flex; gap: 12px; justify-content: flex-end; margin-top: 20px; } .action-btn { padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; } .add-row-btn { background-color: #48bb78; color: white; } .submit-btn { background-color: #2563eb; color: white; } .trigger-btn { position: fixed; top: 20px; left: 20px; z-index: 9998; padding: 12px 20px; background-color: #e53935; color: white; border: none; border-radius: 4px; font-weight: 600; cursor: pointer; } `; document.head.appendChild(style); let isUIOpen = false; const colorList = ['黑色','白色', '棕色', '灰色', '蓝色', '绿色' , '紫色','粉色']; let draggedElement = null; // --- 字数限制配置 --- const WORD_LIMIT = { CN: 250, // 中文标题最大字数 EN: 500 // 英文标题最大字数 }; // --- 逻辑1:获取签名 (来自旧版) --- async function getMD8Signature() { const urlSig = 'https://agentseller.temu.com/general_auth/get_signature?sdk_version=js-0.0.40&tag_name=product-material-tag&scene_id=agent-seller'; const antiContent = document.querySelector('meta[name="anti-content"]')?.content || ''; const resSig = await fetch(urlSig, { method: 'POST', headers: { 'Content-Type': 'application/json', 'anti-content': antiContent }, body: JSON.stringify({ bucket_tag: 'product-material-tag' }) }); const sigData = await resSig.json(); return sigData.signature; } // --- 逻辑2:上传图片 (来自旧版) --- async function uploadSingleImage(file) { const signature = await getMD8Signature(); const formData = new FormData(); formData.append('url_width_height', 'true'); formData.append('upload_sign', signature); formData.append('image', file); const resUp = await fetch('https://agentseller.temu.com/api/galerie/v3/store_image', { method: 'POST', body: formData, headers: { 'anti-content': document.querySelector('meta[name="anti-content"]')?.content || '' } }); const data = await resUp.json(); return data.image_url || data.url || data.data?.image_url; } // --- 逻辑3:提交到本地服务器生成Excel (来自旧版) --- function generateAndDownloadExcelByForm(newsList, apiUrl = 'http://127.0.0.1:8000/generate-excel') { if (!Array.isArray(newsList) || newsList.length === 0) return; const form = document.createElement('form'); form.method = 'POST'; form.action = apiUrl; form.style.display = 'none'; const input = document.createElement('input'); input.type = 'hidden'; input.name = 'newsData'; input.value = JSON.stringify(newsList); form.appendChild(input); document.body.appendChild(form); form.submit(); document.body.removeChild(form); } // ==================== 新增:校验输入框字数 ==================== function validateInput(input, type) { const value = input.value.trim(); const max = type === 'cn' ? WORD_LIMIT.CN : WORD_LIMIT.EN; const parent = input.parentElement; let errorTip = parent.querySelector('.error-tip'); // 移除旧提示 if (errorTip) errorTip.remove(); if (value.length > max) { // 超过字数:添加红色边框 + 错误提示 input.classList.add('error'); const tip = document.createElement('div'); tip.className = 'error-tip'; tip.textContent = `已超过 ${max} 字限制(当前${value.length}字)`; parent.appendChild(tip); return false; } else { // 正常:清除错误样式 input.classList.remove('error'); return true; } } // ==================== 新增:批量校验所有行 ==================== function validateAllRows() { let isValid = true; const rows = document.querySelectorAll('.data-row'); rows.forEach(row => { const cnInput = row.querySelector('.product-name'); const enInput = row.querySelector('.english-name'); const cnOk = validateInput(cnInput, 'cn'); const enOk = validateInput(enInput, 'en'); if (!cnOk || !enOk) isValid = false; }); return isValid; } // --- UI 相关逻辑 --- function createTriggerBtn() { const btn = document.createElement('button'); btn.className = 'trigger-btn'; btn.textContent = '📤 商品批量上传工具'; btn.onclick = toggleUploadUI; document.body.appendChild(btn); } function toggleUploadUI() { if (isUIOpen) { const mask = document.querySelector('.upload-mask'); if (mask) document.body.removeChild(mask); isUIOpen = false; return; } createUploadUI(); isUIOpen = true; bindPasteEvents(); } function createUploadUI() { const mask = document.createElement('div'); mask.className = 'upload-mask'; const container = document.createElement('div'); container.className = 'upload-container'; container.innerHTML = `
| SPU货号 | 商品名称 ≤250字 |
英文名称 ≤500字 |
颜色选择 | 轮播图管理 (6张/色) | 操作 |
|---|