refactor(课堂任务): 「课堂看板」改名「课堂任务」,地址换成 /task;班级 PK 换成 /pk

- 界面上的「课堂看板」「课堂作业」统一叫「课堂任务」,顶栏、老师首页、后台菜单一起改
- 前端 oj/classroom → oj/task、oj/class → oj/pk,两个名字不再只差几个字母却毫不相干;旧地址不留跳转
- 后端 routes/classroom.ts 拆开:课堂任务的接口进 routes/task.ts(/task/board|lesson|today),
  首页的「上次来」「班里在做」进 routes/home.ts;共用的取题口径挪进 services/lesson.ts
- 契约 classroom.ts 同样拆成 task.ts / home.ts,ClassBoard* 改叫 TaskBoard*

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-11-02 22:53:07 +08:00
1 parent 46d3fe2dbe
commit 29c31640b5
82 files changed
+798 -766

No files matched your search

+1 -1
View File
@@ -780,7 +780,7 @@ export function deleteAchievement(id: number) {
return api.delete(`admin/achievements/${id}`)
}
// ---------- 课堂作业(class_lesson) ----------
// ---------- 课堂任务(class_lesson) ----------
export function getAdminLessons(offset: number, limit: number, filters: { className: string; teacher: number | null }) {
return api.get<AdminLessonList>('admin/lessons', {
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { Icon } from '@iconify/vue'
import { LESSON_MODE_LABEL, lessonNeeds, type AdminLesson, type LessonLanguage, type LessonMode } from '@oj2/contract'
import ProblemPicker from 'oj/classroom/components/ProblemPicker.vue'
import ProblemPicker from 'oj/task/components/ProblemPicker.vue'
import { useConfigStore } from 'shared/store/config'
import { errorMessage } from 'utils/api'
import { groupClassOptions } from 'utils/classes'
@@ -10,8 +10,8 @@ import { parseTime } from 'utils/functions'
import { createAdminLesson, updateAdminLesson } from '../../api'
/**
* 后台改一节 / 补一节。改的时候班级、日子、时刻都能动 —— 看板上点错了班、隔天才想起来布置,
* 都在这里纠正;补的是看板外上的课,补了数据统计才认得到。题号可以敲,也可以点「选题」挑
* 后台改一节 / 补一节。改的时候班级、日子、时刻都能动 —— 任务页上点错了班、隔天才想起来布置,
* 都在这里纠正;补的是任务页外上的课,补了数据统计才认得到。题号可以敲,也可以点「选题」挑
*/
const props = defineProps<{
/** null = 补一节 */
@@ -54,7 +54,7 @@ function inputIds() {
return idsInput.value.split(/[\s,,、;;]+/).filter(Boolean)
}
// ---- 选题弹框,和看板上那个是同一个 ----
// ---- 选题弹框,和任务页上那个是同一个 ----
const picking = ref(false)
const pickerInitial = ref<{ id: string; title?: string }[]>([])
function openPicker() {
+4 -4
View File
@@ -17,8 +17,8 @@ import { deleteAdminLesson, getAdminLessons } from '../api'
import LessonEditModal from './components/LessonEditModal.vue'
/**
* 后台「课堂作业」:布置过的每一节课一行,新的在前。课堂看板上当场布置的都在这里,
* 布置错了能改、删;看板外上的课能补一节 —— 数据统计按布置切课,补了才认得到
* 后台「课堂任务」:布置过的每一节课一行,新的在前。课堂任务上当场布置的都在这里,
* 布置错了能改、删;任务页外上的课能补一节 —— 数据统计按布置切课,补了才认得到
*/
const router = useRouter()
const message = useMessage()
@@ -26,7 +26,7 @@ const theme = useThemeVars()
const configStore = useConfigStore()
const { isMobile } = useBreakpoints()
// 从看板「布置过的课」进来带着 ?className=
// 从任务页「布置过的课」进来带着 ?className=
const { query } = usePagination<{ className: string; teacher: string }>({
className: useRouteQuery('className', '').value,
teacher: useRouteQuery('teacher', '').value,
@@ -163,7 +163,7 @@ const columns = computed(() => (isMobile.value ? mobileColumns : desktopColumns)
</script>
<template>
<PageHeader title="课堂作业">
<PageHeader title="课堂任务">
<template #extra>
<n-text v-if="data" depth="3">{{ data.total }} 节</n-text>
</template>
+2 -2
View File
@@ -94,7 +94,7 @@ const shortcuts = [
{ label: '新建题目', to: '/admin/problem/create' },
{ label: '新建比赛', to: '/admin/contest/create' },
{ label: '批量建号', to: '/admin/user/generate' },
{ label: '课堂看板', to: '/classroom' },
{ label: '课堂任务', to: '/task' },
]
// ---------------------------------------------------------------- 抽一个人
@@ -170,7 +170,7 @@ onUnmounted(stopRolling)
<div class="tile">
<span class="label">正在上课</span>
<b>{{ info.activeClass ? classLabel(info.activeClass) : '没有' }}</b>
<router-link v-if="info.activeClass" class="link" :to="{ name: 'classroom board', query: { className: info.activeClass } }"> 去课堂看板 → </router-link>
<router-link v-if="info.activeClass" class="link" :to="{ name: 'task', query: { className: info.activeClass } }"> 去课堂任务 → </router-link>
<span v-else class="note">最近两小时没有哪个班在交题</span>
</div>
</div>