feat(lesson-preparation): add AI evaluation, analytics, attachments, calendar, comments, review, substitutes, formative, and version diff
- Add actions-ai-evaluation, actions-analytics, actions-attachments, actions-calendar, actions-comments, actions-formative, actions-questions, actions-review, actions-substitutes - Add corresponding data-access layers for each new action module - Add calendar-view, curriculum-map-view, version-diff-viewer components - Add editor-slice, selection-slice, version-slice hooks for state management - Add document-diff and scope-check lib utilities - Add default-question-service and external-questions-bridge services
This commit is contained in:
120
src/modules/lesson-preparation/actions-ai-evaluation.ts
Normal file
120
src/modules/lesson-preparation/actions-ai-evaluation.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* M8 AI 评估 - Server Actions
|
||||
*/
|
||||
"use server";
|
||||
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { z } from "zod";
|
||||
import {
|
||||
getEvaluationsByPlanId,
|
||||
getLatestEvaluation,
|
||||
createEvaluation,
|
||||
deleteEvaluation,
|
||||
evaluateDocument,
|
||||
} from "./data-access-ai-evaluation";
|
||||
import type { AiEvaluation } from "./data-access-ai-evaluation";
|
||||
import type { ActionState } from "@/shared/types/action-state";
|
||||
import { getAuthContext, requirePermission } from "@/shared/lib/auth-guard";
|
||||
import { handleActionError } from "@/shared/lib/action-utils";
|
||||
import { Permissions } from "@/shared/types/permissions";
|
||||
import { getLessonPlanById } from "./data-access";
|
||||
import { getStandardsByPlanId } from "../standards/data-access";
|
||||
import { normalizeDocument } from "./lib/document-migration";
|
||||
|
||||
const createEvaluationSchema = z.object({
|
||||
planId: z.string().min(1),
|
||||
versionNo: z.number().int().positive(),
|
||||
});
|
||||
|
||||
/**
|
||||
* 查询课案的所有 AI 评估
|
||||
*/
|
||||
export async function getLessonPlanEvaluationsAction(
|
||||
planId: string,
|
||||
): Promise<ActionState<{ items: AiEvaluation[] }>> {
|
||||
try {
|
||||
await requirePermission(Permissions.LESSON_PLAN_READ);
|
||||
const items = await getEvaluationsByPlanId(planId);
|
||||
return { success: true, data: { items } };
|
||||
} catch (e) {
|
||||
return handleActionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询最新评估
|
||||
*/
|
||||
export async function getLatestEvaluationAction(
|
||||
planId: string,
|
||||
): Promise<ActionState<{ evaluation: AiEvaluation | null }>> {
|
||||
try {
|
||||
await requirePermission(Permissions.LESSON_PLAN_READ);
|
||||
const evaluation = await getLatestEvaluation(planId);
|
||||
return { success: true, data: { evaluation } };
|
||||
} catch (e) {
|
||||
return handleActionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发 AI 评估(当前为本地规则评估,未来可替换为远程 AI API)
|
||||
*/
|
||||
export async function evaluateLessonPlanAction(
|
||||
input: Record<string, unknown>,
|
||||
): Promise<ActionState<{ evaluation: AiEvaluation }>> {
|
||||
try {
|
||||
await requirePermission(Permissions.LESSON_PLAN_READ);
|
||||
const t = await getTranslations("lessonPreparation");
|
||||
const parseResult = createEvaluationSchema.safeParse(input);
|
||||
if (!parseResult.success) {
|
||||
return { success: false, message: t("error.invalidInput") };
|
||||
}
|
||||
|
||||
const { planId, versionNo } = parseResult.data;
|
||||
const auth = await getAuthContext();
|
||||
if (!auth.userId) {
|
||||
return { success: false, message: t("error.unauthorized") };
|
||||
}
|
||||
|
||||
const plan = await getLessonPlanById(planId, auth.userId);
|
||||
if (!plan) {
|
||||
return { success: false, message: t("error.notFound") };
|
||||
}
|
||||
|
||||
const doc = normalizeDocument(plan.content as unknown);
|
||||
const standards = await getStandardsByPlanId(planId);
|
||||
const result = evaluateDocument(doc, {
|
||||
standardsLinkedCount: standards.length,
|
||||
hasInteractiveItems: false, // TODO: 查询 M5 formative items
|
||||
});
|
||||
|
||||
const evaluation = await createEvaluation(
|
||||
{
|
||||
planId,
|
||||
versionNo,
|
||||
overallScore: result.overallScore,
|
||||
dimensionScores: result.dimensionScores,
|
||||
suggestions: result.suggestions,
|
||||
},
|
||||
auth.userId,
|
||||
);
|
||||
return { success: true, data: { evaluation } };
|
||||
} catch (e) {
|
||||
return handleActionError(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除评估
|
||||
*/
|
||||
export async function deleteEvaluationAction(
|
||||
id: string,
|
||||
): Promise<ActionState<null>> {
|
||||
try {
|
||||
await requirePermission(Permissions.LESSON_PLAN_UPDATE);
|
||||
await deleteEvaluation(id);
|
||||
return { success: true, data: null };
|
||||
} catch (e) {
|
||||
return handleActionError(e);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user