// ========== 可访问性优化 ==========
(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('[视口级数据加载] 管理器已就绪');
})();
})();