fix(题目推荐): 已 AC 过滤下推 SQL、难度按语义排序、难度标签渲染
Deploy / deploy (push) Waiting to run

相似题目推荐(GET /problems/:displayId/similar)三个 bug:

- 排除已 AC 的题发生在 limit(5) 之后,候选被筛掉几条就少几条,甚至清零让整块
  不渲染。而这个接口只在刚 AC 或连挂三次时才调用,正是最容易全中的时候。
  (老栈是 .exclude(...) 在切片之前,重写时引入的回归)
- order by difficulty 是 text 字典序,High < Low < Mid,「由易到难」实际是最难的
  先上。改成显式 case 排名,并加上共享标签数作为第一排序键、id 兜稳定序。
- 前端 ref<any[]> 盖住了类型错误:getSimilarProblems 已过 filterResult,难度是
  中文,模板却在比 'Low' / 'High' 再查 DIFFICULTY 表,结果每条推荐都渲染成黄色
  的「中等」。

顺带:比赛题不再发这个请求(接口只在公开题库按 displayId 找,撞号会在比赛中把
题库列给学生);多余的 id in (子查询) 换成 join 中间表。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-22 09:24:46 +08:00
co-authored by Claude Opus 5
parent 954797a9a5
commit b16e11e85d
2 changed files with 46 additions and 32 deletions
@@ -5,8 +5,7 @@ import { storeToRefs } from "pinia"
import { useCodeStore } from "oj/store/code"
import { useProblemStore } from "oj/store/problem"
import { createTestSubmission } from "utils/judge"
import { DIFFICULTY } from "utils/constants"
import type { Problem, ProblemStatus } from "utils/types"
import type { Problem, ProblemFiltered, ProblemStatus } from "utils/types"
import Copy from "shared/components/Copy.vue"
import { useDark } from "@vueuse/core"
import { MdPreview } from "md-editor-v3"
@@ -46,11 +45,14 @@ const sqlChangedTables = computed(() => {
const router = useRouter()
// 相似题目推荐
const similarProblems = ref<any[]>([])
const similarProblems = ref<ProblemFiltered[]>([])
const similarLoaded = ref(false)
async function loadSimilarProblems() {
if (similarLoaded.value || !problem.value) return
// 比赛题不推荐:接口按 displayId 在**公开题库**里找,比赛题的编号默认是 1/2/3,
// 一般白跑一趟 404,撞上同号公开题时反而会在比赛中把题库列给学生。
if (problem.value.contestId !== null) return
try {
similarProblems.value = await getSimilarProblems(problem.value._id)
} catch {
@@ -407,19 +409,19 @@ function type(status: ProblemStatus) {
{{ sp.title }}
</n-button>
</n-flex>
<!-- getSimilarProblems 已经过 filterResult难度是中文不是 Low/Mid/High -->
<n-tag
v-if="sp.difficulty"
size="small"
:type="
sp.difficulty === 'Low'
sp.difficulty === '简单'
? 'success'
: sp.difficulty === 'High'
: sp.difficulty === '困难'
? 'error'
: 'warning'
"
>
{{
DIFFICULTY[sp.difficulty as keyof typeof DIFFICULTY] || "中等"
}}
{{ sp.difficulty }}
</n-tag>
</n-flex>
</n-list-item>