update
Some checks failed
Deploy / deploy (push) Has been cancelled

This commit is contained in:
2025-10-23 16:52:34 +08:00
parent 0a31cc3d2f
commit 67dce91dbe

View File

@@ -44,10 +44,6 @@ function getDifficultyTag(difficulty: string) {
return difficultyMap[difficulty] || { type: "default", text: "未知" } return difficultyMap[difficulty] || { type: "default", text: "未知" }
} }
function goToProblem(problemId: string) {
router.push(`/problemset/${problemSetId.value}/problem/${problemId}`)
}
function getProgressPercentage() { function getProgressPercentage() {
if (!problemSet.value) return 0 if (!problemSet.value) return 0
return Math.round( return Math.round(
@@ -120,118 +116,117 @@ onMounted(init)
</script> </script>
<template> <template>
<div v-if="problemSet"> <n-card v-if="problemSet" style="margin-bottom: 24px">
<!-- 题单信息头部 --> <n-flex justify="space-between" align="center">
<n-card style="margin-bottom: 24px"> <n-flex align="center">
<n-flex justify="space-between" align="center"> <n-tag type="warning" v-if="problemSet.status === 'archived'">
<n-flex align="center"> 已归档
<n-tag type="warning" v-if="problemSet.status === 'archived'"> </n-tag>
已归档 <n-tag :type="getDifficultyTag(problemSet.difficulty).type">
</n-tag> {{ getDifficultyTag(problemSet.difficulty).text }}
<n-tag :type="getDifficultyTag(problemSet.difficulty).type"> </n-tag>
{{ getDifficultyTag(problemSet.difficulty).text }} <n-h2 style="margin: 0">{{ problemSet.title }}</n-h2>
</n-tag> <n-tooltip trigger="hover" v-if="problemSet.description">
<n-h2 style="margin: 0">{{ problemSet.title }}</n-h2> <template #trigger>
<n-tooltip trigger="hover" v-if="problemSet.description"> <Icon width="20" icon="emojione:information" />
<template #trigger> </template>
<Icon width="20" icon="emojione:information" /> {{ problemSet.description }}
</template> </n-tooltip>
{{ problemSet.description }}
</n-tooltip>
</n-flex>
<n-flex align="center">
<!-- 用户徽章显示区域 - 只在已加入且有徽章时显示 -->
<n-flex v-if="isJoined && userBadges.length > 0" align="center">
<n-text>已获徽章</n-text>
<UserBadge
v-for="badge in userBadges"
:key="badge.id"
:badge="badge"
/>
</n-flex>
<!-- 完成进度 - 只在已加入时显示 -->
<n-flex align="center" v-if="isJoined">
<n-text strong>完成进度</n-text>
<n-text>
{{ problemSet.completed_count }} / {{ problemSet.problems_count }}
</n-text>
</n-flex>
<n-progress
v-if="isJoined"
:percentage="getProgressPercentage()"
:height="8"
:border-radius="4"
style="width: 200px"
/>
<n-button
v-if="!isJoined"
type="primary"
size="large"
:loading="isJoining"
@click="handleJoinProblemSet"
>
加入题单
</n-button>
<n-tag v-else type="success" size="large">
<template #icon>
<Icon icon="material-symbols:check-circle" />
</template>
已加入
</n-tag>
</n-flex>
</n-flex> </n-flex>
</n-card>
<!-- 题目列表 --> <n-flex align="center">
<n-grid :cols="isDesktop ? 4 : 1" :x-gap="16" :y-gap="16"> <!-- 用户徽章显示区域 - 只在已加入且有徽章时显示 -->
<n-grid-item <n-flex v-if="isJoined && userBadges.length > 0" align="center">
v-for="(problemSetProblem, index) in problems" <n-text>已获徽章</n-text>
:key="problemSetProblem.id" <UserBadge
> v-for="badge in userBadges"
<n-card :key="badge.id"
hoverable :badge="badge"
@click="handleProblemClick(problemSetProblem.problem._id)" />
style="cursor: pointer" </n-flex>
<!-- 完成进度 - 只在已加入时显示 -->
<n-flex align="center" v-if="isJoined">
<n-text strong>完成进度</n-text>
<n-text>
{{ problemSet.completed_count }} / {{ problemSet.problems_count }}
</n-text>
</n-flex>
<n-progress
v-if="isJoined"
:percentage="getProgressPercentage()"
:height="8"
:border-radius="4"
style="width: 200px"
/>
<n-button
v-if="!isJoined"
type="primary"
size="large"
:loading="isJoining"
@click="handleJoinProblemSet"
> >
<n-flex align="center"> 加入题单
<Icon </n-button>
style="margin-right: 12px" <n-tag v-else type="success" size="large">
width="50" <template #icon>
icon="noto:check-mark-button" <Icon icon="material-symbols:check-circle" />
v-if="problemSetProblem.is_completed" </template>
/> 已加入
</n-tag>
</n-flex>
</n-flex>
</n-card>
<n-grid v-if="problemSet" :cols="isDesktop ? 4 : 1" :x-gap="16" :y-gap="16">
<n-grid-item
v-for="(problemSetProblem, index) in problems"
:key="problemSetProblem.id"
>
<n-card
hoverable
@click="handleProblemClick(problemSetProblem.problem._id)"
style="cursor: pointer"
>
<n-flex align="center">
<Icon
style="margin-right: 12px"
width="50"
icon="noto:check-mark-button"
v-if="problemSetProblem.is_completed"
/>
<n-flex vertical style="flex: 1"> <n-flex vertical style="flex: 1">
<n-flex align="center"> <n-flex align="center">
<n-h4 style="margin: 0">#{{ index + 1 }}</n-h4> <n-h4 style="margin: 0">#{{ index + 1 }}</n-h4>
<n-h4 style="margin: 0">
{{ problemSetProblem.problem.title }}
</n-h4>
</n-flex>
<n-h4 style="margin: 0"> <n-flex align="center" size="small">
{{ problemSetProblem.problem.title }} <n-tag
</n-h4> :type="getTagColor(problemSetProblem.problem.difficulty)"
</n-flex> size="small"
>
<n-flex align="center" size="small"> {{ DIFFICULTY[problemSetProblem.problem.difficulty] }}
<n-tag </n-tag>
:type="getTagColor(problemSetProblem.problem.difficulty)" <n-text type="info"> 分数{{ problemSetProblem.score }} </n-text>
size="small" <n-text v-if="!problemSetProblem.is_required"> 选做 </n-text>
>
{{ DIFFICULTY[problemSetProblem.problem.difficulty] }}
</n-tag>
<n-text type="info">
分数{{ problemSetProblem.score }}
</n-text>
<n-text v-if="!problemSetProblem.is_required">
选做
</n-text>
</n-flex>
</n-flex> </n-flex>
</n-flex> </n-flex>
</n-card> </n-flex>
</n-grid-item> </n-card>
</n-grid> </n-grid-item>
</n-grid>
<div class="tip">
<n-text :deep="3">* 题目完成后会自动返回题单页面</n-text>
</div> </div>
</template> </template>
<style scoped></style> <style scoped>
.tip {
padding: 24px;
text-align: center;
}
</style>