Compare commits
2
Commits
aba3767fc1
...
da30ae1875
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da30ae1875 | ||
|
|
c2e05d423f |
No files matched your search
@@ -70,19 +70,6 @@ const steadier = computed(() => {
|
||||
return `${nameOf(firstLeft > firstRight ? 0 : 1)}更稳`
|
||||
})
|
||||
|
||||
/** 只有一个班布置过的题:不比,列几道名字 */
|
||||
const soloText = computed(() => {
|
||||
const { solo } = props.pk
|
||||
if (!solo.length) return ""
|
||||
const names = solo.slice(0, 2).map((item) => `「${item.title}」`)
|
||||
const owners = new Set(solo.map((item) => item.className))
|
||||
const who =
|
||||
owners.size === 1
|
||||
? `只有${nameOf(props.pk.classes.findIndex((item) => item.className === solo[0]!.className))}做过的`
|
||||
: "只有一个班做过的"
|
||||
return `${who} ${solo.length} 道不比:${names.join("、")}${solo.length > 2 ? " 等" : ""}`
|
||||
})
|
||||
|
||||
const SHOW_MOBILE = 7
|
||||
const expanded = ref(false)
|
||||
const shownRows = computed(() =>
|
||||
@@ -136,7 +123,7 @@ const tab = ref<"weekly" | "dist">("weekly")
|
||||
</span>
|
||||
</div>
|
||||
<div class="mid">
|
||||
<span class="muted">两个班都做过的 {{ rows.length }} 道题 · 谁做对的人多谁赢这道</span>
|
||||
<span class="muted">{{ rows.length }} 道题</span>
|
||||
<span class="big">
|
||||
<b :style="{ color: colors[0] }">{{ score.left }}</b>
|
||||
<i>:</i>
|
||||
@@ -154,13 +141,6 @@ const tab = ref<"weekly" | "dist">("weekly")
|
||||
<div class="card">
|
||||
<div class="card-head">
|
||||
<b>同一批题</b>
|
||||
<span class="muted">
|
||||
条 = 全班做对的人占几成<template v-if="!compact">
|
||||
· 皇冠 = 这道赢了 · 按两班差距从大到小</template
|
||||
>
|
||||
</span>
|
||||
<div class="spacer" />
|
||||
<span v-if="soloText && !compact" class="muted">{{ soloText }}</span>
|
||||
</div>
|
||||
|
||||
<template v-if="!compact">
|
||||
@@ -288,7 +268,7 @@ const tab = ref<"weekly" | "dist">("weekly")
|
||||
</div>
|
||||
<div v-if="!compact || tab === 'weekly'" class="card pad">
|
||||
<div v-if="!compact" class="card-title">
|
||||
<b>每周人均新做对</b><span class="muted">这学期,最近 {{ weeks.list.length }} 周</span>
|
||||
<b>每周人均新做对</b>
|
||||
</div>
|
||||
<div class="weeks">
|
||||
<div v-for="week in weeks.list" :key="week.label" class="week">
|
||||
@@ -310,7 +290,7 @@ const tab = ref<"weekly" | "dist">("weekly")
|
||||
</div>
|
||||
<div v-if="!compact || tab === 'dist'" class="card pad dist">
|
||||
<div v-if="!compact" class="card-title">
|
||||
<b>全班分布</b><span class="muted">一根柱一档,横轴是做对几道 · 虚线是中间那位</span>
|
||||
<b>全班分布</b>
|
||||
</div>
|
||||
<div v-for="(item, index) in [left, right]" :key="item.className" class="dist-one">
|
||||
<span class="dist-name" :style="{ color: colors[index] }">
|
||||
@@ -451,10 +431,6 @@ const tab = ref<"weekly" | "dist">("weekly")
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.row {
|
||||
min-height: 52px;
|
||||
display: grid;
|
||||
|
||||
@@ -90,7 +90,6 @@ const expanded = ref(false)
|
||||
const shownRows = computed(() =>
|
||||
props.compact && !expanded.value ? rows.value.slice(0, SHOW_MOBILE) : rows.value,
|
||||
)
|
||||
const soloCount = computed(() => props.pk.solo.length)
|
||||
|
||||
const tab = ref<"race" | "lead">("race")
|
||||
const medal = (index: number) => palette.value.medal[index]
|
||||
@@ -101,14 +100,9 @@ const medal = (index: number) => palette.value.medal[index]
|
||||
<div class="card table">
|
||||
<div class="card-title">
|
||||
<b>同一批题 · 一格一个班</b>
|
||||
<span class="muted">
|
||||
格子里是全班做对的人占几成,越深越多<template v-if="!compact">
|
||||
· 皇冠 = 这道题做得最好的班(一样多就都算)</template
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
<div class="line heads">
|
||||
<span v-if="!compact" class="name muted">至少两个班布置过的 {{ rows.length }} 道</span>
|
||||
<span v-if="!compact" class="name muted">{{ rows.length }} 道</span>
|
||||
<span
|
||||
v-for="(item, index) in pk.classes"
|
||||
:key="item.className"
|
||||
@@ -173,9 +167,6 @@ const medal = (index: number) => palette.value.medal[index]
|
||||
>
|
||||
{{ expanded ? "收起" : `再看 ${rows.length - SHOW_MOBILE} 道 ›` }}
|
||||
</button>
|
||||
<span v-if="!compact && soloCount" class="muted foot">
|
||||
只有一个班做过的 {{ soloCount }} 道不在格子里 · 鼠标放到格子上看做对几个人、交了几次
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="side" :class="{ compact }">
|
||||
@@ -459,10 +450,6 @@ const medal = (index: number) => palette.value.medal[index]
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.foot {
|
||||
padding-top: 4px;
|
||||
}
|
||||
|
||||
.side {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
|
||||
@@ -289,7 +289,6 @@ async function analyze() {
|
||||
<path d="M12 3l1.8 4.7L18.5 9.5l-4.7 1.8L12 16l-1.8-4.7L5.5 9.5l4.7-1.8z" />
|
||||
</svg>
|
||||
<b>AI 分析</b>
|
||||
<span class="muted">根据上面这些数字写,仅供参考</span>
|
||||
<div class="spacer" />
|
||||
<n-button size="small" :loading="ai.running.value" @click="analyze">重新分析</n-button>
|
||||
</div>
|
||||
|
||||
@@ -358,8 +358,6 @@ const gradeColumns = computed(() => `24px 124px 40px 36px repeat(${problems.valu
|
||||
<b class="amber">{{ idleCount }}</b
|
||||
><span>{{ IDLE_MINUTES }} 分钟以上没交</span>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
<span class="muted small">学生看不到这一页 · 15 秒刷新一次</span>
|
||||
</div>
|
||||
|
||||
<div class="grid-wrap">
|
||||
@@ -594,8 +592,6 @@ const gradeColumns = computed(() => `24px 124px 40px 36px repeat(${problems.valu
|
||||
<span v-if="code" class="muted tiny">
|
||||
{{ code.language }} · {{ parseTime(code.createTime, "M月D日 HH:mm:ss") }}
|
||||
</span>
|
||||
<div class="spacer"></div>
|
||||
<span class="muted tiny">点格子换人换题 · ← → ↑ ↓ 也行 · 看过的格子右上角有个点</span>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else class="code-empty muted">
|
||||
|
||||
@@ -131,8 +131,6 @@ const warning = computed(() => tone("warning"))
|
||||
· 你做对 {{ solvedCount }} 道</template
|
||||
>
|
||||
</span>
|
||||
<div class="spacer"></div>
|
||||
<span v-if="running && !contestStore.rankHidden" class="muted small">做对人数随时更新</span>
|
||||
</div>
|
||||
<RouterLink
|
||||
v-for="item in items"
|
||||
@@ -254,9 +252,6 @@ const warning = computed(() => tone("warning"))
|
||||
<RankMini :rows="rows" :me="me?.userId" />
|
||||
<div v-if="!rows.length" class="muted small empty">还没有人交题</div>
|
||||
</div>
|
||||
<div class="muted small rule">
|
||||
先比做对几道;一样多的,比用时:每道题做对时是第几分钟,加起来;错一次多算 20 分钟。
|
||||
</div>
|
||||
</template>
|
||||
</aside>
|
||||
</div>
|
||||
@@ -533,11 +528,6 @@ const warning = computed(() => tone("warning"))
|
||||
padding: 8px 2px;
|
||||
}
|
||||
|
||||
.rule {
|
||||
line-height: 1.6;
|
||||
font-size: var(--oj-fs-meta);
|
||||
}
|
||||
|
||||
/* 手机:题目名要留得下,人数和「最先」只在右边的排名里看 */
|
||||
@media (max-width: 760px) {
|
||||
.count,
|
||||
|
||||
@@ -237,14 +237,6 @@ const columns = computed(
|
||||
</div>
|
||||
<div v-if="!rows.length" class="empty muted">还没有人交题</div>
|
||||
</div>
|
||||
|
||||
<div class="legend">
|
||||
<span><i class="sw first"></i>这题最先做对</span>
|
||||
<span><i class="sw ac"></i>做对,格子里是第几分钟(-1 是错过 1 次)</span>
|
||||
<span><i class="sw no"></i>还没对,错了几次</span>
|
||||
<div class="spacer"></div>
|
||||
<span>用时 = 每道做对题的分钟数相加,错一次多算 20 分钟</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -542,41 +534,4 @@ const columns = computed(
|
||||
.empty {
|
||||
padding: 32px var(--oj-pad-x);
|
||||
}
|
||||
|
||||
.legend {
|
||||
min-height: 42px;
|
||||
padding: 8px var(--oj-pad-x);
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
font-size: var(--oj-fs-meta);
|
||||
color: v-bind("theme.textColor3");
|
||||
border-top: 1px solid v-bind("theme.dividerColor");
|
||||
}
|
||||
|
||||
.legend span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.sw {
|
||||
width: 28px;
|
||||
height: 16px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.sw.first {
|
||||
background: v-bind("theme.successColor");
|
||||
}
|
||||
|
||||
.sw.ac {
|
||||
background: v-bind("success.background");
|
||||
}
|
||||
|
||||
.sw.no {
|
||||
background: v-bind("danger.background");
|
||||
}
|
||||
</style>
|
||||
@@ -150,12 +150,6 @@ const error = computed(() => tone("error"))
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="foot muted">
|
||||
<span>绿 = 在题单里做对(几点做对的)</span><span>黄 = 交过还没对</span
|
||||
><span>紫色角 = 加入前就做对过</span><span>点格子看这个学生这道题的提交</span>
|
||||
<div class="spacer"></div>
|
||||
<span>按学号排</span>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else class="empty"><n-spin size="small" /></div>
|
||||
</section>
|
||||
@@ -303,18 +297,6 @@ const error = computed(() => tone("error"))
|
||||
border-left: 8px solid transparent;
|
||||
}
|
||||
|
||||
.foot {
|
||||
min-height: 36px;
|
||||
box-sizing: border-box;
|
||||
padding: 8px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px 16px;
|
||||
font-size: var(--oj-fs-meta);
|
||||
border-top: 1px solid v-bind("theme.dividerColor");
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
@@ -193,7 +193,6 @@ const purple = { color: "#5b3fa8", background: "rgba(122, 95, 208, 0.12)" }
|
||||
<n-button type="primary" size="large" :loading="joining" @click="join">
|
||||
加入题单,开始做
|
||||
</n-button>
|
||||
<span class="muted tiny">加入以后,在题单里做对的题才算进度</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -285,7 +284,6 @@ const purple = { color: "#5b3fa8", background: "rgba(122, 95, 208, 0.12)" }
|
||||
</section>
|
||||
</div>
|
||||
<n-empty v-else description="这个题单还没有题目" />
|
||||
<div v-if="joined && problems.length" class="muted tiny foot">做对一道会自动回到这里</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
@@ -578,10 +576,6 @@ a.prow:hover {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.foot {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pill {
|
||||
height: 24px;
|
||||
padding: 0 9px;
|
||||
|
||||
@@ -55,7 +55,6 @@ const others = computed(() =>
|
||||
return Date.parse(b.createTime) - Date.parse(a.createTime)
|
||||
}),
|
||||
)
|
||||
const joinedOthers = computed(() => others.value.filter((set) => set.userProgress.isJoined).length)
|
||||
|
||||
function description(set: ProblemSet) {
|
||||
// 简介大多就是把标题再抄一遍,一样的就不重复显示
|
||||
@@ -93,7 +92,7 @@ const doneBackground = computed(() => rgba(theme.value.successColor, 0.05))
|
||||
|
||||
<template v-if="assigning.length">
|
||||
<div class="sect">
|
||||
布置中<span class="muted">老师现在布置的 · {{ assigning.length }} 个</span>
|
||||
布置中<span class="muted">{{ assigning.length }} 个</span>
|
||||
</div>
|
||||
<div class="big-grid">
|
||||
<a
|
||||
@@ -146,9 +145,7 @@ const doneBackground = computed(() => rgba(theme.value.successColor, 0.05))
|
||||
|
||||
<div v-if="others.length" class="sect">
|
||||
{{ assigning.length ? "其他题单" : "题单" }}
|
||||
<span class="muted"
|
||||
>{{ others.length }} 个<template v-if="joinedOthers"> · 加入过的在前</template></span
|
||||
>
|
||||
<span class="muted">{{ others.length }} 个</span>
|
||||
</div>
|
||||
<div class="small-grid">
|
||||
<a
|
||||
|
||||
@@ -55,7 +55,7 @@ function shortLabel(className: string) {
|
||||
<template>
|
||||
<div class="battle" :class="{ bare }">
|
||||
<div class="title">
|
||||
<b v-if="!bare">班级对抗</b><span class="muted">人均做对 · 全服 · 点班名看详情</span>
|
||||
<b v-if="!bare">班级对抗</b><span class="muted">人均做对</span>
|
||||
<router-link
|
||||
v-if="pk"
|
||||
:to="{ path: '/class', query: mine ? { classes: mine } : {} }"
|
||||
|
||||
@@ -125,9 +125,7 @@ function go(path: string, query: Record<string, string>) {
|
||||
</div>
|
||||
|
||||
<section>
|
||||
<div class="sec-title">
|
||||
全班分布<span class="muted">一个点一个同学,下面是这学期做对几道</span>
|
||||
</div>
|
||||
<div class="sec-title">全班分布</div>
|
||||
<div class="dots">
|
||||
<div v-for="column in columns" :key="column.solved" class="dot-col">
|
||||
<div class="stack">
|
||||
@@ -192,9 +190,7 @@ function go(path: string, query: Record<string, string>) {
|
||||
</section>
|
||||
|
||||
<section v-if="detail.care">
|
||||
<div class="sec-title">
|
||||
要多关心的同学<span class="muted">这学期做对不到 3 道 · 只有老师看得到</span>
|
||||
</div>
|
||||
<div class="sec-title">要多关心的同学</div>
|
||||
<div v-for="row in detail.care" :key="row.user.id" class="care">
|
||||
<RankAvatar :username="row.user.username" :avatar="row.avatar" :size="20" />
|
||||
<UserName :username="row.user.username" />
|
||||
@@ -230,7 +226,6 @@ function go(path: string, query: Record<string, string>) {
|
||||
<path d="M12 3l1.8 4.7L18.5 9.5l-4.7 1.8L12 16l-1.8-4.7L5.5 9.5l4.7-1.8z" />
|
||||
</svg>
|
||||
<b>AI 分析这个班</b>
|
||||
<span class="muted">根据上面这些数字写,仅供参考</span>
|
||||
<div class="spacer" />
|
||||
<n-button
|
||||
size="small"
|
||||
|
||||
@@ -181,7 +181,6 @@ function threatNote(me: RankRow, behind: RankRow) {
|
||||
placeholder="写点什么,让大家认识你"
|
||||
autofocus
|
||||
/>
|
||||
<span class="mood-hint">排名、个人主页上都会显示</span>
|
||||
<div class="mood-actions">
|
||||
<n-button size="small" @click="editing = false">取消</n-button>
|
||||
<n-button size="small" type="primary" attr-type="submit" :loading="saving">
|
||||
@@ -439,11 +438,6 @@ function threatNote(me: RankRow, behind: RankRow) {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.mood-hint {
|
||||
font-size: var(--oj-fs-meta);
|
||||
color: v-bind("theme.textColor3");
|
||||
}
|
||||
|
||||
.mood-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
@@ -17,7 +17,7 @@ import RankAvatar from "./RankAvatar.vue"
|
||||
* 重新挂载,折叠状态跟着复位。
|
||||
*
|
||||
* 桌面的条只有百来像素(老师那边多一个「⋯」,七十来像素),压不下文字标签:「前一名」
|
||||
* 「后一名」靠条的颜色和图例认,「进步最大」改成涨跌那一格的橙底徽章。手机每行有空,标签照旧。
|
||||
* 「后一名」靠条的颜色认(和右边「你」卡里两个标签同色),「进步最大」改成涨跌那一格的橙底徽章。手机每行有空,标签照旧。
|
||||
*
|
||||
* 个性签名(设计稿「签名 A」):桌面一行只有一百来像素的条,放不下一句话,所以有签名的
|
||||
* 名字后面挂一个引号,指上去看;手机每行本来就有空,签名直接写在名字后面。
|
||||
|
||||
+13
-112
@@ -15,7 +15,6 @@ import { useBreakpoints } from "shared/composables/breakpoints"
|
||||
import { useConfigStore } from "shared/store/config"
|
||||
import { useUserStore } from "shared/store/user"
|
||||
import { USERNAME_CLASS_RE } from "utils/constants"
|
||||
import { parseTime } from "utils/functions"
|
||||
import ChampionList from "./components/ChampionList.vue"
|
||||
import ClassBattle from "./components/ClassBattle.vue"
|
||||
import ClassDetailDrawer from "./components/ClassDetailDrawer.vue"
|
||||
@@ -187,11 +186,6 @@ const scale = computed(() => rows.value[1]?.solved || rows.value[0]?.solved || 1
|
||||
const hot = computed(() => hottest(rows.value))
|
||||
|
||||
const me = computed(() => board.value?.me ?? null)
|
||||
/** 全服 100 名以外:「你」卡照样有,但名单上没有你这一行,图例和副标题别再提「你」 */
|
||||
const meListed = computed(() => {
|
||||
const b = board.value
|
||||
return !!b?.me && !(b.cap && b.me.rank > b.cap)
|
||||
})
|
||||
const meId = computed(() => (teacher.value ? undefined : userStore.user?.id))
|
||||
const mateClass = computed(() => (board.value?.scope !== "class" ? classContext.value : null))
|
||||
|
||||
@@ -200,35 +194,12 @@ const title = computed(() =>
|
||||
? `${groupTitle(board.value.scope, board.value.className)} · ${periodLabel(board.value.period)}`
|
||||
: "",
|
||||
)
|
||||
/** 只报人数。同分怎么排、名单折在哪,赛道自己看得出来,不再写一遍(用户嫌解释太多) */
|
||||
const subtitle = computed(() => {
|
||||
const b = board.value
|
||||
if (!b) return ""
|
||||
const head = b.scope === "class" ? `${b.total} 人` : `${b.total} 人做对过`
|
||||
const capped = !!b.cap && b.total > b.cap
|
||||
const part = !b.complete
|
||||
? meListed.value
|
||||
? " · 前面一段 + 你附近一段"
|
||||
: ` · 只列前面 ${b.rows.length} 名`
|
||||
: capped
|
||||
? ` · 只列前 ${b.cap} 名`
|
||||
: ""
|
||||
return `${head} · 一样多的,先做到的在前${part}`
|
||||
return b.scope === "class" ? `${b.total} 人` : `${b.total} 人做对过`
|
||||
})
|
||||
/** 手机上标题旁边那句:只说从哪天起、跟什么时候比 */
|
||||
const shortRule = computed(() => {
|
||||
const b = board.value
|
||||
if (!b) return ""
|
||||
const from = b.start ? `${parseTime(b.start, "M月D日")}起` : "全部历史"
|
||||
return `${from} · ↑↓ 比${b.period === "week" ? "今天早上" : "周一"}`
|
||||
})
|
||||
|
||||
const ruleText = computed(() => {
|
||||
const b = board.value
|
||||
if (!b) return ""
|
||||
const from = b.start ? `${parseTime(b.start, "M月D日")}起` : "全部历史"
|
||||
return `${from} · 每道题按第一次做对算 · ↑↓ 比${b.period === "week" ? "今天早上" : "周一"}`
|
||||
})
|
||||
|
||||
const miniScopes = computed(() =>
|
||||
SCOPE_OPTIONS.map((option) => option.value).filter(
|
||||
(s) => s !== scope.value && (s === "all" || !!myClass.value),
|
||||
@@ -387,7 +358,6 @@ async function restore(userId: number) {
|
||||
<div class="toolbar" :class="{ single: !isDesktop }">
|
||||
<div class="title">
|
||||
<h2>排名</h2>
|
||||
<span v-if="!isDesktop" class="rule">{{ shortRule }}</span>
|
||||
</div>
|
||||
<div class="seg" role="group" aria-label="范围">
|
||||
<button
|
||||
@@ -419,10 +389,6 @@ async function restore(userId: number) {
|
||||
placeholder="选班"
|
||||
:options="teacherClassOptions"
|
||||
/>
|
||||
<template v-if="isDesktop">
|
||||
<div class="spacer" />
|
||||
<span class="rule">{{ ruleText }}</span>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="main" :class="{ single: !isDesktop }">
|
||||
@@ -431,21 +397,6 @@ async function restore(userId: number) {
|
||||
<div class="card-head">
|
||||
<b>{{ title }}</b>
|
||||
<span class="muted">{{ subtitle }}</span>
|
||||
<div class="spacer" />
|
||||
<span v-if="isDesktop || (!teacher && me) || hot" class="legend">
|
||||
<span v-if="isDesktop"
|
||||
><i class="bar-key" :style="{ background: palette.track }"
|
||||
><i :style="{ background: palette.bar }" /></i
|
||||
>做出的题数</span
|
||||
>
|
||||
<template v-if="!teacher && me">
|
||||
<span v-if="meListed"><i :style="{ background: palette.me }" />你</span>
|
||||
<span v-if="board.ahead"><i :style="{ background: palette.chase }" />前一名</span>
|
||||
<span v-if="board.behind"><i :style="{ background: palette.threat }" />后一名</span>
|
||||
<span v-if="mateClass"><i :style="{ background: palette.mate }" />你们班</span>
|
||||
</template>
|
||||
<span v-if="hot"><b class="hot-chip">↑</b>进步最大</span>
|
||||
</span>
|
||||
</div>
|
||||
<RankPodium
|
||||
:rows="podium"
|
||||
@@ -500,7 +451,7 @@ async function restore(userId: number) {
|
||||
/>
|
||||
<div v-else-if="board.hidden" class="note-card">
|
||||
<b>你现在不计入排名</b>
|
||||
<span class="muted">老师把你从排名里拿掉了,榜上看不到你。有疑问去问老师。</span>
|
||||
<span class="muted">有疑问去问老师</span>
|
||||
</div>
|
||||
<div v-else-if="teacher" class="note-card">
|
||||
<b>{{ classContext ? classLabel(classContext) : "全服" }}</b>
|
||||
@@ -530,18 +481,13 @@ async function restore(userId: number) {
|
||||
>班级 PK</n-button
|
||||
>
|
||||
</div>
|
||||
<div class="hidden-list">
|
||||
<!-- 只在本班、且真拿掉过人时出现;怎么拿掉在名单每行的「⋯」里,不用再写一遍 -->
|
||||
<div v-if="board.scope === 'class' && board.hiddenUsers.length" class="hidden-list">
|
||||
<span class="hidden-title">不计入排名的人</span>
|
||||
<template v-if="board.scope === 'class'">
|
||||
<div v-for="user in board.hiddenUsers" :key="user.id" class="hidden-row">
|
||||
<UserName :username="user.username" />
|
||||
<n-button size="small" secondary @click="restore(user.id)">恢复</n-button>
|
||||
</div>
|
||||
<span v-if="!board.hiddenUsers.length" class="muted">
|
||||
还没有。怀疑抄代码的,在名单上点「⋯」拿掉。
|
||||
</span>
|
||||
</template>
|
||||
<span v-else class="muted">切到「本班」看这个班拿掉了谁</span>
|
||||
<div v-for="user in board.hiddenUsers" :key="user.id" class="hidden-row">
|
||||
<UserName :username="user.username" />
|
||||
<n-button size="small" secondary @click="restore(user.id)">恢复</n-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="userStore.isAuthed" class="note-card">
|
||||
@@ -562,20 +508,20 @@ async function restore(userId: number) {
|
||||
<div v-if="isDesktop && classContext" class="below">
|
||||
<div v-if="board?.trend && me" class="card">
|
||||
<div class="card-title">
|
||||
<b>我和前后一名的名次</b><span class="muted">每周日晚上 · 越高越好</span>
|
||||
<b>我和前后一名的名次</b>
|
||||
</div>
|
||||
<RankTrend :trend="board.trend" :lines="trendLines" />
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-title">
|
||||
<b>{{ weekTitle }}</b>
|
||||
<span class="muted">还剩 {{ daysLeft }} 天 · 下周一清零</span>
|
||||
<span class="muted">还剩 {{ daysLeft }} 天</span>
|
||||
</div>
|
||||
<WeekTop :rows="weekBoard?.rows ?? []" :me-id="meId" :loaded="!!weekBoard" @open="open" />
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-title">
|
||||
<b>每周冠军</b><span class="muted">本班 · 每周一清零后重新比</span>
|
||||
<b>每周冠军</b>
|
||||
</div>
|
||||
<ChampionList
|
||||
:champions="champions"
|
||||
@@ -617,7 +563,7 @@ async function restore(userId: number) {
|
||||
:lines="trendLines"
|
||||
/>
|
||||
<template v-else-if="phoneTab === 'week'">
|
||||
<span class="muted">{{ weekTitle }} · 还剩 {{ daysLeft }} 天 · 下周一清零</span>
|
||||
<span class="muted">{{ weekTitle }} · 还剩 {{ daysLeft }} 天</span>
|
||||
<WeekTop :rows="weekBoard?.rows ?? []" :me-id="meId" :loaded="!!weekBoard" @open="open" />
|
||||
</template>
|
||||
<ChampionList
|
||||
@@ -699,11 +645,6 @@ async function restore(userId: number) {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.rule,
|
||||
.muted {
|
||||
font-size: var(--oj-fs-meta);
|
||||
color: v-bind("theme.textColor3");
|
||||
@@ -753,46 +694,6 @@ async function restore(userId: number) {
|
||||
font-size: var(--oj-fs-h2);
|
||||
}
|
||||
|
||||
.legend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
font-size: var(--oj-fs-meta);
|
||||
color: v-bind("theme.textColor2");
|
||||
}
|
||||
|
||||
.legend span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
/* 和赛道里涨跌那一格的徽章同一个样子 */
|
||||
.legend .hot-chip {
|
||||
font-size: 12px;
|
||||
color: #ffffff;
|
||||
background: #c76a12;
|
||||
border-radius: 3px;
|
||||
padding: 0 4px;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.legend i {
|
||||
width: 14px;
|
||||
height: 8px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* 条的图例:底槽里一截条,和赛道上的条同一个样子 */
|
||||
.legend .bar-key {
|
||||
width: 24px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.legend .bar-key i {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.empty {
|
||||
padding: 60px 0;
|
||||
text-align: center;
|
||||
|
||||
@@ -110,7 +110,6 @@ const cells = computed(() =>
|
||||
/>
|
||||
<span v-else-if="code[cell.id] === 'failed'" class="muted">代码没拉下来,点方块打开看</span>
|
||||
<span v-else class="muted">代码加载中…</span>
|
||||
<span class="muted small">点方块在新页面打开这一条</span>
|
||||
</div>
|
||||
</n-popover>
|
||||
</span>
|
||||
@@ -159,8 +158,4 @@ const cells = computed(() =>
|
||||
.muted {
|
||||
opacity: 0.65;
|
||||
}
|
||||
|
||||
.small {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
@@ -109,7 +109,6 @@ const classes = computed(() => {
|
||||
<p v-if="grid.truncated" class="note warn" :style="{ color: tone('warning').color }">
|
||||
范围太大,只取了最近的 5000 条提交,更早的班级可能少算或不在表里。缩短时间段就准了。
|
||||
</p>
|
||||
<p class="note">没选班级,先按班级列出来;点一个班再看每个人。「做完」是这几道题都做对了。</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -85,7 +85,6 @@ const saveStatusTitle = computed(() => {
|
||||
<span v-else>✔</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="description">拖拽节点到画布中</p>
|
||||
</div>
|
||||
|
||||
<!-- 节点列表 -->
|
||||
@@ -167,7 +166,6 @@ const saveStatusTitle = computed(() => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.toolbar-header h3 {
|
||||
@@ -231,12 +229,6 @@ const saveStatusTitle = computed(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
/* 节点列表样式 */
|
||||
.nodes {
|
||||
display: flex;
|
||||
|
||||
Reference in new issue
Block a user