/// script.js document.addEventListener('DOMContentLoaded', () => { const inputTextArea = document.getElementById('predict_info'); const inputButton = document.getElementById('detect_button'); const clearButton = document.getElementById('clear_button'); const normalOrScam = document.getElementById('is_scam'); const confidenceScoreSpan = document.getElementById('confidence_score'); const suspiciousPhrasesDiv = document.getElementById('suspicious_phrases'); const feedbackArea = document.getElementById('feedback_area'); const feedbackCorrectBtn = document.getElementById('feedback_correct'); const feedbackWrongBtn = document.getElementById('feedback_wrong'); const feedbackStatus = document.getElementById('feedback_status'); let lastPrediction = null; // 使用相對路徑,Vercel 會自動解析 const API_URL = '/predict'; const FEEDBACK_API = '/feedback'; inputButton.addEventListener('click', async () => { const message = inputTextArea.value.trim(); if (!message) { alert('請輸入您想檢測的訊息內容。'); return; } normalOrScam.textContent = '檢測中...'; normalOrScam.style.color = 'gray'; confidenceScoreSpan.textContent = '計算中...'; suspiciousPhrasesDiv.innerHTML = '
正在分析訊息,請稍候...
'; feedbackArea.style.display = 'none'; feedbackStatus.textContent = ''; feedbackCorrectBtn.style.display = 'inline-block'; feedbackWrongBtn.style.display = 'inline-block'; try { const response = await fetch(API_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: message }), }); if (!response.ok) throw new Error(`伺服器錯誤: ${response.status} ${response.statusText}`); const data = await response.json(); updateResults(data.status, data.confidence, data.suspicious_keywords); feedbackArea.style.display = 'block'; lastPrediction = { text: message, model_status: data.status }; } catch (error) { console.error('訊息檢測失敗:', error); alert(`訊息檢測失敗,請檢查後端服務。\n錯誤詳情: ${error.message}`); resetResults(); } }); clearButton.addEventListener('click', () => { inputTextArea.value = ''; resetResults(); feedbackArea.style.display = 'none'; feedbackStatus.textContent = ''; }); feedbackCorrectBtn.addEventListener('click', () => submitFeedback('正確')); feedbackWrongBtn.addEventListener('click', () => submitFeedback('錯誤')); async function submitFeedback(user_feedback) { if (!lastPrediction) return; const payload = { ...lastPrediction, user_feedback }; try { const res = await fetch(FEEDBACK_API, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), }); const msg = await res.json(); feedbackStatus.textContent = '✅ 感謝你的回饋!'; feedbackCorrectBtn.style.display = 'none'; feedbackWrongBtn.style.display = 'none'; } catch (e) { feedbackStatus.textContent = '❌ 回饋提交失敗'; } } function updateResults(isScam, confidence, suspiciousParts) { normalOrScam.textContent = isScam; confidenceScoreSpan.textContent = confidence; suspiciousPhrasesDiv.innerHTML = ''; if (suspiciousParts && suspiciousParts.length > 0) { const ul = document.createElement('ul'); suspiciousParts.forEach(phrase => { const li = document.createElement('li'); li.textContent = phrase; ul.appendChild(li); }); suspiciousPhrasesDiv.appendChild(ul); } else { suspiciousPhrasesDiv.innerHTML = '沒有偵測到特別可疑的詞句。
'; } } function resetResults() { normalOrScam.textContent = '待檢測'; normalOrScam.style.color = 'inherit'; confidenceScoreSpan.textContent = '待檢測'; suspiciousPhrasesDiv.innerHTML = '請輸入訊息並點擊「檢測!」按鈕。
'; } });