Compare commits

...
3 Commits
Author SHA1 Message Date
xuyue a4bd4fcd13 update
Deploy / deploy (build:staging, school, 8822, /root/OJ/data/dist) (push) Has been cancelled
Deploy / deploy (build, debian, 22, /root/OJDeploy/data/clientnext) (push) Has been cancelled
2026-06-29 07:52:17 -06:00
xuyue 1d285c8694 update 2026-06-29 07:48:13 -06:00
xuyue 4261bae104 update 2026-06-29 07:19:04 -06:00
23 changed files with 107 additions and 110 deletions
+1 -1
View File
@@ -15,7 +15,7 @@
@click="handleAnalyze" @click="handleAnalyze"
> >
<template #icon> <template #icon>
<Icon icon="mingcute:ai-line" /> <Icon icon="ph:sparkle" />
</template> </template>
开始分析 开始分析
</n-button> </n-button>
+5 -5
View File
@@ -796,7 +796,7 @@ const radarChartOptions = {
style="margin-top: 26px" style="margin-top: 26px"
> >
<template #icon> <template #icon>
<Icon icon="mingcute:ai-line" /> <Icon icon="ph:sparkle" />
</template> </template>
AI分析 AI分析
</n-button> </n-button>
@@ -871,7 +871,7 @@ const radarChartOptions = {
class="stat-avg-ac" class="stat-avg-ac"
> >
<template #suffix> <template #suffix>
<Icon icon="streamline-emojis:chart" width="20" /> <Icon icon="streamline-ultimate-color:analytics-pie-2" width="20" />
</template> </template>
</n-statistic> </n-statistic>
</n-gi> </n-gi>
@@ -883,7 +883,7 @@ const radarChartOptions = {
class="stat-median-ac" class="stat-median-ac"
> >
<template #suffix> <template #suffix>
<Icon icon="streamline-emojis:target" width="20" /> <Icon icon="streamline-ultimate-color:cursor-target-1" width="20" />
</template> </template>
</n-statistic> </n-statistic>
</n-gi> </n-gi>
@@ -895,7 +895,7 @@ const radarChartOptions = {
class="stat-total-submission" class="stat-total-submission"
> >
<template #suffix> <template #suffix>
<Icon icon="streamline-emojis:paper" width="20" /> <Icon icon="streamline-ultimate-color:common-file-text" width="20" />
</template> </template>
</n-statistic> </n-statistic>
</n-gi> </n-gi>
@@ -907,7 +907,7 @@ const radarChartOptions = {
class="stat-ac-rate" class="stat-ac-rate"
> >
<template #suffix> <template #suffix>
<Icon icon="streamline-emojis:check-mark" width="20" /> <Icon icon="fluent-emoji:check-mark-button" width="20" />
</template> </template>
</n-statistic> </n-statistic>
</n-gi> </n-gi>
+1 -1
View File
@@ -55,7 +55,7 @@ const passwordFormVisible = computed(
</n-tag> </n-tag>
<Icon <Icon
v-if="contestStore.isPrivate" v-if="contestStore.isPrivate"
icon="streamline-emojis:locked-with-key" icon="streamline-ultimate-color:shield-lock"
:height="30" :height="30"
></Icon> ></Icon>
<h2 class="contestTitle">{{ contestStore.contest.title }}</h2> <h2 class="contestTitle">{{ contestStore.contest.title }}</h2>
+1 -1
View File
@@ -10,7 +10,7 @@ const router = useRouter()
const contestStore = useContestStore() const contestStore = useContestStore()
const problemsColumns: DataTableColumn<ProblemFiltered>[] = [ const problemsColumns: DataTableColumn<ProblemFiltered>[] = [
{ {
title: renderTableTitle("状态", "streamline-emojis:musical-note"), title: renderTableTitle("状态", "streamline-ultimate-color:music-note-1"),
key: "status", key: "status",
width: 100, width: 100,
render: (row) => h(ProblemStatus, { status: row.status }), render: (row) => h(ProblemStatus, { status: row.status }),
+1 -1
View File
@@ -75,7 +75,7 @@ const columns = ref<DataTableColumn<ContestRank>[]>([
{ {
title: renderTableTitle( title: renderTableTitle(
"正确数/总提交", "正确数/总提交",
"streamline-emojis:artist-palette", "streamline-ultimate-color:color-palette",
), ),
key: "submission", key: "submission",
width: 140, width: 140,
+29 -42
View File
@@ -49,7 +49,7 @@ const codeStore = useCodeStore()
const problemStore = useProblemStore() const problemStore = useProblemStore()
const { problem, languages } = storeToRefs(problemStore) const { problem, languages } = storeToRefs(problemStore)
const { isMobile, isDesktop } = useBreakpoints() const { isDesktop } = useBreakpoints()
const syncEnabled = ref(false) // 用户点击按钮后的意图状态(想要开启/关闭) const syncEnabled = ref(false) // 用户点击按钮后的意图状态(想要开启/关闭)
const statisticPanel = ref(false) const statisticPanel = ref(false)
@@ -65,12 +65,6 @@ const showSyncFeature = computed(
!isContestMode.value, !isContestMode.value,
) )
const menu = computed<DropdownOption[]>(() => [
{ label: "去自测猫", key: "goTestCat", show: isMobile.value },
{ label: "复制代码", key: "copy" },
{ label: "重置代码", key: "reset" },
])
const showGoSubmissionButton = computed(() => { const showGoSubmissionButton = computed(() => {
if (isContestMode.value) return true if (isContestMode.value) return true
else if (userStore.isAdminRole) return true else if (userStore.isAdminRole) return true
@@ -133,15 +127,6 @@ const goEdit = () => {
window.open(router.resolve(url).href, "_blank") window.open(router.resolve(url).href, "_blank")
} }
const handleMenuSelect = (key: string) => {
const actions: Record<string, () => void> = {
reset,
copy,
goTestCat,
}
actions[key]?.()
}
const toggleSync = () => { const toggleSync = () => {
syncEnabled.value = !syncEnabled.value syncEnabled.value = !syncEnabled.value
emit("toggleSync", syncEnabled.value) emit("toggleSync", syncEnabled.value)
@@ -174,41 +159,43 @@ onMounted(() => {
<SubmitCode v-else /> <SubmitCode v-else />
<n-button <IconButton
v-if="showGoSubmissionButton" v-if="showGoSubmissionButton"
:size="buttonSize" icon="streamline-ultimate-color:task-list-text-1"
tip="提交信息"
@click="goSubmissions" @click="goSubmissions"
> />
提交信息
</n-button>
<n-button <IconButton
v-if="userStore.isTeacherOrAbove" v-if="userStore.isTeacherOrAbove"
:size="buttonSize" icon="streamline-ultimate-color:analytics-pie-2"
tip="统计信息"
@click="statisticPanel = true" @click="statisticPanel = true"
> />
{{ isDesktop ? "统计信息" : "统计" }}
</n-button>
<n-button <template v-if="codeStore.code.language !== 'Flowchart'">
v-if="isDesktop && codeStore.code.language !== 'Flowchart'" <IconButton
icon="streamline-ultimate-color:business-lucky-cat"
tip="自测猫"
@click="goTestCat" @click="goTestCat"
> />
自测猫
</n-button>
<n-dropdown <IconButton
v-if="codeStore.code.language !== 'Flowchart'" icon="streamline-ultimate-color:copy-paste-1"
size="large" tip="复制代码"
:options="menu" @click="copy"
@select="handleMenuSelect" />
>
<n-button :size="buttonSize">操作</n-button> <IconButton
</n-dropdown> icon="streamline-ultimate-color:synchronize-arrow"
tip="重置代码"
@click="reset"
/>
</template>
<IconButton <IconButton
v-if="isDesktop && userStore.isSuperAdmin" v-if="isDesktop && userStore.isSuperAdmin"
icon="streamline-ultimate-color:file-code-edit" icon="streamline-ultimate-color:common-file-edit"
tip="编辑题目" tip="编辑题目"
@click="goEdit" @click="goEdit"
/> />
@@ -217,8 +204,8 @@ onMounted(() => {
<IconButton <IconButton
:icon=" :icon="
syncEnabled syncEnabled
? 'streamline-ultimate-color:flash-off' ? 'streamline-ultimate-color:wifi-off'
: 'streamline-ultimate-color:monitor-flash' : 'streamline-ultimate-color:wifi-signal-2'
" "
:tip="syncEnabled ? SYNC_MESSAGES.SYNC_ON : SYNC_MESSAGES.SYNC_OFF" :tip="syncEnabled ? SYNC_MESSAGES.SYNC_ON : SYNC_MESSAGES.SYNC_OFF"
:type="syncEnabled ? 'warning' : 'default'" :type="syncEnabled ? 'warning' : 'default'"
+3 -3
View File
@@ -18,7 +18,7 @@
> >
<Icon <Icon
v-if="hasCommented" v-if="hasCommented"
icon="noto:star" icon="fluent-emoji:star"
:width="24" :width="24"
v-for="(_, i) in description_rating" v-for="(_, i) in description_rating"
:key="i" :key="i"
@@ -35,7 +35,7 @@
> >
<Icon <Icon
v-if="hasCommented" v-if="hasCommented"
icon="noto:star" icon="fluent-emoji:star"
:width="24" :width="24"
v-for="(_, i) in difficulty_rating" v-for="(_, i) in difficulty_rating"
:key="i" :key="i"
@@ -50,7 +50,7 @@
> >
<Icon <Icon
v-if="hasCommented" v-if="hasCommented"
icon="noto:star" icon="fluent-emoji:star"
:width="24" :width="24"
v-for="(_, i) in difficulty_rating" v-for="(_, i) in difficulty_rating"
:key="i" :key="i"
+18 -8
View File
@@ -259,7 +259,7 @@ function type(status: ProblemStatus) {
</n-flex> </n-flex>
<p class="title" :style="style"> <p class="title" :style="style">
<n-flex align="center"> <n-flex align="center">
<Icon icon="streamline-emojis:sparkles"></Icon> <Icon icon="streamline-ultimate-color:checklist"></Icon>
描述 描述
</n-flex> </n-flex>
</p> </p>
@@ -271,7 +271,7 @@ function type(status: ProblemStatus) {
<p class="title" :style="style"> <p class="title" :style="style">
<n-flex align="center"> <n-flex align="center">
<Icon icon="streamline-emojis:four-leaf-clover"></Icon> <Icon icon="streamline-ultimate-color:envelope-back-front"></Icon>
输入 输入
</n-flex> </n-flex>
</p> </p>
@@ -283,7 +283,7 @@ function type(status: ProblemStatus) {
<p class="title" :style="style"> <p class="title" :style="style">
<n-flex align="center"> <n-flex align="center">
<Icon icon="streamline-emojis:herb"></Icon> <Icon icon="streamline-ultimate-color:mailbox-post"></Icon>
输出 输出
</n-flex> </n-flex>
</p> </p>
@@ -296,7 +296,7 @@ function type(status: ProblemStatus) {
<div v-if="problem.hint"> <div v-if="problem.hint">
<p class="title" :style="style"> <p class="title" :style="style">
<n-flex align="center"> <n-flex align="center">
<Icon icon="streamline-emojis:seedling"></Icon> <Icon icon="streamline-emojis:man-tipping-hand-1"></Icon>
提示 提示
</n-flex> </n-flex>
</p> </p>
@@ -311,7 +311,7 @@ function type(status: ProblemStatus) {
<div v-if="astRulesForDisplay.length > 0"> <div v-if="astRulesForDisplay.length > 0">
<p class="title" :style="style"> <p class="title" :style="style">
<n-flex align="center"> <n-flex align="center">
<Icon icon="streamline-emojis:open-book"></Icon> <Icon icon="streamline-ultimate-color:check-button"></Icon>
要求 要求
</n-flex> </n-flex>
</p> </p>
@@ -336,7 +336,12 @@ function type(status: ProblemStatus) {
<div v-for="(sample, index) of samples" :key="index"> <div v-for="(sample, index) of samples" :key="index">
<n-flex align="center"> <n-flex align="center">
<p class="title" :style="style">例子 {{ index + 1 }}</p> <p class="title" :style="style">
<n-flex align="center">
<Icon icon="streamline-emojis:microscope"></Icon>
例子 {{ index + 1 }}
</n-flex>
</p>
<n-button <n-button
size="small" size="small"
:type="type(sample.status)" :type="type(sample.status)"
@@ -375,7 +380,12 @@ function type(status: ProblemStatus) {
</div> </div>
<div v-if="problem.source"> <div v-if="problem.source">
<p class="title" :style="style">来源</p> <p class="title" :style="style">
<n-flex align="center">
<Icon icon="streamline-ultimate-color:book-open-bookmark"></Icon>
来源
</n-flex>
</p>
<MdPreview <MdPreview
preview-theme="vuepress" preview-theme="vuepress"
:model-value="problem.source" :model-value="problem.source"
@@ -388,7 +398,7 @@ function type(status: ProblemStatus) {
<n-divider /> <n-divider />
<p class="title" :style="style"> <p class="title" :style="style">
<n-flex align="center"> <n-flex align="center">
<Icon icon="fluent-emoji-flat:light-bulb"></Icon> <Icon icon="streamline-ultimate-color:like"></Icon>
相似题目推荐 相似题目推荐
</n-flex> </n-flex>
</p> </p>
+2 -2
View File
@@ -49,7 +49,7 @@ const data = computed(() => {
const numbers = computed(() => { const numbers = computed(() => {
return [ return [
{ {
icon: "streamline-emojis:scroll", icon: "streamline-ultimate-color:checklist",
title: problem.value?.submission_number ?? 0, title: problem.value?.submission_number ?? 0,
content: "总提交", content: "总提交",
int: true, int: true,
@@ -63,7 +63,7 @@ const numbers = computed(() => {
suffix: "", suffix: "",
}, },
{ {
icon: "emojione:chart-increasing", icon: "fluent-emoji:chart-increasing",
title: getACRateNumber( title: getACRateNumber(
problem.value?.accepted_number ?? 0, problem.value?.accepted_number ?? 0,
problem.value?.submission_number ?? 0, problem.value?.submission_number ?? 0,
+2 -2
View File
@@ -16,8 +16,8 @@ const color = computed(() => {
<template> <template>
<n-icon v-if="showIcon" :color="color"> <n-icon v-if="showIcon" :color="color">
<Icon icon="ep:select" v-if="status === 'passed'"></Icon> <Icon icon="ph:check" v-if="status === 'passed'"></Icon>
<Icon icon="ep:semi-select" v-if="status === 'failed'"></Icon> <Icon icon="ph:minus" v-if="status === 'failed'"></Icon>
</n-icon> </n-icon>
</template> </template>
@@ -31,7 +31,7 @@ function showCodePanel(id: string, problem: string) {
const columns: DataTableColumn<Submission>[] = [ const columns: DataTableColumn<Submission>[] = [
{ {
title: renderTableTitle("提交时间", "noto:seven-oclock"), title: renderTableTitle("提交时间", "fluent-emoji:seven-oclock"),
key: "create_time", key: "create_time",
width: 200, width: 200,
render: (row) => parseTime(row.create_time, "YYYY-MM-DD HH:mm:ss"), render: (row) => parseTime(row.create_time, "YYYY-MM-DD HH:mm:ss"),
@@ -79,7 +79,7 @@ const columns: DataTableColumn<Submission>[] = [
{ {
title: renderTableTitle( title: renderTableTitle(
"语言", "语言",
"streamline-emojis:globe-showing-europe-africa", "streamline-ultimate-color:earth-pin-2",
), ),
key: "language", key: "language",
width: 100, width: 100,
@@ -175,7 +175,7 @@ const columns: DataTableColumn<Submission["info"]["data"][number]>[] = [
<n-icon <n-icon
:color="rule.passed ? theme.successColor : theme.errorColor" :color="rule.passed ? theme.successColor : theme.errorColor"
> >
<Icon :icon="rule.passed ? 'ep:select' : 'ep:close-bold'" /> <Icon :icon="rule.passed ? 'ph:check' : 'ph:x-bold'" />
</n-icon> </n-icon>
<span>{{ rule.description }}</span> <span>{{ rule.description }}</span>
</n-flex> </n-flex>
+4 -4
View File
@@ -160,12 +160,12 @@ const baseColumns: DataTableColumn<ProblemFiltered>[] = [
render: (row) => h(ProblemStatus, { status: row.status }), render: (row) => h(ProblemStatus, { status: row.status }),
}, },
{ {
title: renderTableTitle("编号", "streamline-emojis:game-dice"), title: renderTableTitle("编号", "streamline-ultimate-color:board-game-dice-1"),
key: "_id", key: "_id",
width: 100, width: 100,
}, },
{ {
title: renderTableTitle("题目", "streamline-emojis:watermelon-2"), title: renderTableTitle("题目", "streamline-ultimate-color:fruit-watermelon"),
key: "title", key: "title",
minWidth: 200, minWidth: 200,
render: (row) => h(ProblemListTitle, { problem: row }), render: (row) => h(ProblemListTitle, { problem: row }),
@@ -178,7 +178,7 @@ const baseColumns: DataTableColumn<ProblemFiltered>[] = [
h(NTag, { type: getTagColor(row.difficulty) }, () => row.difficulty), h(NTag, { type: getTagColor(row.difficulty) }, () => row.difficulty),
}, },
{ {
title: renderTableTitle("标签", "streamline-emojis:paperclip"), title: renderTableTitle("标签", "streamline-ultimate-color:attachment"),
key: "tags", key: "tags",
width: 260, width: 260,
render: (row) => render: (row) =>
@@ -190,7 +190,7 @@ const baseColumns: DataTableColumn<ProblemFiltered>[] = [
width: 130, width: 130,
}, },
{ {
title: renderTableTitle("提交数", "streamline-emojis:writing-hand-2"), title: renderTableTitle("提交数", "streamline-ultimate-color:paper-write"),
key: "submission", key: "submission",
align: "center", align: "center",
width: 100, width: 100,
@@ -57,7 +57,7 @@ function handleJoin() {
<n-h2 style="margin: 0">{{ problemSet.title }}</n-h2> <n-h2 style="margin: 0">{{ problemSet.title }}</n-h2>
<n-tooltip trigger="hover" v-if="problemSet.description"> <n-tooltip trigger="hover" v-if="problemSet.description">
<template #trigger> <template #trigger>
<Icon width="20" icon="emojione:information" /> <Icon width="20" icon="fluent-emoji:information" />
</template> </template>
{{ problemSet.description }} {{ problemSet.description }}
</n-tooltip> </n-tooltip>
@@ -99,7 +99,7 @@ function handleJoin() {
</n-button> </n-button>
<n-tag v-else type="success" size="large"> <n-tag v-else type="success" size="large">
<template #icon> <template #icon>
<Icon icon="material-symbols:check-circle" /> <Icon icon="ph:check-circle-fill" />
</template> </template>
已加入 已加入
</n-tag> </n-tag>
@@ -40,7 +40,7 @@ function handleProblemClick(problemId: string) {
<Icon <Icon
style="margin-right: 10px" style="margin-right: 10px"
width="48" width="48"
icon="noto:check-mark-button" icon="fluent-emoji:check-mark-button"
v-if="problemSetProblem.is_completed" v-if="problemSetProblem.is_completed"
/> />
+7 -7
View File
@@ -221,13 +221,13 @@ const columns: DataTableColumn<Rank>[] = [
align: "center", align: "center",
}, },
{ {
title: renderTableTitle("提交数", "streamline-emojis:rocket"), title: renderTableTitle("提交数", "streamline-ultimate-color:space-rocket-earth"),
key: "submission_number", key: "submission_number",
width: 120, width: 120,
align: "center", align: "center",
}, },
{ {
title: renderTableTitle("正确率", "streamline-emojis:wrapped-gift-1"), title: renderTableTitle("正确率", "streamline-ultimate-color:gift-box-1"),
key: "rate", key: "rate",
width: 120, width: 120,
align: "center", align: "center",
@@ -606,7 +606,7 @@ watch(
class="stat-avg-ac" class="stat-avg-ac"
> >
<template #suffix> <template #suffix>
<Icon icon="streamline-emojis:chart" width="20" /> <Icon icon="streamline-ultimate-color:analytics-pie-2" width="20" />
</template> </template>
</n-statistic> </n-statistic>
</n-gi> </n-gi>
@@ -618,7 +618,7 @@ watch(
class="stat-median-ac" class="stat-median-ac"
> >
<template #suffix> <template #suffix>
<Icon icon="streamline-emojis:target" width="20" /> <Icon icon="streamline-ultimate-color:cursor-target-1" width="20" />
</template> </template>
</n-statistic> </n-statistic>
</n-gi> </n-gi>
@@ -630,7 +630,7 @@ watch(
class="stat-total-submission" class="stat-total-submission"
> >
<template #suffix> <template #suffix>
<Icon icon="streamline-emojis:paper" width="20" /> <Icon icon="streamline-ultimate-color:common-file-text" width="20" />
</template> </template>
</n-statistic> </n-statistic>
</n-gi> </n-gi>
@@ -642,7 +642,7 @@ watch(
class="stat-ac-rate" class="stat-ac-rate"
> >
<template #suffix> <template #suffix>
<Icon icon="streamline-emojis:check-mark" width="20" /> <Icon icon="fluent-emoji:check-mark-button" width="20" />
</template> </template>
</n-statistic> </n-statistic>
</n-gi> </n-gi>
@@ -747,7 +747,7 @@ watch(
@click="analyzeSingleClassWithAI" @click="analyzeSingleClassWithAI"
> >
<template #icon> <template #icon>
<Icon icon="mingcute:ai-line" /> <Icon icon="ph:sparkle" />
</template> </template>
AI分析 AI分析
</n-button> </n-button>
@@ -40,7 +40,7 @@ function filterClass() {
<template #trigger> <template #trigger>
<n-button text @click="filterClass"> <n-button text @click="filterClass">
<template #icon> <template #icon>
<Icon icon="openmoji:filter"></Icon> <Icon icon="ph:funnel"></Icon>
</template> </template>
</n-button> </n-button>
</template> </template>
@@ -11,7 +11,7 @@
@click="showLargeImage = true" @click="showLargeImage = true"
> >
<template #icon> <template #icon>
<Icon icon="mdi:fullscreen" /> <Icon icon="ph:corners-out" />
</template> </template>
查看大图 查看大图
</n-button> </n-button>
@@ -28,7 +28,7 @@
<div v-if="showLargeImage" class="fullscreen-toolbar"> <div v-if="showLargeImage" class="fullscreen-toolbar">
<n-button secondary round @click="showLargeImage = false"> <n-button secondary round @click="showLargeImage = false">
<template #icon> <template #icon>
<Icon icon="mdi:fullscreen-exit" /> <Icon icon="ph:corners-in" />
</template> </template>
退出大图 退出大图
</n-button> </n-button>
+4 -4
View File
@@ -230,7 +230,7 @@ watch(
const columns = computed(() => { const columns = computed(() => {
const res: DataTableColumn<SubmissionListItem>[] = [ const res: DataTableColumn<SubmissionListItem>[] = [
{ {
title: renderTableTitle("提交时间", "noto:seven-oclock"), title: renderTableTitle("提交时间", "fluent-emoji:seven-oclock"),
key: "create_time", key: "create_time",
minWidth: 200, minWidth: 200,
render: (row) => parseTime(row.create_time, "YYYY-MM-DD HH:mm:ss"), render: (row) => parseTime(row.create_time, "YYYY-MM-DD HH:mm:ss"),
@@ -269,7 +269,7 @@ const columns = computed(() => {
{ {
title: renderTableTitle( title: renderTableTitle(
"语言", "语言",
"streamline-emojis:globe-showing-europe-africa", "streamline-ultimate-color:earth-pin-2",
), ),
key: "language", key: "language",
minWidth: 120, minWidth: 120,
@@ -319,7 +319,7 @@ const columns = computed(() => {
const flowchartColumns = computed(() => { const flowchartColumns = computed(() => {
const res: DataTableColumn<FlowchartSubmissionListItem>[] = [ const res: DataTableColumn<FlowchartSubmissionListItem>[] = [
{ {
title: renderTableTitle("提交时间", "noto:seven-oclock"), title: renderTableTitle("提交时间", "fluent-emoji:seven-oclock"),
key: "create_time", key: "create_time",
render: (row) => parseTime(row.create_time, "YYYY-MM-DD HH:mm:ss"), render: (row) => parseTime(row.create_time, "YYYY-MM-DD HH:mm:ss"),
}, },
@@ -347,7 +347,7 @@ const flowchartColumns = computed(() => {
), ),
}, },
{ {
title: renderTableTitle("评分", "streamline-emojis:bar-chart"), title: renderTableTitle("评分", "streamline-ultimate-color:analytics-bars-3d"),
key: "ai_score", key: "ai_score",
render: (row) => h(Grade, { score: row.ai_score, grade: row.ai_grade }), render: (row) => h(Grade, { score: row.ai_score, grade: row.ai_grade }),
}, },
+1 -1
View File
@@ -10,7 +10,7 @@ defineProps<{ contest: Contest }>()
<Icon <Icon
v-if="contest.contest_type === ContestType.private" v-if="contest.contest_type === ContestType.private"
:height="24" :height="24"
icon="streamline-emojis:locked-with-key" icon="streamline-ultimate-color:shield-lock"
></Icon> ></Icon>
<span>{{ contest.title }}</span> <span>{{ contest.title }}</span>
</n-flex> </n-flex>
+2 -2
View File
@@ -6,8 +6,8 @@ defineProps<{ value: string }>()
const [copied, toggle] = useToggle() const [copied, toggle] = useToggle()
const { start } = useTimeoutFn(() => toggle(false), 1000, { immediate: false }) const { start } = useTimeoutFn(() => toggle(false), 1000, { immediate: false })
const COPY = h(Icon, { icon: "twemoji:clipboard" }) const COPY = h(Icon, { icon: "fluent-emoji:clipboard" })
const OK = h(Icon, { icon: "twemoji:check-mark-button" }) const OK = h(Icon, { icon: "fluent-emoji:check-mark-button" })
async function handleClick(value: string) { async function handleClick(value: string) {
const success = await copyToClipboard(value) const success = await copyToClipboard(value)
+15 -15
View File
@@ -120,47 +120,47 @@ const menus = computed<MenuOption[]>(() => [
{ {
label: () => h(RouterLink, { to: "/learn/01" }, { default: () => "自学" }), label: () => h(RouterLink, { to: "/learn/01" }, { default: () => "自学" }),
key: "learn", key: "learn",
icon: renderIcon("twemoji:books"), icon: renderIcon("fluent-emoji:books"),
}, },
{ {
label: () => h(RouterLink, { to: "/" }, { default: () => "题目" }), label: () => h(RouterLink, { to: "/" }, { default: () => "题目" }),
key: "problem", key: "problem",
icon: renderIcon("twemoji:memo"), icon: renderIcon("fluent-emoji:memo"),
}, },
{ {
label: () => label: () =>
h(RouterLink, { to: "/problemset" }, { default: () => "题单" }), h(RouterLink, { to: "/problemset" }, { default: () => "题单" }),
key: "problemset", key: "problemset",
icon: renderIcon("twemoji:clipboard"), icon: renderIcon("fluent-emoji:clipboard"),
}, },
{ {
label: () => label: () =>
h(RouterLink, { to: "/submission" }, { default: () => "提交" }), h(RouterLink, { to: "/submission" }, { default: () => "提交" }),
key: "submission", key: "submission",
icon: renderIcon("twemoji:inbox-tray"), icon: renderIcon("fluent-emoji:inbox-tray"),
show: userStore.showSubmissions, show: userStore.showSubmissions,
}, },
{ {
label: () => h(RouterLink, { to: "/contest" }, { default: () => "比赛" }), label: () => h(RouterLink, { to: "/contest" }, { default: () => "比赛" }),
key: "contest", key: "contest",
icon: renderIcon("twemoji:chequered-flag"), icon: renderIcon("fluent-emoji:chequered-flag"),
}, },
{ {
label: () => h(RouterLink, { to: "/rank" }, { default: () => "排名" }), label: () => h(RouterLink, { to: "/rank" }, { default: () => "排名" }),
key: "rank", key: "rank",
icon: renderIcon("twemoji:trophy"), icon: renderIcon("fluent-emoji:trophy"),
}, },
{ {
label: () => h(RouterLink, { to: "/class/pk" }, { default: () => "班级" }), label: () => h(RouterLink, { to: "/class/pk" }, { default: () => "班级" }),
show: false, show: false,
key: "class", key: "class",
icon: renderIcon("twemoji:crossed-swords"), icon: renderIcon("fluent-emoji:crossed-swords"),
}, },
{ {
label: () => label: () =>
h(RouterLink, { to: "/announcement" }, { default: () => "公告" }), h(RouterLink, { to: "/announcement" }, { default: () => "公告" }),
key: "announcement", key: "announcement",
icon: renderIcon("twemoji:loudspeaker"), icon: renderIcon("fluent-emoji:loudspeaker"),
}, },
{ {
label: () => label: () =>
@@ -171,7 +171,7 @@ const menus = computed<MenuOption[]>(() => [
), ),
show: userStore.isAdminRole, show: userStore.isAdminRole,
key: "admin", key: "admin",
icon: renderIcon("twemoji:gear"), icon: renderIcon("fluent-emoji:gear"),
}, },
]) ])
@@ -179,7 +179,7 @@ const options: Array<DropdownOption | DropdownDividerOption> = [
{ {
label: "我的主页", label: "我的主页",
key: "home", key: "home",
icon: renderIcon("streamline-emojis:newspaper"), icon: renderIcon("streamline-ultimate-color:newspaper-fold"),
props: { props: {
onClick: () => router.push("/user"), onClick: () => router.push("/user"),
}, },
@@ -196,7 +196,7 @@ const options: Array<DropdownOption | DropdownDividerOption> = [
{ {
label: "我的提交", label: "我的提交",
key: "status", key: "status",
icon: renderIcon("streamline-emojis:bar-chart"), icon: renderIcon("streamline-ultimate-color:analytics-bars-3d"),
props: { props: {
onClick: () => router.push("/submission?myself=1"), onClick: () => router.push("/submission?myself=1"),
}, },
@@ -221,7 +221,7 @@ const options: Array<DropdownOption | DropdownDividerOption> = [
{ {
label: "退出", label: "退出",
key: "logout", key: "logout",
icon: renderIcon("streamline-emojis:hot-beverage-2"), icon: renderIcon("streamline-ultimate-color:coffee-cold"),
props: { onClick: handleLogout }, props: { onClick: handleLogout },
}, },
] ]
@@ -263,7 +263,7 @@ function handleMenuSelect(key: string) {
@select="handleMenuSelect" @select="handleMenuSelect"
> >
<n-button> <n-button>
<Icon icon="twemoji:artist-palette" height="20"></Icon> <Icon icon="fluent-emoji:artist-palette" height="20"></Icon>
<span style="padding-left: 8px">菜单</span> <span style="padding-left: 8px">菜单</span>
</n-button> </n-button>
</n-dropdown> </n-dropdown>
@@ -304,8 +304,8 @@ function handleMenuSelect(key: string) {
</div> </div>
<n-button :bordered="false" circle @click="toggleDark"> <n-button :bordered="false" circle @click="toggleDark">
<template #icon> <template #icon>
<Icon v-if="isDark" icon="twemoji:sun-behind-small-cloud"></Icon> <Icon v-if="isDark" icon="fluent-emoji:sun-behind-small-cloud"></Icon>
<Icon v-else icon="twemoji:cloud-with-lightning-and-rain"></Icon> <Icon v-else icon="fluent-emoji:cloud-with-lightning-and-rain"></Icon>
</template> </template>
</n-button> </n-button>
</n-flex> </n-flex>
+1 -1
View File
@@ -1,7 +1,7 @@
<template> <template>
<n-tooltip> <n-tooltip>
<template #trigger> <template #trigger>
<n-button circle :type="type ?? 'default'" @click="$emit('click')"> <n-button round :type="type ?? 'default'" @click="$emit('click')">
<template #icon> <template #icon>
<Icon :icon="icon" /> <Icon :icon="icon" />
</template> </template>