From 7ee074249fc7aab3d15cdddc353ca64183a0ff8a Mon Sep 17 00:00:00 2001 From: shenjianZ Date: Tue, 29 Jul 2025 15:35:34 +0800 Subject: [PATCH] feat: fix backend sql error;fix frontend i18n display error --- backend/app.js | 17 ++++++---- backend/saveEmail.js | 2 +- frontend/src/i18n/index.js | 10 ++++++ frontend/src/views/Home.vue | 62 +++++++++++++------------------------ 4 files changed, 43 insertions(+), 48 deletions(-) diff --git a/backend/app.js b/backend/app.js index 1442863..1e3f4a8 100644 --- a/backend/app.js +++ b/backend/app.js @@ -100,7 +100,7 @@ app.delete('/api/messages', async (req, res) => { return res.status(400).send('Recipient is required'); } try { - await db.execute('DELETE FROM emails WHERE recipient = ?', [recipient]); + await db.execute('DELETE FROM emails WHERE recipient LIKE ?', [`%${recipient}%`]); logger.info('All messages for recipient deleted successfully', { recipient }); res.status(204).send(); // No Content } catch (error) { @@ -142,14 +142,19 @@ wss.on('connection', (ws, req) => { }); emitter.on('newEmail', (email) => { - const recipient = email.recipient; - if (clients.has(recipient)) { - const ws = clients.get(recipient); - logger.info(`Sending new email notification to`, { recipient }); - ws.send(JSON.stringify(email)); + const dbRecipient = email.recipient; // 比如 "6471" <6471@shenjianl.cn> + + // 遍历所有 clients,用 includes 判断 + for (const [clientRecipient, ws] of clients.entries()) { + if (dbRecipient.includes(clientRecipient)) { + logger.info(`Sending new email notification to`, { recipient: clientRecipient }); + ws.send(JSON.stringify(email)); + break; // 如果只想发给第一个匹配的就 break + } } }); + // Start API server server.listen(apiPort, () => { logger.info(`Backend API and WebSocket server listening at http://localhost:${apiPort}`); diff --git a/backend/saveEmail.js b/backend/saveEmail.js index 382e5d5..7e00f4b 100644 --- a/backend/saveEmail.js +++ b/backend/saveEmail.js @@ -23,7 +23,7 @@ async function saveEmail(stream) { const recipient = parsed.to ? parsed.to.text : 'undisclosed-recipients'; const sender = parsed.from ? parsed.from.text : 'unknown-sender'; - const subject = parsed.subject; + const subject = parsed.subject || 'No Subject'; const body = parsed.text || (parsed.html || ''); const [result] = await db.execute( diff --git a/frontend/src/i18n/index.js b/frontend/src/i18n/index.js index 01c814f..805c7c5 100644 --- a/frontend/src/i18n/index.js +++ b/frontend/src/i18n/index.js @@ -34,8 +34,13 @@ const messages = { deleteFailed: '删除邮件失败。', confirmClearAll: '确定要清空这个收件箱的所有邮件吗?此操作不可恢复。', clearFailed: '清空收件箱失败。', + generateRandomSuccess: '已生成随机邮箱地址', + checkInboxStart: '正在查询收件箱', copyFailed: '复制失败!', + copySuccess: '复制成功!', // <-- 这里添加 actionCancelled: '操作已取消', + deleteSuccess: '删除成功!', + clearSuccess: '收件箱已清空!', }, newMailNotification: '收到新邮件!', } @@ -73,8 +78,13 @@ const messages = { deleteFailed: 'Failed to delete email.', confirmClearAll: 'Are you sure you want to clear all emails in this inbox? This action cannot be undone.', clearFailed: 'Failed to clear inbox.', + generateRandomSuccess: 'Random email address generated', + checkInboxStart: 'Checking inbox', copyFailed: 'Copy failed!', + copySuccess: 'Copied successfully!', // <-- 这里添加 actionCancelled: 'Action cancelled', + deleteSuccess: 'Deleted successfully!', + clearSuccess: 'Inbox cleared!', }, newMailNotification: 'New mail received!', } diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue index 311431c..ef636dc 100644 --- a/frontend/src/views/Home.vue +++ b/frontend/src/views/Home.vue @@ -168,6 +168,7 @@ const fetchMessages = async () => { ElMessage.warning(t('home.alerts.enterEmail')); return; } + ElMessage.info(t('home.alerts.checkInboxStart')); loading.value = true; selectedMessage.value = null; attachments.value = []; @@ -326,60 +327,39 @@ const generateRandomEmail = () => { } else { prefix = `${word1}${separator}${word2}${number}`; } - + ElMessage.success(t('home.alerts.generateRandomSuccess')); recipient.value = `${prefix}@${domain}`; }; -const copyEmail = () => { +const copyEmail = async () => { if (!recipient.value) return; - const textToCopy = recipient.value; - - if (navigator.clipboard && window.isSecureContext) { - navigator.clipboard.writeText(textToCopy).then(() => { - showCopySuccess(); - }).catch(err => { - console.error('Modern copy failed: ', err); - fallbackCopy(textToCopy); - }); - } else { - fallbackCopy(textToCopy); - } -}; - -const fallbackCopy = (text) => { - const textArea = document.createElement('textarea'); - textArea.value = text; - - textArea.style.position = 'fixed'; - textArea.style.top = '-9999px'; - textArea.style.left = '-9999px'; - - document.body.appendChild(textArea); - textArea.focus(); - textArea.select(); - try { - const successful = document.execCommand('copy'); - if (successful) { - showCopySuccess(); + if (navigator.clipboard && window.isSecureContext) { + await navigator.clipboard.writeText(recipient.value); } else { - throw new Error('Fallback copy was unsuccessful'); + // fallback 方案 + const textArea = document.createElement('textarea'); + textArea.value = recipient.value; + textArea.style.position = 'fixed'; // 防止滚动时跳动 + textArea.style.left = '-9999px'; + textArea.style.top = '-9999px'; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + const success = document.execCommand('copy'); + document.body.removeChild(textArea); + if (!success) throw new Error('Fallback copy failed'); } + copyStatus.value = 'copied'; + ElMessage.success(t('home.alerts.copySuccess')); + setTimeout(() => copyStatus.value = 'idle', 2000); } catch (err) { - console.error('Fallback copy failed: ', err); + console.error('Copy failed:', err); ElMessage.error(t('home.alerts.copyFailed')); } - - document.body.removeChild(textArea); }; -const showCopySuccess = () => { - copyStatus.value = 'copied'; - setTimeout(() => { - copyStatus.value = 'idle'; - }, 2000); -};