现有 38 个成就全是累计量(通过几题、提交几次、连续几天),起步的人人都有、往上的够不着, 而且没有一个在说「你学会了什么」。连续打卡在这里结构上做不到:2025 秋学生最长连续交题 天数的中位数是 1 天,连续 7 天的只有 3 人。 - GET /me/knowledge:题数 ≥10 的知识点标签(10 个),每个给做对几道、档位、周一时的档位、 下一档门槛;四档 入门 1 / 会了 3 / 熟练 题数 40%(≤10)/ 精通 75%(≤20)。 回测 2025 秋:中位数学生一学期升 5 档;「入门」一档是给只做对一两道的 71 人加的 - 同班 ≥30% 点亮过的知识点才会出现在「还没碰过」里,免得 Python 班看到「C 语言」 - 个人主页加「我的知识点」,只在看自己时显示;首页一句话:本周升级 > 离下一档最近的 > 去点亮一个班里在学的,点了去按知识点筛的题目列表 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a63bf6ea07
commit
a7f6ebaf49
8 files changed
+446
No files matched your search
@@ -4,6 +4,7 @@ import {
|
||||
getAnnouncement,
|
||||
getAnnouncementList,
|
||||
getClassActivity,
|
||||
getKnowledgeMap,
|
||||
getContestList,
|
||||
getLearnProgress,
|
||||
getSubmissions,
|
||||
@@ -13,6 +14,7 @@ import {
|
||||
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 } from "utils/constants"
|
||||
import { duration, parseTime, zonedParts } from "utils/functions"
|
||||
@@ -49,6 +51,8 @@ const submissions = ref<SubmissionListItem[]>([])
|
||||
const announcements = ref<AnnouncementListItem[]>([])
|
||||
const weekly = ref<WeeklyRank | null>(null)
|
||||
const classActivity = ref<ClassActivity | null>(null)
|
||||
/** 知识点地图挑出来的那一句(本周升级 / 再做几道升档 / 去点亮一个),见 oj/user/knowledge.ts */
|
||||
const knowledgeHeadline = ref<Headline | null>(null)
|
||||
const loaded = ref(false)
|
||||
const keyword = ref("")
|
||||
|
||||
@@ -121,6 +125,10 @@ async function loadAnnouncements() {
|
||||
announcements.value = res.results
|
||||
}
|
||||
|
||||
async function loadKnowledge() {
|
||||
knowledgeHeadline.value = pickHeadline(await getKnowledgeMap())
|
||||
}
|
||||
|
||||
async function loadClassActivity() {
|
||||
classActivity.value = await getClassActivity()
|
||||
}
|
||||
@@ -160,6 +168,7 @@ async function load() {
|
||||
loadAnnouncements(),
|
||||
loadWeekly(),
|
||||
loadClassActivity(),
|
||||
loadKnowledge(),
|
||||
])
|
||||
loaded.value = true
|
||||
}
|
||||
@@ -226,6 +235,13 @@ async function openAnnouncement(item: AnnouncementListItem) {
|
||||
<router-link to="/rank" class="plain-link">{{ weeklyText }}</router-link>
|
||||
</template>
|
||||
</n-text>
|
||||
<div v-if="knowledgeHeadline" class="knowledge-line">
|
||||
<router-link v-if="knowledgeHeadline.to" :to="knowledgeHeadline.to" class="plain-link">
|
||||
{{ knowledgeHeadline.text }}
|
||||
</router-link>
|
||||
<span v-else>{{ knowledgeHeadline.text }}</span>
|
||||
<router-link to="/user" class="more">我的知识点</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<n-input-group class="search">
|
||||
<n-input
|
||||
@@ -421,6 +437,21 @@ async function openAnnouncement(item: AnnouncementListItem) {
|
||||
margin: 0 0 6px;
|
||||
}
|
||||
|
||||
.knowledge-line {
|
||||
margin-top: 6px;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: baseline;
|
||||
color: #18a058;
|
||||
}
|
||||
|
||||
/* 这一行本身就是链接(去按知识点筛的题目列表),下划线说明它能点 */
|
||||
.knowledge-line .plain-link {
|
||||
color: #18a058;
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
}
|
||||
|
||||
.search {
|
||||
width: 320px;
|
||||
max-width: 100%;
|
||||
|
||||
Reference in new issue
Block a user