feat: drag-drop preview upload with file type/size validation

This commit is contained in:
2026-07-27 10:46:08 +08:00
parent 44c0383dc1
commit 2d5cdc0d3b
+42 -9
View File
@@ -222,21 +222,54 @@ const PageMarket = {
_upload() {
if (!this._marketToken) { Toast.show('请先登录', 'error'); return; }
const overlay = document.createElement('div'); overlay.className = 'modal-overlay';
overlay.innerHTML = '<div class="modal" style="min-width:480px;max-width:520px;padding:24px"><h3 style="font-size:18px;font-weight:600;margin-bottom:4px">发布作品</h3><p style="font-size:12px;color:var(--text-secondary);margin-bottom:18px">选择要发布的仪表盘或场景</p><div style="margin-bottom:12px"><label class="switch-label" style="font-size:13px"><input type="checkbox" id="pub-preview-toggle"><span class="switch-track"></span> 上传预览图</label><span id="pub-preview-file" style="display:none;margin-left:8px;font-size:12px;color:var(--text-tertiary)"></span></div><button id="pub-file-btn" class="btn btn-primary btn-sm" style="width:100%;margin-bottom:10px">📁 选择文件 (.tsd / .tss)</button><div style="font-size:13px;color:var(--text-tertiary);margin:10px 0;text-align:center">— 或从本地选择 —</div><div id="pub-local-list" style="max-height:300px;overflow-y:auto">加载中...</div></div>';
overlay.innerHTML = '<div class="modal" style="min-width:480px;max-width:520px;padding:24px"><h3 style="font-size:18px;font-weight:600;margin-bottom:4px">发布作品</h3><p style="font-size:12px;color:var(--text-secondary);margin-bottom:18px">选择要发布的仪表盘或场景</p><div style="margin-bottom:12px"><label class="switch-label" style="font-size:13px"><input type="checkbox" id="pub-preview-toggle"><span class="switch-track"></span> 上传预览图</label></div><button id="pub-file-btn" class="btn btn-primary btn-sm" style="width:100%;margin-bottom:10px">📁 选择文件 (.tsd / .tss)</button><div style="font-size:13px;color:var(--text-tertiary);margin:10px 0;text-align:center">— 或从本地选择 —</div><div id="pub-local-list" style="max-height:300px;overflow-y:auto">加载中...</div></div>';
document.body.appendChild(overlay);
overlay.addEventListener('click', (e) => { if (e.target === overlay) overlay.remove(); });
let previewFile = null;
const previewDrop = document.createElement('div');
previewDrop.id = 'pub-preview-drop';
previewDrop.style.cssText = 'display:none;border:2px dashed var(--border-normal);border-radius:8px;padding:20px;text-align:center;color:var(--text-tertiary);font-size:13px;cursor:pointer;margin-top:8px;transition:all .2s';
previewDrop.textContent = '点击或拖放图片到此处 (最大 6MB)';
overlay.querySelector('.modal').insertBefore(previewDrop, overlay.querySelector('#pub-file-btn'));
function pickPreview() {
const inp = document.createElement('input'); inp.type = 'file'; inp.accept = 'image/*'; inp.style.display = 'none';
inp.onchange = function() {
const f = this.files[0];
if (!f) return;
if (f.size > 6291456) { Toast.show('预览图不能超过 6MB', 'error'); return; }
if (!f.type.startsWith('image/')) { Toast.show('仅支持图片格式', 'error'); return; }
previewFile = f;
previewDrop.textContent = '✓ ' + f.name + ' (' + (f.size/1024/1024).toFixed(1) + ' MB)';
previewDrop.style.borderColor = 'var(--accent)'; previewDrop.style.color = 'var(--accent)';
};
document.body.appendChild(inp); inp.click();
}
['dragenter','dragover'].forEach(ev => previewDrop.addEventListener(ev, e => { e.preventDefault(); previewDrop.style.borderColor = 'var(--accent)'; }));
['dragleave','drop'].forEach(ev => previewDrop.addEventListener(ev, e => { e.preventDefault(); previewDrop.style.borderColor = 'var(--border-normal)'; }));
previewDrop.addEventListener('drop', function(e) {
e.preventDefault();
const f = e.dataTransfer.files[0];
if (!f) return;
if (!f.type.startsWith('image/')) { Toast.show('仅支持图片格式', 'error'); return; }
if (f.size > 6291456) { Toast.show('预览图不能超过 6MB', 'error'); return; }
previewFile = f;
previewDrop.textContent = '✓ ' + f.name + ' (' + (f.size/1024/1024).toFixed(1) + ' MB)';
previewDrop.style.borderColor = 'var(--accent)'; previewDrop.style.color = 'var(--accent)';
});
previewDrop.addEventListener('click', pickPreview);
overlay.querySelector('#pub-preview-toggle').addEventListener('change', function() {
if (this.checked) {
const inp = document.createElement('input'); inp.type = 'file'; inp.accept = 'image/*';
inp.style.display = 'none'; inp.id = 'pub-preview-input';
inp.onchange = function() {
previewFile = this.files[0];
if (previewFile && previewFile.size > 6291456) { Toast.show('预览图不能超过 6MB', 'error'); previewFile = null; this.value = ''; }
const el = document.getElementById('pub-preview-file'); if(el){el.textContent=previewFile?previewFile.name:'';el.style.display=previewFile?'':'none'} };
document.body.appendChild(inp); inp.click();
} else { previewFile=null; const o=document.getElementById('pub-preview-input');if(o)o.remove(); const el=document.getElementById('pub-preview-file');if(el)el.style.display='none' }
previewDrop.style.display = '';
} else {
previewFile = null;
previewDrop.style.display = 'none';
previewDrop.textContent = '点击或拖放图片到此处 (最大 6MB)';
previewDrop.style.borderColor = 'var(--border-normal)'; previewDrop.style.color = 'var(--text-tertiary)';
}
});
overlay.querySelector('#pub-file-btn').addEventListener('click', () => {