AimdRecorder
当你希望把 AIMD 输入控件直接渲染在协议正文流里时,使用 AimdRecorder。
示例
vue
<script setup lang="ts">
import { ref } from "vue"
import {
AimdRecorder,
createEmptyProtocolRecordData,
type AimdProtocolRecordData,
} from "@airalogy/aimd-recorder"
import "@airalogy/aimd-recorder/styles"
const content = ref(`# Protocol
样本名:{{var|sample_name: str}}
记录者:{{var|operator: UserName}}
记录时间:{{var|current_time: CurrentTime}}
温度设置:{{var|temperature: float = 25.0}}
实验摘要:{{var|summary: AiralogyMarkdown}}
质粒:{{var|plasmid: DNASequence}}`)
const record = ref<AimdProtocolRecordData>(createEmptyProtocolRecordData())
</script>
<template>
<AimdRecorder
v-model="record"
:content="content"
locale="zh-CN"
current-user-name="张三"
/>
</template>record 数据结构:
json
{
"var": {},
"step": {},
"check": {},
"quiz": {}
}内建 Recorder 行为
CurrentTime和UserName可以从运行时上下文自动填值。AiralogyMarkdown会渲染为横铺的 AIMD/Markdown 内嵌编辑器,默认打开源码模式,同时保留切换到所见即所得的能力。DNASequence会渲染专用序列控件,支持交互式模式、原始结构模式、文件导入导出、拓扑切换、feature 编辑,以及基于SeqViz的可视化。ref_var如果已有记录值,会优先以内联只读内容显示当前值。choice、blank、open三类 quiz 都有内建 recorder 输入。
Client Assigner
前端受限的 client assigner 会在 recorder 中本地执行。
aimd
Water: {{var|water_volume_ml: float}}
Lemon: {{var|lemon_juice_ml: float}}
Total: {{var|total_liquid_ml: float}}
```assigner runtime=client
assigner(
{
mode: "auto",
dependent_fields: ["water_volume_ml", "lemon_juice_ml"],
assigned_fields: ["total_liquid_ml"],
},
function calculate_total_liquid_ml({ water_volume_ml, lemon_juice_ml }) {
return {
total_liquid_ml: Math.round((water_volume_ml + lemon_juice_ml) * 100) / 100,
};
}
);
```如果使用 mode: "manual",AimdRecorder 会通过组件 ref 暴露显式触发方法:
ts
recorderRef.value?.runClientAssigner("calculate_total_liquid_ml")
recorderRef.value?.runManualClientAssigners()语言与单独 Quiz 组件
AimdRecorder 和 AimdQuizRecorder 都支持通过 locale 切换内建标签:
vue
<AimdRecorder locale="zh-CN" />
<AimdQuizRecorder :quiz="quiz" locale="zh-CN" />单独题目控件用法:
vue
<script setup lang="ts">
import { ref } from "vue"
import { AimdQuizRecorder } from "@airalogy/aimd-recorder"
import "@airalogy/aimd-recorder/styles"
const answer = ref("")
const quiz = {
id: "quiz_single_1",
type: "choice",
mode: "single",
stem: "请选择一个选项",
options: [
{ key: "A", text: "选项 A" },
{ key: "B", text: "选项 B" },
],
}
</script>
<template>
<AimdQuizRecorder v-model="answer" :quiz="quiz" />
</template>显示评分结果
如果宿主已经在别处完成了评分,可以把结果回传给 AimdRecorder 或 AimdQuizRecorder 直接展示。
整份 recorder:
vue
<AimdRecorder
v-model="record"
:content="content"
:quiz-grades="quizGrades"
choice-option-explanation-mode="selected"
/>单题组件:
vue
<AimdQuizRecorder
v-model="answer"
:quiz="quiz"
choice-option-explanation-mode="graded"
:grade="{
quiz_id: 'quiz_single_1',
earned_score: 4,
max_score: 5,
status: 'partial',
method: 'keyword_rubric',
feedback: '答案方向正确,但还缺少一个要点。',
review_required: true,
}"
/>推荐做法:
choice与常规blank可以直接本地自动评分open题或高开放性blank建议由后端 provider 评分- 练习题可以实时传入
quizGrades,让学生立即看到状态、得分和反馈 - 如果
choice选项里定义了explanation,可以用choiceOptionExplanationMode="selected"在选中后立即显示讲解 - 如果希望学生提交后再显示选项讲解,可以配合
:submitted="isSubmitted"和choiceOptionExplanationMode="submitted" - 如果希望等评分完成后再显示选项讲解,可以使用
choiceOptionExplanationMode="graded" - 考试题可以先不传
quizGrades,等统一评分后再展示结果 - 尚未作答且状态为
ungraded的题目,默认不会显示评分面板 - 正式考试不要把真实模型密钥传给前端
作业或提交后讲解示例:
vue
<AimdRecorder
v-model="record"
:content="content"
:submitted="isSubmitted"
choice-option-explanation-mode="submitted"
/>其中 submitted 由宿主应用控制。AimdRecorder 本身不会自动判断“是否已提交”,也不内建交卷按钮。