refactor: React 前端重构,新旧平台合并为莞易学

This commit is contained in:
study-tool
2026-10-29 23:50:46 +08:00
parent 35853891c9
commit e8634a6317
62 changed files with 8923 additions and 4623 deletions
+90
View File
@@ -0,0 +1,90 @@
"""系统设置(大模型 + 学习方式)读写。"""
from study_tool import store
from study_tool.webapp import app
from study_tool.config import *
from study_tool.models import *
from study_tool.runtime import log
# ------------------------------------------------------------------ settings
SETTINGS_NAME = "llm"
DEFAULT_LLM = {
"base_url": "https://api.openai.com/v1",
"api_key": "",
"model": "gpt-4o-mini",
"temperature": 0.2,
"timeout": 120,
"prompt": "",
}
# 学习方式:fast = 只调 study/log 接口,不开浏览器;normal = 真播视频(可多路并发)
DEFAULT_STUDY = {
"mode": "fast",
"parallel": 2,
}
DEFAULT_ANSWER_PROMPT = (
"你是考试答题助手。根据题干和选项判断正确答案。\n"
"单选题返回一个选项字母;多选题返回多个字母,用 # 连接(如 A#C);判断题只返回 A 或 B(A=正确,B=错误)。\n"
"只输出 JSON:{\"answers\":{\"题号\":\"答案\"}},不要输出解释或多余文字。"
)
TYPE_LABEL = {"01": "单选", "02": "多选", "03": "判断", "04": "问答"}
def load_settings():
data = store.get_setting(SETTINGS_NAME) or {}
llm = dict(DEFAULT_LLM)
study = dict(DEFAULT_STUDY)
if isinstance(data, dict):
raw = data.get("llm")
if isinstance(raw, dict):
llm.update({k: v for k, v in raw.items() if k in DEFAULT_LLM and v is not None})
st = data.get("study")
if isinstance(st, dict):
study.update({k: v for k, v in st.items() if v is not None})
study["mode"] = study.get("mode") if study.get("mode") in ("fast", "normal") else "fast"
try:
study["parallel"] = max(1, min(int(study.get("parallel") or 2), 5))
except (TypeError, ValueError):
study["parallel"] = 2
return {"llm": llm, "study": study}
def save_settings(data):
store.set_setting(SETTINGS_NAME, {"llm": data.get("llm") or {},
"study": data.get("study") or {}})
@app.get("/api/settings")
def api_get_settings():
cfg = load_settings()
llm = cfg["llm"]
key = llm.get("api_key") or ""
out = dict(llm)
out["api_key"] = ""
out["has_key"] = bool(key)
out["key_hint"] = (key[:4] + "…" + key[-4:]) if len(key) > 10 else ("已设置" if key else "")
return {"ok": True, "llm": out, "study": cfg["study"]}
@app.post("/api/settings")
def api_set_settings(b: LlmCfgIn):
cur = load_settings()
llm = cur["llm"]
if b.base_url.strip():
llm["base_url"] = b.base_url.strip()
if b.api_key.strip(): # 留空 = 保留原 key,前端不回显明文
llm["api_key"] = b.api_key.strip()
if b.model.strip():
llm["model"] = b.model.strip()
llm["temperature"] = max(0.0, min(2.0, float(b.temperature or 0)))
llm["timeout"] = max(10, min(600, int(b.timeout or 120)))
llm["prompt"] = b.prompt or ""
if b.study_mode in ("fast", "normal"): # 空串 = 不改
cur["study"]["mode"] = b.study_mode
if b.study_parallel: # 0 = 不改
cur["study"]["parallel"] = max(1, min(int(b.study_parallel), 5))
save_settings(cur)
log("system", "设置已更新:模型 %s(%s),学习方式 %s/%s 路" % (
cur["llm"]["model"], cur["llm"]["base_url"],
cur["study"]["mode"], cur["study"]["parallel"]))
return {"ok": True, "study": cur["study"]}