refactor(achievement): 稀有度配色收进 constants,文字色适配浅色模式
四份重复的 RARITY_COLOR / RARITY_LABEL 合并到 utils/constants。 拆成两套:边框色块继续用饱和的原色,文字改走 useRarityColor, 按明暗主题切换,两套都压到 4.5:1 以上——原色是照深色底调的, 白底上白金只有 1.7:1、黄金 2.2:1,卡片上的稀有度 tag 看不清。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,12 @@ import {
|
||||
type MetricOption,
|
||||
} from "admin/api"
|
||||
import AchievementIcon from "shared/components/AchievementIcon.vue"
|
||||
import { RARITY_LABEL } from "utils/constants"
|
||||
|
||||
const rarityOptions = Object.entries(RARITY_LABEL).map(([value, label]) => ({
|
||||
label,
|
||||
value,
|
||||
}))
|
||||
|
||||
const props = defineProps<{
|
||||
show: boolean
|
||||
@@ -118,15 +124,7 @@ async function save() {
|
||||
</n-flex>
|
||||
</n-form-item>
|
||||
<n-form-item label="稀有度">
|
||||
<n-select
|
||||
v-model:value="form.rarity"
|
||||
:options="[
|
||||
{ label: '青铜', value: 'bronze' },
|
||||
{ label: '白银', value: 'silver' },
|
||||
{ label: '黄金', value: 'gold' },
|
||||
{ label: '白金', value: 'platinum' },
|
||||
]"
|
||||
/>
|
||||
<n-select v-model:value="form.rarity" :options="rarityOptions" />
|
||||
</n-form-item>
|
||||
<n-form-item label="指标" required>
|
||||
<n-select
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
} from "admin/api"
|
||||
import AchievementIcon from "shared/components/AchievementIcon.vue"
|
||||
import AchievementModal from "./components/AchievementModal.vue"
|
||||
import { RARITY_LABEL } from "utils/constants"
|
||||
|
||||
const message = useMessage()
|
||||
const dialog = useDialog()
|
||||
@@ -16,13 +17,6 @@ const loading = ref(false)
|
||||
const showModal = ref(false)
|
||||
const editing = ref<AdminAchievement | null>(null)
|
||||
|
||||
const RARITY_LABEL: Record<string, string> = {
|
||||
bronze: "青铜",
|
||||
silver: "白银",
|
||||
gold: "黄金",
|
||||
platinum: "白金",
|
||||
}
|
||||
|
||||
// 下架的只在有的时候才提,全部上架时标题不啰嗦
|
||||
const title = computed(() => {
|
||||
if (!list.value.length) return "成就管理"
|
||||
|
||||
@@ -1,22 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import AchievementIcon from "shared/components/AchievementIcon.vue"
|
||||
import { useRarityColor } from "shared/composables/rarity"
|
||||
import { RARITY_COLOR, RARITY_LABEL } from "utils/constants"
|
||||
import type { Achievement } from "utils/types"
|
||||
|
||||
const props = defineProps<{ achievement: Achievement }>()
|
||||
|
||||
const RARITY_COLOR: Record<string, string> = {
|
||||
bronze: "#b87333",
|
||||
silver: "#9fa6b2",
|
||||
gold: "#e0a300",
|
||||
platinum: "#7dd3fc",
|
||||
}
|
||||
|
||||
const RARITY_LABEL: Record<string, string> = {
|
||||
bronze: "青铜",
|
||||
silver: "白银",
|
||||
gold: "黄金",
|
||||
platinum: "白金",
|
||||
}
|
||||
// 边框用原色,tag 里的文字用跟主题走的那套
|
||||
const rarityTextColor = useRarityColor()
|
||||
|
||||
// 隐藏且未解锁:后端已把名称/描述/图标和条件三件套都遮成 ??? 和 null,
|
||||
// 这里只负责不要把 null 渲染出来,也不要画出会泄露门槛的进度条
|
||||
@@ -78,7 +69,7 @@ const unlockDate = computed(() => {
|
||||
size="tiny"
|
||||
:color="{
|
||||
borderColor: RARITY_COLOR[achievement.rarity],
|
||||
textColor: RARITY_COLOR[achievement.rarity],
|
||||
textColor: rarityTextColor[achievement.rarity],
|
||||
}"
|
||||
>
|
||||
{{ RARITY_LABEL[achievement.rarity] }}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { getAchievements, getAchievementSummary } from "oj/achievement/api"
|
||||
import { getUserBadges } from "oj/api"
|
||||
import { useRarityColor } from "shared/composables/rarity"
|
||||
import type { Achievement, AchievementSummary } from "utils/types"
|
||||
import AchievementCard from "./components/AchievementCard.vue"
|
||||
|
||||
@@ -18,27 +19,8 @@ interface UserBadge {
|
||||
const route = useRoute()
|
||||
const name = computed(() => (route.query.name as string) || undefined)
|
||||
|
||||
// 稀有度配色分明暗两套:AchievementCard 那组原色是照着深色底调的,
|
||||
// 直接拿到白底上,白金只有 1.7:1、黄金 2.2:1,小字根本看不清
|
||||
const isDark = useDark()
|
||||
|
||||
const RARITY_COLOR_DARK: Record<string, string> = {
|
||||
bronze: "#d18d4f",
|
||||
silver: "#b6bcc7",
|
||||
gold: "#e0a300",
|
||||
platinum: "#7dd3fc",
|
||||
}
|
||||
|
||||
const RARITY_COLOR_LIGHT: Record<string, string> = {
|
||||
bronze: "#9a5b25",
|
||||
silver: "#6b7280",
|
||||
gold: "#a37500",
|
||||
platinum: "#0284c7",
|
||||
}
|
||||
|
||||
const rarityColor = computed(() =>
|
||||
isDark.value ? RARITY_COLOR_DARK : RARITY_COLOR_LIGHT,
|
||||
)
|
||||
// 标签和进度条同色,整行读作一个单位
|
||||
const rarityColor = useRarityColor()
|
||||
|
||||
const achievements = ref<Achievement[]>([])
|
||||
const summary = ref<AchievementSummary | null>(null)
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import AchievementIcon from "shared/components/AchievementIcon.vue"
|
||||
import { useAchievementStore } from "shared/store/achievement"
|
||||
import { RARITY_COLOR } from "utils/constants"
|
||||
|
||||
const store = useAchievementStore()
|
||||
const { current, queue } = storeToRefs(store)
|
||||
const visible = ref(false)
|
||||
|
||||
const RARITY_COLOR: Record<string, string> = {
|
||||
bronze: "#b87333",
|
||||
silver: "#9fa6b2",
|
||||
gold: "#e0a300",
|
||||
platinum: "#7dd3fc",
|
||||
}
|
||||
|
||||
let timer: ReturnType<typeof setTimeout> | null = null
|
||||
let gapTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
|
||||
15
src/shared/composables/rarity.ts
Normal file
15
src/shared/composables/rarity.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { useDark } from "@vueuse/core"
|
||||
import { computed } from "vue"
|
||||
import { RARITY_TEXT_COLOR } from "utils/constants"
|
||||
|
||||
/**
|
||||
* 成就稀有度的文字配色,跟随明暗主题切换。
|
||||
* 两套色值都压到 4.5:1 以上,不然浅色模式下白金和黄金的小字看不清。
|
||||
* 边框和色块不用这个,直接用 RARITY_COLOR 的原色。
|
||||
*/
|
||||
export function useRarityColor() {
|
||||
const isDark = useDark()
|
||||
return computed(() =>
|
||||
isDark.value ? RARITY_TEXT_COLOR.dark : RARITY_TEXT_COLOR.light,
|
||||
)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { SUBMISSION_RESULT } from "./types"
|
||||
import type { AchievementRarity, SUBMISSION_RESULT } from "./types"
|
||||
|
||||
export enum SubmissionStatus {
|
||||
compile_error = -2,
|
||||
@@ -276,6 +276,42 @@ export enum ChartType {
|
||||
Activity,
|
||||
}
|
||||
|
||||
// 成就稀有度
|
||||
export const RARITY_LABEL: Record<AchievementRarity, string> = {
|
||||
bronze: "青铜",
|
||||
silver: "白银",
|
||||
gold: "黄金",
|
||||
platinum: "白金",
|
||||
}
|
||||
|
||||
// 边框、色块用的原色:饱和度够高,明暗底上都醒目
|
||||
export const RARITY_COLOR: Record<AchievementRarity, string> = {
|
||||
bronze: "#b87333",
|
||||
silver: "#9fa6b2",
|
||||
gold: "#e0a300",
|
||||
platinum: "#7dd3fc",
|
||||
}
|
||||
|
||||
// 文字要另配一套。上面那组是照深色底调的,搬到白底上白金只有 1.7:1、
|
||||
// 黄金 2.2:1,12px 的稀有度标签根本看不清。取色见 useRarityColor
|
||||
export const RARITY_TEXT_COLOR: Record<
|
||||
"dark" | "light",
|
||||
Record<AchievementRarity, string>
|
||||
> = {
|
||||
dark: {
|
||||
bronze: "#d18d4f",
|
||||
silver: "#b6bcc7",
|
||||
gold: "#e0a300",
|
||||
platinum: "#7dd3fc",
|
||||
},
|
||||
light: {
|
||||
bronze: "#9a5b25",
|
||||
silver: "#6b7280",
|
||||
gold: "#a37500",
|
||||
platinum: "#0284c7",
|
||||
},
|
||||
}
|
||||
|
||||
// 时间范围配置
|
||||
export const DURATION_OPTIONS = [
|
||||
{ label: "本节课内", value: "hours:1" },
|
||||
|
||||
Reference in New Issue
Block a user