jerrynnms commited on
Commit
d7efe6e
·
verified ·
1 Parent(s): 84c1cd1

Update script.js

Browse files
Files changed (1) hide show
  1. script.js +174 -141
script.js CHANGED
@@ -1,148 +1,181 @@
1
  document.addEventListener('DOMContentLoaded', () => {
2
- const inputTextArea = document.getElementById('predict_info');
3
- const inputButton = document.getElementById('detect_button');
4
- const clearButton = document.getElementById('clear_button');
5
- const normalOrScam = document.getElementById('is_scam');
6
- const confidenceScoreSpan = document.getElementById('confidence_score');
7
- const suspiciousPhrasesDiv = document.getElementById('suspicious_phrases');
8
- const feedbackArea = document.getElementById('feedback_area');
9
- const feedbackCorrectBtn = document.getElementById('feedback_correct');
10
- const feedbackWrongBtn = document.getElementById('feedback_wrong');
11
- const feedbackStatus = document.getElementById('feedback_status');
12
- const ocrResult = document.getElementById('ocr_result');
13
- const imageUpload = document.getElementById('image_upload');
14
- const imageControls = document.getElementById('image_controls');
15
-
16
- let lastPrediction = null;
17
-
18
- const API_URL = '/predict';
19
- const FEEDBACK_API = '/feedback';
20
- const IMAGE_API = '/analyze-image';
21
-
22
- inputButton.addEventListener('click', async () => {
23
- const message = inputTextArea.value.trim();
24
- if (!message) {
25
- alert('請輸入您想檢測的訊息內容。');
26
- return;
27
- }
28
-
29
- normalOrScam.textContent = '檢測中...';
30
- normalOrScam.style.color = 'gray';
31
- confidenceScoreSpan.textContent = '計算中...';
32
- suspiciousPhrasesDiv.innerHTML = '<p>正在分析訊息,請稍候...</p>';
33
- feedbackArea.style.display = 'none';
34
- feedbackStatus.textContent = '';
35
- feedbackCorrectBtn.style.display = 'inline-block';
36
- feedbackWrongBtn.style.display = 'inline-block';
37
-
38
- try {
39
- const response = await fetch(API_URL, {
40
- method: 'POST',
41
- headers: { 'Content-Type': 'application/json' },
42
- body: JSON.stringify({ text: message }),
43
- });
44
-
45
- if (!response.ok) throw new Error(`伺服器錯誤: ${response.status} ${response.statusText}`);
46
- const data = await response.json();
47
-
48
- updateResults(data.status, data.confidence, data.suspicious_keywords);
49
- feedbackArea.style.display = 'block';
50
- lastPrediction = { text: message, model_status: data.status };
51
- } catch (error) {
52
- console.error('訊息檢測失敗:', error);
53
- alert(`訊息檢測失敗,請檢查後端服務。\n錯誤詳情: ${error.message}`);
54
- resetResults();
55
- }
56
- });
57
-
58
- clearButton.addEventListener('click', () => {
59
- inputTextArea.value = '';
60
- resetResults();
61
- feedbackArea.style.display = 'none';
62
- feedbackStatus.textContent = '';
63
- });
64
-
65
- feedbackCorrectBtn.addEventListener('click', () => submitFeedback('正確'));
66
- feedbackWrongBtn.addEventListener('click', () => submitFeedback('錯誤'));
67
-
68
- async function submitFeedback(user_feedback) {
69
- if (!lastPrediction) return;
70
- const payload = { ...lastPrediction, user_feedback };
71
- try {
72
- const res = await fetch(FEEDBACK_API, {
73
- method: 'POST',
74
- headers: { 'Content-Type': 'application/json' },
75
- body: JSON.stringify(payload),
76
- });
77
- const msg = await res.json();
78
- feedbackStatus.textContent = '✅ 感謝你的回饋!';
79
- feedbackCorrectBtn.style.display = 'none';
80
- feedbackWrongBtn.style.display = 'none';
81
- } catch (e) {
82
- feedbackStatus.textContent = '❌ 回饋提交失敗';
83
- }
84
  }
85
 
86
- function updateResults(isScam, confidence, suspiciousParts) {
87
- normalOrScam.textContent = isScam;
88
- confidenceScoreSpan.textContent = confidence;
89
- suspiciousPhrasesDiv.innerHTML = '';
90
- if (suspiciousParts && suspiciousParts.length > 0) {
91
- const ul = document.createElement('ul');
92
- suspiciousParts.forEach(phrase => {
93
- const li = document.createElement('li');
94
- li.textContent = phrase;
95
- ul.appendChild(li);
96
- });
97
- suspiciousPhrasesDiv.appendChild(ul);
98
- } else {
99
- suspiciousPhrasesDiv.innerHTML = '<p>沒有偵測到特別可疑的詞句。</p>';
100
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  }
102
 
103
- function resetResults() {
104
- normalOrScam.textContent = '待檢測';
105
- normalOrScam.style.color = 'inherit';
106
- confidenceScoreSpan.textContent = '待檢測';
107
- suspiciousPhrasesDiv.innerHTML = '<p>請輸入訊息並點擊「檢測!」按鈕。</p>';
108
- ocrResult.innerHTML = '';
109
- imageUpload.value = '';
110
- if (imageControls) imageControls.style.display = 'block';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  }
 
112
 
113
- // ✅ 圖片上傳 + OCR 分析
114
- window.analyzeImage = async function () {
115
- if (!imageUpload.files.length) {
116
- alert('請選擇圖片');
117
- return;
118
- }
119
-
120
- const formData = new FormData();
121
- formData.append('file', imageUpload.files[0]);
122
-
123
- ocrResult.innerHTML = '<p>⏳ 處理中...</p>';
124
-
125
- try {
126
- const response = await fetch(IMAGE_API, {
127
- method: 'POST',
128
- body: formData
129
- });
130
-
131
- const data = await response.json();
132
-
133
- const result = data.analysis_result || {
134
- status: "無法辨識",
135
- confidence: 0,
136
- suspicious_keywords: ["無法擷取分析結果"]
137
- };
138
-
139
- updateResults(result.status, result.confidence, result.suspicious_keywords);
140
-
141
- ocrResult.innerHTML = `
142
- <p><strong>📄 擷取文字:</strong> ${data.extracted_text || "(無)"}</p>
143
- `;
144
- } catch (error) {
145
- ocrResult.innerHTML = `<p style="color:red;">❌ 分析失敗:${error.message}</p>`;
146
- }
147
- };
148
- });
 
1
  document.addEventListener('DOMContentLoaded', () => {
2
+ // ─────────────────────────────────────────────────────────────────────────
3
+ // 文字分析相关
4
+ const inputTextArea = document.getElementById('predict_info');
5
+ const inputButton = document.getElementById('detect_button');
6
+ const clearButton = document.getElementById('clear_button');
7
+ const normalOrScam = document.getElementById('is_scam');
8
+ const confidenceScoreSpan = document.getElementById('confidence_score');
9
+ const suspiciousPhrasesDiv = document.getElementById('suspicious_phrases');
10
+ const feedbackArea = document.getElementById('feedback_area');
11
+ const feedbackCorrectBtn = document.getElementById('feedback_correct');
12
+ const feedbackWrongBtn = document.getElementById('feedback_wrong');
13
+ const feedbackStatus = document.getElementById('feedback_status');
14
+ let lastPrediction = null;
15
+
16
+ const TEXT_API = '/predict';
17
+ const FEEDBACK_API = '/feedback';
18
+
19
+ inputButton.addEventListener('click', async () => {
20
+ const message = inputTextArea.value.trim();
21
+ if (!message) {
22
+ alert('請輸入您想檢測的訊息內容。');
23
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  }
25
 
26
+ // 顯示 Loading
27
+ normalOrScam.textContent = '檢測中...';
28
+ normalOrScam.style.color = 'gray';
29
+ confidenceScoreSpan.textContent = '計算中...';
30
+ suspiciousPhrasesDiv.innerHTML = '<p>正在分析訊息,請稍候...</p>';
31
+ feedbackArea.style.display = 'none';
32
+ feedbackStatus.textContent = '';
33
+ feedbackCorrectBtn.style.display = 'inline-block';
34
+ feedbackWrongBtn.style.display = 'inline-block';
35
+
36
+ try {
37
+ const res = await fetch(TEXT_API, {
38
+ method: 'POST',
39
+ headers: { 'Content-Type': 'application/json' },
40
+ body: JSON.stringify({ text: message })
41
+ });
42
+ if (!res.ok) throw new Error(`伺服器錯誤: ${res.status}`);
43
+ const data = await res.json();
44
+
45
+ // 更新纯文字分析结果
46
+ normalOrScam.textContent = data.status;
47
+ confidenceScoreSpan.textContent = data.confidence + '%';
48
+ suspiciousPhrasesDiv.innerHTML = '';
49
+ if (Array.isArray(data.suspicious_keywords) && data.suspicious_keywords.length) {
50
+ const ul = document.createElement('ul');
51
+ data.suspicious_keywords.forEach(kw => {
52
+ const li = document.createElement('li');
53
+ li.textContent = kw;
54
+ ul.appendChild(li);
55
+ });
56
+ suspiciousPhrasesDiv.appendChild(ul);
57
+ } else {
58
+ suspiciousPhrasesDiv.innerHTML = '<p>沒有偵測到可疑詞句。</p>';
59
+ }
60
+
61
+ feedbackArea.style.display = 'block';
62
+ lastPrediction = { text: message, model_status: data.status };
63
+ } catch (err) {
64
+ console.error('文字檢測失敗:', err);
65
+ alert(`文字檢測失敗,請檢查後端。\n錯誤:${err.message}`);
66
+ // 回復預設
67
+ normalOrScam.textContent = '待檢測';
68
+ normalOrScam.style.color = 'inherit';
69
+ confidenceScoreSpan.textContent = '待檢測';
70
+ suspiciousPhrasesDiv.innerHTML = '<p>請輸入訊息並點擊「檢測!」按鈕。</p>';
71
+ }
72
+ });
73
+
74
+ clearButton.addEventListener('click', () => {
75
+ inputTextArea.value = '';
76
+ // 清空文字结果
77
+ normalOrScam.textContent = '待檢測';
78
+ normalOrScam.style.color = 'inherit';
79
+ confidenceScoreSpan.textContent = '待檢測';
80
+ suspiciousPhrasesDiv.innerHTML = '<p>請輸入訊息並點擊「檢測!」按鈕。</p>';
81
+ feedbackArea.style.display = 'none';
82
+ feedbackStatus.textContent = '';
83
+ // 清空图片结果
84
+ extractedTextSpan.textContent = '尚未上傳圖片';
85
+ imgIsScamSpan.textContent = '尚未上傳圖片';
86
+ imgConfidenceSpan.textContent = '尚未上傳圖片';
87
+ imgSuspiciousDiv.innerHTML = '<p>尚未上傳圖片。</p>';
88
+ imageUpload.value = '';
89
+ });
90
+
91
+ feedbackCorrectBtn.addEventListener('click', () => submitFeedback('正確'));
92
+ feedbackWrongBtn.addEventListener('click', () => submitFeedback('錯誤'));
93
+
94
+ async function submitFeedback(user_feedback) {
95
+ if (!lastPrediction) return;
96
+ const payload = { ...lastPrediction, user_feedback };
97
+ try {
98
+ const r = await fetch(FEEDBACK_API, {
99
+ method: 'POST',
100
+ headers: { 'Content-Type': 'application/json' },
101
+ body: JSON.stringify(payload)
102
+ });
103
+ await r.json();
104
+ feedbackStatus.textContent = '✅ 感謝你的回饋!';
105
+ feedbackCorrectBtn.style.display = 'none';
106
+ feedbackWrongBtn.style.display = 'none';
107
+ } catch (e) {
108
+ feedbackStatus.textContent = '❌ 回饋提交失敗';
109
+ }
110
+ }
111
+ // ─────────────────────────────────────────────────────────────────────────
112
+
113
+
114
+ // ─────────────────────────────────────────────────────────────────────────
115
+ // 圖片OCR相關元素
116
+ const imageUpload = document.getElementById('image_upload');
117
+ const imageButton = document.getElementById('image_button');
118
+ const extractedTextSpan = document.getElementById('extracted_text');
119
+ const imgIsScamSpan = document.getElementById('img_is_scam');
120
+ const imgConfidenceSpan = document.getElementById('img_confidence');
121
+ const imgSuspiciousDiv = document.getElementById('img_suspicious_phrases');
122
+
123
+ const IMAGE_API = '/analyze-image';
124
+
125
+ imageButton.addEventListener('click', async () => {
126
+ // 确保用户选了文件
127
+ if (!imageUpload.files.length) {
128
+ alert('請先選擇一個圖片檔案。');
129
+ return;
130
  }
131
 
132
+ // 显示 Loading 文案
133
+ extractedTextSpan.textContent = '辨識中...';
134
+ imgIsScamSpan.textContent = '辨識中...';
135
+ imgConfidenceSpan.textContent = '辨識中...';
136
+ imgSuspiciousDiv.innerHTML = '<p>正在分析圖片,稍候...</p>';
137
+
138
+ // 构造 FormData
139
+ const formData = new FormData();
140
+ formData.append('file', imageUpload.files[0]);
141
+
142
+ // 调用后端
143
+ try {
144
+ const resp = await fetch(IMAGE_API, {
145
+ method: 'POST',
146
+ body: formData
147
+ });
148
+ if (!resp.ok) throw new Error(`伺服器錯誤: ${resp.status}`);
149
+ const data = await resp.json();
150
+
151
+ const extracted = data.extracted_text || '';
152
+ const result = data.analysis_result || {};
153
+
154
+ // 更新 OCR + BERT 结果
155
+ extractedTextSpan.textContent = extracted || '(無文字)';
156
+ imgIsScamSpan.textContent = result.status || '(無法辨識)';
157
+ imgConfidenceSpan.textContent = result.confidence !== undefined
158
+ ? result.confidence + '%'
159
+ : '(無法辨識)';
160
+ imgSuspiciousDiv.innerHTML = '';
161
+ if (Array.isArray(result.suspicious_keywords) && result.suspicious_keywords.length) {
162
+ const ul2 = document.createElement('ul');
163
+ result.suspicious_keywords.forEach(kw => {
164
+ const li2 = document.createElement('li');
165
+ li2.textContent = kw;
166
+ ul2.appendChild(li2);
167
+ });
168
+ imgSuspiciousDiv.appendChild(ul2);
169
+ } else {
170
+ imgSuspiciousDiv.innerHTML = '<p>無可疑詞句。</p>';
171
+ }
172
+ } catch (err) {
173
+ console.error('圖片辨識失敗:', err);
174
+ extractedTextSpan.textContent = '(圖片辨識失敗)';
175
+ imgIsScamSpan.textContent = '(失敗)';
176
+ imgConfidenceSpan.textContent = '0%';
177
+ imgSuspiciousDiv.innerHTML = `<p style="color:red;">❌ ${err.message}</p>`;
178
  }
179
+ });
180
 
181
+ });