- 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
121 lines
3.5 KiB
TypeScript
121 lines
3.5 KiB
TypeScript
/**
|
||
* 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);
|
||
}
|
||
}
|