const API_ENDPOINT = 'https://dev.obscura.work/v1'; // 确保 selectedLang 在 module.js 中可用 if (typeof selectedLang === 'undefined') { selectedLang = 'zh'; // 如果未定义,设置默认值 } async function showFeature() { try { const userInfo = await fetchUserInfo(); if (!userInfo) { alert(lang[selectedLang].pleaseLogin); window.location.href = 'login.html'; return; } // 检查邮箱验证状态 const emailVerified = userInfo.email_verified === 'True' || userInfo.email_verified === true; console.log('Email Verified:', emailVerified); // 打印邮箱验证状态 if (!emailVerified ) { alert(lang[selectedLang].pleaseVerifyEmail); showUserCenterSection('profile'); return; } // 如果用户已登录且邮箱已验证,继续显示功能 const chatContent = document.getElementById('chatContent'); const dashboardContent = document.getElementById('dashboardContent'); const usersContent = document.getElementById('usersContent'); const pageTitle = document.getElementById('pageTitle'); const featureContent = document.getElementById('featureContent'); const userCenterContent = document.getElementById('userCenterContent'); const apiKeyInput = document.getElementById('apiKeyInput'); const showApiDocs = document.getElementById('showApiDocs'); const apiDocsContent = document.getElementById('apiDocsContent'); if (apiDocsContent) apiDocsContent.style.display = 'none'; if (featureContent) featureContent.style.display = 'flex'; if (chatContent) chatContent.style.display = 'none'; if (dashboardContent) dashboardContent.style.display = 'none'; if (usersContent) usersContent.style.display = 'none'; if (userCenterContent) userCenterContent.style.display = 'none'; if (showApiDocs) showApiDocs.style.display = 'none'; if (pageTitle) pageTitle.innerText = lang[selectedLang].featureDemo; } catch (error) { console.error('Error in showFeature:', error); alert(lang[selectedLang].errorGettingUserInfo); } } function displayTokenUsage(data) { console.log(lang[selectedLang].tokenUsage, data); } document.addEventListener('DOMContentLoaded', function() { // 首先声明所有需要的变量 const aiInput = document.getElementById('aiInput'); const fileInput = document.getElementById('fileInput'); const fileInputButton = document.getElementById('fileInputButton'); const takePictureButton = document.getElementById('takePictureButton'); const recordVideoButton = document.getElementById('recordVideoButton'); const clearButton = document.getElementById('clearButton'); const stopRecordingButton = document.getElementById('stopRecordingButton'); const previewArea = document.getElementById('previewArea'); const resultArea = document.getElementById('resultArea'); const loadingIndicator = document.getElementById('loadingIndicator'); const poseButton = document.getElementById('poseButton'); const fallButton = document.getElementById('fallButton'); const cpmButton = document.getElementById('cpmButton'); const objectButton = document.getElementById('objectButton'); const faceButton = document.getElementById('faceButton'); const compareButton = document.getElementById('compareButton'); const mediapipeButton = document.getElementById('mediapipeButton'); const qwenvlButton = document.getElementById('qwenvlButton'); const cpmanalyzeButton = document.getElementById('cpmanalyzeButton'); const qwenvlanalyzeButton = document.getElementById('qwenvlanalyzeButton'); let mediaRecorder; let recordedChunks = []; // 定义任务类型 const TASK_TYPES = { POSE: 'pose', CPM: 'cpm', QWENVL: 'qwenvl', YOLO: 'yolo', FALL: 'fall', FACE: 'face', MEDIAPIPE: 'mediapipe', COMPARE: 'compare', CPM_ANALYZE: 'cpm_analyze', QWENVL_ANALYZE: 'qwenvl_analyze' }; // 然后添加事件监听器 if (fileInput) { fileInput.addEventListener('change', function(e) { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = function(e) { previewArea.innerHTML = ''; if (file.type.startsWith('image/')) { const img = document.createElement('img'); img.src = e.target.result; previewArea.appendChild(img); } else if (file.type.startsWith('video/')) { const video = document.createElement('video'); video.src = e.target.result; video.controls = true; previewArea.appendChild(video); } } reader.readAsDataURL(file); } }); } if (fileInputButton) { fileInputButton.addEventListener('click', function() { fileInput.click(); }); } function uploadFile(taskType) { const file = fileInput.files[0]; console.log("Selected file:", file); const apiKey = apiKeyInput.value.trim(); console.log("API Key:", apiKey); if (!file) { alert(lang[selectedLang].pleaseSelectFile); return; } if (!apiKey) { alert(lang[selectedLang].pleaseEnterApiKey); return; } loadingIndicator.style.display = 'block'; disableAllButtons(); const formData = new FormData(); formData.append('file', file); console.log(`Sending request to: ${API_ENDPOINT}/${taskType}`); fetch(`${API_ENDPOINT}/${taskType}`, { method: 'POST', body: formData, headers: { 'Authorization': `Bearer ${apiKey}` } }) .then(response => response.json()) .then(data => { console.log('Upload response:', data); if (data.task_id) { pollResult(data.task_id, apiKey, taskType); displayTokenUsage(data); } }) .catch(error => { console.error('Error:', error); alert(lang[selectedLang].errorUploadingFile); loadingIndicator.style.display = 'none'; enableAllButtons(); }); } // 新的轮询函数 function pollResult(taskId, apiKey, taskType) { const pollInterval = setInterval(() => { fetch(`${API_ENDPOINT}/result/${taskId}`, { headers: { 'Authorization': `Bearer ${apiKey}` } }) .then(response => response.json()) .then(data => { console.log('Poll response:', data); if (data.status === 'completed') { clearInterval(pollInterval); addResultCard(getAnalysisTitle(taskType), data); if (taskType !== 'cpm' && taskType !== 'qwenvl' && taskType !== 'qwenvl_analyze' && taskType !== 'cpm_analyze') { fetchAnnotatedFile(API_ENDPOINT, taskId, apiKey); } loadingIndicator.style.display = 'none'; enableAllButtons(); } else if (data.status === 'failed') { clearInterval(pollInterval); alert(lang[selectedLang].processingFailed); loadingIndicator.style.display = 'none'; enableAllButtons(); } }) .catch(error => { console.error('Error:', error); clearInterval(pollInterval); alert(lang[selectedLang].errorGettingResults); loadingIndicator.style.display = 'none'; enableAllButtons(); }); }, 2000); // 每2秒轮询一次 } // 辅助函数 function getAnalysisTitle(analysisType) { switch(analysisType) { case 'pose': return '姿态分析'; case 'fall': return '跌倒检测'; case 'cpm': return 'MiniCPM内容分析'; case 'object': return '目标检测'; case 'face': return '人脸检测'; case 'compare': return '面部特征提取'; case 'mediapipe': return 'mediapipe面部识别'; case 'qwenvl': return 'Qwen内容分析'; case 'qwenvl_analyze': return 'qwenvl_OCR分析'; case 'cpm_analyze': return 'cpm_OCR分析'; default: return '分析结果'; } } function fetchAnnotatedFile(apiEndpoint, taskId, apiKey) { fetch(`${apiEndpoint}/annotated/${taskId}`, { headers: { 'Authorization': `Bearer ${apiKey}` } }) .then(response => { if (response.ok) { return response.blob(); } if (response.status === 404) { throw new Error(lang[selectedLang].resultImageNotFound); } throw new Error('Network response was not ok.'); }) .then(blob => { const url = URL.createObjectURL(blob); updatePreviewWithAnnotated(url, `result_${taskId}.png`); }) .catch(error => { console.error('Error:', error); if (error.message === lang[selectedLang].resultImageNotFound) { alert(lang[selectedLang].resultImageNotFound); } else { alert(lang[selectedLang].errorGettingResultImage); } }); } function addResultCard(title, data) { const card = document.createElement('div'); card.className = 'result-card'; card.innerHTML = `

${title}

${JSON.stringify(data, null, 2)}
`; resultArea.innerHTML = `

${lang[selectedLang].detectionResult}

`; // 保留标题 resultArea.appendChild(card); } function updatePreviewWithAnnotated(url, filename) { previewArea.innerHTML = ''; const isImage = filename.match(/\.(jpg|jpeg|png|gif)$/i); if (isImage) { const img = document.createElement('img'); img.src = url; img.alt = "Annotated Image"; img.style.maxWidth = "100%"; previewArea.appendChild(img); } else { const video = document.createElement('video'); video.src = url; video.controls = true; video.style.maxWidth = "100%"; previewArea.appendChild(video); } } function clearAll() { aiInput.value = ''; fileInput.value = ''; previewArea.innerHTML = '

请输入图片URL或上传图片

'; resultArea.innerHTML = '

检测结果

'; loadingIndicator.style.display = 'none'; enableAllButtons(); } function disableAllButtons() { poseButton.disabled = true; fallButton.disabled = true; cpmButton.disabled = true; objectButton.disabled = true; faceButton.disabled = true; qwenvlButton.disabled = true; mediapipeButton.disabled = true; takePictureButton.disabled = true; recordVideoButton.disabled = true; compareButton.disabled = true; qwenvlanalyzeButton.disabled =true; cpmanalyzeButton.disabled = true } function enableAllButtons() { poseButton.disabled = false; fallButton.disabled = false; cpmButton.disabled = false; objectButton.disabled = false; faceButton.disabled = false; qwenvlButton.disabled = false; mediapipeButton.disabled = false; takePictureButton.disabled = false; recordVideoButton.disabled = false; compareButton.disabled = false; qwenvlanalyzeButton.disabled =false; cpmanalyzeButton.disabled = false } function takePicture() { navigator.mediaDevices.getUserMedia({ video: true }) .then(function(stream) { const video = document.createElement('video'); video.srcObject = stream; video.play(); video.onloadedmetadata = function(e) { const canvas = document.createElement('canvas'); canvas.width = video.videoWidth; canvas.height = video.videoHeight; canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height); stream.getTracks().forEach(track => track.stop()); previewArea.innerHTML = ''; const img = document.createElement('img'); img.src = canvas.toDataURL('image/jpeg'); previewArea.appendChild(img); canvas.toBlob(function(blob) { const file = new File([blob], "camera_photo.jpg", { type: "image/jpeg" }); const dataTransfer = new DataTransfer(); dataTransfer.items.add(file); fileInput.files = dataTransfer.files; }, 'image/jpeg'); }; }) .catch(function(err) { console.error(lang[selectedLang].cameraAccessFailed, err); alert(lang[selectedLang].cameraPermissionDenied); }); } function startRecording() { navigator.mediaDevices.getUserMedia({ video: true, audio: true }) .then(function(stream) { previewArea.innerHTML = ''; const liveVideo = document.getElementById('liveVideo'); liveVideo.srcObject = stream; mediaRecorder = new MediaRecorder(stream); mediaRecorder.ondataavailable = function(e) { if (e.data.size > 0) { recordedChunks.push(e.data); } }; mediaRecorder.onstop = function() { const blob = new Blob(recordedChunks, { type: 'video/webm' }); const videoURL = URL.createObjectURL(blob); previewArea.innerHTML = ''; const recordedVideo = document.getElementById('recordedVideo'); recordedVideo.src = videoURL; const file = new File([blob], "camera_video.webm", { type: "video/webm" }); const dataTransfer = new DataTransfer(); dataTransfer.items.add(file); fileInput.files = dataTransfer.files; stream.getTracks().forEach(track => track.stop()); }; mediaRecorder.start(); recordVideoButton.style.display = 'none'; stopRecordingButton.style.display = 'block'; setTimeout(() => { if (mediaRecorder.state === 'recording') { stopRecording(); } }, 15000); }) .catch(function(err) { console.error(lang[selectedLang].cameraAccessFailed, err); alert(lang[selectedLang].cameraPermissionDenied); }); } function stopRecording() { if (mediaRecorder && mediaRecorder.state === 'recording') { mediaRecorder.stop(); recordVideoButton.style.display = 'block'; stopRecordingButton.style.display = 'none'; } } // 最后添加其他按钮的事件监听器 if (recordVideoButton) recordVideoButton.addEventListener('click', startRecording); if (stopRecordingButton) stopRecordingButton.addEventListener('click', stopRecording); if (clearButton) clearButton.addEventListener('click', clearAll); if (takePictureButton) takePictureButton.addEventListener('click', takePicture); if (poseButton) poseButton.addEventListener('click', () => uploadFile(TASK_TYPES.POSE)); if (fallButton) fallButton.addEventListener('click', () => uploadFile(TASK_TYPES.FALL)); if (objectButton) objectButton.addEventListener('click', () => uploadFile(TASK_TYPES.YOLO)); if (faceButton) faceButton.addEventListener('click', () => uploadFile(TASK_TYPES.FACE)); if (compareButton) compareButton.addEventListener('click', () => uploadFile(TASK_TYPES.COMPARE)); if (mediapipeButton) mediapipeButton.addEventListener('click', () => uploadFile(TASK_TYPES.MEDIAPIPE)); if (cpmButton) cpmButton.addEventListener('click', () => uploadFile(TASK_TYPES.CPM)); if (qwenvlButton) qwenvlButton.addEventListener('click', () => uploadFile(TASK_TYPES.QWENVL)); if (qwenvlanalyzeButton) qwenvlanalyzeButton.addEventListener('click', () => uploadFile(TASK_TYPES.QWENVL_ANALYZE)); if (cpmanalyzeButton) cpmanalyzeButton.addEventListener('click', () => uploadFile(TASK_TYPES.CPM_ANALYZE)); }); // 获取用户信息的函数 async function fetchUserInfo() { try { const token = localStorage.getItem('access_token'); if (!token) { console.error('No access token found'); return null; } const response = await fetch(`${BASE_URL}/me`, { headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error('Failed to fetch user info'); } const userInfo = await response.json(); return userInfo; } catch (error) { console.error('Error fetching user info:', error); // 可以在这里处理错误,比如清除 token 并重定向到登录页面 localStorage.removeItem('access_token'); window.location.href = 'login.html'; // 重定向到登录页面 return null; } }