From 10d2638c23eadd1ae9ce95b91a9aaff808cf951a Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Tue, 13 Oct 2026 14:53:38 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E9=A6=96=E9=A1=B5):=20=E5=AD=A6=E7=94=9F?= =?UTF-8?q?=E4=B8=8A=E8=AF=BE=E6=97=B6=E9=A6=96=E9=A1=B5=E6=9C=80=E4=B8=8A?= =?UTF-8?q?=E9=9D=A2=E5=B0=B1=E6=98=AF=E8=BF=99=E8=8A=82=E8=AF=BE=E5=92=8C?= =?UTF-8?q?=E3=80=8C=E6=8E=A5=E7=9D=80=E5=81=9A=E3=80=8D=EF=BC=8C=E8=AF=BE?= =?UTF-8?q?=E5=90=8E=E5=85=88=E7=9C=8B=E4=B8=8A=E6=AC=A1=E6=B2=A1=E5=81=9A?= =?UTF-8?q?=E5=AE=8C=E7=9A=84=EF=BC=9B=E8=80=81=E5=B8=88=E6=9C=89=E4=BA=86?= =?UTF-8?q?=E8=87=AA=E5=B7=B1=E7=9A=84=E9=A6=96=E9=A1=B5=EF=BC=8C=E7=9C=8B?= =?UTF-8?q?=E4=BB=8A=E5=A4=A9=E5=93=AA=E4=BA=9B=E7=8F=AD=E5=9C=A8=E4=B8=8A?= =?UTF-8?q?=E8=AF=BE=E3=80=81=E7=82=B9=E8=BF=9B=E8=AF=BE=E5=A0=82=E7=9C=8B?= =?UTF-8?q?=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 去掉和顶栏重复的找题框、常年空着的比赛卡、底部快捷入口,公告只留置顶那条。 修了当天上午上课、下午再登录时写「上次(今天的日期)还有几道没过」。 Co-Authored-By: Claude Opus 5.5 --- apps/web/src/oj/api.ts | 6 + apps/web/src/oj/home/TeacherHome.vue | 313 ++++++++++++++++++++++++ apps/web/src/oj/home/dashboard.vue | 344 ++++++++++++--------------- apps/web/src/oj/home/index.vue | 8 +- 4 files changed, 480 insertions(+), 191 deletions(-) create mode 100644 apps/web/src/oj/home/TeacherHome.vue 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) {