- 作业:老师选实验、起点(界面已做好 / 空白工程)、截止时间、每项分值(自动评分项 + 老师评分项); 起点工程由设计器引擎从参考答案生成(去掉事件绑定和事件处理方法),布置时保存起点和评分规则快照 - 提交:后台排队评分(全站同时最多评 3 份、跑 6 个检查项),重启后继续评;评分中不能再交,截止后不能交 - 学生:"我的作业"列表;实验页的作业模式(作业名、截止时间、提交、得分),评分结果弹出逐项显示 - 老师:班级管理页加"作业"标签页,布置、修改、删除作业,查看全班提交情况;改分值后重新算分 - 串口列表为空时提示在 Load 或 Click 事件里填充 - 测试:作业接口(可见范围、排队评分、部分得分、改分值、截止、删除);10 个示例两种起点都能编译 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
43 lines
1.6 KiB
TypeScript
43 lines
1.6 KiB
TypeScript
import { readdir } from 'node:fs/promises'
|
|
import { join, relative, resolve } from 'node:path'
|
|
import type { SourceFile } from '@iot/shared'
|
|
import { config } from './config'
|
|
|
|
const SAMPLES_DIR = config.samplesDir
|
|
|
|
export interface SampleInfo {
|
|
id: string
|
|
title: string
|
|
}
|
|
|
|
/** 示例工程:samples/ 下每个子目录是一个工程,meta.json 里写标题 */
|
|
export async function listSamples(): Promise<SampleInfo[]> {
|
|
const entries = await readdir(SAMPLES_DIR, { withFileTypes: true })
|
|
const samples: SampleInfo[] = []
|
|
for (const entry of entries) {
|
|
if (!entry.isDirectory()) continue
|
|
const meta = await Bun.file(join(SAMPLES_DIR, entry.name, 'meta.json')).json()
|
|
samples.push({ id: entry.name, title: meta.title })
|
|
}
|
|
return samples.sort((a, b) => a.id.localeCompare(b.id))
|
|
}
|
|
|
|
export async function loadSample(id: string): Promise<SourceFile[] | null> {
|
|
const dir = resolve(SAMPLES_DIR, id)
|
|
if (!dir.startsWith(`${SAMPLES_DIR}/`)) return null
|
|
const files: SourceFile[] = []
|
|
const glob = new Bun.Glob('**/*.cs')
|
|
for await (const path of glob.scan({ cwd: dir })) {
|
|
files.push({ path: relative(dir, join(dir, path)), content: await Bun.file(join(dir, path)).text() })
|
|
}
|
|
return files.length > 0 ? files.sort((a, b) => a.path.localeCompare(b.path)) : null
|
|
}
|
|
|
|
/** 示例的评分规则(checks.yaml 原文);没有规则返回 null */
|
|
export async function loadChecks(id: string): Promise<string | null> {
|
|
const path = resolve(SAMPLES_DIR, id, 'checks.yaml')
|
|
if (!path.startsWith(`${SAMPLES_DIR}/`)) return null
|
|
const file = Bun.file(path)
|
|
return (await file.exists()) ? file.text() : null
|
|
}
|