Compare commits
3 Commits
2da0d098b9
...
a4bd4fcd13
| Author | SHA1 | Date | |
|---|---|---|---|
| a4bd4fcd13 | |||
| 1d285c8694 | |||
| 4261bae104 |
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 }),
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
@click="goTestCat"
|
icon="streamline-ultimate-color:business-lucky-cat"
|
||||||
>
|
tip="自测猫"
|
||||||
自测猫
|
@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'"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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 }),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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,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>
|
||||||
|
|||||||
Reference in New Issue
Block a user