Implement registration invite code flow and admin invite codes

This commit is contained in:
2026-04-30 20:49:38 +08:00
parent 2aef81e51d
commit 42aab671ed
32 changed files with 1241 additions and 179 deletions

View File

@@ -876,6 +876,28 @@ static ADMIN_CONSOLE_HTML: &str = r#"<!doctype html>
</div>
</section>
<section class="panel">
<div class="panel-head">
<h2>邀请码管理</h2>
<p>创建或更新管理员邀请码。</p>
</div>
<div class="panel-body">
<form id="invite-code-form" class="form">
<label>邀请码
<input id="invite-code-value" autocomplete="off" />
</label>
<label>Metadata JSON
<textarea id="invite-code-metadata">{}</textarea>
</label>
<div class="btn-row">
<button id="invite-code-submit" type="submit">保存邀请码</button>
</div>
<div id="invite-code-message" class="hint"></div>
<div id="invite-code-result" class="result-panel" style="display:none;"></div>
</form>
</div>
</section>
<section class="panel">
<div class="panel-head">
<h2>API 调试</h2>
@@ -950,6 +972,8 @@ static ADMIN_CONSOLE_HTML: &str = r#"<!doctype html>
const overviewTablesEl = document.getElementById('overview-tables');
const overviewErrorsEl = document.getElementById('overview-errors');
const debugResultEl = document.getElementById('debug-result');
const inviteCodeMessageEl = document.getElementById('invite-code-message');
const inviteCodeResultEl = document.getElementById('invite-code-result');
function getToken() {
return window.localStorage.getItem(TOKEN_KEY) || '';
@@ -1030,6 +1054,16 @@ static ADMIN_CONSOLE_HTML: &str = r#"<!doctype html>
`;
}
function renderInviteCodeResult(result) {
inviteCodeResultEl.style.display = 'grid';
inviteCodeResultEl.innerHTML = `
<div><strong>User ID</strong>${result.userId || '-'}</div>
<div><strong>邀请码:</strong>${result.inviteCode || '-'}</div>
<div><strong>更新时间:</strong>${result.updatedAt || '-'}</div>
<div><strong>Metadata</strong><pre>${JSON.stringify(result.metadata || {}, null, 2)}</pre></div>
`;
}
async function loadMe() {
const token = getToken();
if (!token) {
@@ -1107,6 +1141,26 @@ static ADMIN_CONSOLE_HTML: &str = r#"<!doctype html>
}
});
document.getElementById('invite-code-form').addEventListener('submit', async (event) => {
event.preventDefault();
inviteCodeMessageEl.textContent = '正在保存...';
try {
const rawMetadata = document.getElementById('invite-code-metadata').value.trim() || '{}';
const metadata = JSON.parse(rawMetadata);
const result = await request('/admin/api/profile/invite-codes', {
method: 'POST',
json: {
inviteCode: document.getElementById('invite-code-value').value,
metadata,
},
});
inviteCodeMessageEl.textContent = '已保存';
renderInviteCodeResult(result);
} catch (error) {
inviteCodeMessageEl.textContent = error.message;
}
});
loadMe().then(loadOverview);
</script>
</body>