diff --git a/apps/web/src/oj/api.ts b/apps/web/src/oj/api.ts index f26f560..05842f5 100644 --- a/apps/web/src/oj/api.ts +++ b/apps/web/src/oj/api.ts @@ -13,6 +13,7 @@ import { type TutorialSummary, type Tutorial, type ClassActivity, + type ClassToday, type LastVisit, type ClassBoard, type ClassLesson, @@ -305,6 +306,11 @@ export function getClassActivity() { return api.get("me/class-activity") } +/** 老师首页「今天的课」:今天在上课的每个班 */ +export function getClassToday() { + return api.get("classroom/today") +} + /** 首页「上次来」卡:上次登录到这次登录之间交过什么、哪道还没做对 */ export function getLastVisit() { return api.get("me/last-visit") diff --git a/apps/web/src/oj/home/TeacherHome.vue b/apps/web/src/oj/home/TeacherHome.vue new file mode 100644 index 0000000..cae9ecc --- /dev/null +++ b/apps/web/src/oj/home/TeacherHome.vue @@ -0,0 +1,313 @@ + + + + + diff --git a/apps/web/src/oj/home/dashboard.vue b/apps/web/src/oj/home/dashboard.vue index d37bec6..69619a2 100644 --- a/apps/web/src/oj/home/dashboard.vue +++ b/apps/web/src/oj/home/dashboard.vue @@ -15,7 +15,6 @@ import { } from "oj/api" import SubmissionResultTag from "shared/components/SubmissionResultTag.vue" import { useBreakpoints } from "shared/composables/breakpoints" -import { useProblemJump } from "shared/composables/problemJump" import { pickHeadline, type Headline } from "oj/user/knowledge" import { useUserStore } from "shared/store/user" import { ContestStatus, CONTEST_STATUS, JUDGE_STATUS, LANGUAGE_SHOW_VALUE } from "utils/constants" @@ -56,7 +55,6 @@ const lastVisit = ref(null) /** 知识点地图挑出来的那一句(本周升级 / 再做几道升档 / 去点亮一个),见 oj/user/knowledge.ts */ const knowledgeHeadline = ref(null) const loaded = ref(false) -const keyword = ref("") /** 头一回登录、还没交过:问候换成「欢迎」,告诉他题在哪找 */ const firstVisit = computed( @@ -151,9 +149,10 @@ async function loadSubmissions() { submissions.value = res.results } +/** 首页只放置顶的公告(用户定的),其余从顶栏「公告」进 */ async function loadAnnouncements() { - const res = await getAnnouncementList(0, 4) - announcements.value = res.results + const res = await getAnnouncementList(0, 10) + announcements.value = res.results.filter((item) => item.top) } async function loadKnowledge() { @@ -216,6 +215,24 @@ const classSummaryText = computed(() => { : `那天班里一起做了 ${problems.length} 道,你做对了 ${done} 道` }) +/** + * 「上次还有 N 道没过」那一句:上次来就是今天(上午上课、下午又登录)时不说 —— + * 原来照样写「上次(10月13日)」,和今天是同一天 + */ +const visitBeforeToday = computed( + () => + !!lastVisit.value?.previousLogin && + dayKey(lastVisit.value.previousLogin) !== dayKey(new Date()), +) + +/** 这节课下一道没做对的:卡底「接着做」那个大按钮 */ +const nextProblem = computed( + () => classActivity.value?.problems.find((item) => item.myStatus !== "accepted") ?? null, +) +const doneInClass = computed( + () => classActivity.value?.problems.filter((item) => item.myStatus === "accepted").length ?? 0, +) + const solvedText = computed(() => (visit.value?.solved ?? []).map((item) => `${item.problemDisplayId} ${item.title}`).join("、"), ) @@ -227,9 +244,9 @@ const classActivityTitle = computed(() => { // 老师在课堂看板布置的,说成「老师布置的」,比「班里在做」更让人知道该做这几道 if (classActivity.value?.source === "teacher") { const language = classActivity.value.language - return `今天老师布置的题${language ? ` · 用${LANGUAGE_SHOW_VALUE[language]}做` : ""}` + return `这节课${language ? ` · 用${LANGUAGE_SHOW_VALUE[language]}做` : ""}` } - if (classToday.value) return "今天班里在做" + if (classToday.value) return "这节课" const [, month, date] = day.split("-").map(Number) return `${month}月${date}日班里做了` }) @@ -238,9 +255,9 @@ const MY_STATUS: Record< ClassActivityProblem["myStatus"], { label: string; type: "success" | "warning" | "default" } > = { - accepted: { label: "已通过", type: "success" }, - tried: { label: "未通过", type: "warning" }, - none: { label: "没做", type: "default" }, + accepted: { label: "已做对", type: "success" }, + tried: { label: "没做对", type: "warning" }, + none: { label: "还没做", type: "default" }, } async function loadWeekly() { @@ -272,8 +289,6 @@ function learnLink(track: Track) { return lessonPath(track.type, track.step) } -const { jump, jumping } = useProblemJump() - function openSubmission(row: SubmissionListItem) { if (row.showLink) router.push(`/submission/${row.id}`) else router.push(`/problem/${row.problemDisplayId}`) @@ -313,45 +328,87 @@ async function openAnnouncement(item: AnnouncementListItem) {