feat(achievement): 个人主页与排行榜添加成就入口

个人主页显示完成度与最近获得的成就,可跳转奖杯馆;
全服 Top100 和班级排名每行加一个跳转按钮。

成就摘要单独请求,不并进 init 里那个按位置取值的 promises 数组,
且失败时静默降级——它不该拖垮整个个人主页。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-04 06:57:07 -06:00
parent d7d80e1c1b
commit d31bfd8b8f
2 changed files with 136 additions and 37 deletions

View File

@@ -198,17 +198,30 @@ const columns: DataTableColumn<Rank>[] = [
"streamline-emojis:smiling-face-with-sunglasses",
),
key: "username",
width: 200,
width: 240,
render: (row) =>
h(
NButton,
{
text: true,
type: "info",
onClick: () => router.push("/user?name=" + row.user.username),
},
() => row.user.username,
),
h("div", { style: "display:flex;align-items:center;gap:6px" }, [
h(
NButton,
{
text: true,
type: "info",
onClick: () => router.push("/user?name=" + row.user.username),
},
() => row.user.username,
),
h(
NButton,
{
text: true,
size: "tiny",
title: "查看成就",
onClick: () =>
router.push("/achievement?name=" + row.user.username),
},
() => "🏆",
),
]),
},
{
title: renderTableTitle(
@@ -378,32 +391,44 @@ const myClassColumns: DataTableColumn<UserRank>[] = [
{
title: "用户名",
key: "username",
width: 200,
width: 240,
render: (row) =>
h(
NButton,
{
text: true,
type: "info",
onClick: () => router.push("/user?name=" + row.username),
},
() =>
row.rank === myRank.value
? h(
NFlex,
{ align: "flex-end" },
{
default: () => [
h("span", {}, row.username),
h(Icon, {
width: 20,
icon: "fluent-emoji:person-raising-hand",
}),
],
},
)
: row.username,
),
h("div", { style: "display:flex;align-items:center;gap:6px" }, [
h(
NButton,
{
text: true,
type: "info",
onClick: () => router.push("/user?name=" + row.username),
},
() =>
row.rank === myRank.value
? h(
NFlex,
{ align: "flex-end" },
{
default: () => [
h("span", {}, row.username),
h(Icon, {
width: 20,
icon: "fluent-emoji:person-raising-hand",
}),
],
},
)
: row.username,
),
h(
NButton,
{
text: true,
size: "tiny",
title: "查看成就",
onClick: () => router.push("/achievement?name=" + row.username),
},
() => "🏆",
),
]),
},
{
title: "已解决",