refactor(grades,diagnostic): 成绩和学情诊断模块审计修复

P0-1: 10 个页面补充 requirePermission 权限校验
P0-2: diagnostic/data-access-reports.ts 移除直查 users 表,改用 getUserNamesByIds
P0-3: 新增 grade/grades/diagnostic 三组 i18n 翻译文件(zh-CN/en)
P0-4: 新增 /management/grade 重定向页面

P1-2: 抽取 toNumber/normalize/buildScopeClassFilter 到 lib/grade-utils.ts
P1-3: 为 12 个 Action 新增 Zod safeParse 校验(schema.ts +12 查询 schema)
P1-4: 修复 as 断言违规,改用类型守卫函数

P2-2: 移除 diagnostic 组件中 Tailwind 任意值

同步更新架构图文档 004 和 005
This commit is contained in:
SpecialX
2026-06-22 16:23:34 +08:00
parent 20691f53ce
commit 45ee1ae43c
29 changed files with 2276 additions and 186 deletions

View File

@@ -131,7 +131,7 @@ export function ClassDiagnosticView({ summary }: ClassDiagnosticViewProps) {
className={`flex flex-col items-center justify-center rounded-md px-3 py-2 text-white ${masteryColor(kp.averageMastery)}`}
title={`${kp.knowledgePointName}: ${kp.averageMastery.toFixed(1)}% (mastered ${kp.masteredCount}/${kp.totalStudents})`}
>
<span className="max-w-[120px] truncate text-xs font-medium">
<span className="max-w-32 truncate text-xs font-medium">
{kp.knowledgePointName}
</span>
<span className="text-sm font-bold">{kp.averageMastery.toFixed(0)}%</span>
@@ -252,7 +252,7 @@ export function ClassDiagnosticView({ summary }: ClassDiagnosticViewProps) {
type="month"
value={period}
onChange={(e) => setPeriod(e.target.value)}
className="w-[180px]"
className="w-44"
/>
</div>
<Button onClick={handleGenerate} disabled={isGenerating}>

View File

@@ -42,7 +42,7 @@ export function MasteryRadarChart({ data }: MasteryRadarChartProps) {
domain={[0, 100]}
tickCount={5}
showLegend={hasClassAverage}
heightClassName="mx-auto h-[360px] w-full max-w-[520px]"
heightClassName="mx-auto h-96 w-full max-w-lg"
gridStrokeDasharray="4 4"
series={[
{

View File

@@ -195,7 +195,7 @@ export function StudentDiagnosticView({ summary, reports, classAverageMastery }:
<span className="text-sm font-medium">
{r.period ?? "Untitled period"}
</span>
<Badge variant="outline" className="text-[10px]">
<Badge variant="outline" className="text-xs">
{r.reportType}
</Badge>
</div>