From 184e5ebbb72c071bb7e349b03863fd79eacdbb03 Mon Sep 17 00:00:00 2001 From: HuangHai <10402852@qq.com> Date: Wed, 2 Jul 2025 20:17:36 +0800 Subject: [PATCH] 'commit' --- dsRag/Start.py | 72 +++++++++----- dsRag/Util/MySQLUtil.py | 5 +- .../__pycache__/MySQLUtil.cpython-310.pyc | Bin 1477 -> 1499 bytes dsRag/static/tree.html | 91 +++++++++++++++++- 4 files changed, 134 insertions(+), 34 deletions(-) diff --git a/dsRag/Start.py b/dsRag/Start.py index 1b1e1102..1166a77d 100644 --- a/dsRag/Start.py +++ b/dsRag/Start.py @@ -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)} diff --git a/dsRag/Util/MySQLUtil.py b/dsRag/Util/MySQLUtil.py index a6269e93..59e878dc 100644 --- a/dsRag/Util/MySQLUtil.py +++ b/dsRag/Util/MySQLUtil.py @@ -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() - - - - diff --git a/dsRag/Util/__pycache__/MySQLUtil.cpython-310.pyc b/dsRag/Util/__pycache__/MySQLUtil.cpython-310.pyc index 45ab5be6a9517bb2b1b8d2bbbf822fa07dba746f..9c44fc773fdcc49fad337dfa05c3605dfd8b9f01 100644 GIT binary patch delta 392 zcmX@geVbc5pO=@50SM;Fr)Df-Wng#=;vfS~AjbiSi?b$b`zoby&EbgRPvK7CX<>*G z;AH1yOyN)AP2p={j1o*?3TDt0m^h=tEsDLgB+Vi>$wZUm7E4Bcamg)~g8U*NSz4T0 zbc>@PvADQAzbNGvQ%ce;_T0?8;>@a4AS1B?!br|YEGkYdne4*o&n*D7x(Gr{p2z6O zF9UK43y@%H5MeA5-u#ZSm`NF-NC+r%OQ<-pEHxfzN=bZ4etd3aabb?)o;*a7}QaCT_0YtSt|h?)S$;NWooAeURb5Wb63yq}}5Ymp$x zS;8Pf0Yo4i0A_(*!C{k|pHiBWYR3pvQLF|eSQt2%d6*_IXBFXLVr2Wl!OO(T#K`v_ E0OUPn6#xJL delta 341 zcmcc3eUw`}pO=@50SLI~resWDWng#=;vfSKAjbiSi!&x_`zp*~kK#|^O5tu{h!Wsr z=VVObOW{f3ZDEWOOkoOU(Bz*utAa_BeX=a0f>0EDZf0I_W>xAf_T0n@5My!#qdzwv z(5xZ|F?kcCBfm7rY!)EF)F8rGB)FN0sh9~#k-+2z7I8*}$un4#8RaJLVQHw3;_{6Q z4)lrl@DC1wu><^r;Ox*~*Ptjqh?)S$;NWooAeSg!2;api-p|q3wTK_&2tg1b2O^N% z1mX$+iCY{tx%nxjIjMGxKwhy5kYHipVCG?x<6shC=3-=GVPZr;wx1k4Osq_deE$LZ C1w(HD diff --git a/dsRag/static/tree.html b/dsRag/static/tree.html index e6c91d30..2fd3283c 100644 --- a/dsRag/static/tree.html +++ b/dsRag/static/tree.html @@ -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 += '' + (node.prerequisite && node.prerequisite.length > 0 ? node.prerequisite.map(p => p.title).join(', ') : '') + ''; - html += '' + (node.related || '') + ''; + html += '' + (node.related && node.related.length > 0 ? + node.related.map(r => r.title).join(', ') : '') + ''; html += '' + (isThirdLevel ? ' ' + '' : '') + ''; @@ -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 = '
'; + html += '
'; + + 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 += '
'; + html += ''; + html += '
'; + } + }); + + html += '
'; + html += '
'; + + // 弹出层 + 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())