Skip to content

Commit 51ef0f5

Browse files
committed
feat(profile): 个人中心支持刷新与重设 MC ID
- 新增 Minecraft 正版 ID 区块:显示当前 ID 与 UUID,改名后可一键从 UUID 刷新玩家名 - 重新设置 MC ID 时服务端重新解析并核验正版账号后写入 UUID
1 parent 8dca150 commit 51ef0f5

1 file changed

Lines changed: 128 additions & 0 deletions

File tree

‎src/.vitepress/theme/components/profile-center.vue‎

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ async function refreshMe() {
128128
me.value = j.user
129129
fillForm(j.user)
130130
loadMyApps().catch(() => {})
131+
loadMyEntry().catch(() => {})
131132
}
132133
} catch {
133134
/* 忽略 */
@@ -266,6 +267,92 @@ function loadImage(file: File): Promise<HTMLImageElement> {
266267
})
267268
}
268269
270+
// ---------- MC 正版 ID 自助管理 ----------
271+
// 条目数据:mc_id 为名称缓存,mc_uuid 为解析所得 UUID(改名不影响白名单准入)
272+
interface MyEntry {
273+
id: string
274+
mc_id: string
275+
mc_uuid: string
276+
}
277+
const myEntry = ref<MyEntry | null>(null)
278+
const mcBusy = ref(false)
279+
const mcMsg = ref('')
280+
const mcErr = ref('')
281+
const mcInput = ref('')
282+
283+
async function loadMyEntry() {
284+
if (!token.value || !me.value) return
285+
try {
286+
const r = await fetch(apiURL(`/contributors?user_id=${me.value.id}`), {
287+
headers: {Authorization: `Bearer ${token.value}`},
288+
})
289+
if (r.ok) {
290+
const j = await r.json()
291+
const list: MyEntry[] = j.entries ?? []
292+
myEntry.value = list.length ? list[list.length - 1] : null
293+
mcInput.value = myEntry.value?.mc_id ?? ''
294+
}
295+
} catch { /* 忽略 */ }
296+
}
297+
298+
// 从 UUID 重新获取当前玩家名(改名后刷新缓存)
299+
async function refreshMCID() {
300+
if (!token.value || mcBusy.value) return
301+
mcBusy.value = true
302+
mcMsg.value = ''
303+
mcErr.value = ''
304+
try {
305+
const r = await fetch(apiURL('/users/me/mc-id/refresh'), {
306+
method: 'POST', headers: {Authorization: `Bearer ${token.value}`},
307+
})
308+
const j = await r.json()
309+
if (!r.ok) {
310+
mcErr.value = j.error ?? '刷新失败'
311+
return
312+
}
313+
myEntry.value = j.entry
314+
mcInput.value = j.entry.mc_id
315+
mcMsg.value = `已刷新为 ${j.entry.mc_id}`
316+
} catch {
317+
mcErr.value = '刷新失败:网络错误,请重试'
318+
} finally {
319+
mcBusy.value = false
320+
}
321+
}
322+
323+
// 重新设置 MC ID(服务端重新解析 UUID 并校验正版账号)
324+
async function resetMCID() {
325+
if (!token.value || mcBusy.value) return
326+
const id = mcInput.value.trim()
327+
if (!/^[0-9A-Za-z_]{3,16}$/.test(id)) {
328+
mcErr.value = 'MC ID 须为 3-16 位,只能包含数字、大小写字母和下划线'
329+
mcMsg.value = ''
330+
return
331+
}
332+
mcBusy.value = true
333+
mcMsg.value = ''
334+
mcErr.value = ''
335+
try {
336+
const r = await fetch(apiURL('/users/me/mc-id'), {
337+
method: 'PUT',
338+
headers: {'Content-Type': 'application/json', Authorization: `Bearer ${token.value}`},
339+
body: JSON.stringify({mc_id: id}),
340+
})
341+
const j = await r.json()
342+
if (!r.ok) {
343+
mcErr.value = j.error ?? '设置失败'
344+
return
345+
}
346+
myEntry.value = j.entry
347+
mcInput.value = j.entry.mc_id
348+
mcMsg.value = `已设置为 ${j.entry.mc_id}`
349+
} catch {
350+
mcErr.value = '设置失败:网络错误,请重试'
351+
} finally {
352+
mcBusy.value = false
353+
}
354+
}
355+
269356
// ---------- 邀请码注册为管理员 ----------
270357
const inviteCode = ref('')
271358
const regBusy = ref(false)
@@ -416,6 +503,28 @@ onMounted(async () => {
416503
<button class="btn primary" :disabled="saving" @click="saveProfile">{{ saving ? '保存中…' : '保存资料' }}</button>
417504
<p v-if="msg" class="ok">{{ msg }}</p>
418505

506+
<h4>Minecraft 正版 ID</h4>
507+
<template v-if="myEntry">
508+
<div class="field">
509+
<span>当前 ID(白名单以 UUID 为准,改名不影响准入)</span>
510+
<div class="mc-row">
511+
<button
512+
class="btn icon-btn"
513+
:disabled="mcBusy || !myEntry.mc_uuid"
514+
:title="myEntry.mc_uuid ? '从 Mojang 重新获取当前玩家名' : '尚未解析 UUID,请使用重新设置'"
515+
@click="refreshMCID"
516+
>↻</button>
517+
<code class="mc-id">{{ myEntry.mc_id || '未设置' }}</code>
518+
</div>
519+
<span v-if="myEntry.mc_uuid" class="hint small-tip">UUID:{{ myEntry.mc_uuid }}</span>
520+
</div>
521+
<label class="field">重新设置<input v-model="mcInput" maxlength="16" placeholder="3-16 位数字、大小写字母或下划线,设置时重新解析 UUID" /></label>
522+
<button class="btn primary" :disabled="mcBusy" @click="resetMCID">{{ mcBusy ? '处理中…' : '保存 MC ID' }}</button>
523+
<p v-if="mcMsg" class="ok">{{ mcMsg }}</p>
524+
<p v-if="mcErr" class="error">{{ mcErr }}</p>
525+
</template>
526+
<p v-else class="hint">暂无绑定的贡献者条目(申请审核通过后自动绑定,届时可在此管理 MC ID)。</p>
527+
419528
<h4>邮箱 TOTP 绑定(管理员注册需要)</h4>
420529
<div v-if="totpStep === 'done'">
421530
<p class="hint">已绑定邮箱:{{ totpEmail || me.email || '—' }}</p>
@@ -586,6 +695,25 @@ onMounted(async () => {
586695
font-size: 12px;
587696
margin-top: 4px;
588697
}
698+
.mc-row {
699+
display: flex;
700+
align-items: center;
701+
gap: 8px;
702+
margin-top: 4px;
703+
}
704+
.mc-id {
705+
font-size: 15px;
706+
font-weight: 600;
707+
}
708+
.btn.icon-btn {
709+
padding: 4px 10px;
710+
font-size: 15px;
711+
line-height: 1;
712+
}
713+
.btn.icon-btn:disabled {
714+
opacity: 0.5;
715+
cursor: not-allowed;
716+
}
589717
.my-apps {
590718
list-style: none;
591719
margin: 8px 0;

0 commit comments

Comments
 (0)