// ==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 += `
`;
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();
})();