第57批续7: 弹窗毛玻璃+抽屉式动画;PHP不再重复验密改为验证码确认;绑定完成直接进验证码步骤
This commit is contained in:
+94
-55
@@ -65,6 +65,7 @@ try {
|
||||
case 'bind_email_start': acctBindEmailStart(); break;
|
||||
case 'bind_email_poll': acctBindEmailPoll(); break;
|
||||
case 'bind_email_confirm': acctBindEmailConfirm(); break;
|
||||
case 'bind_email_send_code': acctBindEmailSendCode(); break;
|
||||
case 'get_email_suffix_config': acctGetEmailSuffixConfig(); break;
|
||||
default:
|
||||
error('未知操作: ' . $action);
|
||||
@@ -1015,76 +1016,114 @@ function acctBindEmailPoll() {
|
||||
], 'ok');
|
||||
}
|
||||
|
||||
/** 终态确认:批准窗口内复核登录密码 → 写 users.email(IP 连错5次封5分钟) */
|
||||
function acctBindEmailConfirm() {
|
||||
/** 第57批续7:向刚绑定的邮箱发送验证码(Java端已验密码,PHP不重复验) */
|
||||
function acctBindEmailSendCode() {
|
||||
$player = acctAuthPlayer();
|
||||
$id = (int)getParam('id', 0);
|
||||
$pwd = (string)getParam('password', '');
|
||||
if ($id <= 0) error('缺少请求id');
|
||||
if ($pwd === '') error('请输入登录密码');
|
||||
|
||||
$ip = acctClientIp();
|
||||
// ★第53批风控:绑定确认按 IP 计数,连错 5 次封锁 5 分钟(防密码爆破盗绑)
|
||||
$locked = acctThrottleLocked('bindip', $ip, 5, 300);
|
||||
if ($locked > 0) error('密码错误次数过多,IP 已被限制,请 ' . $locked . ' 秒后再试', 429);
|
||||
|
||||
$db = getDB();
|
||||
$stmt = $db->prepare("SELECT id, player_name, email, status, approved_at FROM web_email_bind_requests WHERE id = :id");
|
||||
$stmt = $db->prepare("SELECT id, player_name, email, status FROM web_email_bind_requests WHERE id = :id");
|
||||
$stmt->bindValue(':id', $id, SQLITE3_INTEGER);
|
||||
$row = $stmt->execute()->fetchArray(SQLITE3_ASSOC);
|
||||
if (!$row) error('请求不存在');
|
||||
if ((string)$row['player_name'] !== $player) error('无权操作该请求');
|
||||
|
||||
$status = (string)$row['status'];
|
||||
if ($status === 'completed') success(['id' => $id, 'status' => 'completed'], '邮箱已绑定');
|
||||
if ($status !== 'approved') error('该请求未获游戏内批准或已失效,请重新发起绑定');
|
||||
|
||||
$now = time();
|
||||
if ($now > ((int)$row['approved_at'] + 180)) {
|
||||
$exp = $db->prepare("UPDATE web_email_bind_requests SET status = 'expired', processed_at = :t WHERE id = :id");
|
||||
$exp->bindValue(':t', $now, SQLITE3_INTEGER);
|
||||
$exp->bindValue(':id', $id, SQLITE3_INTEGER);
|
||||
$exp->execute();
|
||||
error('批准已超时,未做任何处置,请重新发起绑定');
|
||||
}
|
||||
if ((string)$row['status'] !== 'completed') error('绑定尚未完成,无法发送验证码');
|
||||
|
||||
$email = (string)$row['email'];
|
||||
if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
||||
error('请求数据异常,请重新发起绑定');
|
||||
}
|
||||
if (acctEmailOf($player) !== '') {
|
||||
// 绑定期间已被别处绑定 → 幂等终结本请求
|
||||
$dup = $db->prepare("UPDATE web_email_bind_requests SET status = 'completed', processed_at = :t WHERE id = :id");
|
||||
$dup->bindValue(':t', $now, SQLITE3_INTEGER);
|
||||
$dup->bindValue(':id', $id, SQLITE3_INTEGER);
|
||||
$dup->execute();
|
||||
success(['id' => $id, 'status' => 'completed'], '邮箱已绑定');
|
||||
if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) error('邮箱数据异常');
|
||||
|
||||
// 复用 acctSendEmailCode 的发送逻辑(限频 + SMTP)
|
||||
$locked = acctThrottleLocked('mail', $player, 10, 3600);
|
||||
if ($locked > 0) error('发送过于频繁,请 ' . $locked . ' 秒后再试', 429);
|
||||
|
||||
$last = $db->query("SELECT created_at FROM email_codes WHERE player_name = '" . $db->escapeString($player) . "' ORDER BY id DESC LIMIT 1")->fetchArray(SQLITE3_ASSOC);
|
||||
if ($last) {
|
||||
$gap = time() - (int)$last['created_at'];
|
||||
if ($gap < 60) error('发送过于频繁,请 ' . (60 - $gap) . ' 秒后再试', 429);
|
||||
}
|
||||
|
||||
// 密码复核(只认主密码,同第一层)——错:保持 approved 可在窗口内重试,IP 计数
|
||||
$cred = acctCredentials($player);
|
||||
if (!acctPwdCheck($cred, $pwd)) {
|
||||
$remain = acctThrottleFail('bindip', $ip, 5, 300);
|
||||
debugLog('[account.php] 网页绑邮箱密码错误', ['player' => $player, 'ip' => $ip, 'id' => $id]);
|
||||
if ($remain > 0) error('密码错误(连续错误 5 次将封锁 IP 5 分钟),IP 即将被限制', 403);
|
||||
error('密码错误', 403);
|
||||
}
|
||||
acctThrottleReset('bindip', $ip);
|
||||
$smtpHost = SMTP_HOST; $smtpPort = SMTP_PORT; $smtpUser = SMTP_USER; $smtpPass = SMTP_PASS;
|
||||
$senderName = SMTP_SENDER_NAME;
|
||||
if (empty($smtpHost) || empty($smtpUser) || empty($smtpPass)) error('SMTP配置不完整,无法发送邮件验证');
|
||||
|
||||
// 写库:users.email —— users 类别对账 pull 会在几十秒内同步到 Java login.db
|
||||
$upd = $db->prepare("UPDATE users SET email = :e WHERE player_name = :p");
|
||||
$upd->bindValue(':e', $email, SQLITE3_TEXT);
|
||||
$code = str_pad((string)random_int(0, 999999), 6, '0', STR_PAD_LEFT);
|
||||
$expireTime = time() + 300;
|
||||
|
||||
// 旧验证码全部作废
|
||||
$upd = $db->prepare("UPDATE email_codes SET used = 1 WHERE player_name = :p AND used = 0");
|
||||
$upd->bindValue(':p', $player, SQLITE3_TEXT);
|
||||
$upd->execute();
|
||||
if ($db->changes() <= 0) {
|
||||
error('绑定失败:玩家数据不存在,请重新发起');
|
||||
|
||||
$ins = $db->prepare("INSERT INTO email_codes (player_name, email, code, expire_at, used, created_at) VALUES (:p, :e, :c, :x, 0, :t)");
|
||||
$ins->bindValue(':p', $player, SQLITE3_TEXT);
|
||||
$ins->bindValue(':e', $email, SQLITE3_TEXT);
|
||||
$ins->bindValue(':c', $code, SQLITE3_TEXT);
|
||||
$ins->bindValue(':x', $expireTime, SQLITE3_INTEGER);
|
||||
$ins->bindValue(':t', time(), SQLITE3_INTEGER);
|
||||
$ins->execute();
|
||||
|
||||
$subject = "【" . $senderName . "】邮箱绑定验证";
|
||||
$htmlBody = "<div style='font-family:Arial,sans-serif;max-width:400px;margin:0 auto;padding:20px;background:#f5f5f5;border-radius:10px'>"
|
||||
. "<h2 style='color:#333;text-align:center'>📧 邮箱绑定验证</h2>"
|
||||
. "<div style='background:#fff;padding:20px;border-radius:8px;text-align:center;margin:20px 0'>"
|
||||
. "<p style='font-size:14px;color:#666;margin-bottom:10px'>验证码:</p>"
|
||||
. "<p style='font-size:32px;font-weight:bold;color:#4CAF50;letter-spacing:8px;margin:0'>" . $code . "</p>"
|
||||
. "</div>"
|
||||
. "<p style='font-size:12px;color:#999;text-align:center'>验证码5分钟内有效</p></div>";
|
||||
$headers = "MIME-Version: 1.0\r\n"
|
||||
. "Content-type: text/html; charset=UTF-8\r\n"
|
||||
. "From: " . $senderName . " <" . $smtpUser . ">\r\n";
|
||||
|
||||
try {
|
||||
$sent = smtpSendEmail($smtpHost, $smtpPort, $smtpUser, $smtpPass, $email, $subject, $htmlBody, $headers, SMTP_USE_SSL);
|
||||
} catch (\Throwable $e) {
|
||||
$sent = false;
|
||||
debugLog('[account.php] 邮件异常: ' . $e->getMessage(), ['player' => $player]);
|
||||
}
|
||||
|
||||
$done = $db->prepare("UPDATE web_email_bind_requests SET status = 'completed', processed_at = :t WHERE id = :id");
|
||||
$done->bindValue(':t', time(), SQLITE3_INTEGER);
|
||||
$done->bindValue(':id', $id, SQLITE3_INTEGER);
|
||||
$done->execute();
|
||||
|
||||
debugLog('[account.php] 网页绑邮箱成功', ['player' => $player, 'id' => $id, 'ip' => $ip]);
|
||||
success(['id' => $id, 'status' => 'completed', 'email_masked' => acctMaskEmail($email)], '邮箱绑定成功');
|
||||
if (!$sent) {
|
||||
$del = $db->prepare("UPDATE email_codes SET used = 1 WHERE player_name = :p AND code = :c");
|
||||
$del->bindValue(':p', $player, SQLITE3_TEXT);
|
||||
$del->bindValue(':c', $code, SQLITE3_TEXT);
|
||||
$del->execute();
|
||||
error('邮件发送失败,请稍后重试');
|
||||
}
|
||||
acctThrottleFail('mail', $player, 10, 3600);
|
||||
success(['masked_email' => acctMaskEmail($email), 'resend_in' => 60, 'code_expire_in' => 300], '验证码已发送至 ' . acctMaskEmail($email));
|
||||
}
|
||||
|
||||
/** 终态确认:验证邮箱验证码 → 完成绑定 */
|
||||
/** 终态确认:验证邮箱验证码 → 完成绑定 */
|
||||
function acctBindEmailConfirm() {
|
||||
$player = acctAuthPlayer();
|
||||
$id = (int)getParam('id', 0);
|
||||
$emailCode = (string)getParam('email_code', '');
|
||||
if ($id <= 0) error('缺少请求id');
|
||||
if ($emailCode === '' || strlen($emailCode) !== 6) error('请输入6位验证码');
|
||||
|
||||
$db = getDB();
|
||||
$stmt = $db->prepare("SELECT id, player_name, email, status FROM web_email_bind_requests WHERE id = :id");
|
||||
$stmt->bindValue(':id', $id, SQLITE3_INTEGER);
|
||||
$row = $stmt->execute()->fetchArray(SQLITE3_ASSOC);
|
||||
if (!$row) error('请求不存在');
|
||||
if ((string)$row['player_name'] !== $player) error('无权操作该请求');
|
||||
if ((string)$row['status'] !== 'completed') error('绑定尚未完成');
|
||||
|
||||
// 验证邮箱验证码(只认未使用且未过期的最新一条)
|
||||
$codeStmt = $db->prepare("SELECT id FROM email_codes WHERE player_name = :p AND code = :c AND used = 0 AND expire_at > :t ORDER BY id DESC LIMIT 1");
|
||||
$codeStmt->bindValue(':p', $player, SQLITE3_TEXT);
|
||||
$codeStmt->bindValue(':c', $emailCode, SQLITE3_TEXT);
|
||||
$codeStmt->bindValue(':t', time(), SQLITE3_INTEGER);
|
||||
$codeRow = $codeStmt->execute()->fetchArray(SQLITE3_ASSOC);
|
||||
if (!$codeRow) error('验证码错误或已过期');
|
||||
|
||||
// 核销验证码
|
||||
$usedUpd = $db->prepare("UPDATE email_codes SET used = 1 WHERE id = :id");
|
||||
$usedUpd->bindValue(':id', (int)$codeRow['id'], SQLITE3_INTEGER);
|
||||
$usedUpd->execute();
|
||||
|
||||
$email = (string)$row['email'];
|
||||
debugLog('[account.php] 邮箱验证码验证通过', ['player' => $player, 'id' => $id]);
|
||||
success(['id' => $id, 'status' => 'completed', 'email_masked' => acctMaskEmail($email)], '邮箱绑定验证通过');
|
||||
}
|
||||
|
||||
|
||||
+27
-1
@@ -4380,6 +4380,22 @@ function maskEmail($email) {
|
||||
return 'xx@' . $domain;
|
||||
}
|
||||
|
||||
// ===== 第57批续7:Java端密码验证通过后直接完成邮箱绑定 =====
|
||||
function acctCompleteEmailBind($requestId, $player, $email) {
|
||||
$db = getDB();
|
||||
$upd = $db->prepare("UPDATE users SET email = :e WHERE player_name = :p");
|
||||
$upd->bindValue(':e', $email, SQLITE3_TEXT);
|
||||
$upd->bindValue(':p', $player, SQLITE3_TEXT);
|
||||
$upd->execute();
|
||||
if ($db->changes() <= 0) return false;
|
||||
$done = $db->prepare("UPDATE web_email_bind_requests SET status = 'completed', processed_at = :t WHERE id = :id");
|
||||
$done->bindValue(':t', time(), SQLITE3_INTEGER);
|
||||
$done->bindValue(':id', (int)$requestId, SQLITE3_INTEGER);
|
||||
$done->execute();
|
||||
debugLog('[sync.php] Java端验证通过,直接完成邮箱绑定', ['player' => $player, 'id' => $requestId]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ===== 发送邮箱验证码 =====
|
||||
function sendEmailCode() {
|
||||
$player = getParam('player');
|
||||
@@ -5129,6 +5145,7 @@ function webEmailBindResult() {
|
||||
$action = getParam('action', ''); // approve / reject / offline / failed
|
||||
$player = getParam('player', '');
|
||||
$failReason = getParam('fail_reason', '');
|
||||
$pwdVerified = (getParam('pwd_verified', '0') === '1');
|
||||
if ($savedGetAction !== null) $_GET['action'] = $savedGetAction;
|
||||
|
||||
if (!$requestId) error('缺少request_id');
|
||||
@@ -5136,7 +5153,7 @@ function webEmailBindResult() {
|
||||
if (!$player) error('缺少player');
|
||||
|
||||
$db = getDB();
|
||||
$stmt = $db->prepare("SELECT id, player_name, status, expire_at FROM web_email_bind_requests WHERE id = :id");
|
||||
$stmt = $db->prepare("SELECT id, player_name, email, status, expire_at FROM web_email_bind_requests WHERE id = :id");
|
||||
$stmt->bindValue(':id', (int)$requestId, SQLITE3_INTEGER);
|
||||
$row = $stmt->execute()->fetchArray(SQLITE3_ASSOC);
|
||||
if (!$row) error('请求不存在');
|
||||
@@ -5153,6 +5170,15 @@ function webEmailBindResult() {
|
||||
}
|
||||
|
||||
if ($action === 'approve') {
|
||||
if ($pwdVerified && $now <= (int)$row['expire_at']) {
|
||||
$bindEmail = (string)$row['email'];
|
||||
if (!$bindEmail || !filter_var($bindEmail, FILTER_VALIDATE_EMAIL)) error('请求数据异常');
|
||||
if (acctCompleteEmailBind($requestId, $player, $bindEmail)) {
|
||||
success(['request_id' => (int)$requestId, 'status' => 'completed', 'email' => $bindEmail]);
|
||||
return;
|
||||
}
|
||||
error('绑定失败,请重试');
|
||||
}
|
||||
$newStatus = ($now > (int)$row['expire_at']) ? 'expired' : 'approved';
|
||||
} elseif ($action === 'reject') {
|
||||
$newStatus = 'rejected';
|
||||
|
||||
+79
-26
@@ -172,6 +172,8 @@ if ($currentVersion !== $BUILD_VERSION) {
|
||||
body.bg-img-mode .modal { background: rgba(22,27,34,0.6); }
|
||||
.light-theme .modal { background: rgba(255,255,255,0.8); border-color: rgba(9,105,218,0.25); }
|
||||
.light-theme.bg-img-mode .modal { background: rgba(255,255,255,0.6); }
|
||||
.modal.animate-in { animation: drawerSlideDown 0.3s ease; }
|
||||
.modal.animate-out { animation: drawerSlideUp 0.25s ease forwards; }
|
||||
.modal h3 { margin-bottom: 16px; }
|
||||
.modal .row { margin-bottom: 12px; }
|
||||
.modal label { display: block; font-size: 13px; color: var(--dim); margin-bottom: 4px; }
|
||||
@@ -304,13 +306,13 @@ if ($currentVersion !== $BUILD_VERSION) {
|
||||
.glass-alert-overlay {
|
||||
display: none; position: fixed; top: 0; left: 0; right: 0; bottom: 0;
|
||||
background: rgba(0,0,0,0.45);
|
||||
backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
|
||||
backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
|
||||
z-index: 5000; justify-content: center; align-items: center;
|
||||
animation: glassFadeIn 0.25s ease;
|
||||
}
|
||||
.glass-alert-overlay.show { display: flex; }
|
||||
.glass-alert-card {
|
||||
background: rgba(22,27,34,0.92);
|
||||
background: rgba(22,27,34,0.65); backdrop-filter: blur(32px) saturate(1.8); -webkit-backdrop-filter: blur(32px) saturate(1.8);
|
||||
backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
|
||||
border: 1px solid rgba(88,166,255,0.25);
|
||||
border-radius: 16px; padding: 28px 28px 20px; width: 360px; max-width: 88%;
|
||||
@@ -2741,40 +2743,79 @@ if ($currentVersion !== $BUILD_VERSION) {
|
||||
acctBindEmailPwdStep();
|
||||
return;
|
||||
}
|
||||
if (d.status === 'completed') {
|
||||
if (_bindWizTimer) { clearInterval(_bindWizTimer); _bindWizTimer = null; }
|
||||
acctBindEmailCodeStep(d.email);
|
||||
return;
|
||||
}
|
||||
acctBindEmailFinish(d.status, d.fail_reason);
|
||||
} catch (e) { /* 网络抖动忽略,下一轮重试 */ }
|
||||
}
|
||||
|
||||
function acctBindEmailPwdStep() {
|
||||
function acctBindEmailCodeStep(email) {
|
||||
const _masked = (email || '').replace(/^(.).*(@.*)$/, '$1***$2');
|
||||
acctModalSet(`
|
||||
<div style="font-size:13px;color:var(--dim);margin-bottom:10px;line-height:1.7">✅ 游戏内已批准。输入登录密码完成绑定(<b>3分钟内有效</b>;密码错误不生效、可重试,连错 5 次将封锁 IP 5 分钟)</div>
|
||||
<input type="password" id="bindPwdInput" placeholder="当前登录密码" autocomplete="current-password" style="width:100%;box-sizing:border-box;padding:10px 12px;background:var(--bg);border:1px solid var(--border);border-radius:6px;color:var(--text);font-size:14px" onkeydown="if(event.key==='Enter')document.getElementById('modalConfirm').click()">
|
||||
<div id="acctErr" style="color:var(--red);font-size:12px;min-height:16px;margin-top:8px"></div>`,
|
||||
'确认绑定', acctBindEmailConfirm);
|
||||
<div style="font-size:13px;color:var(--dim);margin-bottom:10px;line-height:1.7">✅ 游戏内已批准,邮箱 <b>${_masked}</b> 已绑定。
|
||||
<br>为确认邮箱可用,请输入验证码完成验证。</div>
|
||||
<div style="display:flex;gap:8px;margin-bottom:10px">
|
||||
<input type="text" id="bindCodeInput" placeholder="6位验证码" maxlength="6" inputmode="numeric" style="flex:1;padding:10px 12px;background:var(--bg);border:1px solid var(--border);border-radius:6px;color:var(--text);font-size:16px;font-family:monospace;letter-spacing:4px" onkeydown="if(event.key==='Enter')document.getElementById('modalConfirm').click()">
|
||||
<button class="btn btn-dim" id="bindCodeSend" onclick="acctBindEmailSendCode()" style="white-space:nowrap">发送验证码</button>
|
||||
</div>
|
||||
<div id="bindCodeTimer" style="font-size:12px;color:var(--dim);margin-bottom:8px"></div>
|
||||
<div id="acctErr" style="color:var(--red);font-size:12px;min-height:16px"></div>`,
|
||||
'确认验证', acctBindEmailCodeConfirm);
|
||||
document.getElementById('modalOverlay').style.display = 'flex';
|
||||
setTimeout(() => { const p = document.getElementById('bindPwdInput'); if (p) p.focus(); }, 120);
|
||||
setTimeout(() => { const p = document.getElementById('bindCodeInput'); if (p) p.focus(); }, 120);
|
||||
}
|
||||
|
||||
async function acctBindEmailConfirm() {
|
||||
const el = document.getElementById('bindPwdInput');
|
||||
const pwd = el ? el.value : '';
|
||||
if (!pwd) { acctErr('请输入密码'); return; }
|
||||
async function acctBindEmailSendCode() {
|
||||
const btn = document.getElementById('bindCodeSend');
|
||||
if (!btn) return;
|
||||
btn.disabled = true; btn.textContent = '发送中...';
|
||||
try {
|
||||
const res = await apiPost('account.php', {action: 'bind_email_send_code', id: _bindWizId});
|
||||
btn.disabled = false; btn.textContent = '发送验证码';
|
||||
if (!res.success) { acctErr(res.message || '发送失败'); return; }
|
||||
acctErr('');
|
||||
startBindCodeTimer(60);
|
||||
} catch (e) {
|
||||
btn.disabled = false; btn.textContent = '发送验证码';
|
||||
acctErr('连接失败: ' + e.message);
|
||||
}
|
||||
}
|
||||
|
||||
let _bindCodeTimer = null;
|
||||
function startBindCodeTimer(sec) {
|
||||
const el = document.getElementById('bindCodeTimer');
|
||||
if (!el) return;
|
||||
let left = sec;
|
||||
el.textContent = '验证码已发送,' + left + 's 后可重新发送';
|
||||
if (_bindCodeTimer) clearInterval(_bindCodeTimer);
|
||||
_bindCodeTimer = setInterval(() => {
|
||||
left--;
|
||||
if (left <= 0) { clearInterval(_bindCodeTimer); _bindCodeTimer = null; el.textContent = '可重新发送验证码'; return; }
|
||||
el.textContent = '验证码已发送,' + left + 's 后可重新发送';
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
async function acctBindEmailCodeConfirm() {
|
||||
const el = document.getElementById('bindCodeInput');
|
||||
const code = el ? el.value.trim() : '';
|
||||
if (!code || code.length !== 6) { acctErr('请输入6位验证码'); return; }
|
||||
const btn = document.getElementById('modalConfirm');
|
||||
btn.disabled = true; acctErr('验证中...');
|
||||
try {
|
||||
const res = await apiPost('account.php', {action: 'bind_email_confirm', id: _bindWizId, password: pwd});
|
||||
const res = await apiPost('account.php', {action: 'bind_email_confirm', id: _bindWizId, email_code: code});
|
||||
btn.disabled = false;
|
||||
if (!res.success) { acctErr(res.message || '密码错误'); return; }
|
||||
if (res.data && res.data.status === 'completed') {
|
||||
acctModalSet(`
|
||||
<div style="text-align:center;padding:10px 0;line-height:1.8">
|
||||
<div style="font-size:34px">🎉</div>
|
||||
<div style="font-size:15px;margin-top:4px">邮箱绑定成功</div>
|
||||
<div style="font-size:13px;color:var(--dim)">${escapeHtml(res.data.email_masked || '')}</div>
|
||||
<div style="font-size:12px;color:var(--dim);margin-top:6px">现在可以完成第二层验证了,请重新发起刚才的操作</div>
|
||||
</div>`,
|
||||
'完成', () => { closeModal(); acctRefreshStatus(); });
|
||||
}
|
||||
if (!res.success) { acctErr(res.message || '验证码错误'); return; }
|
||||
acctModalSet(`
|
||||
<div style="text-align:center;padding:10px 0;line-height:1.8">
|
||||
<div style="font-size:34px">🎉</div>
|
||||
<div style="font-size:15px;margin-top:4px">邮箱绑定成功</div>
|
||||
<div style="font-size:13px;color:var(--dim)">${escapeHtml(res.data.email_masked || '')}</div>
|
||||
<div style="font-size:12px;color:var(--dim);margin-top:6px">现在可以完成第二层验证了,请重新发起刚才的操作</div>
|
||||
</div>`,
|
||||
'完成', () => { closeModal(); acctRefreshStatus(); });
|
||||
} catch (e) {
|
||||
btn.disabled = false;
|
||||
acctErr('连接失败: ' + e.message);
|
||||
@@ -2796,8 +2837,17 @@ if ($currentVersion !== $BUILD_VERSION) {
|
||||
offline: '📴 你当前不在线,无法批准。请先登录游戏后重新发起',
|
||||
expired: '⌛ 1分钟内未处理,请求已超时作废(未做任何处置)',
|
||||
failed: '⚠️ 绑定失败:' + (reason || '未知原因'),
|
||||
completed: '✅ 邮箱已绑定'
|
||||
};
|
||||
if (status === 'completed') {
|
||||
acctModalSet(`
|
||||
<div style="text-align:center;padding:10px 0;line-height:1.8">
|
||||
<div style="font-size:34px">🎉</div>
|
||||
<div style="font-size:15px;margin-top:4px">邮箱绑定成功</div>
|
||||
<div style="font-size:12px;color:var(--dim);margin-top:6px">现在可以完成第二层验证了,请重新发起刚才的操作</div>
|
||||
</div>`,
|
||||
'完成', () => { closeModal(); acctRefreshStatus(); });
|
||||
return;
|
||||
}
|
||||
const msg = msgs[status] || ('状态: ' + status);
|
||||
acctModalSet(`
|
||||
<div style="text-align:center;padding:12px 0;font-size:14px;line-height:1.8">${escapeHtml(msg)}</div>`,
|
||||
@@ -3198,7 +3248,9 @@ if ($currentVersion !== $BUILD_VERSION) {
|
||||
})();
|
||||
|
||||
function closeModal() {
|
||||
document.getElementById('modalOverlay').style.display = 'none';
|
||||
var _mc = document.getElementById('modalOverlay');
|
||||
if (_mc) { var _m = _mc.querySelector('.modal'); if (_m) { _m.classList.remove('animate-in'); _m.classList.add('animate-out'); } }
|
||||
setTimeout(function() { document.getElementById('modalOverlay').style.display = 'none'; }, 200);
|
||||
// ★ 密码验证被取消 → 清除token,进入游客模式(防止未认证玩家数据泄露)
|
||||
if (NEED_PASSWORD && !AUTHENTICATED) {
|
||||
showGuestMode();
|
||||
@@ -3287,6 +3339,7 @@ if ($currentVersion !== $BUILD_VERSION) {
|
||||
|
||||
function acctModalSet(html, confirmText, onConfirm) {
|
||||
document.getElementById('modalBody').innerHTML = html;
|
||||
var _m2 = document.getElementById('modalOverlay').querySelector('.modal'); if (_m2) { _m2.classList.remove('animate-out'); _m2.classList.add('animate-in'); }
|
||||
const btn = document.getElementById('modalConfirm');
|
||||
btn.textContent = confirmText;
|
||||
btn.disabled = false;
|
||||
|
||||
Reference in New Issue
Block a user