Files
Brain/brain-h5/worker/index.js
MingNian b0fce840a3 首次提交:脑晴测 H5 项目
包含前端源码、预构建产物(dist/)、零依赖 Node.js 服务器(server.mjs)、
Cloudflare Worker 版本(worker/)、部署文档(DEPLOY.md)和交接文档。

技术总监可直接 clone 后运行 node server.mjs 启动,无需安装 React 或 build。
DEEPSEEK_API_KEY 通过环境变量注入,未纳入仓库。
2026-07-28 10:24:47 +08:00

53 lines
3.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const SYSTEM_PROMPT = `你是一名数字脑健康表现报告助手。根据用户完成游戏时产生的结构化数据,生成通俗、克制、非医疗化的中文报告。不得诊断疾病,不得推荐药物或医疗处置,不得使用“异常、受损、提示存在问题或挑战”等暗示医学结论的说法。只描述本次表现,优先使用“反应相对偏慢、注意表现有波动、容易遗漏、仍有提升空间”。只输出合法 JSON{"summary":"80字内总结","strength":"60字内相对优势","opportunity":"60字内提升空间","recommendations":["建议1","建议2","建议3"]}`;
async function analyze(request, env) {
if (!env.DEEPSEEK_API_KEY) return Response.json({ error: "AI service is not configured" }, { status: 503 });
try {
const assessment = await request.json();
const upstream = await fetch("https://api.deepseek.com/chat/completions", {
method: "POST",
headers: { "content-type": "application/json", authorization: `Bearer ${env.DEEPSEEK_API_KEY}` },
body: JSON.stringify({
model: "deepseek-chat",
temperature: 0.35,
response_format: { type: "json_object" },
messages: [
{ role: "system", content: SYSTEM_PROMPT },
{ role: "user", content: JSON.stringify({ profile: assessment.profile, metrics: assessment.metrics, eventCount: assessment.events?.length ?? 0 }) },
],
}),
signal: AbortSignal.timeout(15000),
});
if (!upstream.ok) return Response.json({ error: "AI service request failed" }, { status: 502 });
const payload = await upstream.json();
const content = payload?.choices?.[0]?.message?.content;
const rawReport = JSON.parse(String(content || "{}").replace(/^```json\s*|\s*```$/g, ""));
const parsed = {
summary: String(rawReport.summary || "本次四项任务已经完成。"),
strength: String(rawReport.strength || "部分任务表现相对稳定。"),
opportunity: String(rawReport.opportunity || "仍有可以通过规律练习提升的空间。"),
recommendations: Array.isArray(rawReport.recommendations) ? rawReport.recommendations.slice(0, 3).map(String) : [],
};
return Response.json(parsed, { headers: { "cache-control": "no-store" } });
} catch {
return Response.json({ error: "AI report could not be generated" }, { status: 502 });
}
}
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname === "/api/analyze") {
if (request.method !== "POST") return new Response("Method not allowed", { status: 405 });
return analyze(request, env);
}
const response = await env.ASSETS.fetch(request);
const acceptsHtml = request.headers.get("accept")?.includes("text/html");
if (response.status !== 404 || !acceptsHtml || !["GET", "HEAD"].includes(request.method)) return response;
const indexUrl = new URL(request.url);
indexUrl.pathname = "/index.html";
indexUrl.search = "";
return env.ASSETS.fetch(new Request(indexUrl, request));
},
};