Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion skills/qml-authoring/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ description: Use this skill when authoring, reviewing, fixing, or documenting QM
- 维护 traits 量表问卷的维度说明、分析建议与 Front Matter 解释口径
- 维护问卷 `intro` / `outro` 图片及其展示约定
- 排查 QML 解析错误
- 更新 QML 规范文档或 QML 示例
- 更新 `qml.md` 或 QML 示例
- 评审 QML 语法与 parser 行为是否一致

## 工作流
Expand Down
2 changes: 2 additions & 0 deletions skills/quiz-repo-spec/references/repo-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

- 必须存在 `md-quiz-repo.yaml`
- 必须存在 `README.md`
- 新增、删除或重命名 quiz 后,必须同步更新 `md-quiz-repo.yaml` 与 `README.md`
- 不再支持根目录散落 `*.md`

### manifest 要求
Expand All @@ -44,6 +45,7 @@ quizzes:
- `quizzes` 必须是非空列表
- 每个 `path` 只能是 `quizzes/<quiz_id>/quiz.md`
- `path` 不能重复,不能越界,必须真实存在
- 新增或删除 quiz 时,`quizzes` 列表必须同步反映实际仓库内容
- 当前仓库规范版本号与 QML 头部推荐的 `schema_version: 2` / `format: qml-v2` 保持同一代际

## Quiz 目录规则
Expand Down
40 changes: 28 additions & 12 deletions static/admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -3312,16 +3312,6 @@
font-size: 1.05rem;
}
}
.xl\:sticky {
@media (width >= 80rem) {
position: sticky;
}
}
.xl\:top-6 {
@media (width >= 80rem) {
top: calc(var(--spacing) * 6);
}
}
.xl\:hidden {
@media (width >= 80rem) {
display: none;
Expand Down Expand Up @@ -3678,6 +3668,12 @@
position: relative;
min-width: 0;
}
.admin-sticky-aside {
min-width: 0;
}
.admin-sticky-aside__body {
min-width: 0;
}
.admin-subsurface {
border-color: rgba(37, 99, 235, 0.12);
box-shadow: 0 14px 30px rgba(15, 23, 42, 0.05);
Expand All @@ -3698,7 +3694,7 @@
}
.admin-primary-nav__track {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
grid-template-columns: repeat(var(--admin-primary-nav-columns, 5), minmax(0, 1fr));
gap: 0.45rem;
border-radius: 1rem;
border: 1px solid rgba(37, 99, 235, 0.14);
Expand Down Expand Up @@ -3791,6 +3787,26 @@
width: 6.5rem;
height: 6.5rem;
}
@media (min-width: 1280px) {
.admin-sticky-aside {
position: sticky;
top: 1.5rem;
display: flex;
max-height: calc(100vh - 3rem);
flex-direction: column;
overflow: hidden;
align-self: flex-start;
}
.admin-sticky-aside__body {
flex: 1 1 auto;
min-height: 0;
overflow-y: auto;
overscroll-behavior: contain;
scrollbar-gutter: stable;
padding-right: 0.35rem;
margin-right: -0.35rem;
}
}
.assignment-surface {
position: relative;
isolation: isolate;
Expand Down Expand Up @@ -4861,4 +4877,4 @@
--tw-translate-z: 0;
}
}
}
}
7 changes: 6 additions & 1 deletion static/admin/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,12 @@ <h1 class="mt-1 truncate text-3xl font-semibold tracking-[-0.04em] text-slate-90

<div x-show="isAdminCompactLayout" x-cloak class="admin-mobile-nav-shell md:hidden">
<div class="admin-primary-nav">
<div class="admin-primary-nav__track" role="navigation" aria-label="后台主导航">
<div
class="admin-primary-nav__track"
role="navigation"
aria-label="后台主导航"
:style="{ '--admin-primary-nav-columns': navItems.length }"
>
<template x-for="item in navItems" :key="'compact-' + item.href">
<button
type="button"
Expand Down
148 changes: 75 additions & 73 deletions static/admin/pages/attempt-detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -151,102 +151,104 @@ <h2 class="text-xl font-semibold tracking-[-0.03em] text-slate-900">答题回放

<section
x-show="adminCompactPanelVisible('attempt-detail', 'evaluation')"
class="admin-surface self-start rounded-3xl border border-white/70 bg-white/82 p-5 shadow-[var(--admin-shadow)] backdrop-blur-xl xl:sticky xl:top-6"
class="admin-surface admin-sticky-aside rounded-3xl border border-white/70 bg-white/82 p-5 shadow-[var(--admin-shadow)] backdrop-blur-xl"
>
<div>
<h2 class="text-xl font-semibold tracking-[-0.03em] text-slate-900">智能评价</h2>
<p class="mt-1 text-sm text-slate-600">汇总总分、主倾向、综合分析和候选人简评。</p>
</div>

<div class="mt-5 grid gap-3">
<div class="grid gap-3 sm:grid-cols-2">
<div x-show="attemptEvaluationShowScore()" class="rounded-[1.1rem] border border-blue-100 bg-blue-50/55 px-4 py-3">
<div class="text-[12px] font-semibold uppercase tracking-[0.18em] text-blue-700">总分</div>
<div class="mt-2 text-2xl font-black tracking-[-0.04em] text-slate-900" x-text="attemptReviewEvaluation().score_display || '-'"></div>
</div>
<div class="rounded-[1.1rem] border border-slate-200 bg-slate-50/80 px-4 py-3">
<div class="text-[12px] font-semibold uppercase tracking-[0.18em] text-slate-500">结果模式</div>
<div class="mt-2 text-lg font-bold tracking-[-0.03em] text-slate-900" x-text="attemptEvaluationResultModeLabel()"></div>
<div class="admin-sticky-aside__body">
<div class="mt-5 grid gap-3">
<div class="grid gap-3 sm:grid-cols-2">
<div x-show="attemptEvaluationShowScore()" class="rounded-[1.1rem] border border-blue-100 bg-blue-50/55 px-4 py-3">
<div class="text-[12px] font-semibold uppercase tracking-[0.18em] text-blue-700">总分</div>
<div class="mt-2 text-2xl font-black tracking-[-0.04em] text-slate-900" x-text="attemptReviewEvaluation().score_display || '-'"></div>
</div>
<div class="rounded-[1.1rem] border border-slate-200 bg-slate-50/80 px-4 py-3">
<div class="text-[12px] font-semibold uppercase tracking-[0.18em] text-slate-500">结果模式</div>
<div class="mt-2 text-lg font-bold tracking-[-0.03em] text-slate-900" x-text="attemptEvaluationResultModeLabel()"></div>
</div>
</div>
</div>

<div x-show="attemptEvaluationPrimaryDimensions().length" class="border-t border-slate-200/80 pt-4">
<div class="text-[12px] font-semibold uppercase tracking-[0.18em] text-sky-700">主倾向</div>
<div class="mt-3 flex flex-wrap gap-2">
<template x-for="dimension in attemptEvaluationPrimaryDimensions()" :key="dimension">
<span :style="traitBadgeStyle(dimension)" class="rounded-full border px-3 py-1 text-xs font-semibold" x-text="dimension"></span>
</template>
<div x-show="attemptEvaluationPrimaryDimensions().length" class="border-t border-slate-200/80 pt-4">
<div class="text-[12px] font-semibold uppercase tracking-[0.18em] text-sky-700">主倾向</div>
<div class="mt-3 flex flex-wrap gap-2">
<template x-for="dimension in attemptEvaluationPrimaryDimensions()" :key="dimension">
<span :style="traitBadgeStyle(dimension)" class="rounded-full border px-3 py-1 text-xs font-semibold" x-text="dimension"></span>
</template>
</div>
</div>
</div>

<div x-show="attemptEvaluationTraitPairs().length" class="border-t border-slate-200/80 pt-4">
<div class="text-sm font-semibold text-slate-900">维度对照</div>
<div class="mt-3 divide-y divide-slate-200/80">
<template x-for="pair in attemptEvaluationTraitPairs()" :key="`${pair.left || ''}-${pair.right || ''}`">
<div class="py-3 first:pt-0 last:pb-0">
<div class="flex items-start justify-between gap-3">
<div>
<div class="text-sm font-semibold tabular-nums text-slate-800" x-text="`${pair.left || '-'} ${pair.left_score || 0} / ${pair.right || '-'} ${pair.right_score || 0}`"></div>
<div class="mt-1 text-xs leading-5 text-slate-500" x-text="pair.description || '按对立维度对照输出主倾向。'"></div>
<div x-show="attemptEvaluationTraitPairs().length" class="border-t border-slate-200/80 pt-4">
<div class="text-sm font-semibold text-slate-900">维度对照</div>
<div class="mt-3 divide-y divide-slate-200/80">
<template x-for="pair in attemptEvaluationTraitPairs()" :key="`${pair.left || ''}-${pair.right || ''}`">
<div class="py-3 first:pt-0 last:pb-0">
<div class="flex items-start justify-between gap-3">
<div>
<div class="text-sm font-semibold tabular-nums text-slate-800" x-text="`${pair.left || '-'} ${pair.left_score || 0} / ${pair.right || '-'} ${pair.right_score || 0}`"></div>
<div class="mt-1 text-xs leading-5 text-slate-500" x-text="pair.description || '按对立维度对照输出主倾向。'"></div>
</div>
<span :style="traitBadgeStyle(pair.winner || '')" class="rounded-full border px-2.5 py-1 text-[11px] font-semibold" x-text="pair.winner || '-'"></span>
</div>
<span :style="traitBadgeStyle(pair.winner || '')" class="rounded-full border px-2.5 py-1 text-[11px] font-semibold" x-text="pair.winner || '-'"></span>
</div>
</div>
</template>
</template>
</div>
</div>
</div>

<div x-show="!attemptEvaluationTraitPairs().length && attemptEvaluationDimensionList().length" class="border-t border-slate-200/80 pt-4">
<div class="text-sm font-semibold text-slate-900">维度累计</div>
<div class="mt-3 divide-y divide-slate-200/80">
<template x-for="item in attemptEvaluationDimensionList()" :key="item.dimension || ''">
<div class="py-3 first:pt-0 last:pb-0">
<div class="flex items-center justify-between gap-3">
<span class="text-sm font-semibold text-slate-800" x-text="item.dimension || '-'"></span>
<span class="text-sm font-bold text-slate-900" x-text="item.score || 0"></span>
<div x-show="!attemptEvaluationTraitPairs().length && attemptEvaluationDimensionList().length" class="border-t border-slate-200/80 pt-4">
<div class="text-sm font-semibold text-slate-900">维度累计</div>
<div class="mt-3 divide-y divide-slate-200/80">
<template x-for="item in attemptEvaluationDimensionList()" :key="item.dimension || ''">
<div class="py-3 first:pt-0 last:pb-0">
<div class="flex items-center justify-between gap-3">
<span class="text-sm font-semibold text-slate-800" x-text="item.dimension || '-'"></span>
<span class="text-sm font-bold text-slate-900" x-text="item.score || 0"></span>
</div>
<div class="mt-1 text-xs leading-5 text-slate-500" x-text="item.meaning || '当前维度暂无额外说明。'"></div>
</div>
<div class="mt-1 text-xs leading-5 text-slate-500" x-text="item.meaning || '当前维度暂无额外说明。'"></div>
</div>
</template>
</template>
</div>
</div>
</div>

<div x-show="attemptReviewEvaluation().final_analysis" class="border-t border-slate-200/80 pt-4">
<div class="text-sm font-semibold text-emerald-800">综合分析</div>
<div class="mt-2 whitespace-pre-line text-sm leading-6 text-slate-700" x-text="attemptReviewEvaluation().final_analysis"></div>
</div>
<div x-show="attemptReviewEvaluation().final_analysis" class="border-t border-slate-200/80 pt-4">
<div class="text-sm font-semibold text-emerald-800">综合分析</div>
<div class="mt-2 whitespace-pre-line text-sm leading-6 text-slate-700" x-text="attemptReviewEvaluation().final_analysis"></div>
</div>

<div x-show="attemptReviewEvaluation().candidate_remark" class="border-t border-slate-200/80 pt-4">
<div class="text-sm font-semibold text-blue-800">候选人简评</div>
<div class="mt-2 whitespace-pre-line text-sm leading-6 text-slate-700" x-text="attemptReviewEvaluation().candidate_remark"></div>
</div>
<div x-show="attemptReviewEvaluation().candidate_remark" class="border-t border-slate-200/80 pt-4">
<div class="text-sm font-semibold text-blue-800">候选人简评</div>
<div class="mt-2 whitespace-pre-line text-sm leading-6 text-slate-700" x-text="attemptReviewEvaluation().candidate_remark"></div>
</div>

<div
x-show="assignmentStatusValue(attemptDetail.quiz_paper) === 'grading' && !attemptEvaluationHasContent()"
class="grading-placeholder rounded-[1.1rem] border border-dashed border-amber-200 bg-amber-50/70 px-4 py-5"
>
<div class="grading-placeholder__hero">
<div class="grading-placeholder__spinner" aria-hidden="true">
<span class="material-symbols-rounded text-[20px]">grading</span>
<div
x-show="assignmentStatusValue(attemptDetail.quiz_paper) === 'grading' && !attemptEvaluationHasContent()"
class="grading-placeholder rounded-[1.1rem] border border-dashed border-amber-200 bg-amber-50/70 px-4 py-5"
>
<div class="grading-placeholder__hero">
<div class="grading-placeholder__spinner" aria-hidden="true">
<span class="material-symbols-rounded text-[20px]">grading</span>
</div>
<div>
<div class="text-sm font-semibold text-amber-800">正在判卷</div>
<p class="mt-2 text-sm leading-6 text-amber-700/90">系统正在汇总题目得分和大模型分析,完成后这里会自动显示总分、主倾向和综合评价。</p>
</div>
</div>
<div>
<div class="text-sm font-semibold text-amber-800">正在判卷</div>
<p class="mt-2 text-sm leading-6 text-amber-700/90">系统正在汇总题目得分和大模型分析,完成后这里会自动显示总分、主倾向和综合评价。</p>
<div class="grading-placeholder__bars" aria-hidden="true">
<span class="grading-placeholder__bar grading-placeholder__bar--primary"></span>
<span class="grading-placeholder__bar grading-placeholder__bar--secondary"></span>
<span class="grading-placeholder__bar grading-placeholder__bar--tertiary"></span>
</div>
</div>
<div class="grading-placeholder__bars" aria-hidden="true">
<span class="grading-placeholder__bar grading-placeholder__bar--primary"></span>
<span class="grading-placeholder__bar grading-placeholder__bar--secondary"></span>
<span class="grading-placeholder__bar grading-placeholder__bar--tertiary"></span>
</div>
</div>

<div
x-show="assignmentStatusValue(attemptDetail.quiz_paper) !== 'grading' && !attemptEvaluationHasContent()"
class="rounded-[1.1rem] border border-dashed border-slate-200 bg-slate-50/80 px-4 py-5"
>
<div class="text-sm font-semibold text-slate-700">当前暂无评价摘要</div>
<p class="mt-2 text-sm leading-6 text-slate-500">该记录尚未生成可展示的综合分析;如果刚完成判卷,刷新后会自动补齐。</p>
<div
x-show="assignmentStatusValue(attemptDetail.quiz_paper) !== 'grading' && !attemptEvaluationHasContent()"
class="rounded-[1.1rem] border border-dashed border-slate-200 bg-slate-50/80 px-4 py-5"
>
<div class="text-sm font-semibold text-slate-700">当前暂无评价摘要</div>
<p class="mt-2 text-sm leading-6 text-slate-500">该记录尚未生成可展示的综合分析;如果刚完成判卷,刷新后会自动补齐。</p>
</div>
</div>
</div>
</section>
Expand Down
Loading