158 lines
5.1 KiB
Vue
158 lines
5.1 KiB
Vue
<template>
|
||
<header class="app-header">
|
||
<div class="logo">Email Unlimit</div>
|
||
<nav class="nav-links">
|
||
<a href="https://gitea.shenjianl.cn/shenjianZ/email-unlimit" target="_blank">Gitee</a>
|
||
<a href="#" @click.prevent="showHowItWorks">How it Works</a>
|
||
</nav>
|
||
</header>
|
||
|
||
<main id="app-main">
|
||
<section class="hero-section">
|
||
<h1>您的专属临时邮箱,无限且私密</h1>
|
||
<p>输入任何<code>@shenjianl.cn</code>地址,立即在此查看收件箱。</p>
|
||
<form @submit.prevent="fetchMessages" class="input-group">
|
||
<input
|
||
type="email"
|
||
v-model="recipient"
|
||
class="email-input"
|
||
placeholder="输入您的临时邮箱地址..."
|
||
required
|
||
/>
|
||
<button type="submit" class="btn btn-primary">查看收件箱</button>
|
||
<button @click="generateRandomEmail" type="button" class="btn btn-secondary">随机生成</button>
|
||
</form>
|
||
</section>
|
||
|
||
<section class="inbox-section">
|
||
<div class="inbox-container">
|
||
<div class="message-list">
|
||
<div class="message-list-header">
|
||
<h2>收件箱</h2>
|
||
<button @click="fetchMessages" class="refresh-btn" title="刷新">
|
||
↻
|
||
</button>
|
||
</div>
|
||
<div v-if="loading" class="loading-state">正在加载...</div>
|
||
<div v-else-if="messages.length === 0" class="empty-state">暂无邮件</div>
|
||
<div v-else>
|
||
<div
|
||
v-for="message in messages"
|
||
:key="message.id"
|
||
class="message-item"
|
||
:class="{ selected: selectedMessage && selectedMessage.id === message.id }"
|
||
@click="selectMessage(message)"
|
||
>
|
||
<div class="from">{{ message.sender }}</div>
|
||
<div class="subject">{{ message.subject }}</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="message-detail">
|
||
<div v-if="!selectedMessage" class="empty-state">
|
||
<p>请从左侧选择一封邮件查看</p>
|
||
</div>
|
||
<div v-else>
|
||
<div class="message-content-header">
|
||
<h3>{{ selectedMessage.subject }}</h3>
|
||
<p><strong>发件人:</strong> {{ selectedMessage.sender }}</p>
|
||
<p><strong>收件人:</strong> {{ selectedMessage.recipient }}</p>
|
||
</div>
|
||
<div class="message-body">
|
||
{{ selectedMessage.body }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
|
||
<!-- How it Works Modal -->
|
||
<div v-if="showModal" class="modal-overlay" @click.self="closeModal">
|
||
<div class="modal-content">
|
||
<button @click="closeModal" class="close-btn">×</button>
|
||
<h3>工作原理</h3>
|
||
<ol>
|
||
<li>在上面的输入框中,随意编造一个以<code>@{{ domain }}</code>结尾的邮箱地址。</li>
|
||
<li>使用这个地址去注册任何网站或接收邮件。</li>
|
||
<li>在这里输入您刚刚使用的地址,点击“查看收件箱”,即可看到邮件。</li>
|
||
</ol>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { ref, onMounted } from 'vue';
|
||
|
||
export default {
|
||
name: 'App',
|
||
setup() {
|
||
const recipient = ref('');
|
||
const messages = ref([]);
|
||
const selectedMessage = ref(null);
|
||
const loading = ref(false);
|
||
const showModal = ref(false);
|
||
// !!! 生产环境<E78EAF><E5A283>要提示 !!!
|
||
// 请务必将下面的 'yourdomain.com' 替换为您的真实域名
|
||
const domain = 'shenjianl.cn';
|
||
|
||
const fetchMessages = async () => {
|
||
if (!recipient.value) {
|
||
alert('请输入一个邮箱地址');
|
||
return;
|
||
}
|
||
loading.value = true;
|
||
selectedMessage.value = null; // Clear selected message on new fetch
|
||
try {
|
||
// API URL 已修改为相对路径,以适配 Nginx 反向代理
|
||
const response = await fetch(`/api/messages?recipient=${recipient.value}`);
|
||
if (!response.ok) {
|
||
throw new Error('Network response was not ok');
|
||
}
|
||
const data = await response.json();
|
||
messages.value = data;
|
||
// Automatically select the first message if available
|
||
if (messages.value.length > 0) {
|
||
selectedMessage.value = messages.value[0];
|
||
}
|
||
} catch (error) {
|
||
console.error('Failed to fetch messages:', error);
|
||
alert('无法获取邮件,请检查后端服务和 Nginx 配置是否正常。');
|
||
} finally {
|
||
loading.value = false;
|
||
}
|
||
};
|
||
|
||
const selectMessage = (message) => {
|
||
selectedMessage.value = message;
|
||
};
|
||
|
||
const generateRandomEmail = () => {
|
||
const randomPart = Math.random().toString(36).substring(2, 10);
|
||
recipient.value = `${randomPart}@${domain}`;
|
||
};
|
||
|
||
const showHowItWorks = () => {
|
||
showModal.value = true;
|
||
};
|
||
|
||
const closeModal = () => {
|
||
showModal.value = false;
|
||
};
|
||
|
||
return {
|
||
recipient,
|
||
messages,
|
||
selectedMessage,
|
||
loading,
|
||
showModal,
|
||
domain,
|
||
fetchMessages,
|
||
selectMessage,
|
||
generateRandomEmail,
|
||
showHowItWorks,
|
||
closeModal,
|
||
};
|
||
},
|
||
};
|
||
</script> |