main
HuangHai 3 weeks ago
parent f901d3e3b4
commit 184e5ebbb7

@ -46,6 +46,7 @@ client = AsyncOpenAI(
base_url=Config.MODEL_API_URL,
)
async def lifespan(app: FastAPI):
# 抑制HTTPS相关警告
warnings.filterwarnings('ignore', message='Connecting to .* using TLS with verify_certs=False is insecure')
@ -173,25 +174,31 @@ async def get_tree_data():
await conn.ping()
async with conn.cursor() as cur:
await cur.execute("""
SELECT id, title, parent_id, is_leaf,
prerequisite, related
FROM knowledge_points
ORDER BY parent_id, id
""")
SELECT id,
title,
parent_id,
is_leaf,
prerequisite,
related
FROM knowledge_points
ORDER BY parent_id, id
""")
rows = await cur.fetchall()
# 构建节点映射
nodes = {}
for row in rows:
prerequisite_data = json.loads(row[4]) if row[4] else []
# 转换先修知识格式
if isinstance(prerequisite_data, list) and len(prerequisite_data) > 0 and isinstance(prerequisite_data[0], dict):
if isinstance(prerequisite_data, list) and len(prerequisite_data) > 0 and isinstance(prerequisite_data[0],
dict):
# 已经是新格式
prerequisites = prerequisite_data
else:
# 转换为新格式
prerequisites = [{"id": str(id), "title": title} for id, title in (prerequisite_data or [])] if prerequisite_data else None
prerequisites = [{"id": str(id), "title": title} for id, title in
(prerequisite_data or [])] if prerequisite_data else None
nodes[row[0]] = {
"id": row[0],
"title": row[1],
@ -201,7 +208,7 @@ async def get_tree_data():
"related": json.loads(row[5]) if row[5] and len(json.loads(row[5])) > 0 else None,
"open": True
}
# 构建树形结构
tree_data = []
for node_id, node in nodes.items():
@ -213,39 +220,52 @@ async def get_tree_data():
if "children" not in nodes[parent_id]:
nodes[parent_id]["children"] = []
nodes[parent_id]["children"].append(node)
return {"code": 0, "data": tree_data}
except Exception as e:
return {"code": 1, "msg": str(e)}
@app.post("/api/update-prerequisites")
async def update_prerequisites(request: fastapi.Request):
@app.post("/api/update-knowledge")
async def update_knowledge(request: fastapi.Request):
try:
data = await request.json()
node_id = data.get('node_id')
prerequisites = data.get('prerequisites', [])
knowledge = data.get('knowledge', [])
update_type = data.get('update_type', 'prerequisite') # 默认为先修知识
if not node_id:
raise ValueError("Missing node_id")
mysql_pool = await init_mysql_pool()
async with mysql_pool.acquire() as conn:
await conn.ping()
async with conn.cursor() as cur:
await cur.execute(
"""
UPDATE knowledge_points
SET prerequisite = %s
WHERE id = %s
""",
(json.dumps([{"id": p["id"], "title": p["title"]} for p in prerequisites]), node_id)
)
if update_type == 'prerequisite':
await cur.execute(
"""
UPDATE knowledge_points
SET prerequisite = %s
WHERE id = %s
""",
(json.dumps([{"id": p["id"], "title": p["title"]} for p in knowledge], ensure_ascii=False),
node_id)
)
else: # related knowledge
await cur.execute(
"""
UPDATE knowledge_points
SET related = %s
WHERE id = %s
""",
(json.dumps([{"id": p["id"], "title": p["title"]} for p in knowledge], ensure_ascii=False),
node_id)
)
await conn.commit()
return {"code": 0, "msg": "更新成功"}
except Exception as e:
logger.error(f"更新先修知识失败: {str(e)}")
logger.error(f"更新知识失败: {str(e)}")
return {"code": 1, "msg": str(e)}

@ -20,6 +20,7 @@ MYSQL_CONFIG = {
"db": MYSQL_DB_NAME,
"minsize": 1,
"maxsize": 20,
"charset": "utf8mb4"
}
@ -40,7 +41,3 @@ async def save_chat_to_mysql(mysql_pool, person_id, prompt, result, audio_url, d
image_height)
)
await conn.commit()

@ -50,7 +50,6 @@
#treeTable th:nth-child(2), #treeTable td:nth-child(2),
#treeTable th:nth-child(3), #treeTable td:nth-child(3),
#treeTable th:nth-child(4), #treeTable td:nth-child(4) {
width: 220px;
min-width: 220px;
@ -132,7 +131,8 @@
const isThirdLevel = node.parent_id && allNodes.find(n => n.id === node.parent_id)?.parent_id;
html += '<td>' + (node.prerequisite && node.prerequisite.length > 0 ?
node.prerequisite.map(p => p.title).join(', ') : '') + '</td>';
html += '<td>' + (node.related || '') + '</td>';
html += '<td>' + (node.related && node.related.length > 0 ?
node.related.map(r => r.title).join(', ') : '') + '</td>';
html += '<td>' + (isThirdLevel ?
'<button class="layui-btn layui-btn-sm" onclick="prerequisiteUpdate(\'' + node.id + '\')">先修知识</button> ' +
'<button class="layui-btn layui-btn-sm layui-btn-normal" onclick="relatedUpdate(\'' + node.id + '\')">相关知识</button>' : '') + '</td>';
@ -227,14 +227,97 @@
});
// 调用后端接口
fetch('/api/update-prerequisites', {
fetch('/api/update-knowledge', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
node_id: nodeId,
prerequisites: selectedNodes
knowledge: selectedNodes, // 修改参数名
update_type: 'prerequisite'
})
})
.then(response => response.json())
.then(data => {
if (data.code === 0) {
layer.msg('保存成功', {icon: 1});
setTimeout(() => location.reload(), 1000);
} else {
layer.msg('保存失败: ' + data.message, {icon: 2});
}
})
.catch(error => {
console.error('Error:', error);
layer.msg('保存出错', {icon: 2});
});
layer.close(index);
}
});
form.render();
});
}
function relatedUpdate(nodeId) {
layui.use(['layer', 'form'], function () {
var layer = layui.layer;
var form = layui.form;
// 获取当前节点
const currentNode = findNodeById(treeData, nodeId);
// 构建HTML内容
let html = '<div style="padding: 20px;">';
html += '<form class="layui-form">';
allNodes.forEach(node => {
if (node.id !== nodeId && !node.isParent) {
const isSelected = currentNode && currentNode.related &&
currentNode.related.some(p => p.id === node.id);
// 获取父节点标题
const parentTitle = findParentTitle(node);
const displayTitle = parentTitle ? `【${parentTitle}】${node.title}` : node.title;
html += '<div class="layui-form-item">';
html += '<input type="checkbox" name="node" value="' + node.id + '" title="' + displayTitle + '"' + (isSelected ? ' checked' : '') + '>';
html += '</div>';
}
});
html += '</form>';
html += '</div>';
// 弹出层
layer.open({
type: 1,
title: '选择相关知识',
content: html,
area: ['500px', '400px'],
btn: ['确定', '取消'],
yes: function (index, layero) {
const selectedNodes = [];
$('input[name="node"]:checked').each(function () {
const node = findNodeById(treeData, $(this).val());
if (node) {
selectedNodes.push({
id: node.id,
title: node.title
});
}
});
// 调用后端接口
fetch('/api/update-knowledge', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
node_id: nodeId,
knowledge: selectedNodes, // 修改参数名
update_type: 'related'
})
})
.then(response => response.json())

Loading…
Cancel
Save