feat(排名): 本周进步榜移到全服 Top100 右边,左 2/3 右 1/3
Some checks failed
Deploy / deploy (push) Has been cancelled

两张榜分开上下放的时候,谁也看不见谁:上面那张是历史全部 AC 的总榜,名次几乎不动;
下面那张的分母只有这一周。并排摆在同一屏里,「总榜追不上」和「这周还能进前十」
才是一眼对照出来的。桌面 cols=3、Top100 占 2 栏,移动端退回 cols=1 上下堆叠。

周榜宽度从整屏缩到 1/3,列跟着收:列头去掉「本周」前缀(卡片标题已经写着),
宽度压到 70/120min/100/90,用户名加 ellipsis tooltip —— 1280 那一档也不出横向滚动条。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-17 02:03:04 -06:00
parent 24af385f33
commit a8de8f3932

View File

@@ -317,11 +317,13 @@ const subOptions = computed<Duration>(
durationFromValue(LONG_DURATION_OPTIONS[1]!.value)!, durationFromValue(LONG_DURATION_OPTIONS[1]!.value)!,
) )
// 周榜占的是三栏里的一栏,列头不再重复「本周」(卡片标题已经写着),
// 宽度也压到 1280 那一档能整张放下,不出横向滚动条
const weeklyColumns: DataTableColumn<WeeklyRankItem>[] = [ const weeklyColumns: DataTableColumn<WeeklyRankItem>[] = [
{ {
title: renderTableTitle("排名", "streamline-emojis:flexed-biceps-1"), title: renderTableTitle("排名", "streamline-emojis:flexed-biceps-1"),
key: "rank", key: "rank",
width: 80, width: 70,
align: "center", align: "center",
// rank 是服务端给的周榜名次,不是行号 —— 换算回 Index 要的 0 基下标 // rank 是服务端给的周榜名次,不是行号 —— 换算回 Index 要的 0 基下标
render: (row) => h(Index, { index: row.rank - 1, page: 1, limit: 10 }), render: (row) => h(Index, { index: row.rank - 1, page: 1, limit: 10 }),
@@ -332,7 +334,8 @@ const weeklyColumns: DataTableColumn<WeeklyRankItem>[] = [
"streamline-emojis:smiling-face-with-sunglasses", "streamline-emojis:smiling-face-with-sunglasses",
), ),
key: "username", key: "username",
minWidth: 160, minWidth: 120,
ellipsis: { tooltip: true },
render: (row) => render: (row) =>
h( h(
NButton, NButton,
@@ -345,15 +348,15 @@ const weeklyColumns: DataTableColumn<WeeklyRankItem>[] = [
), ),
}, },
{ {
title: renderTableTitle("本周新解决", "fluent-emoji:party-popper"), title: renderTableTitle("新解决", "fluent-emoji:party-popper"),
key: "solvedCount", key: "solvedCount",
width: 120, width: 100,
align: "center", align: "center",
}, },
{ {
title: renderTableTitle("本周提交", "streamline-emojis:rocket"), title: renderTableTitle("提交", "streamline-emojis:rocket"),
key: "submissionCount", key: "submissionCount",
width: 110, width: 90,
align: "center", align: "center",
}, },
] ]
@@ -622,92 +625,108 @@ watch(
</n-card> </n-card>
</n-gi> </n-gi>
</n-grid> </n-grid>
<n-card> <!--
<template #header> 两张榜并排左边全服总榜分母是历史全部 AC名次几乎不动右边本周进步榜
<n-flex align="center" :size="8"> 分母只有这一周同一屏里对照着看追不上这周还能进前十是一眼的事
<span>本周进步榜</span> -->
<n-text depth="3" style="font-size: 13px"> <n-grid :cols="isDesktop ? 3 : 1" :x-gap="20" :y-gap="20">
{{ weeklyStart ? parseTime(weeklyStart, "M月D日") + "起" : "" }} · <n-gi :span="isDesktop ? 2 : 1">
每周一清零 <n-card>
</n-text> <template #header>全服 Top100</template>
</n-flex> <template #header-extra>
</template> <n-tag
<template #header-extra> v-if="onlineCount > 0"
<n-select round
v-if="userStore.user?.className" :bordered="false"
style="width: 140px" type="success"
:options="[ >
{ label: '本班', value: 'class' }, 当前在线 {{ onlineCount }}
{ label: '全服', value: 'global' }, </n-tag>
]"
v-model:value="weeklyScope"
/>
</template>
<n-data-table
v-if="weeklyData.length"
:data="weeklyData"
:columns="weeklyColumns"
:row-class-name="
(row: WeeklyRankItem) =>
weeklyMe && row.rank === weeklyMe.rank ? 'me-row' : ''
"
/>
<n-empty
v-else
style="padding: 20px 0"
description="这周还没有人解决新题目 现在做出一题就是第一名"
/>
<!--
本周一题没做出来时 weeklyMe 是 null这一行照样要出现它是这张榜对
「还没上榜的人」说的话,而那恰好是最需要被推一把的那批学生。
-->
<template #footer v-if="weeklyMeOffBoard">
<n-tag type="info" round :bordered="false">
<template #icon>
<Icon width="18" icon="fluent-emoji:person-raising-hand" />
</template> </template>
<template v-if="weeklyMe"> <n-data-table
我这周第 {{ weeklyMe.rank }} 名(共 {{ weeklyTotal }} 人上榜)· :data="data"
新解决 {{ weeklyMe.solvedCount }} 题 :columns="columns"
</template> :row-class-name="rowClassName"
<template v-else>
我这周还没有解决新题目,做出 1 题就能上榜
</template>
</n-tag>
</template>
</n-card>
<n-card>
<template #header>全服 Top100</template>
<template #header-extra>
<n-tag v-if="onlineCount > 0" round :bordered="false" type="success">
当前在线 {{ onlineCount }} 人
</n-tag>
</template>
<n-data-table
:data="data"
:columns="columns"
:row-class-name="rowClassName"
/>
<template #footer>
<n-flex align="center" justify="space-between" :wrap="false">
<!-- 前 100 名之外的学生榜上找不到自己,这里单独给一行 -->
<n-tag v-if="meOffBoard" type="info" round :bordered="false">
<template #icon>
<Icon width="18" icon="fluent-emoji:person-raising-hand" />
</template>
我的排名:第 {{ me!.rank }} 名 · 已解决 {{ me!.acceptedNumber }} ·
提交 {{ me!.submissionNumber }} · 正确率
{{ getACRate(me!.acceptedNumber, me!.submissionNumber) }}
</n-tag>
<span v-else />
<Pagination
:total="total"
v-model:page="query.page"
v-model:limit="query.limit"
/> />
</n-flex> <template #footer>
</template> <n-flex align="center" justify="space-between" :wrap="false">
</n-card> <!-- 100 名之外的学生榜上找不到自己这里单独给一行 -->
<n-tag v-if="meOffBoard" type="info" round :bordered="false">
<template #icon>
<Icon width="18" icon="fluent-emoji:person-raising-hand" />
</template>
我的排名 {{ me!.rank }} · 已解决
{{ me!.acceptedNumber }} · 提交 {{ me!.submissionNumber }} ·
正确率
{{ getACRate(me!.acceptedNumber, me!.submissionNumber) }}
</n-tag>
<span v-else />
<Pagination
:total="total"
v-model:page="query.page"
v-model:limit="query.limit"
/>
</n-flex>
</template>
</n-card>
</n-gi>
<n-gi :span="1">
<n-card>
<template #header>
<n-flex align="center" :size="8">
<span>本周进步榜</span>
<n-text depth="3" style="font-size: 13px">
{{ weeklyStart ? parseTime(weeklyStart, "M月D日") + "起" : "" }}
· 每周一清零
</n-text>
</n-flex>
</template>
<template #header-extra>
<n-select
v-if="userStore.user?.className"
style="width: 140px"
:options="[
{ label: '本班', value: 'class' },
{ label: '全服', value: 'global' },
]"
v-model:value="weeklyScope"
/>
</template>
<n-data-table
v-if="weeklyData.length"
:data="weeklyData"
:columns="weeklyColumns"
:row-class-name="
(row: WeeklyRankItem) =>
weeklyMe && row.rank === weeklyMe.rank ? 'me-row' : ''
"
/>
<n-empty
v-else
style="padding: 20px 0"
description="这周还没有人解决新题目 现在做出一题就是第一名"
/>
<!--
本周一题没做出来时 weeklyMe 是 null这一行照样要出现它是这张榜对
「还没上榜的人」说的话,而那恰好是最需要被推一把的那批学生。
-->
<template #footer v-if="weeklyMeOffBoard">
<n-tag type="info" round :bordered="false">
<template #icon>
<Icon width="18" icon="fluent-emoji:person-raising-hand" />
</template>
<template v-if="weeklyMe">
我这周第 {{ weeklyMe.rank }} 名(共 {{ weeklyTotal }} 人上榜)·
新解决 {{ weeklyMe.solvedCount }} 题
</template>
<template v-else>
我这周还没有解决新题目,做出 1 题就能上榜
</template>
</n-tag>
</template>
</n-card>
</n-gi>
</n-grid>
<n-grid :cols="isDesktop ? 2 : 1" :x-gap="20" :y-gap="20"> <n-grid :cols="isDesktop ? 2 : 1" :x-gap="20" :y-gap="20">
<n-gi :span="1"> <n-gi :span="1">
<n-card> <n-card>