feat(统计): 没填班级的学生也能和班级一样看——班级下拉多一项「没填班级」,一起上的课能切出来、点进去看小方块;零散提交也能点了
- 班级筛选多一个取值 NO_CLASS("none"),统计、方块串、流程图、提交列表都认;只圈普通学生, 老师管理员的号本来就不填班级,不挡的话试题的提交会算进去 - 切课时没填班级的号合在一起当一个班切(原来 class_name is null 直接排除,7 月 4 日那两节课看不到) - 没填班级不是真班:不列「还没交」,课上只写几人不写几人之几 - 「另有零散提交」每一项可点,进那个班那一整天 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c2ef55b10b
commit
923f3efeca
10 files changed
+153
-66
No files matched your search
@@ -1,11 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { Icon } from "@iconify/vue"
|
||||
import { useThemeVars } from "naive-ui"
|
||||
import type {
|
||||
FlowchartStatistics,
|
||||
SubmissionLessons,
|
||||
SubmissionStatistics,
|
||||
SubmissionStatisticsGrid,
|
||||
import {
|
||||
NO_CLASS,
|
||||
type FlowchartStatistics,
|
||||
type SubmissionLessons,
|
||||
type SubmissionStatistics,
|
||||
type SubmissionStatisticsGrid,
|
||||
} from "@oj2/contract"
|
||||
import {
|
||||
getFlowchartStatistics,
|
||||
@@ -16,8 +17,8 @@ import {
|
||||
import { useConfigStore } from "shared/store/config"
|
||||
import { fromPickerValue, toPickerValue } from "utils/functions"
|
||||
import { useTone } from "oj/submission/composables/tone"
|
||||
import { classLabel } from "oj/submission/utils"
|
||||
import { DEFAULT_PERIOD, PERIOD_OPTIONS, periodRange, type Period } from "../period"
|
||||
import { classSelectOptions } from "oj/submission/utils"
|
||||
import { DEFAULT_PERIOD, PERIOD_OPTIONS, dayStartOfDate, periodRange, type Period } from "../period"
|
||||
import { resultName, useResultColor } from "../results"
|
||||
import ByClass from "./ByClass.vue"
|
||||
import CodeStats from "./CodeStats.vue"
|
||||
@@ -106,11 +107,9 @@ function pickDates(value: [number, number] | null) {
|
||||
/** 学生框:包含匹配。班级另外单独传(按 class_name 精确匹配,见后端 scopedUsers) */
|
||||
const studentParam = computed(() => username.value.trim())
|
||||
|
||||
const classOptions = computed(() => {
|
||||
const list = configStore.config?.classList ?? []
|
||||
const all = className.value && !list.includes(className.value) ? [className.value, ...list] : list
|
||||
return all.map((item) => ({ label: classLabel(item), value: item }))
|
||||
})
|
||||
const classOptions = computed(() =>
|
||||
classSelectOptions(configStore.config?.classList ?? [], className.value),
|
||||
)
|
||||
|
||||
// ---------- 取数 ----------
|
||||
|
||||
@@ -306,7 +305,7 @@ function pickClass(value: string) {
|
||||
/** 点一节课:这个班、这节课的题、这节课第一条到最后一条(多留 1 秒:库里存到微秒,转成毫秒会截掉零头) */
|
||||
function pickLesson(lesson: SubmissionLessons["lessons"][number]) {
|
||||
remember()
|
||||
className.value = lesson.className
|
||||
className.value = lesson.className ?? NO_CLASS
|
||||
username.value = ""
|
||||
problem.value = lesson.problems.join(" ")
|
||||
from.value = String(Date.parse(lesson.start))
|
||||
@@ -314,6 +313,18 @@ function pickLesson(lesson: SubmissionLessons["lessons"][number]) {
|
||||
period.value = "lesson"
|
||||
}
|
||||
|
||||
/** 点某天的零散提交:这个班(或没填班级的)那一整天,题号不限 —— 补做、课后练的都在里面 */
|
||||
function pickScattered(item: SubmissionLessons["scattered"][number]) {
|
||||
remember()
|
||||
className.value = item.className ?? NO_CLASS
|
||||
username.value = ""
|
||||
problem.value = ""
|
||||
const day = String(dayStartOfDate(item.day))
|
||||
from.value = day
|
||||
to.value = day
|
||||
period.value = "custom"
|
||||
}
|
||||
|
||||
/** 点「错得最多的题」里的一道:只看这道,按班级汇总 */
|
||||
function pickProblem(displayId: string) {
|
||||
remember()
|
||||
@@ -478,6 +489,7 @@ function resultWidth(value: number) {
|
||||
:timeline="shown.withinToday"
|
||||
:loading-more="loadingMore"
|
||||
@pick="pickLesson"
|
||||
@scattered="pickScattered"
|
||||
@problem="pickProblem"
|
||||
@more="loadMore"
|
||||
/>
|
||||
|
||||
Reference in new issue
Block a user