天好供应链看板
初始化...
// ========== 可访问性优化 ========== (function(){ // 为图标按钮添加aria-label function fixAccessibility(){ var buttons = document.querySelectorAll('button'); buttons.forEach(function(btn){ if(!btn.textContent.trim() && !btn.getAttribute('aria-label')){ var icon = btn.querySelector('svg, [class*="icon"], [class*="Icon"]'); if(icon){ var title = icon.getAttribute('title') || icon.getAttribute('aria-label') || '按钮'; btn.setAttribute('aria-label', title); btn.setAttribute('title', title); } } }); // 为图片添加alt属性 var images = document.querySelectorAll('img:not([alt])'); images.forEach(function(img){ img.setAttribute('alt', img.getAttribute('title') || '图片'); }); } // 初始执行 if(document.readyState === 'loading'){ document.addEventListener('DOMContentLoaded', fixAccessibility); } else { fixAccessibility(); } // 监听DOM变化 var observer = new MutationObserver(function(){ setTimeout(fixAccessibility, 500); }); observer.observe(document.body, {childList: true, subtree: true}); console.log('[可访问性] 优化已启用'); })(); // ========== 字段级增量上传辅助函数 ========== (function(){ window.__fieldDiff = function(original, updated){ var diff = {}; var hasDiff = false; for(var key in updated){ if(updated.hasOwnProperty(key) && original[key] !== updated[key]){ diff[key] = updated[key]; hasDiff = true; } } return hasDiff ? diff : null; }; window.__trackOriginal = function(data){ return JSON.parse(JSON.stringify(data)); }; })(); // ========== 字段级增量上传:全局数据库函数包装 ========== (function(){ var originalDataCache = {}; // 表名 -> {主键值: 原始数据} var uploadStats = {total: 0, skipped: 0, fieldLevel: 0}; // 包装upsert函数,实现字段级差异上传 window.__wrapUpsert = function(table, data, onConflict){ if(!data || !data.length) return data; // 初始化表缓存 if(!originalDataCache[table]){ originalDataCache[table] = {}; } var changedRecords = []; var skippedCount = 0; data.forEach(function(record){ var key = onConflict ? record[onConflict] : record.id || record.sku; if(!key){ changedRecords.push(record); return; } var original = originalDataCache[table][key]; if(original){ // 计算字段级差异 var diff = window.__fieldDiff(original, record); if(diff){ // 只上传变化的字段 + 主键 var fieldLevelRecord = {}; fieldLevelRecord[onConflict || 'id'] = key; for(var k in diff){ fieldLevelRecord[k] = diff[k]; } changedRecords.push(fieldLevelRecord); uploadStats.fieldLevel++; } else { skippedCount++; // 无变化,跳过 } } else { changedRecords.push(record); // 新记录,全量上传 } // 更新缓存 originalDataCache[table][key] = JSON.parse(JSON.stringify(record)); }); uploadStats.total += data.length; uploadStats.skipped += skippedCount; if(skippedCount > 0){ console.log('[字段级增量] ' + table + ': ' + data.length + '条中跳过' + skippedCount + '条无变化记录'); } return changedRecords; }; // 暴露统计信息 window.__getUploadStats = function(){ return uploadStats; }; // 清除缓存(页面切换时调用) window.__clearUploadCache = function(table){ if(table){ delete originalDataCache[table]; } else { for(var k in originalDataCache) delete originalDataCache[k]; } }; console.log('[字段级增量上传] 全局包装器已就绪'); })(); // ========== 视口级数据加载:全局数据加载管理器 ========== (function(){ var loadQueue = []; var isProcessing = false; var loadedSections = new Set(); // 注册需要视口加载的数据 window.__registerViewportLoad = function(sectionId, loadFn){ loadQueue.push({id: sectionId, fn: loadFn, loaded: false}); }; // 处理加载队列 function processQueue(){ if(isProcessing || loadQueue.length === 0) return; isProcessing = true; var nextLoad = loadQueue.find(function(item){ return !item.loaded && document.getElementById(item.id) && window.__isInViewport && window.__isInViewport(document.getElementById(item.id)); }); if(nextLoad){ nextLoad.loaded = true; loadedSections.add(nextLoad.id); Promise.resolve(nextLoad.fn()).finally(function(){ isProcessing = false; setTimeout(processQueue, 100); }); } else { isProcessing = false; } } // 监听视口变化 document.addEventListener('viewport-enter', function(e){ var sectionId = e.target.id; if(sectionId && !loadedSections.has(sectionId)){ setTimeout(processQueue, 50); } }); // 滚动时处理队列 var scrollTimeout = null; window.addEventListener('scroll', function(){ if(scrollTimeout) clearTimeout(scrollTimeout); scrollTimeout = setTimeout(processQueue, 200); }, {passive: true}); window.__viewportLoadManager = { register: window.__registerViewportLoad, process: processQueue, getLoaded: function(){ return Array.from(loadedSections); } }; console.log('[视口级数据加载] 管理器已就绪'); })(); })();