Deploy / deploy (push) Canceled after 0s
- index.css 加一张 --oj-* 尺寸表和 .oj-page 外壳,二十几个前台页面改成引用它: 正文 14→15、页标题 20→24、题目/提交列表行高 40→48、比赛/公告 56、筛选控件 28→34 - 阅读型页面限宽 1200 居中;题目/提交列表 1600、比赛详情 1400、排名 1280、班级 PK 1440 - 1280 宽的筛选条放大后放不下,题目/提交列表在 1366 以下退回 13px 的字 - 班级 PK 五个班起格子里不写「一次 x%」(只剩「一次 8…」);赛跑图线尾的数字不再被截掉 - 手机上比赛列表的「没参加」挪到比赛名下面;题单里「以前做对过 · 旧代码先藏着」缩成「做对过」 - 题目详情页(编辑器)和后台不在这一轮 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
126 lines
2.9 KiB
Vue
126 lines
2.9 KiB
Vue
<script setup lang="ts">
|
|
import type { RankRow, WeeklyChampion } from "@oj2/contract"
|
|
import { useThemeVars } from "naive-ui"
|
|
import UserName from "shared/components/UserName.vue"
|
|
import { parseTime } from "utils/functions"
|
|
import RankAvatar from "./RankAvatar.vue"
|
|
|
|
/** 本班最近几周的每周冠军,底下再挂这张榜上「进步最大」的那个人 */
|
|
defineProps<{
|
|
champions: WeeklyChampion[]
|
|
hot: RankRow | null
|
|
/** 「这周升了」还是「今天升了」:这周的榜比的是今天早上 */
|
|
since: string
|
|
meId?: number
|
|
}>()
|
|
defineEmits<{ open: [username: string] }>()
|
|
|
|
const theme = useThemeVars()
|
|
|
|
function weekLabel(start: string) {
|
|
return `${parseTime(start, "M月D日")}那周`
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="champions">
|
|
<div v-for="champion in champions" :key="champion.weekStart" class="row">
|
|
<span class="muted week">{{ weekLabel(champion.weekStart) }}</span>
|
|
<svg
|
|
width="16"
|
|
height="16"
|
|
viewBox="0 0 24 24"
|
|
fill="#f2c94c"
|
|
stroke="#9a6700"
|
|
stroke-width="1.6"
|
|
stroke-linejoin="round"
|
|
aria-hidden="true"
|
|
>
|
|
<path d="M3 8l4.5 4L12 5l4.5 7L21 8l-2 11H5z" />
|
|
</svg>
|
|
<RankAvatar
|
|
:username="champion.user.username"
|
|
:avatar="champion.avatar"
|
|
:size="20"
|
|
:me="champion.user.id === meId"
|
|
/>
|
|
<button class="who" @click="$emit('open', champion.user.username)">
|
|
<UserName :username="champion.user.username" />
|
|
</button>
|
|
<span class="muted num">{{ champion.solved }} 道</span>
|
|
</div>
|
|
<span v-if="!champions.length" class="muted">最近几周还没有冠军</span>
|
|
<div v-if="hot" class="row hot-line">
|
|
<span class="hot-tag">进步最大</span>
|
|
<RankAvatar
|
|
:username="hot.user.username"
|
|
:avatar="hot.avatar"
|
|
:size="20"
|
|
:me="hot.user.id === meId"
|
|
/>
|
|
<button class="who" @click="$emit('open', hot.user.username)">
|
|
<UserName :username="hot.user.username" />
|
|
</button>
|
|
<span class="muted">{{ since }}升了 {{ hot.change }} 名</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.champions {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.row {
|
|
height: 32px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
font-size: var(--oj-fs-sec);
|
|
}
|
|
|
|
.muted {
|
|
font-size: var(--oj-fs-meta);
|
|
color: v-bind("theme.textColor3");
|
|
}
|
|
|
|
.week {
|
|
width: 86px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.who {
|
|
flex-grow: 1;
|
|
padding: 0;
|
|
border: 0;
|
|
background: none;
|
|
font: inherit;
|
|
cursor: pointer;
|
|
display: flex;
|
|
min-width: 0;
|
|
}
|
|
|
|
.num {
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
|
|
.hot-line {
|
|
margin-top: 4px;
|
|
padding-top: 8px;
|
|
height: auto;
|
|
border-top: 1px solid v-bind("theme.dividerColor");
|
|
}
|
|
|
|
.hot-tag {
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
color: #ffffff;
|
|
background: #c76a12;
|
|
border-radius: 3px;
|
|
padding: 0 6px;
|
|
line-height: 18px;
|
|
white-space: nowrap;
|
|
}
|
|
</style>
|