第57批续4:绑邮箱向导展示可绑定邮箱类型+drawer卡片毛玻璃效果

This commit is contained in:
ypsdf1
2026-10-26 12:00:57 +08:00
parent 6d93d69226
commit c8a7cd73a6
2 changed files with 74 additions and 7 deletions
+41 -1
View File
@@ -65,6 +65,7 @@ try {
case 'bind_email_start': acctBindEmailStart(); break;
case 'bind_email_poll': acctBindEmailPoll(); break;
case 'bind_email_confirm': acctBindEmailConfirm(); break;
case 'get_email_suffix_config': acctGetEmailSuffixConfig(); break;
default:
error('未知操作: ' . $action);
}
@@ -859,6 +860,33 @@ function acctRecoveryRegen() {
success(['recovery_codes' => $codes], '恢复代码已重新生成,旧代码全部作废');
}
// ★ 第57批续4:获取邮箱后缀配置(供前端展示可绑定的邮箱类型)
function acctGetEmailSuffixConfig() {
$player = acctAuthPlayer();
$db = getDB();
try {
$cfgRow = $db->query("SELECT mode, suffix_list FROM email_suffix_config WHERE id = 1")->fetchArray(SQLITE3_ASSOC);
} catch (\Throwable $e) {
success(['email_mode' => '默认', 'email_suffixes' => []]);
return;
}
if (!$cfgRow) {
success(['email_mode' => '默认', 'email_suffixes' => []]);
return;
}
$mode = (string)$cfgRow['mode'];
$suffixList = (string)$cfgRow['suffix_list'];
if ($mode === '默认' || $suffixList === '') {
success(['email_mode' => '默认', 'email_suffixes' => []]);
return;
}
$suffixes = preg_split('/[,;\n]+/', $suffixList);
$suffixes = array_map('trim', $suffixes);
$suffixes = array_map('strtolower', $suffixes);
$suffixes = array_filter($suffixes, function ($s) { return $s !== ''; });
success(['email_mode' => $mode, 'email_suffixes' => array_values($suffixes)]);
}
// ===================== 第53批:网页端绑定邮箱(游戏内批准流) =====================
//
// 流程:bind_email_start 建 60 秒请求(要求玩家在线)→ Java 定时器A 拉取并游戏内发
@@ -928,7 +956,19 @@ function acctBindEmailStart() {
$id = (int)$db->lastInsertRowID();
debugLog('[account.php] 发起网页绑邮箱', ['player' => $player, 'id' => $id, 'ip' => acctClientIp()]);
success(['id' => $id, 'expire_in' => 60], '请求已发送,等待游戏内批准');
// ★ 第57批续4:返回后缀配置,供前端展示可绑定的邮箱类型
$mode = '默认'; $suffixList = '';
try {
$cfgRow = $db->query("SELECT mode, suffix_list FROM email_suffix_config WHERE id = 1")->fetchArray(SQLITE3_ASSOC);
if ($cfgRow) {
$mode = (string)$cfgRow['mode'];
$suffixList = (string)$cfgRow['suffix_list'];
}
} catch (\Throwable $_e) {}
$suffixes = array_filter(array_map('trim', preg_split('/[,;\n]+/', $suffixList)));
$suffixes = array_map(function ($s) { return strtolower($s); }, $suffixes);
success(['id' => $id, 'expire_in' => 60, 'email_mode' => $mode, 'email_suffixes' => array_values($suffixes)], '请求已发送,等待游戏内批准');
}
/** 前端轮询请求状态(1秒一次):pending/notified/approved/rejected/offline/expired/completed/failed */
+30 -3
View File
@@ -277,10 +277,13 @@ if ($currentVersion !== $BUILD_VERSION) {
}
.drawer-overlay.show { display: flex; }
.drawer-card {
background: var(--card); border: 1px solid var(--border);
border-radius: 12px 12px 0 0; padding: 24px;
background: rgba(22,27,34,0.85); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
border: 1px solid rgba(88,166,255,0.2); border-radius: 12px 12px 0 0; padding: 24px;
width: 420px; max-width: 90%;
box-shadow: 0 -8px 32px rgba(0,0,0,0.3);
box-shadow: 0 -8px 32px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.05);
}
.light-theme .drawer-card {
background: rgba(255,255,255,0.85); border-color: rgba(9,105,218,0.2);
}
.drawer-card.animate-in { animation: drawerSlideDown 0.3s ease; }
.drawer-card.animate-out { animation: drawerSlideUp 0.25s ease forwards; }
@@ -2638,12 +2641,36 @@ if ($currentVersion !== $BUILD_VERSION) {
if (IS_PREVIEW || !TOKEN || !currentPlayer) { showToast('请先登录游戏后再操作', 'error'); return; }
if (_bindWizTimer) { clearInterval(_bindWizTimer); _bindWizTimer = null; }
drawerOpen('📧 网页绑定邮箱');
// ★ 第57批续4:先获取邮箱后缀配置,展示可绑定的邮箱类型
apiPost('account.php', {action: 'get_email_suffix_config'}).then(res => {
let hintHtml = '';
if (res.success && res.data) {
const mode = res.data.email_mode || '默认';
const suffixes = res.data.email_suffixes || [];
if (suffixes.length > 0) {
if (mode === '白名单') {
hintHtml = '<div style="font-size:12px;color:var(--green);margin-bottom:8px;line-height:1.6">✅ 仅允许绑定以下邮箱:<br>' + suffixes.map(s => '<span style="background:rgba(63,185,80,0.15);padding:2px 8px;border-radius:4px;margin:2px;font-family:monospace">@' + s + '</span>').join('') + '</div>';
} else if (mode === '黑名单') {
hintHtml = '<div style="font-size:12px;color:var(--red);margin-bottom:8px;line-height:1.6">❌ 以下邮箱被禁止绑定:<br>' + suffixes.map(s => '<span style="background:rgba(248,81,73,0.15);padding:2px 8px;border-radius:4px;margin:2px;font-family:monospace">@' + s + '</span>').join('') + '</div>';
}
}
}
drawerSet(`
<div style="font-size:13px;color:var(--dim);margin-bottom:10px;line-height:1.7">输入邮箱后,你的游戏内会收到一条批准通知(需在线)。<b>1分钟内</b>点击「✔ 批准」,再回到这里输入登录密码即可完成绑定;拒绝或超时则直接折返,不做任何处置。</div>
${hintHtml}
<input type="email" id="bindEmailInput" placeholder="you@example.com" autocomplete="email" 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>`,
'发送批准请求 →', acctBindEmailStart);
setTimeout(() => { const el = document.getElementById('bindEmailInput'); if (el) el.focus(); }, 120);
}).catch(() => {
// API 失败也展示基础向导
drawerSet(`
<div style="font-size:13px;color:var(--dim);margin-bottom:10px;line-height:1.7">输入邮箱后,你的游戏内会收到一条批准通知(需在线)。<b>1分钟内</b>点击「✔ 批准」,再回到这里输入登录密码即可完成绑定;拒绝或超时则直接折返,不做任何处置。</div>
<input type="email" id="bindEmailInput" placeholder="you@example.com" autocomplete="email" 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>`,
'发送批准请求 →', acctBindEmailStart);
setTimeout(() => { const el = document.getElementById('bindEmailInput'); if (el) el.focus(); }, 120);
});
}
async function acctBindEmailStart() {