fix: 修复邮箱绑定验证错误及多项改进

1. 修复email_verified字段缺失导致的500错误
2. 将邮件主题从"知识管理平台"改为"自动化学习"
3. 增大验证码字体(28->42)和图片尺寸(120x40->160x60)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-11 22:45:44 +08:00
parent 65e2414ede
commit 79cf3c2f30
4 changed files with 163 additions and 21 deletions

View File

@@ -768,6 +768,20 @@
<button class="btn btn-text" onclick="unbindEmail()" style="color: #e74c3c;">解绑</button>
</div>
</div>
<!-- 邮件通知开关 -->
<div id="emailNotifySection" style="margin-top: 15px; padding-top: 15px; border-top: 1px dashed #ddd; display: none;">
<div style="display: flex; justify-content: space-between; align-items: center;">
<div>
<span style="color: #333;">任务完成通知</span>
<div style="font-size: 12px; color: #666; margin-top: 3px;">定时任务完成后发送邮件</div>
</div>
<label style="position: relative; display: inline-block; width: 50px; height: 26px;">
<input type="checkbox" id="emailNotifySwitch" onchange="toggleEmailNotify()" style="opacity: 0; width: 0; height: 0;">
<span style="position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; transition: .3s; border-radius: 26px;"></span>
<span id="emailNotifySlider" style="position: absolute; content: ''; height: 20px; width: 20px; left: 3px; bottom: 3px; background-color: white; transition: .3s; border-radius: 50%;"></span>
</label>
</div>
</div>
</div>
<!-- 修改密码 -->
@@ -2081,6 +2095,7 @@
.then(data => {
const bindSection = document.getElementById('emailBindSection');
const boundSection = document.getElementById('emailBoundSection');
const notifySection = document.getElementById('emailNotifySection');
const statusSpan = document.getElementById('emailStatus');
const boundEmail = document.getElementById('boundEmail');
const bindInput = document.getElementById('bindEmail');
@@ -2088,16 +2103,21 @@
if (data.email && data.email_verified) {
bindSection.style.display = 'none';
boundSection.style.display = 'block';
notifySection.style.display = 'block';
boundEmail.textContent = data.email;
statusSpan.innerHTML = '<span style="color: #27ae60;">已验证</span>';
// 加载邮件通知偏好
loadEmailNotify();
} else if (data.email) {
bindSection.style.display = 'block';
boundSection.style.display = 'none';
notifySection.style.display = 'none';
bindInput.value = data.email;
statusSpan.innerHTML = '<span style="color: #f39c12;">待验证</span>';
} else {
bindSection.style.display = 'block';
boundSection.style.display = 'none';
notifySection.style.display = 'none';
bindInput.value = '';
statusSpan.innerHTML = '<span style="color: #999;">未绑定</span>';
}
@@ -2105,6 +2125,63 @@
.catch(() => {});
}
function loadEmailNotify() {
fetch('/api/user/email-notify')
.then(r => r.json())
.then(data => {
const checkbox = document.getElementById('emailNotifySwitch');
const slider = document.getElementById('emailNotifySlider');
const bg = checkbox.nextElementSibling;
checkbox.checked = data.enabled;
if (data.enabled) {
bg.style.backgroundColor = '#27ae60';
slider.style.transform = 'translateX(24px)';
} else {
bg.style.backgroundColor = '#ccc';
slider.style.transform = 'translateX(0)';
}
})
.catch(() => {});
}
function toggleEmailNotify() {
const checkbox = document.getElementById('emailNotifySwitch');
const slider = document.getElementById('emailNotifySlider');
const bg = checkbox.nextElementSibling;
const enabled = checkbox.checked;
// 立即更新UI
if (enabled) {
bg.style.backgroundColor = '#27ae60';
slider.style.transform = 'translateX(24px)';
} else {
bg.style.backgroundColor = '#ccc';
slider.style.transform = 'translateX(0)';
}
fetch('/api/user/email-notify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ enabled: enabled })
})
.then(r => r.json())
.then(data => {
if (data.success) {
showToast(enabled ? '已开启邮件通知' : '已关闭邮件通知', 'success');
} else {
// 恢复状态
checkbox.checked = !enabled;
loadEmailNotify();
showToast('设置失败', 'error');
}
})
.catch(() => {
checkbox.checked = !enabled;
loadEmailNotify();
showToast('网络错误', 'error');
});
}
function bindEmail() {
const email = document.getElementById('bindEmail').value.trim();
if (!email) {