document.addEventListener('DOMContentLoaded', () => { lucide.createIcons(); const submitBtn = document.getElementById('submitBtn'); const pointsDisplay = document.getElementById('pointsDisplay'); const headerPoints = document.getElementById('headerPoints'); const resultVideo = document.getElementById('resultVideo'); const finalWrapper = document.getElementById('finalWrapper'); const placeholder = document.getElementById('placeholder'); const statusInfo = document.getElementById('statusInfo'); const promptInput = document.getElementById('promptInput'); const fileInput = document.getElementById('fileInput'); const imagePreview = document.getElementById('imagePreview'); const modelSelect = document.getElementById('modelSelect'); const ratioSelect = document.getElementById('ratioSelect'); const promptTemplates = document.getElementById('promptTemplates'); const enhancePrompt = document.getElementById('enhancePrompt'); // 历史记录相关 const historyList = document.getElementById('historyList'); const historyCount = document.getElementById('historyCount'); const historyEmpty = document.getElementById('historyEmpty'); const loadMoreBtn = document.getElementById('loadMoreBtn'); let uploadedImageUrl = null; let historyPage = 1; let isLoadingHistory = false; // 初始化配置 async function initConfig() { try { const r = await fetch('/api/config'); if (!r.ok) throw new Error('API 响应失败'); const d = await r.json(); if (d.video_models && d.video_models.length > 0) { modelSelect.innerHTML = d.video_models.map(m => `` ).join(''); } if (d.video_prompts && d.video_prompts.length > 0) { promptTemplates.innerHTML = d.video_prompts.map(p => `` ).join(''); } } catch (e) { console.error('加载系统配置失败:', e); } } // 载入历史记录 async function loadHistory(page = 1, append = false) { if (isLoadingHistory) return; isLoadingHistory = true; try { const r = await fetch(`/api/history?page=${page}&per_page=10&filter_type=video`); const d = await r.json(); // 服务端已完成过滤 const videoRecords = d.history; if (videoRecords.length > 0) { const html = videoRecords.map(item => { const videoObj = item.urls.find(u => u.type === 'video') || { url: item.urls[0] }; const videoUrl = typeof videoObj === 'string' ? videoObj : videoObj.url; return `
`; }).join(''); if (append) { historyList.insertAdjacentHTML('beforeend', html); } else { historyList.innerHTML = html; } historyEmpty.classList.add('hidden'); historyCount.innerText = videoRecords.length + (append ? parseInt(historyCount.innerText) : 0); if (d.history.length >= 10) { loadMoreBtn.classList.remove('hidden'); } else { loadMoreBtn.classList.add('hidden'); } } else if (!append) { historyEmpty.classList.remove('hidden'); historyList.innerHTML = ''; } lucide.createIcons(); } catch (e) { console.error('加载历史失败:', e); } finally { isLoadingHistory = false; } } window.playHistoryVideo = (url) => { showVideo(url); window.scrollTo({ top: 0, behavior: 'smooth' }); }; window.downloadUrl = (url) => { // 使用后端代理强制下载,绕过跨域限制 showToast('开始下载...', 'info'); const filename = `vision-video-${Date.now()}.mp4`; const proxyUrl = `/api/download_proxy?url=${encodeURIComponent(url)}&filename=${filename}`; // 创建隐藏的 iframe 触发下载,相比 a 标签兼容性更好 const iframe = document.createElement('iframe'); iframe.style.display = 'none'; iframe.src = proxyUrl; document.body.appendChild(iframe); // 1分钟后清理 iframe setTimeout(() => document.body.removeChild(iframe), 60000); }; loadMoreBtn.onclick = () => { historyPage++; loadHistory(historyPage, true); }; initConfig(); loadHistory(); window.applyTemplate = (text) => { promptInput.value = text; showToast('已应用提示词模板', 'success'); }; // 上传图片逻辑 fileInput.onchange = async (e) => { const files = e.target.files; if (files.length === 0) return; const formData = new FormData(); formData.append('images', files[0]); try { submitBtn.disabled = true; const r = await fetch('/api/upload', { method: 'POST', body: formData }); const d = await r.json(); if (d.urls && d.urls.length > 0) { uploadedImageUrl = d.urls[0]; imagePreview.innerHTML = `