From 97de708469950d8cca57ded1e306971a58ed2521 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Mon, 27 Jul 2026 10:51:36 +0800 Subject: [PATCH] feat: update button opens full publish modal, keeps old preview if not changed --- static/js/pages/market.js | 86 ++++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 10 deletions(-) diff --git a/static/js/pages/market.js b/static/js/pages/market.js index c6898ed..2e2f7a3 100644 --- a/static/js/pages/market.js +++ b/static/js/pages/market.js @@ -139,16 +139,7 @@ const PageMarket = { } if (btnUpdate) { - const input = document.createElement('input'); input.type = 'file'; input.accept = btnUpdate.dataset.type; - input.onchange = async (ev) => { - const file = ev.target.files[0]; if (!file) return; - const fd = new FormData(); fd.append('file', file); fd.append('token', this._marketToken); - const url = btnUpdate.dataset.coll === 'scenes' ? '/api/market/scenes/upload' : '/api/market/upload'; - const res = await fetch(url, { method: 'POST', body: fd }); - const data = await res.json(); - Toast.show(data.error ? '更新失败: ' + data.error : '上传成功(新记录)', data.error ? 'error' : 'success'); - if (!data.error) this._loadItems(); - }; input.click(); + this._showUpdateModal(btnUpdate.dataset); return; } if (btnDelete) { @@ -402,6 +393,81 @@ const PageMarket = { return `

${msg||'暂无'}

`; }, + _showUpdateModal(ds) { + if (!this._marketToken) { Toast.show('请先登录', 'error'); return; } + const isScene = ds.coll === 'scenes'; + const overlay = document.createElement('div'); overlay.className = 'modal-overlay'; + overlay.innerHTML = ''; + document.body.appendChild(overlay); + overlay.addEventListener('click', (e) => { if (e.target === overlay) overlay.remove(); }); + + let updateFile = null, previewFile = null; + const previewDrop = document.createElement('div'); + previewDrop.style.cssText = 'border:2px dashed var(--border-normal);border-radius:8px;padding:20px;text-align:center;color:var(--text-tertiary);font-size:13px;cursor:pointer;margin:8px 0;transition:all .2s'; + previewDrop.textContent = '点击或拖放新预览图 (最大 6MB)'; + overlay.querySelector('.modal').insertBefore(previewDrop, overlay.querySelector('#pub-update-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() { + previewDrop.style.display = this.checked ? '' : 'none'; + if (!this.checked) { previewFile = null; previewDrop.textContent = '点击或拖放新预览图 (最大 6MB)'; previewDrop.style.borderColor = 'var(--border-normal)'; previewDrop.style.color = 'var(--text-tertiary)'; } + }); + + overlay.querySelector('#pub-update-btn').addEventListener('click', () => { + const input = document.createElement('input'); input.type = 'file'; input.accept = isScene ? '.tss' : '.tsd'; + input.onchange = function(e) { updateFile = e.target.files[0]; if (updateFile) { const btn = overlay.querySelector('#pub-update-btn'); btn.textContent = '✓ '+updateFile.name; btn.style.background = 'var(--accent)'; btn.style.color = '#fff'; } }; + input.click(); + }); + + overlay.querySelector('#pub-update-btn').insertAdjacentHTML('afterend', ''); + overlay.querySelector('#pub-do-update').addEventListener('click', async () => { + if (!updateFile && !previewFile) { Toast.show('请选择文件或预览图', 'error'); return; } + const fd = new FormData(); fd.append('token', this._marketToken); + if (updateFile) fd.append('file', updateFile); + if (previewFile) fd.append('preview', previewFile); + // If no new preview given, fetch old one from record + if (!previewFile && ds.preview) { + try { + const prevRes = await fetch('https://turbosu.yeij.top/api/files/'+ds.coll+'/'+ds.id+'/'+ds.preview); + if (prevRes.ok) { + const blob = await prevRes.blob(); + fd.append('preview', blob, ds.preview); + } + } catch(e) {} + } + const url = isScene ? '/api/market/scenes/upload' : '/api/market/upload'; + const res = await fetch(url, { method: 'POST', body: fd }); + const data = await res.json(); + if (!data.error && data.id) { + // Delete old record + await fetch('/api/market/delete', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({id: ds.id, collection: ds.coll, token: this._marketToken}) }); + } + Toast.show(data.error ? '更新失败: '+data.error : '更新成功', data.error ? 'error' : 'success'); + if (!data.error) { overlay.remove(); this._loadItems(); } + }); + }, + _template() { return `