feat(前台): 各页直达后台对应功能——编辑这一课、新建比赛、编辑这条公告……
Deploy / deploy (push) Canceled after 0s

题目页「编辑题目」从只给超管放宽到有权改这道题的人(含学生管理员改自己出的题);
题目、比赛、题单列表加「新建」;自学首页加「自学情况」「管理教程」,课文加「编辑这一课」;
公告加「编辑这条」「发公告」;成就加「管理成就」;智能分析加「AI 报告」,看某个学生时
带着用户名过去直接筛到他。按钮统一走 shared/components/AdminLink.vue。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-10-15 14:02:29 +08:00
1 parent e7b6e27b85
commit 0ffc405a20
12 files changed
+140 -3

No files matched your search

@@ -0,0 +1,19 @@
<script setup lang="ts">
import { RouterLink, type RouteLocationRaw } from "vue-router"
/**
* 前台页面上直达后台对应功能的按钮(「编辑这一课」「新建比赛」……),和题单页的
* 「编辑题单」、比赛页的「比赛设置」同一种样子。渲染成真的 <a>:老师常要一边看前台
* 一边改,中键 / Ctrl 点开新标签页得能用。给谁看由调用方用 v-if 管,要和
* routes.ts 里目标路由的 meta 对齐,否则点下去被守卫静默踢回首页。
*/
withDefaults(defineProps<{ to: RouteLocationRaw; size?: "tiny" | "small" | "medium" }>(), {
size: "medium",
})
</script>
<template>
<RouterLink v-slot="{ href, navigate }" :to="to" custom>
<n-button tag="a" :href="href" :size="size" @click="navigate"><slot /></n-button>
</RouterLink>
</template>
+17
View File
@@ -49,6 +49,22 @@ export const useUserStore = defineStore("user", () => {
const canToggleDemoMode = computed(() => realIsSuperAdmin.value)
/**
* 前台「编辑题目」入口给谁看,对齐后端 admin/problem.ts 的 canEdit:
* 公开题看题目的创建者(或题目权限是「全部」),比赛题看比赛的创建者。
* 题目页拿不到比赛的创建者,比赛题就按题目的创建者估 —— 比赛题基本是出题老师
* 自己建或克隆的;估错了后台会拦,只是多一个点进去 404 的入口。
*/
function canEditProblem(problem: { contestId: number | null; createdBy: { id: number } }) {
if (isSuperAdmin.value) return true
const mine = problem.createdBy.id === user.value?.id
if (problem.contestId !== null) return isTeacherOrAbove.value && mine
return (
hasProblemPermission.value &&
(mine || user.value?.problemPermission === PROBLEM_PERMISSION.ALL)
)
}
function toggleDemoMode() {
demoSwitch.value = !demoSwitch.value
storage.set(STORAGE_KEY.DEMO_MODE, demoSwitch.value)
@@ -124,6 +140,7 @@ export const useUserStore = defineStore("user", () => {
hasProblemPermission,
demoMode,
canToggleDemoMode,
canEditProblem,
toggleDemoMode,
isAuthed,
showSubmissions,