- 学生画的图现在按例子和测试数据评(拼成程序跑),参考图用不上了:「让学生自己画」 只剩一句说明,保存前改成检查有没有例子;「给学生的提示」那一栏去掉(学生从来看不到, 16 道题也都没填) - 「给学生看一张参考流程图」改用学生画图的同一个编辑器,存结构树(problem.flowchart_data, 原来是死列),Mermaid 由后端照它生成,题面里的图和学生交的图同一套形状 - 「AI 照 Python 答案画一张」改成出结构树,直接摆在画布上接着改;for 循环画成 计数变量 + 当型循环 - 老题手写的 Mermaid 照旧给代码框,旁边「改用画布画」 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b9ece7d38f
commit
6e946c99fb
8 files changed
+168
-57
No files matched your search
@@ -1,4 +1,6 @@
|
||||
import {
|
||||
flowToMermaid,
|
||||
parseFlowDoc,
|
||||
addContestProblemRequestSchema,
|
||||
reorderContestProblemsRequestSchema,
|
||||
astCheckRequestSchema,
|
||||
@@ -206,6 +208,7 @@ async function serialize(row: ProblemRow) {
|
||||
allowFlowchart: row.allowFlowchart,
|
||||
showFlowchart: row.showFlowchart,
|
||||
mermaidCode: row.mermaidCode,
|
||||
flowchartData: asRecord(row.flowchartData),
|
||||
flowchartHint: row.flowchartHint,
|
||||
astRules: row.astRules,
|
||||
answers: Array.isArray(row.answers) ? row.answers : [],
|
||||
@@ -276,6 +279,17 @@ async function generateSqlDisplay(
|
||||
return { display: outcome.value }
|
||||
}
|
||||
|
||||
/**
|
||||
* 参考流程图:画布画的(结构树)以它为准,Mermaid 照它生成 —— 题面里给学生看的、评分退回
|
||||
* 老办法时拿来比的都是这份,和学生交的图同一套形状。只有手写 Mermaid 的老题原样存
|
||||
*/
|
||||
function referenceFlowchart(raw: Record<string, unknown> | null, mermaidCode: string | null) {
|
||||
const doc = parseFlowDoc(raw)
|
||||
return doc && doc.steps.length
|
||||
? { flowchartData: doc, mermaidCode: flowToMermaid(doc) }
|
||||
: { flowchartData: {}, mermaidCode }
|
||||
}
|
||||
|
||||
function problemValues(data: ReturnType<typeof createProblemRequestSchema.parse>, isSql: boolean) {
|
||||
return {
|
||||
displayId: data._id,
|
||||
@@ -296,7 +310,7 @@ function problemValues(data: ReturnType<typeof createProblemRequestSchema.parse>
|
||||
source: data.source,
|
||||
allowFlowchart: data.allowFlowchart,
|
||||
showFlowchart: data.showFlowchart,
|
||||
mermaidCode: data.mermaidCode,
|
||||
...referenceFlowchart(data.flowchartData, data.mermaidCode),
|
||||
flowchartHint: data.flowchartHint,
|
||||
astRules: pickAstRules(data.astRules, data.languages),
|
||||
answers: data.answers,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
parseFlowDoc,
|
||||
batchProblemTagRequestSchema,
|
||||
generateFlowchartRequestSchema,
|
||||
renameTagRequestSchema,
|
||||
@@ -16,7 +17,7 @@ import type { AuthUser } from "../../auth/session"
|
||||
import { db, schema } from "../../db"
|
||||
import { failure, parseBody, success } from "../../http"
|
||||
import { completeChat } from "../../services/ai"
|
||||
import { queryInteger } from "../helpers"
|
||||
import { asRecord, queryInteger } from "../helpers"
|
||||
import { canEdit, findTagsByName, normalizeTagNames } from "./problem"
|
||||
|
||||
export const adminTagRoutes = new Hono<AppEnv>()
|
||||
@@ -254,18 +255,32 @@ adminTagRoutes.put("/problems/:id/visibility", requireProblemPermission, async (
|
||||
|
||||
// ---------------------------------------------------------------- Python → 流程图
|
||||
|
||||
/**
|
||||
* 照标准答案画参考流程图。原来让 AI 直接写 Mermaid,老师拿到的是一段代码,要改只能改代码;
|
||||
* 现在出结构树,后台画布直接摆上去,和学生画图是同一个编辑器
|
||||
*/
|
||||
const PYTHON_TO_FLOWCHART = `把下面这段 Python 标准答案画成流程图,给中职学生看。只返回 JSON:{"steps":[…]}
|
||||
每一步是下面五种之一(开始、结束不用写):
|
||||
{"kind":"input","text":"输入 n"}
|
||||
{"kind":"output","text":"输出 a(保留两位小数)"}
|
||||
{"kind":"process","text":"i = i + 1"}
|
||||
{"kind":"if","text":"a > b","yes":[…],"no":[…]}
|
||||
{"kind":"while","text":"i < 365","body":[…]}
|
||||
- 框里写中文和简单的式子,像课本上那样;不要写 input、print、int、range 这些函数名
|
||||
- for 循环改成计数变量 + while:先一个处理框给变量赋初值,while 写条件,循环体最后一个处理框让变量加一
|
||||
- elif 写成 else 里再套一个 if
|
||||
- break、continue、函数定义尽量改写成等价的顺序 / 判断 / 循环;实在改不了就用一个处理框写一句说明`
|
||||
|
||||
adminTagRoutes.post("/problems/flowchart", requireProblemPermission, async (c) => {
|
||||
const parsed = await parseBody(c, generateFlowchartRequestSchema, "python 代码不能为空")
|
||||
if (!parsed.success) return parsed.response
|
||||
try {
|
||||
const flowchart = await completeChat(
|
||||
`你是一个可以将Python代码转换为mermaid的助手。
|
||||
请将用户提供的Python代码转换为 Mermaid 纯文本。
|
||||
注意括号内的内容用引号包裹,如果本身就有引号,请注意双引号和单引号的问题。
|
||||
请只返回 mermaid 代码,连 \`\`\` 都不需要。`,
|
||||
parsed.data.python,
|
||||
const reply = asRecord(
|
||||
JSON.parse(await completeChat(PYTHON_TO_FLOWCHART, parsed.data.python, { json: true })),
|
||||
)
|
||||
return success(c, { flowchart } satisfies GenerateFlowchartResponse)
|
||||
const doc = parseFlowDoc({ version: 2, steps: reply.steps })
|
||||
if (!doc || !doc.steps.length) throw new Error("AI returned no flowchart steps")
|
||||
return success(c, { doc: { ...doc } } satisfies GenerateFlowchartResponse)
|
||||
} catch (error) {
|
||||
console.error("Flowchart generation failed", error)
|
||||
return failure(c, 502, "ai-unavailable", "生成失败,请稍后再试")
|
||||
|
||||
Reference in new issue
Block a user