()
| 426 | |
| 427 | // 渲染自定义邮箱服务列表 |
| 428 | function renderCustomServices() { |
| 429 | if (customServices.length === 0) { |
| 430 | elements.customTable.innerHTML = ` |
| 431 | <tr> |
| 432 | <td colspan="9"> |
| 433 | <div class="empty-state"> |
| 434 | <div class="empty-state-icon">📭</div> |
| 435 | <div class="empty-state-title">暂无自定义邮箱服务</div> |
| 436 | <div class="empty-state-description">点击「添加服务」按钮创建新服务</div> |
| 437 | </div> |
| 438 | </td> |
| 439 | </tr> |
| 440 | `; |
| 441 | return; |
| 442 | } |
| 443 | |
| 444 | elements.customTable.innerHTML = customServices.map(service => { |
| 445 | return ` |
| 446 | <tr data-id="${service.id}"> |
| 447 | <td><input type="checkbox" data-id="${service.id}" ${selectedCustom.has(service.id) ? 'checked' : ''}></td> |
| 448 | <td>${escapeHtml(service.name)}</td> |
| 449 | <td>${getCustomServiceTypeBadge(service._subType)}</td> |
| 450 | <td style="font-size: 0.75rem; min-width: 400px;">${getCustomServiceAddress(service)}</td> |
| 451 | <td>--</td> |
| 452 | <td title="${service.enabled ? '已启用' : '已禁用'}">${service.enabled ? '✅' : '⭕'}</td> |
| 453 | <td>${service.priority}</td> |
| 454 | <td>${format.date(service.last_used)}</td> |
| 455 | <td> |
| 456 | <div style="display:flex;gap:4px;align-items:center;white-space:nowrap;"> |
| 457 | <button class="btn btn-secondary btn-sm" onclick="editCustomService(${service.id}, '${service._subType}')">编辑</button> |
| 458 | <button class="btn ${service.enabled ? 'btn-warning' : 'btn-success'} btn-sm" onclick="toggleService(${service.id}, ${!service.enabled})">${service.enabled ? '禁用' : '启用'}</button> |
| 459 | <button class="btn btn-secondary btn-sm" onclick="testService(${service.id})">测试</button> |
| 460 | <button class="btn btn-danger btn-sm" onclick="deleteService(${service.id}, '${escapeHtml(service.name)}')">删除</button> |
| 461 | </div> |
| 462 | </td> |
| 463 | </tr>`; |
| 464 | }).join(''); |
| 465 | |
| 466 | elements.customTable.querySelectorAll('input[type="checkbox"][data-id]').forEach(cb => { |
| 467 | cb.addEventListener('change', (e) => { |
| 468 | const id = parseInt(e.target.dataset.id); |
| 469 | if (e.target.checked) selectedCustom.add(id); |
| 470 | else selectedCustom.delete(id); |
| 471 | }); |
| 472 | }); |
| 473 | } |
| 474 | |
| 475 | // 加载临时邮箱配置 |
| 476 | async function loadTempmailConfig() { |
no test coverage detected