Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
734f4aed05 | ||
|
|
36f2a45c5e |
No files matched your search
@@ -35,7 +35,7 @@ const showBadges = computed(() => props.group.name === "题单和比赛" && !!pr
|
|||||||
:to="{ name: 'problemset', params: { problemSetId: b.problemSet.id } }"
|
:to="{ name: 'problemset', params: { problemSetId: b.problemSet.id } }"
|
||||||
class="badge"
|
class="badge"
|
||||||
>
|
>
|
||||||
<AchievementIcon :icon="b.badge.icon" :size="32" />
|
<AchievementIcon :icon="b.badge.icon" :size="24" />
|
||||||
<span>{{ b.badge.name }}</span>
|
<span>{{ b.badge.name }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
@@ -89,24 +89,19 @@ h3 small {
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 奖章名最长 9 个字(「有趣和无趣的观察者」),竖排在格子里放不下,横排写全 */
|
||||||
.badge {
|
.badge {
|
||||||
width: 72px;
|
display: inline-flex;
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 6px;
|
||||||
font-size: 12px;
|
height: 34px;
|
||||||
line-height: 15px;
|
padding: 0 10px 0 6px;
|
||||||
text-align: center;
|
border-radius: 6px;
|
||||||
color: v-bind("theme.textColor1");
|
font-size: var(--oj-fs-sec);
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge span {
|
|
||||||
max-width: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
color: v-bind("theme.textColor1");
|
||||||
|
background: v-bind("theme.actionColor");
|
||||||
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.compact {
|
.compact {
|
||||||
|
|||||||
@@ -24,6 +24,14 @@ const color = computed(() => RARITY_COLOR[props.rarity])
|
|||||||
const r = computed(() => props.size / 2 + 3)
|
const r = computed(() => props.size / 2 + 3)
|
||||||
const box = computed(() => props.size + 8)
|
const box = computed(() => props.size + 8)
|
||||||
const circumference = computed(() => 2 * Math.PI * r.value)
|
const circumference = computed(() => 2 * Math.PI * r.value)
|
||||||
|
// 底色都是半透明的,下面垫一层卡片底色 —— 不然成就线的进度线会从徽章中间透出来
|
||||||
|
const onBg = computed(
|
||||||
|
() => `linear-gradient(${color.value}26, ${color.value}26), ${theme.value.cardColor}`,
|
||||||
|
)
|
||||||
|
const offBg = computed(
|
||||||
|
() =>
|
||||||
|
`linear-gradient(${theme.value.actionColor}, ${theme.value.actionColor}), ${theme.value.cardColor}`,
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -55,7 +63,7 @@ const circumference = computed(() => 2 * Math.PI * r.value)
|
|||||||
v-else
|
v-else
|
||||||
class="disc"
|
class="disc"
|
||||||
:class="state"
|
:class="state"
|
||||||
:style="state === 'on' ? { borderColor: color, background: `${color}26` } : undefined"
|
:style="state === 'on' ? { borderColor: color, background: onBg } : undefined"
|
||||||
>
|
>
|
||||||
<AchievementIcon :icon="icon" :size="Math.round(size * 0.56)" />
|
<AchievementIcon :icon="icon" :size="Math.round(size * 0.56)" />
|
||||||
</span>
|
</span>
|
||||||
@@ -98,7 +106,7 @@ const circumference = computed(() => 2 * Math.PI * r.value)
|
|||||||
|
|
||||||
.disc.off {
|
.disc.off {
|
||||||
border-color: v-bind("theme.borderColor");
|
border-color: v-bind("theme.borderColor");
|
||||||
background: v-bind("theme.actionColor");
|
background: v-bind(offBg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.disc.off :deep(svg),
|
.disc.off :deep(svg),
|
||||||
@@ -110,7 +118,7 @@ const circumference = computed(() => 2 * Math.PI * r.value)
|
|||||||
|
|
||||||
.disc.unknown {
|
.disc.unknown {
|
||||||
border: 1.5px dashed v-bind("theme.borderColor");
|
border: 1.5px dashed v-bind("theme.borderColor");
|
||||||
background: v-bind("theme.actionColor");
|
background: v-bind(offBg);
|
||||||
color: v-bind("theme.textColor3");
|
color: v-bind("theme.textColor3");
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ import { useRarityColor } from "shared/composables/rarity"
|
|||||||
import type { Near } from "../series"
|
import type { Near } from "../series"
|
||||||
import Medal from "./Medal.vue"
|
import Medal from "./Medal.vue"
|
||||||
|
|
||||||
/** 「快拿到了」:每个只说还差什么,进度条底下是现在几 / 要几、本班几人有 */
|
/**
|
||||||
defineProps<{ items: Near[]; compact?: boolean }>()
|
* 「快拿到了」:每个只说还差什么,进度条底下是现在几 / 要几、本班几人有。
|
||||||
|
* `wide`:旁边没有「本班」(没有班级的号)时三个横着排,占满整宽
|
||||||
|
*/
|
||||||
|
defineProps<{ items: Near[]; compact?: boolean; wide?: boolean }>()
|
||||||
|
|
||||||
const theme = useThemeVars()
|
const theme = useThemeVars()
|
||||||
const rarityText = useRarityColor()
|
const rarityText = useRarityColor()
|
||||||
@@ -22,38 +25,40 @@ const percent = (item: Near) => Math.round((item.series.value / item.achievement
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="card" :class="{ compact }">
|
<section class="card" :class="{ compact, wide }">
|
||||||
<h3>快拿到了</h3>
|
<h3>快拿到了</h3>
|
||||||
<div v-for="item in items" :key="item.achievement.id" class="item">
|
<div class="list">
|
||||||
<Medal
|
<div v-for="item in items" :key="item.achievement.id" class="item">
|
||||||
:icon="item.achievement.icon"
|
<Medal
|
||||||
:rarity="item.achievement.rarity"
|
:icon="item.achievement.icon"
|
||||||
:size="compact ? 44 : 48"
|
:rarity="item.achievement.rarity"
|
||||||
state="off"
|
:size="compact ? 44 : 48"
|
||||||
:ring="item.series.value / item.achievement.threshold!"
|
state="off"
|
||||||
/>
|
:ring="item.series.value / item.achievement.threshold!"
|
||||||
<div class="body">
|
|
||||||
<div class="head">
|
|
||||||
<b>{{ item.achievement.name }}</b>
|
|
||||||
<span class="tag" :style="{ color: rarityText[item.achievement.rarity] }">
|
|
||||||
{{ RARITY_LABEL[item.achievement.rarity] }}
|
|
||||||
</span>
|
|
||||||
<span class="remain">{{ item.remain }}</span>
|
|
||||||
</div>
|
|
||||||
<n-progress
|
|
||||||
type="line"
|
|
||||||
:percentage="percent(item)"
|
|
||||||
:height="6"
|
|
||||||
:show-indicator="false"
|
|
||||||
:color="theme.primaryColor"
|
|
||||||
:border-radius="3"
|
|
||||||
:fill-border-radius="3"
|
|
||||||
/>
|
/>
|
||||||
<div class="foot">
|
<div class="body">
|
||||||
<span>{{ now(item) }}</span>
|
<div class="head">
|
||||||
<span v-if="item.achievement.classHolders !== null">
|
<b>{{ item.achievement.name }}</b>
|
||||||
本班 {{ item.achievement.classHolders }} 人有
|
<span class="tag" :style="{ color: rarityText[item.achievement.rarity] }">
|
||||||
</span>
|
{{ RARITY_LABEL[item.achievement.rarity] }}
|
||||||
|
</span>
|
||||||
|
<span class="remain">{{ item.remain }}</span>
|
||||||
|
</div>
|
||||||
|
<n-progress
|
||||||
|
type="line"
|
||||||
|
:percentage="percent(item)"
|
||||||
|
:height="6"
|
||||||
|
:show-indicator="false"
|
||||||
|
:color="theme.primaryColor"
|
||||||
|
:border-radius="3"
|
||||||
|
:fill-border-radius="3"
|
||||||
|
/>
|
||||||
|
<div class="foot">
|
||||||
|
<span>{{ now(item) }}</span>
|
||||||
|
<span v-if="item.achievement.classHolders !== null">
|
||||||
|
本班 {{ item.achievement.classHolders }} 人有
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -116,6 +121,20 @@ h3 {
|
|||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wide {
|
||||||
|
padding-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wide .list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wide .item {
|
||||||
|
border-top: 1px solid v-bind("theme.dividerColor");
|
||||||
|
}
|
||||||
|
|
||||||
/* 手机:「还差什么」换到名字下面一行 */
|
/* 手机:「还差什么」换到名字下面一行 */
|
||||||
.compact {
|
.compact {
|
||||||
padding: 12px 14px 4px;
|
padding: 12px 14px 4px;
|
||||||
|
|||||||
@@ -85,9 +85,14 @@ watch(name, load)
|
|||||||
<router-link v-if="other" to="/achievement" class="mine">看我的 ›</router-link>
|
<router-link v-if="other" to="/achievement" class="mine">看我的 ›</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 只有一张(老师没有班级、或看别人)时也只占半边,别把进度条拉得一屏宽 -->
|
<!-- 没有班级(老师、自己注册的号)就没有「本班」,「快拿到了」三个横排占满整宽 -->
|
||||||
<div v-if="near.length || data.classBoard" class="top">
|
<div v-if="near.length || data.classBoard" class="top" :class="{ alone: !data.classBoard }">
|
||||||
<NearCard v-if="near.length" :items="near" :compact="!isDesktop" />
|
<NearCard
|
||||||
|
v-if="near.length"
|
||||||
|
:items="near"
|
||||||
|
:compact="!isDesktop"
|
||||||
|
:wide="isDesktop && !data.classBoard"
|
||||||
|
/>
|
||||||
<ClassCard
|
<ClassCard
|
||||||
v-if="data.classBoard"
|
v-if="data.classBoard"
|
||||||
:board="data.classBoard"
|
:board="data.classBoard"
|
||||||
@@ -177,6 +182,10 @@ h2 {
|
|||||||
margin-bottom: var(--oj-gap);
|
margin-bottom: var(--oj-gap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.top.alone {
|
||||||
|
grid-template-columns: minmax(0, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
.columns {
|
.columns {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
|||||||
Reference in new issue
Block a user