diff --git a/README.md b/README.md
index 1c2ac1e..52598a6 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,9 @@
- **多邮箱服务支持**
- Tempmail.lol(临时邮箱,无需配置)
- Outlook(IMAP + XOAUTH2,支持批量导入)
- - 自定义域名(REST API)
+ - 自定义域名(两种子类型)
+ - **MoeMail**:标准 REST API,配置 API 地址 + API 密钥
+ - **TempMail**:自部署 Cloudflare Worker 临时邮箱,配置 Worker 地址 + Admin 密码
- **注册模式**
- 单次注册
@@ -278,7 +280,8 @@ docker-compose build --no-cache
- CPA 上传始终直连,不经过代理
- Team Manager 上传始终直连,不经过代理
- 支付链接生成使用账号 access_token 鉴权,走全局代理配置
-- 无痕浏览器依次尝试 Chrome、Edge,未找到时返回失败提示
+- 无痕浏览器优先使用 playwright(注入 cookie 直达支付页);未安装时降级为系统 Chrome/Edge 无痕模式
+- 安装完整支付功能:`pip install playwright && playwright install chromium`(可选)
- 订阅状态自动检测调用 `chatgpt.com/backend-api/me`,走全局代理
- 批量注册并发数上限为 50,线程池大小已相应调整
diff --git a/static/js/email_services.js b/static/js/email_services.js
index 69abb4e..e142480 100644
--- a/static/js/email_services.js
+++ b/static/js/email_services.js
@@ -4,7 +4,7 @@
// 状态
let outlookServices = [];
-let customServices = [];
+let customServices = []; // 合并 custom_domain + temp_mail
let selectedOutlook = new Set();
let selectedCustom = new Set();
@@ -31,7 +31,7 @@ const elements = {
selectAllOutlook: document.getElementById('select-all-outlook'),
batchDeleteOutlookBtn: document.getElementById('batch-delete-outlook-btn'),
- // 自定义域名
+ // 自定义域名(合并)
customTable: document.getElementById('custom-services-table'),
addCustomBtn: document.getElementById('add-custom-btn'),
selectAllCustom: document.getElementById('select-all-custom'),
@@ -47,30 +47,25 @@ const elements = {
addCustomForm: document.getElementById('add-custom-form'),
closeCustomModal: document.getElementById('close-custom-modal'),
cancelAddCustom: document.getElementById('cancel-add-custom'),
+ customSubType: document.getElementById('custom-sub-type'),
+ addMoemailFields: document.getElementById('add-moemail-fields'),
+ addTempmailFields: document.getElementById('add-tempmail-fields'),
// 编辑自定义域名模态框
editCustomModal: document.getElementById('edit-custom-modal'),
editCustomForm: document.getElementById('edit-custom-form'),
closeEditCustomModal: document.getElementById('close-edit-custom-modal'),
cancelEditCustom: document.getElementById('cancel-edit-custom'),
+ editMoemailFields: document.getElementById('edit-moemail-fields'),
+ editTempmailFields: document.getElementById('edit-tempmail-fields'),
+ editCustomTypeBadge: document.getElementById('edit-custom-type-badge'),
+ editCustomSubTypeHidden: document.getElementById('edit-custom-sub-type-hidden'),
// 编辑 Outlook 模态框
editOutlookModal: document.getElementById('edit-outlook-modal'),
editOutlookForm: document.getElementById('edit-outlook-form'),
closeEditOutlookModal: document.getElementById('close-edit-outlook-modal'),
cancelEditOutlook: document.getElementById('cancel-edit-outlook'),
-
- // Temp-Mail 服务
- tempMailTable: document.getElementById('tempmail-services-table'),
- addTempMailBtn: document.getElementById('add-tempmail-btn'),
- addTempMailModal: document.getElementById('add-tempmail-modal'),
- addTempMailForm: document.getElementById('add-tempmail-form'),
- closeAddTempMailModal: document.getElementById('close-add-tempmail-modal'),
- cancelAddTempMail: document.getElementById('cancel-add-tempmail'),
- editTempMailModal: document.getElementById('edit-tempmail-modal'),
- editTempMailForm: document.getElementById('edit-tempmail-form'),
- closeEditTempMailModal: document.getElementById('close-edit-tempmail-modal'),
- cancelEditTempMail: document.getElementById('cancel-edit-tempmail')
};
// 初始化
@@ -78,7 +73,6 @@ document.addEventListener('DOMContentLoaded', () => {
loadStats();
loadOutlookServices();
loadCustomServices();
- loadTempMailServices();
loadTempmailConfig();
initEventListeners();
});
@@ -105,11 +99,8 @@ function initEventListeners() {
checkboxes.forEach(cb => {
cb.checked = e.target.checked;
const id = parseInt(cb.dataset.id);
- if (e.target.checked) {
- selectedOutlook.add(id);
- } else {
- selectedOutlook.delete(id);
- }
+ if (e.target.checked) selectedOutlook.add(id);
+ else selectedOutlook.delete(id);
});
updateBatchButtons();
});
@@ -117,80 +108,64 @@ function initEventListeners() {
// Outlook 批量删除
elements.batchDeleteOutlookBtn.addEventListener('click', handleBatchDeleteOutlook);
- // 添加自定义域名
- elements.addCustomBtn.addEventListener('click', () => {
- elements.addCustomModal.classList.add('active');
- });
-
- elements.closeCustomModal.addEventListener('click', () => {
- elements.addCustomModal.classList.remove('active');
- });
-
- elements.cancelAddCustom.addEventListener('click', () => {
- elements.addCustomModal.classList.remove('active');
- });
-
- elements.addCustomForm.addEventListener('submit', handleAddCustom);
-
- // 编辑自定义域名模态框
- elements.closeEditCustomModal.addEventListener('click', () => {
- elements.editCustomModal.classList.remove('active');
- });
-
- elements.cancelEditCustom.addEventListener('click', () => {
- elements.editCustomModal.classList.remove('active');
- });
-
- elements.editCustomForm.addEventListener('submit', handleEditCustom);
-
- // 编辑 Outlook 模态框
- elements.closeEditOutlookModal.addEventListener('click', () => {
- elements.editOutlookModal.classList.remove('active');
- });
-
- elements.cancelEditOutlook.addEventListener('click', () => {
- elements.editOutlookModal.classList.remove('active');
- });
-
- elements.editOutlookForm.addEventListener('submit', handleEditOutlook);
-
// 自定义域名全选
elements.selectAllCustom.addEventListener('change', (e) => {
const checkboxes = elements.customTable.querySelectorAll('input[type="checkbox"][data-id]');
checkboxes.forEach(cb => {
cb.checked = e.target.checked;
const id = parseInt(cb.dataset.id);
- if (e.target.checked) {
- selectedCustom.add(id);
- } else {
- selectedCustom.delete(id);
- }
+ if (e.target.checked) selectedCustom.add(id);
+ else selectedCustom.delete(id);
});
});
+ // 添加自定义域名
+ elements.addCustomBtn.addEventListener('click', () => {
+ elements.addCustomForm.reset();
+ switchAddSubType('moemail');
+ elements.addCustomModal.classList.add('active');
+ });
+ elements.closeCustomModal.addEventListener('click', () => elements.addCustomModal.classList.remove('active'));
+ elements.cancelAddCustom.addEventListener('click', () => elements.addCustomModal.classList.remove('active'));
+ elements.addCustomForm.addEventListener('submit', handleAddCustom);
+
+ // 类型切换(添加表单)
+ elements.customSubType.addEventListener('change', (e) => switchAddSubType(e.target.value));
+
+ // 编辑自定义域名
+ elements.closeEditCustomModal.addEventListener('click', () => elements.editCustomModal.classList.remove('active'));
+ elements.cancelEditCustom.addEventListener('click', () => elements.editCustomModal.classList.remove('active'));
+ elements.editCustomForm.addEventListener('submit', handleEditCustom);
+
+ // 编辑 Outlook
+ elements.closeEditOutlookModal.addEventListener('click', () => elements.editOutlookModal.classList.remove('active'));
+ elements.cancelEditOutlook.addEventListener('click', () => elements.editOutlookModal.classList.remove('active'));
+ elements.editOutlookForm.addEventListener('submit', handleEditOutlook);
+
// 临时邮箱配置
elements.tempmailForm.addEventListener('submit', handleSaveTempmail);
elements.testTempmailBtn.addEventListener('click', handleTestTempmail);
+}
- // Temp-Mail 服务
- elements.addTempMailBtn.addEventListener('click', () => {
- elements.addTempMailModal.classList.add('active');
- });
- elements.closeAddTempMailModal.addEventListener('click', () => {
- elements.addTempMailModal.classList.remove('active');
- });
- elements.cancelAddTempMail.addEventListener('click', () => {
- elements.addTempMailModal.classList.remove('active');
- });
- elements.addTempMailForm.addEventListener('submit', handleAddTempMail);
+// 切换添加表单子类型
+function switchAddSubType(subType) {
+ elements.customSubType.value = subType;
+ if (subType === 'moemail') {
+ elements.addMoemailFields.style.display = '';
+ elements.addTempmailFields.style.display = 'none';
+ } else {
+ elements.addMoemailFields.style.display = 'none';
+ elements.addTempmailFields.style.display = '';
+ }
+}
- elements.closeEditTempMailModal.addEventListener('click', () => {
- elements.editTempMailModal.classList.remove('active');
- });
- elements.cancelEditTempMail.addEventListener('click', () => {
- elements.editTempMailModal.classList.remove('active');
- });
- elements.editTempMailForm.addEventListener('submit', handleEditTempMail);
+// 切换编辑表单子类型显示
+function switchEditSubType(subType) {
+ elements.editCustomSubTypeHidden.value = subType;
+ const isMoe = subType === 'moemail';
+ elements.editMoemailFields.style.display = isMoe ? '' : 'none';
+ elements.editTempmailFields.style.display = isMoe ? 'none' : '';
+ elements.editCustomTypeBadge.textContent = isMoe ? '🔗 MoeMail(自定义域名 API)' : '📮 TempMail(自部署 Cloudflare Worker)';
}
// 加载统计信息
@@ -198,7 +173,7 @@ async function loadStats() {
try {
const data = await api.get('/email-services/stats');
elements.outlookCount.textContent = data.outlook_count || 0;
- elements.customCount.textContent = data.custom_count || 0;
+ elements.customCount.textContent = (data.custom_count || 0) + (data.temp_mail_count || 0);
elements.tempmailStatus.textContent = data.tempmail_available ? '可用' : '不可用';
elements.totalEnabled.textContent = data.enabled_count || 0;
} catch (error) {
@@ -229,10 +204,7 @@ async function loadOutlookServices() {
elements.outlookTable.innerHTML = outlookServices.map(service => `
- |
-
- |
+ |
${escapeHtml(service.config?.email || service.name)} |
@@ -248,65 +220,50 @@ async function loadOutlookServices() {
| ${format.date(service.last_used)} |
-
-
-
-
+
+
+
+
|
`).join('');
- // 绑定复选框事件
elements.outlookTable.querySelectorAll('input[type="checkbox"][data-id]').forEach(cb => {
cb.addEventListener('change', (e) => {
const id = parseInt(e.target.dataset.id);
- if (e.target.checked) {
- selectedOutlook.add(id);
- } else {
- selectedOutlook.delete(id);
- }
+ if (e.target.checked) selectedOutlook.add(id);
+ else selectedOutlook.delete(id);
updateBatchButtons();
});
});
} catch (error) {
console.error('加载 Outlook 服务失败:', error);
- elements.outlookTable.innerHTML = `
-
- |
-
- |
-
- `;
+ elements.outlookTable.innerHTML = ` |
`;
}
}
-// 加载自定义域名服务
+// 加载自定义域名服务(custom_domain + temp_mail 合并)
async function loadCustomServices() {
try {
- const data = await api.get('/email-services?service_type=custom_domain');
- customServices = data.services || [];
+ const [r1, r2] = await Promise.all([
+ api.get('/email-services?service_type=custom_domain'),
+ api.get('/email-services?service_type=temp_mail')
+ ]);
+ customServices = [
+ ...(r1.services || []).map(s => ({ ...s, _subType: 'moemail' })),
+ ...(r2.services || []).map(s => ({ ...s, _subType: 'tempmail' }))
+ ];
if (customServices.length === 0) {
elements.customTable.innerHTML = `
- |
+ |
📭
暂无自定义域名服务
- 点击"添加服务"按钮创建新服务
+ 点击「添加服务」按钮创建新服务
|
@@ -314,49 +271,35 @@ async function loadCustomServices() {
return;
}
- elements.customTable.innerHTML = customServices.map(service => `
+ elements.customTable.innerHTML = customServices.map(service => {
+ const isMoe = service._subType === 'moemail';
+ const typeLabel = isMoe ? 'MoeMail' : 'TempMail';
+ const addr = isMoe ? (service.config?.base_url || '-') : (service.config?.base_url || '-');
+ return `
- |
-
- |
+ |
${escapeHtml(service.name)} |
- ${escapeHtml(service.config?.base_url || '-')} |
-
-
- ${service.enabled ? '启用' : '禁用'}
-
- |
+ ${typeLabel} |
+ ${escapeHtml(addr)} |
+ ${service.enabled ? '启用' : '禁用'} |
${service.priority} |
${format.date(service.last_used)} |
-
-
-
-
+
+
+
+
|
-
- `).join('');
+ `;
+ }).join('');
- // 绑定复选框事件
elements.customTable.querySelectorAll('input[type="checkbox"][data-id]').forEach(cb => {
cb.addEventListener('change', (e) => {
const id = parseInt(e.target.dataset.id);
- if (e.target.checked) {
- selectedCustom.add(id);
- } else {
- selectedCustom.delete(id);
- }
+ if (e.target.checked) selectedCustom.add(id);
+ else selectedCustom.delete(id);
});
});
@@ -381,10 +324,7 @@ async function loadTempmailConfig() {
// Outlook 导入
async function handleOutlookImport() {
const data = elements.outlookImportData.value.trim();
- if (!data) {
- toast.error('请输入导入数据');
- return;
- }
+ if (!data) { toast.error('请输入导入数据'); return; }
elements.outlookImportBtn.disabled = true;
elements.outlookImportBtn.textContent = '导入中...';
@@ -402,14 +342,7 @@ async function handleOutlookImport() {
✅ 成功导入: ${result.success || 0}
❌ 失败: ${result.failed || 0}
- ${result.errors?.length ? `
-
-
错误详情:
-
- ${result.errors.map(e => `- ${escapeHtml(e)}
`).join('')}
-
-
- ` : ''}
+ ${result.errors?.length ? `错误详情:${result.errors.map(e => `- ${escapeHtml(e)}
`).join('')}
` : ''}
`;
if (result.success > 0) {
@@ -418,7 +351,6 @@ async function handleOutlookImport() {
loadStats();
elements.outlookImportData.value = '';
}
-
} catch (error) {
toast.error('导入失败: ' + error.message);
} finally {
@@ -427,19 +359,34 @@ async function handleOutlookImport() {
}
}
-// 添加自定义域名服务
+// 添加自定义域名服务(根据子类型区分)
async function handleAddCustom(e) {
e.preventDefault();
-
const formData = new FormData(e.target);
- const data = {
- service_type: 'custom_domain',
- name: formData.get('name'),
- config: {
+ const subType = formData.get('sub_type');
+
+ let serviceType, config;
+ if (subType === 'moemail') {
+ serviceType = 'custom_domain';
+ config = {
base_url: formData.get('api_url'),
api_key: formData.get('api_key'),
default_domain: formData.get('domain')
- },
+ };
+ } else {
+ serviceType = 'temp_mail';
+ config = {
+ base_url: formData.get('tm_base_url'),
+ admin_password: formData.get('tm_admin_password'),
+ domain: formData.get('tm_domain'),
+ enable_prefix: true
+ };
+ }
+
+ const data = {
+ service_type: serviceType,
+ name: formData.get('name'),
+ config,
enabled: formData.get('enabled') === 'on',
priority: parseInt(formData.get('priority')) || 0
};
@@ -473,11 +420,8 @@ async function toggleService(id, enabled) {
async function testService(id) {
try {
const result = await api.post(`/email-services/${id}/test`);
- if (result.success) {
- toast.success('测试成功');
- } else {
- toast.error('测试失败: ' + (result.error || '未知错误'));
- }
+ if (result.success) toast.success('测试成功');
+ else toast.error('测试失败: ' + (result.error || '未知错误'));
} catch (error) {
toast.error('测试失败: ' + error.message);
}
@@ -487,7 +431,6 @@ async function testService(id) {
async function deleteService(id, name) {
const confirmed = await confirm(`确定要删除 "${name}" 吗?`);
if (!confirmed) return;
-
try {
await api.delete(`/email-services/${id}`);
toast.success('已删除');
@@ -504,10 +447,8 @@ async function deleteService(id, name) {
// 批量删除 Outlook
async function handleBatchDeleteOutlook() {
if (selectedOutlook.size === 0) return;
-
const confirmed = await confirm(`确定要删除选中的 ${selectedOutlook.size} 个账户吗?`);
if (!confirmed) return;
-
try {
const result = await api.request('/email-services/outlook/batch', {
method: 'DELETE',
@@ -525,7 +466,6 @@ async function handleBatchDeleteOutlook() {
// 保存临时邮箱配置
async function handleSaveTempmail(e) {
e.preventDefault();
-
try {
await api.post('/settings/tempmail', {
api_url: elements.tempmailApi.value,
@@ -541,17 +481,12 @@ async function handleSaveTempmail(e) {
async function handleTestTempmail() {
elements.testTempmailBtn.disabled = true;
elements.testTempmailBtn.textContent = '测试中...';
-
try {
const result = await api.post('/email-services/test-tempmail', {
api_url: elements.tempmailApi.value
});
-
- if (result.success) {
- toast.success('临时邮箱连接正常');
- } else {
- toast.error('连接失败: ' + (result.error || '未知错误'));
- }
+ if (result.success) toast.success('临时邮箱连接正常');
+ else toast.error('连接失败: ' + (result.error || '未知错误'));
} catch (error) {
toast.error('测试失败: ' + error.message);
} finally {
@@ -577,27 +512,32 @@ function escapeHtml(text) {
// ============== 编辑功能 ==============
-// 编辑自定义域名服务
-async function editCustomService(id) {
+// 编辑自定义域名服务(支持 moemail / tempmail)
+async function editCustomService(id, subType) {
try {
- // 获取完整的服务详情
const service = await api.get(`/email-services/${id}/full`);
+ const resolvedSubType = subType || (service.service_type === 'temp_mail' ? 'tempmail' : 'moemail');
- // 填充表单
document.getElementById('edit-custom-id').value = service.id;
document.getElementById('edit-custom-name').value = service.name || '';
- document.getElementById('edit-custom-api-url').value = service.config?.base_url || '';
- document.getElementById('edit-custom-api-key').value = service.config?.api_key || '';
- document.getElementById('edit-custom-domain').value = service.config?.domain || '';
document.getElementById('edit-custom-priority').value = service.priority || 0;
document.getElementById('edit-custom-enabled').checked = service.enabled;
- // 清空密码提示
- document.getElementById('edit-custom-api-key').placeholder = service.config?.has_api_key ? '已设置,留空保持不变' : 'API Key';
+ switchEditSubType(resolvedSubType);
+
+ if (resolvedSubType === 'moemail') {
+ document.getElementById('edit-custom-api-url').value = service.config?.base_url || '';
+ document.getElementById('edit-custom-api-key').value = '';
+ document.getElementById('edit-custom-api-key').placeholder = service.config?.has_api_key ? '已设置,留空保持不变' : 'API Key';
+ document.getElementById('edit-custom-domain').value = service.config?.default_domain || service.config?.domain || '';
+ } else {
+ document.getElementById('edit-tm-base-url').value = service.config?.base_url || '';
+ document.getElementById('edit-tm-admin-password').value = '';
+ document.getElementById('edit-tm-admin-password').placeholder = service.config?.admin_password ? '已设置,留空保持不变' : '请输入 Admin 密码';
+ document.getElementById('edit-tm-domain').value = service.config?.domain || '';
+ }
- // 显示模态框
elements.editCustomModal.classList.add('active');
-
} catch (error) {
toast.error('获取服务信息失败: ' + error.message);
}
@@ -606,31 +546,35 @@ async function editCustomService(id) {
// 保存编辑自定义域名服务
async function handleEditCustom(e) {
e.preventDefault();
-
const id = document.getElementById('edit-custom-id').value;
const formData = new FormData(e.target);
+ const subType = formData.get('sub_type');
+
+ let config;
+ if (subType === 'moemail') {
+ config = {
+ base_url: formData.get('api_url'),
+ default_domain: formData.get('domain')
+ };
+ const apiKey = formData.get('api_key');
+ if (apiKey && apiKey.trim()) config.api_key = apiKey.trim();
+ } else {
+ config = {
+ base_url: formData.get('tm_base_url'),
+ domain: formData.get('tm_domain'),
+ enable_prefix: true
+ };
+ const pwd = formData.get('tm_admin_password');
+ if (pwd && pwd.trim()) config.admin_password = pwd.trim();
+ }
- // 构建更新数据
const updateData = {
name: formData.get('name'),
priority: parseInt(formData.get('priority')) || 0,
- enabled: formData.get('enabled') === 'on'
+ enabled: formData.get('enabled') === 'on',
+ config
};
- // 构建配置
- const config = {
- base_url: formData.get('api_url'),
- default_domain: formData.get('domain')
- };
-
- // 只有在填写了 API Key 时才更新
- const apiKey = formData.get('api_key');
- if (apiKey && apiKey.trim()) {
- config.api_key = apiKey.trim();
- }
-
- updateData.config = config;
-
try {
await api.patch(`/email-services/${id}`, updateData);
toast.success('服务更新成功');
@@ -645,10 +589,7 @@ async function handleEditCustom(e) {
// 编辑 Outlook 服务
async function editOutlookService(id) {
try {
- // 获取完整的服务详情
const service = await api.get(`/email-services/${id}/full`);
-
- // 填充表单
document.getElementById('edit-outlook-id').value = service.id;
document.getElementById('edit-outlook-email').value = service.config?.email || service.name || '';
document.getElementById('edit-outlook-password').value = '';
@@ -658,10 +599,7 @@ async function editOutlookService(id) {
document.getElementById('edit-outlook-refresh-token').placeholder = service.config?.refresh_token ? '已设置,留空保持不变' : 'OAuth Refresh Token';
document.getElementById('edit-outlook-priority').value = service.priority || 0;
document.getElementById('edit-outlook-enabled').checked = service.enabled;
-
- // 显示模态框
elements.editOutlookModal.classList.add('active');
-
} catch (error) {
toast.error('获取服务信息失败: ' + error.message);
}
@@ -670,11 +608,9 @@ async function editOutlookService(id) {
// 保存编辑 Outlook 服务
async function handleEditOutlook(e) {
e.preventDefault();
-
const id = document.getElementById('edit-outlook-id').value;
const formData = new FormData(e.target);
- // 获取当前服务信息以保留未修改的敏感字段
let currentService;
try {
currentService = await api.get(`/email-services/${id}/full`);
@@ -683,23 +619,18 @@ async function handleEditOutlook(e) {
return;
}
- // 构建更新数据
const updateData = {
- name: formData.get('email'), // 使用邮箱作为名称
+ name: formData.get('email'),
priority: parseInt(formData.get('priority')) || 0,
- enabled: formData.get('enabled') === 'on'
+ enabled: formData.get('enabled') === 'on',
+ config: {
+ email: formData.get('email'),
+ password: formData.get('password')?.trim() || currentService.config?.password || '',
+ client_id: formData.get('client_id')?.trim() || currentService.config?.client_id || '',
+ refresh_token: formData.get('refresh_token')?.trim() || currentService.config?.refresh_token || ''
+ }
};
- // 构建配置,保留未修改的敏感字段
- const config = {
- email: formData.get('email'),
- password: formData.get('password')?.trim() || currentService.config?.password || '',
- client_id: formData.get('client_id')?.trim() || currentService.config?.client_id || '',
- refresh_token: formData.get('refresh_token')?.trim() || currentService.config?.refresh_token || ''
- };
-
- updateData.config = config;
-
try {
await api.patch(`/email-services/${id}`, updateData);
toast.success('账户更新成功');
@@ -710,134 +641,3 @@ async function handleEditOutlook(e) {
toast.error('更新失败: ' + error.message);
}
}
-
-
-// ============== Temp-Mail 服务功能 ==============
-
-// 加载 Temp-Mail 服务列表
-async function loadTempMailServices() {
- try {
- const data = await api.get('/email-services?service_type=temp_mail');
- const services = data.services || [];
-
- if (services.length === 0) {
- elements.tempMailTable.innerHTML = `
-
-
- 📮
- 暂无 Temp-Mail 服务
- 点击「添加服务」配置自部署 Cloudflare Worker 临时邮箱
-
- |
- `;
- return;
- }
-
- elements.tempMailTable.innerHTML = services.map(service => {
- const config = service.config || {};
- return `
-
- | ${escapeHtml(service.name)} |
- ${escapeHtml(config.base_url || '-')} |
- ${escapeHtml(config.domain || '-')} |
-
-
- ${service.enabled ? '已启用' : '已禁用'}
-
- |
- ${service.priority || 0} |
-
-
-
-
-
-
-
- |
-
- `;
- }).join('');
- } catch (error) {
- console.error('加载 Temp-Mail 服务失败:', error);
- }
-}
-
-// 添加 Temp-Mail 服务
-async function handleAddTempMail(e) {
- e.preventDefault();
- const formData = new FormData(e.target);
- const data = {
- service_type: 'temp_mail',
- name: formData.get('name'),
- config: {
- base_url: formData.get('base_url'),
- admin_password: formData.get('admin_password'),
- domain: formData.get('domain'),
- enable_prefix: true
- },
- enabled: formData.get('enabled') === 'on',
- priority: parseInt(formData.get('priority')) || 0
- };
- try {
- await api.post('/email-services', data);
- toast.success('服务添加成功');
- elements.addTempMailModal.classList.remove('active');
- e.target.reset();
- loadTempMailServices();
- loadStats();
- } catch (error) {
- toast.error('添加失败: ' + error.message);
- }
-}
-
-// 编辑 Temp-Mail 服务
-async function editTempMailService(id) {
- try {
- const service = await api.get(`/email-services/${id}/full`);
- document.getElementById('edit-tm-id').value = service.id;
- document.getElementById('edit-tm-name').value = service.name || '';
- document.getElementById('edit-tm-base-url').value = service.config?.base_url || '';
- document.getElementById('edit-tm-admin-password').value = '';
- document.getElementById('edit-tm-admin-password').placeholder = service.config?.admin_password ? '已设置,留空保持不变' : '请输入 Admin 密码';
- document.getElementById('edit-tm-domain').value = service.config?.domain || '';
- document.getElementById('edit-tm-priority').value = service.priority || 0;
- document.getElementById('edit-tm-enabled').checked = service.enabled;
- elements.editTempMailModal.classList.add('active');
- } catch (error) {
- toast.error('获取服务信息失败: ' + error.message);
- }
-}
-
-// 保存编辑 Temp-Mail 服务
-async function handleEditTempMail(e) {
- e.preventDefault();
- const id = document.getElementById('edit-tm-id').value;
- const formData = new FormData(e.target);
- const config = {
- base_url: formData.get('base_url'),
- domain: formData.get('domain'),
- enable_prefix: true
- };
- // 只有填写了密码才更新
- const pwd = formData.get('admin_password');
- if (pwd && pwd.trim()) {
- config.admin_password = pwd.trim();
- }
- const updateData = {
- name: formData.get('name'),
- priority: parseInt(formData.get('priority')) || 0,
- enabled: formData.get('enabled') === 'on',
- config
- };
- try {
- await api.patch(`/email-services/${id}`, updateData);
- toast.success('服务更新成功');
- elements.editTempMailModal.classList.remove('active');
- loadTempMailServices();
- loadStats();
- } catch (error) {
- toast.error('更新失败: ' + error.message);
- }
-}
diff --git a/templates/email_services.html b/templates/email_services.html
index dce1c41..dbe4e9c 100644
--- a/templates/email_services.html
+++ b/templates/email_services.html
@@ -92,7 +92,7 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
- | 名称 |
- Worker 地址 |
- 邮箱域名 |
- 状态 |
- 优先级 |
- 操作 |
-
-
-
-
- |
+ |
-
+
|