// ==UserScript== // @name 图片样本上传 // @namespace http://tampermonkey.net/ // @version 2.9.6 // @description 图片上传工具(手动点击自动填充修复) // @author Hanabi // @match *://*/* // @grant GM_xmlhttpRequest // @grant GM_log // @grant GM_setValue // @grant GM_getValue // @license MIT // ==/UserScript== (function () { 'use strict'; // ===== 核心配置 ===== const SWITCH_KEY = 'blackSampleScriptSwitch'; const CONFIG_KEY = 'blackSampleSampleUploadConfig'; let isFillingForm = false; // ===== 上传队列 全局变量 ===== let uploadQueue = []; let uploadPanel = null; let uploadedFiles = new Set(); let lastFileUploadTime = 0; const UPLOAD_DEBOUNCE_INTERVAL = 3000; // ===== 核心:页面校验函数 ===== function isTargetPage() { return window.location.href.includes('library/list?breadcrumb') || window.location.href.includes('library/detail') || window.location.hash.includes('library/list?breadcrumb') || window.location.hash.includes('library/detail'); } console.log('黑样本上传脚本已加载,当前页面检测:', isTargetPage() ? '目标页面' : '非目标页面'); // ===== 开关状态管理 ===== function getSwitchState() { const state = GM_getValue(SWITCH_KEY, true); console.log('当前脚本开关状态:', state ? '开启' : '关闭'); return state; } function setSwitchState(state) { GM_setValue(SWITCH_KEY, state); console.log('脚本开关已切换为:', state ? '开启' : '关闭'); updateSwitchUI(state); } // ===== 默认配置 ===== const DEFAULT_CONFIG = { tag: '', contentSource: '', dangerLevel: '', selectedBusinesses: [], remark: '', autoClickBtn: false }; const OPTIONS = { tags: ['' ], contentSources: ['舆情事件', '日常总结', '平台要求'], dangerLevels: ['一般', '低危', '中危', '高危'], businesses: ['视频', '视频封面', '直播封面', '图文', '直播'] }; let currentConfig = GM_getValue(CONFIG_KEY, DEFAULT_CONFIG); if (currentConfig.excludedBusinesses && !currentConfig.selectedBusinesses) { currentConfig.selectedBusinesses = OPTIONS.businesses.filter(biz => !currentConfig.excludedBusinesses.includes(biz) ); delete currentConfig.excludedBusinesses; GM_setValue(CONFIG_KEY, currentConfig); } let configPanel = null; let controlPanelCreated = false; let observer = null; function saveConfig(config) { currentConfig = { ...currentConfig, ...config }; GM_setValue(CONFIG_KEY, currentConfig); console.log('配置已保存:', currentConfig); if (uploadQueue && uploadQueue.length) { uploadQueue.forEach(file => { file.customConfig = { ...currentConfig }; }); renderQueue(); } } // ===== 创建控制面板 ===== function createControlPanel() { if (controlPanelCreated || document.getElementById('blackSampleControlPanel')) return; const controlPanel = document.createElement('div'); controlPanel.id = 'blackSampleControlPanel'; controlPanel.style.cssText = ` display: flex; align-items: center; gap: 12px; padding: 0 16px; height: 100%; margin-left: auto; font-family: Helvetica Neue, Helvetica, PingFang SC, Microsoft YaHei, sans-serif; `; const switchText = document.createElement('span'); switchText.id = 'blackSampleSwitchText'; switchText.style.cssText = ` font-size: 14px; font-weight: 500; color: #303133; white-space: nowrap; `; switchText.textContent = getSwitchState() ? '已开启' : '已关闭'; const switchBtn = document.createElement('div'); switchBtn.id = 'blackSampleSwitchBtn'; switchBtn.style.cssText = ` width: 40px; height: 20px; border-radius: 10px; background: ${getSwitchState() ? '#409EFF' : '#C0C4CC'}; position: relative; cursor: pointer; transition: all 0.3s ease; `; const switchSlider = document.createElement('div'); switchSlider.style.cssText = ` width: 16px; height: 16px; border-radius: 50%; background: #fff; position: absolute; top: 2px; left: ${getSwitchState() ? '22px' : '2px'}; transition: left 0.3s ease; box-shadow: 0 2px 4px rgba(0,0,0,0.2); `; switchBtn.appendChild(switchSlider); const configBtn = document.createElement('button'); configBtn.id = 'blackSampleConfigBtn'; configBtn.textContent = '配置'; configBtn.style.cssText = ` padding: 6px 12px; background: #409EFF; color: #fff; border: none; border-radius: 4px; font-size: 14px; font-weight: 500; cursor: pointer; transition: background 0.2s ease; `; configBtn.addEventListener('mouseover', () => configBtn.style.background = '#66B1FF'); configBtn.addEventListener('mouseout', () => configBtn.style.background = '#409EFF'); const uploadBtn = document.createElement('button'); uploadBtn.textContent = '图片队列'; uploadBtn.style.cssText = ` padding: 6px 12px; background: #1890ff; color: #fff; border: none; border-radius: 4px; font-size: 14px; font-weight: 500; cursor: pointer; transition: background 0.2s ease; `; uploadBtn.addEventListener('mouseover', () => uploadBtn.style.background = '#40a9ff'); uploadBtn.addEventListener('mouseout', () => uploadBtn.style.background = '#1890ff'); uploadBtn.addEventListener('click', toggleUploadPanel); controlPanel.appendChild(switchText); controlPanel.appendChild(switchBtn); controlPanel.appendChild(configBtn); controlPanel.appendChild(uploadBtn); const topbar = document.querySelector('.library-topbar'); if (topbar) { topbar.appendChild(controlPanel); controlPanelCreated = true; } switchBtn.addEventListener('click', () => { const currentState = getSwitchState(); setSwitchState(!currentState); }); configBtn.addEventListener('click', () => { if (!configPanel) createConfigPanel(); configPanel.style.display = configPanel.style.display === 'none' ? 'block' : 'none'; }); } function updateSwitchUI(state) { const switchText = document.getElementById('blackSampleSwitchText'); const switchBtn = document.getElementById('blackSampleSwitchBtn'); const switchSlider = switchBtn?.querySelector('div'); if (switchText) switchText.textContent = state ? '已开启' : '已关闭'; if (switchBtn) switchBtn.style.background = state ? '#409EFF' : '#C0C4CC'; if (switchSlider) switchSlider.style.left = state ? '22px' : '2px'; } // ===== 创建全局配置面板 ===== function createConfigPanel() { if (configPanel) return; configPanel = document.createElement('div'); configPanel.id = 'blackSampleConfigPanel'; configPanel.style.cssText = ` position: fixed; top: 70px; right: 20px; width: 350px; background: #fff; border: 1px solid #E4E7ED; border-radius: 4px; box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); z-index: 999999; font-family: Helvetica Neue, Helvetica, PingFang SC, Microsoft YaHei, sans-serif; overflow: hidden; display: block; `; const header = document.createElement('div'); header.style.cssText = ` padding: 15px 20px; background: #F5F7FA; color: #303133; font-weight: 500; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #E4E7ED; `; header.innerHTML = ` 图片默认配置 `; configPanel.appendChild(header); const content = document.createElement('div'); content.style.cssText = `padding: 20px;`; content.innerHTML += `
${OPTIONS.businesses.map(business => ` `).join('')}
`; const saveBtn = document.createElement('button'); saveBtn.id = 'saveConfigBtn'; saveBtn.textContent = '保存配置'; saveBtn.style.cssText = ` width: 100%; padding: 10px; background: #409EFF; color: #fff; border: none; border-radius: 4px; font-weight: 500; cursor: pointer; transition: background 0.2s; font-size:14px; `; saveBtn.addEventListener('mouseover', () => saveBtn.style.background = '#66B1FF'); saveBtn.addEventListener('mouseout', () => saveBtn.style.background = '#409EFF'); content.appendChild(saveBtn); configPanel.appendChild(content); document.body.appendChild(configPanel); document.getElementById('closeConfigBtn').addEventListener('click', () => { configPanel.style.display = 'none'; }); document.getElementById('closeConfigBtn').addEventListener('mouseover', function(){ this.style.color = '#F56C6C'; }); document.getElementById('closeConfigBtn').addEventListener('mouseout', function(){ this.style.color = '#909399'; }); document.getElementById('saveConfigBtn').addEventListener('click', () => { const tag = document.getElementById('tagInput').value; const remark = document.getElementById('remarkInput').value; const contentSource = document.getElementById('sourceSelect').value; const dangerLevel = document.getElementById('dangerLevelSelect').value; const autoClickBtn = document.getElementById('autoClickBtn').checked; const selectedBusinesses = Array.from( document.querySelectorAll('#businessCheckboxes input[type="checkbox"]:checked') ).map(checkbox => checkbox.value); saveConfig({ tag, remark, contentSource, dangerLevel, selectedBusinesses, autoClickBtn }); const saveSuccess = document.createElement('div'); saveSuccess.textContent = '配置已保存!'; saveSuccess.style.cssText = ` position: fixed;top: 40px;right: 40px;padding: 10px 15px;background: #67C23A;color: #fff;border-radius: 4px;font-weight: 500;box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);z-index: 999999;transition: all 0.3s;font-size:14px; `; document.body.appendChild(saveSuccess); setTimeout(() => { saveSuccess.style.opacity = '0'; setTimeout(() => document.body.removeChild(saveSuccess), 300); }, 3000); configPanel.style.display = 'none'; }); } // ===== 初始化/销毁 ===== function initPage() { console.log('初始化目标页面:创建控制面板 + 启动弹窗监听'); createControlPanel(); if (observer) observer.disconnect(); startObserver(); } function destroyPage() { console.log('离开目标页面:移除控制面板 + 停止弹窗监听'); const controlPanel = document.getElementById('blackSampleControlPanel'); if (controlPanel) controlPanel.remove(); if (configPanel) { configPanel.remove(); configPanel = null; } if(uploadPanel){ uploadPanel.remove(); uploadPanel = null; } controlPanelCreated = false; if (observer) { observer.disconnect(); observer = null; } } // ===== URL监听 ===== function setupUrlChangeListener() { window.addEventListener('hashchange', checkPageStatus); const originalPushState = history.pushState; const originalReplaceState = history.replaceState; history.pushState = function(...args) { originalPushState.apply(this, args); checkPageStatus(); }; history.replaceState = function(...args) { originalReplaceState.apply(this, args); checkPageStatus(); }; checkPageStatus(); } function checkPageStatus() { console.log('检查页面状态,当前URL:', window.location.href); isTargetPage() ? initPage() : destroyPage(); } // ===== 🔥 彻底修复:弹窗监听(直接监听弹窗,不依赖遮罩) ===== function startObserver() { // 移除旧状态锁,避免拦截手动点击 let lastDialog = null; observer = new MutationObserver(() => { if (!getSwitchState()) return; // 直接查找可见的弹窗(核心修复:不依赖遮罩层) const dialog = document.querySelector('.aegis-v3-el-dialog:not([style*="display: none"]):not([style*="visibility: hidden"])'); if (!dialog) return; // 防止重复触发 if (dialog === lastDialog) return; lastDialog = dialog; console.log('检测到弹窗打开(手动/JS点击均生效)'); // 延时300ms,确保弹窗DOM完全渲染 setTimeout(() => { fillForm(currentConfig); }, 300); }); // 强化监听范围 observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); } // 🔥 废弃旧逻辑,直接由监听触发填充 async function startAutomation() {} async function fillForm(uploadConfig = currentConfig) { if (isFillingForm) return; if (!getSwitchState()) return; isFillingForm = true; console.log('✅ 填充执行', uploadConfig); try { await sleep(500); // 标签填充 const tagInput = document.querySelector('.aegis-v3-el-select__input'); if (tagInput && uploadConfig.tag) { tagInput.value = uploadConfig.tag; triggerEvent(tagInput, 'input'); triggerEvent(tagInput, 'change'); triggerEvent(tagInput, 'blur'); await sleep(150); const dropdownList = document.querySelector('.aegis-v3-el-select-dropdown.is-multiple .aegis-v3-el-select-dropdown__list') || document.querySelector('.aegis-v3-el-select-dropdown__list'); if (dropdownList) { const firstItem = dropdownList.querySelector('.aegis-v3-el-select-dropdown__item:not(.hidden)'); if (firstItem) { firstItem.click(); await sleep(100); } } } // 处理方案填充 const remarkInput = document.querySelector('input.aegis-v3-el-input__inner[placeholder="该内容的应对处理方案"]'); if (remarkInput) { remarkInput.value = uploadConfig.remark; triggerEvent(remarkInput, 'input'); triggerEvent(remarkInput, 'change'); } await sleep(200); // 业务勾选填充 const businessCheckboxes = document.querySelectorAll('.aegis-v3-el-checkbox'); businessCheckboxes.forEach(checkbox => { const label = checkbox.querySelector('.aegis-v3-el-checkbox__label'); if (label && OPTIONS.businesses.some(biz => label.textContent.includes(biz))) { if (checkbox.classList.contains('is-checked')) checkbox.click(); } }); await sleep(100); businessCheckboxes.forEach(checkbox => { const label = checkbox.querySelector('.aegis-v3-el-checkbox__label'); if (label && uploadConfig.selectedBusinesses.some(biz => label.textContent.includes(biz))) { if (!checkbox.classList.contains('is-checked')) checkbox.click(); } }); await sleep(200); // 取消文字违规勾选 const violationCheckboxes = document.querySelectorAll('.aegis-v3-el-checkbox'); violationCheckboxes.forEach(checkbox => { const label = checkbox.querySelector('.aegis-v3-el-checkbox__label'); if (label && label.textContent.includes('文字违规') && checkbox.classList.contains('is-checked')) { checkbox.click(); } }); await sleep(200); // 内容来源填充 const sourceSelect = document.querySelector('input[placeholder="选择来源"]'); if (sourceSelect) { sourceSelect.click(); await sleep(100); const dropdowns = document.querySelectorAll('.aegis-v3-el-select-dropdown:not([style*="display: none"])'); if (dropdowns.length > 0) { const visibleDropdown = dropdowns[dropdowns.length - 1]; const allOptions = Array.from(visibleDropdown.querySelectorAll('.aegis-v3-el-select-dropdown__item')); const sourceOption = allOptions.find(item => item.textContent.trim().includes(uploadConfig.contentSource)); if (sourceOption) sourceOption.click(); } } await sleep(200); // 危险程度填充 const dangerInputs = document.querySelectorAll('input[placeholder="危险程度"]'); if (dangerInputs.length > 1) { const dangerSelect = dangerInputs[1]; if (dangerSelect) { dangerSelect.click(); await sleep(100); const dropdowns = document.querySelectorAll('.aegis-v3-el-select-dropdown:not([style*="display: none"])'); if (dropdowns.length > 0) { const visibleDropdown = dropdowns[dropdowns.length - 2]; const allOptions = Array.from(visibleDropdown.querySelectorAll('.aegis-v3-el-select-dropdown__item')); const dangerOption = allOptions.find(item => item.textContent.trim().includes(uploadConfig.dangerLevel)); if (dangerOption) dangerOption.click(); } } } // 填充成功提示 const successNotification = document.createElement('div'); successNotification.textContent = '配置已自动应用!'; successNotification.style.cssText = ` position: fixed;top: 40px;right: 40px;padding: 10px 15px;background: #67C23A;color: #fff;border-radius: 4px;font-weight: 500;box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);z-index: 999999;transition: all 0.3s;font-size: 14px; `; document.body.appendChild(successNotification) setTimeout(() => { successNotification.style.opacity = '0'; setTimeout(() => document.body.removeChild(successNotification), 300); }, 3000); // 自动确认逻辑 if (getSwitchState()) { const timer = setInterval(() => { const avatarWrapper = document.querySelector('.avatar-wrapper'); if (!avatarWrapper) return; const img = avatarWrapper.querySelector('img'); if (!img || !img.src) return; clearInterval(timer); const finalAutoClick = currentConfig.autoClickBtn; if (finalAutoClick) { const buttons = document.querySelectorAll('.aegis-v3-el-button.aegis-v3-el-button--primary'); if (buttons.length > 0) buttons[buttons.length - 1].click(); setTimeout(() => { const newButtons = document.querySelectorAll('.aegis-v3-el-button.aegis-v3-el-button--primary'); if (newButtons.length > 0) newButtons[newButtons.length - 1].click(); }, 750); } else { const btns = document.querySelectorAll('.aegis-v3-el-button.aegis-v3-el-button--primary'); const clickHandler = () => { setTimeout(() => { const newButtons = document.querySelectorAll('.aegis-v3-el-button.aegis-v3-el-button--primary'); if (newButtons.length > 0) newButtons[newButtons.length - 1].click(); }, 750); btns.forEach(b => b.removeEventListener('click', clickHandler)); }; btns.forEach(b => b.addEventListener('click', clickHandler)); } }, 500); setTimeout(() => clearInterval(timer), 10000); } } finally { isFillingForm = false; } } function triggerEvent(element, eventType) { const event = new Event(eventType, { bubbles: true }); element.dispatchEvent(event); } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function waitForOverlayHidden() { const maxWaitTime = 15000; const startTime = Date.now(); return new Promise(resolve => { const timer = setInterval(() => { const list = document.querySelectorAll('.aegis-v3-el-overlay-dialog'); let allHide = true; list.forEach(el => { if (getComputedStyle(el).display !== 'none') allHide = false; }) if (allHide || Date.now() - startTime > maxWaitTime) { clearInterval(timer); resolve(); } }, 200); }); } function toggleUploadPanel() { if (!uploadPanel) createUploadPanel(); uploadPanel.style.display = uploadPanel.style.display === 'none' ? 'block' : 'none'; } // 创建上传队列面板 function createUploadPanel() { if (uploadPanel) return; uploadPanel = document.createElement('div'); uploadPanel.id = 'uploadQueuePanel_FINAL'; uploadPanel.style.cssText = ` position: fixed; top: 70px; right: 20px; width: 460px; background: #fff; border-radius: 4px; box-shadow: 0 2px 12px rgba(0,0,0,0.1); z-index: 9999999; font-family: Helvetica Neue, Helvetica, PingFang SC, Microsoft YaHei, sans-serif; border: 1px solid #E4E7ED; overflow: hidden; display: none; `; const header = document.createElement('div'); header.style.cssText = 'padding:12px 15px;background:#F5F7FA;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid #E4E7ED;'; header.innerHTML = ` 批量上传队列
`; const fileInput = document.createElement('input'); fileInput.type = 'file'; fileInput.accept = 'image/*'; fileInput.multiple = true; fileInput.style.display = 'none'; fileInput.id = 'fileInput_FINAL'; const queueContainer = document.createElement('div'); queueContainer.id = 'queueContainer_FINAL'; queueContainer.style.cssText = 'max-height:400px;overflow-y:auto;padding:10px;'; uploadPanel.append(header, fileInput, queueContainer); document.body.appendChild(uploadPanel); document.getElementById('closePanelBtn_FINAL').onclick = () => { uploadPanel.style.display = 'none'; }; document.getElementById('selectFilesBtn_FINAL').onclick = () => { document.getElementById('fileInput_FINAL').click(); }; document.getElementById('fileInput_FINAL').onchange = handleFileSelect; document.getElementById('clearAllBtn_FINAL').onclick = () => { uploadQueue.forEach(file => file.previewURL && URL.revokeObjectURL(file.previewURL)); uploadQueue = []; uploadedFiles.clear(); renderQueue(); showToast('已清空所有图片', '#67C23A'); }; } function handleFileSelect(e) { const files = Array.from(e.target.files); if (!files.length) return; files.forEach(file => { file.customConfig = {...currentConfig}; }); uploadQueue = [...uploadQueue, ...files]; renderQueue(); e.target.value = ''; } function deleteFile(fileName) { const fileToDelete = uploadQueue.find(file => file.name === fileName); if (fileToDelete) URL.revokeObjectURL(fileToDelete.previewURL); uploadQueue = uploadQueue.filter(file => file.name !== fileName); uploadedFiles.delete(fileName); renderQueue(); } function closeAllAccordions(e) { const panelContainer = document.getElementById('queueContainer_FINAL'); if (!panelContainer) return; if (!panelContainer.contains(e.target)) { document.querySelectorAll('#queueContainer_FINAL > div > div:last-child').forEach(panel => { panel.style.maxHeight = '0'; }); } } // 自定义上拉菜单 class CustomPullUpSelect { constructor(container, options, selectedValue, onChange) { this.container = container; this.options = options; this.selectedValue = selectedValue; this.onChange = onChange; this.isOpen = false; this.init(); } init() { this.selectContainer = document.createElement('div'); this.selectContainer.className = 'custom-pullup-select'; this.selectContainer.style.cssText = ` position: relative; width: 100%; box-sizing: border-box; `; this.trigger = document.createElement('div'); this.trigger.className = 'custom-select-trigger'; this.trigger.style.cssText = ` width: 100%; padding: 2px 4px; border: 1px solid #ddd; border-radius: 2px; background: white; cursor: pointer; display: flex; justify-content: space-between; align-items: center; font-size: 12px; `; this.trigger.textContent = this.getSelectedText(); this.trigger.innerHTML += ''; this.menu = document.createElement('div'); this.menu.className = 'custom-select-menu'; this.menu.style.cssText = ` position: absolute; bottom: 100%; left: 0; right: 0; max-height: 150px; overflow-y: auto; background: white; border: 1px solid #ddd; border-radius: 2px; box-shadow: 0 -2px 5px rgba(0,0,0,0.1); z-index: 9999; display: none; margin-bottom: 2px; `; this.options.forEach(option => { const item = document.createElement('div'); item.className = 'custom-select-item'; item.style.cssText = ` padding: 4px 6px; cursor: pointer; font-size: 12px; `; item.textContent = option; item.dataset.value = option; if (option === this.selectedValue) { item.style.backgroundColor = '#e8f4ff'; } item.addEventListener('click', () => this.selectItem(item)); this.menu.appendChild(item); }); this.selectContainer.appendChild(this.trigger); this.selectContainer.appendChild(this.menu); this.container.appendChild(this.selectContainer); this.trigger.addEventListener('click', () => this.toggleMenu()); document.addEventListener('click', (e) => this.handleClickOutside(e)); } getSelectedText() { return this.selectedValue || this.options[0] || '请选择'; } toggleMenu() { this.isOpen = !this.isOpen; this.menu.style.display = this.isOpen ? 'block' : 'none'; this.trigger.querySelector('span').textContent = this.isOpen ? '▼' : '▲'; } selectItem(item) { this.selectedValue = item.dataset.value; this.trigger.firstChild.textContent = this.selectedValue; this.menu.querySelectorAll('.custom-select-item').forEach(el => { el.style.backgroundColor = ''; }); item.style.backgroundColor = '#e8f4ff'; this.toggleMenu(); this.onChange(this.selectedValue); } handleClickOutside(e) { if (!this.selectContainer.contains(e.target)) { this.isOpen = false; this.menu.style.display = 'none'; this.trigger.querySelector('span').textContent = '▲'; } } } // 🔥 修复:仅更新当前行文本,样式完全不变 function updateRowDisplay(index) { const file = uploadQueue[index]; if (!file) return; const container = document.getElementById('queueContainer_FINAL'); const row = container?.children[index]; if (!row) return; const statusText = row.querySelector('div[style*="font-size:11px"]'); if (statusText) { const config = file.customConfig; statusText.textContent = `标签:${config.tag||'无'} | 危险:${config.dangerLevel||'无'} | 业务:${config.selectedBusinesses.join('、')||'全部'}`; } } // 渲染队列 function renderQueue() { const container = document.getElementById('queueContainer_FINAL'); if (!container) return; container.innerHTML = ''; if (uploadQueue.length === 0) { container.innerHTML = '
暂无上传文件
'; return; } document.removeEventListener('click', closeAllAccordions); document.addEventListener('click', closeAllAccordions); uploadQueue.forEach((file, index) => { const isUploaded = uploadedFiles.has(file.name); const config = file.customConfig || currentConfig; const row = document.createElement('div'); row.style.cssText = ` border-bottom:1px solid #E4E7ED; ${isUploaded ? 'background:#F0F9FF;' : ''} transition: background 0.2s ease; cursor: pointer; `; const mainRow = document.createElement('div'); mainRow.style.cssText = `display:flex;align-items:center;gap:10px;padding:8px;`; const triggerArea = document.createElement('div'); triggerArea.style.cssText = "display:flex;align-items:center;gap:10px;flex:1;"; if (!file.previewURL) file.previewURL = URL.createObjectURL(file); const img = document.createElement('img'); img.src = file.previewURL; img.style.cssText = 'width:40px;height:40px;object-fit:cover;border-radius:4px;'; const info = document.createElement('div'); info.style.cssText = 'flex:1;overflow:hidden;'; info.innerHTML = `
${file.name}
${formatFileSize(file.size)}
标签:${config.tag||'无'} | 危险:${config.dangerLevel||'无'} | 业务:${config.selectedBusinesses.join('、')||'全部'}
`; triggerArea.append(img, info); const actionArea = document.createElement('div'); actionArea.style.cssText = "display:flex;gap:6px;"; const uploadBtn = document.createElement('button'); uploadBtn.textContent = isUploaded ? '已传' : '上传'; uploadBtn.style.cssText = `padding:4px 8px;${isUploaded ? 'background:#909399;' : 'background:#67C23A;'}color:white;border:none;border-radius:4px;cursor:pointer;font-size:12px;`; uploadBtn.onclick = (e) => { e.stopPropagation(); uploadBtn.disabled = true; uploadBtn.style.background = '#C0C4CC'; uploadBtn.style.cursor = 'not-allowed'; startSingleUpload(file, uploadBtn); }; const delBtn = document.createElement('button'); delBtn.textContent = '删除'; delBtn.style.cssText = 'padding:4px 8px;background:#F56C6C;color:white;border:none;border-radius:4px;cursor:pointer;font-size:12px;'; delBtn.onclick = (e) => { e.stopPropagation(); deleteFile(file.name); }; actionArea.append(uploadBtn, delBtn); mainRow.append(triggerArea, actionArea); const accordionPanel = document.createElement('div'); accordionPanel.style.cssText = ` max-height:0;overflow:hidden;transition:max-height 0.3s ease;padding:0 10px; border-top:1px dashed #E4E7ED;background:#fafafa; `; const formContainer = document.createElement('div'); formContainer.style.cssText = `padding:8px 0;display:grid;grid-template-columns:1fr 1fr;gap:8px;font-size:12px;`; const tagGroup = document.createElement('div'); tagGroup.innerHTML = ` `; const remarkGroup = document.createElement('div'); remarkGroup.innerHTML = ` `; const sourceGroup = document.createElement('div'); sourceGroup.innerHTML = ``; const sourceSelectContainer = document.createElement('div'); sourceGroup.appendChild(sourceSelectContainer); const dangerGroup = document.createElement('div'); dangerGroup.innerHTML = ``; const dangerSelectContainer = document.createElement('div'); dangerGroup.appendChild(dangerSelectContainer); const businessGroup = document.createElement('div'); businessGroup.style.gridColumn = 'span 2'; businessGroup.innerHTML = `
${OPTIONS.businesses.map(b => ` `).join('')}
`; formContainer.append(tagGroup, remarkGroup, sourceGroup, dangerGroup, businessGroup); accordionPanel.appendChild(formContainer); row.append(mainRow, accordionPanel); container.appendChild(row); mainRow.onclick = (e) => { e.stopPropagation(); const isOpen = accordionPanel.style.maxHeight === '200px'; document.querySelectorAll('#queueContainer_FINAL > div > div:last-child').forEach(p => { p.style.maxHeight = '0'; }); accordionPanel.style.maxHeight = isOpen ? '0' : '200px'; }; accordionPanel.onclick = (e) => { e.stopPropagation(); }; row.onmouseenter = () => { if (!isUploaded) row.style.background = '#F5F7FA'; }; row.onmouseleave = () => { if (!isUploaded) row.style.background = ''; }; // 下拉框修改实时更新 new CustomPullUpSelect(sourceSelectContainer, OPTIONS.contentSources, config.contentSource, (v) => { file.customConfig.contentSource = v; updateRowDisplay(index); }); new CustomPullUpSelect(dangerSelectContainer, OPTIONS.dangerLevels, config.dangerLevel, (v) => { file.customConfig.dangerLevel = v; updateRowDisplay(index); }); bindRowConfigEvents(index); }); } // 绑定行内修改事件 function bindRowConfigEvents(index) { const file = uploadQueue[index]; if (!file) return; document.querySelector(`.row-tag[data-index="${index}"]`).addEventListener('change', function(){ file.customConfig.tag = this.value; updateRowDisplay(index); }); document.querySelector(`.row-remark[data-index="${index}"]`).addEventListener('change', function(){ file.customConfig.remark = this.value; }); document.querySelectorAll(`.row-biz[data-index="${index}"]`).forEach(checkbox => { checkbox.addEventListener('change', function(){ const allChecked = Array.from(document.querySelectorAll(`.row-biz[data-index="${index}"]:checked`)).map(i=>i.value); file.customConfig.selectedBusinesses = allChecked; updateRowDisplay(index); }); }); } function formatFileSize(bytes) { if (bytes < 1024) return bytes + ' B'; if (bytes < 1048576) return (bytes / 1024).toFixed(1) + ' KB'; return (bytes / 1048576).toFixed(1) + ' MB'; } async function startSingleUpload(file, btn) { if (!getSwitchState()) { showToast('脚本已关闭,无法上传', '#F56C6C'); restoreUploadBtn(btn, file); return; } try { const btns = document.querySelectorAll('.aegis-v3-el-button.aegis-v3-el-button--primary'); if (btns.length >= 2) btns[1].click(); await sleep(500); const now = Date.now(); if (now - lastFileUploadTime < UPLOAD_DEBOUNCE_INTERVAL) { const remainSeconds = Math.ceil((UPLOAD_DEBOUNCE_INTERVAL - (now - lastFileUploadTime)) / 1000); showToast(`操作频繁,请等待${remainSeconds}秒后再上传`, '#F56C6C'); return; } const fileInput = document.querySelector('input[name="file"]'); if (!fileInput) { showToast('未找到上传输入框', '#F56C6C'); return; } lastFileUploadTime = now; const dataTransfer = new DataTransfer(); dataTransfer.items.add(file); fileInput.files = dataTransfer.files; fileInput.dispatchEvent(new Event('change', { bubbles: true })); fileInput.dispatchEvent(new Event('input', { bubbles: true })); await fillForm(file.customConfig); uploadedFiles.add(file.name); renderQueue(); console.log(`上传成功:${file.name}`); } catch (err) { showToast(`上传失败:${err.message}`, '#F56C6C'); console.error(err); } finally { await waitForOverlayHidden(); restoreUploadBtn(btn, file); } } function restoreUploadBtn(btn, file) { if (!btn) return; const isUploaded = uploadedFiles.has(file.name); btn.disabled = false; btn.style.cursor = 'pointer'; btn.textContent = isUploaded ? '已传' : '上传'; btn.style.background = isUploaded ? '#909399' : '#67C23A'; } function showToast(msg, bg) { const div = document.createElement('div'); div.style.cssText = `position:fixed;top:100px;right:40px;padding:8px 15px;background:${bg};color:white;border-radius:4px;z-index:999999;transition:opacity 0.3s;font-size:14px;`; div.textContent = msg; document.body.appendChild(div); setTimeout(() => { div.style.opacity = '0'; setTimeout(() => div.remove(), 300); }, 2000); } // ===== 初始化 ===== setupUrlChangeListener(); })();