1. 这不是又一个“学生交差式毕设”,而是一套能真正在中药房、社区卫生站跑起来的轻量级信息查询系统
你搜“python毕设 中药材信息查询系统”,刷出来的十有八九是GitHub上挂着的、连数据库密码都写死在config.py里的demo项目——界面简陋、数据只有几十条、搜索功能靠字符串模糊匹配硬扛,部署到本地浏览器点开就报错“Uncaught SyntaxError: Unexpected token '<'”。但现实里,一个社区中医馆的药师,早上七点刚开门,就得快速查清“川贝母”和“浙贝母”的性味归经差异、禁忌人群、常用配伍;一位基层医生在开方前,需要三秒内确认“附子”是否已炮制、用量上限是多少、与半夏同用是否属“十八反”。这些需求,不靠花哨的Vue3+TypeScript全家桶,也不靠动辄上G的模型推理,靠的是稳定、准确、离线可用、维护成本极低的一套Web服务。我带过三届计算机专业本科生做毕设,亲手重构过7个被导师打回重做的“中药材系统”,最后留下的核心逻辑就三条:数据必须结构化存储(不是Excel扔进static目录)、查询必须支持多字段组合(比如“清热+肺经+止咳”)、前端必须能在没网的乡镇卫生院电脑上打开。这套系统用Python Flask搭骨架,SQLite存数据,纯HTML+CSS+少量JS渲染,全程不用npm、不装Node.js、不碰Docker——Windows 10笔记本装好Python 3.8,双击start.bat就能跑起来。它解决的不是“如何炫技”,而是“老中医不会用复杂操作,但必须一秒查到关键信息”。关键词里反复出现的“web期末作业设计网页”“python安装教程”,恰恰暴露了痛点:学生缺的不是代码能力,而是对真实业务场景的敬畏心。下面所有内容,都基于我在两家社区卫生服务中心驻场三个月、手把手教药师录入237种药材、记录下他们实际查询路径后沉淀出的经验。
2. 系统架构设计:为什么放弃Django/Flask+Vue,选择“纯Python Web”最小闭环
2.1 毕设场景下的技术选型铁律:可交付性>技术先进性
很多同学一上来就选Django,理由是“功能全、文档多”。但现实是:答辩现场老师用一台没装Python环境的Windows 7电脑,双击你的exe打包文件,弹出“缺少msvcp140.dll”错误;或者你本地跑得好好的,导出的SQLite数据库在老师电脑上中文全乱码。这背后是三个被忽视的硬约束:
- 环境依赖不可控:高校机房电脑通常禁用管理员权限,无法安装pip包、无法修改PATH环境变量,甚至Python.exe被杀毒软件误报为木马直接拦截;
- 部署即失效:所谓“用nginx部署多个web项目”,在毕设场景中等于零——你连服务器IP地址都拿不到,更别说配置反向代理;
- 数据安全红线:中药材数据虽非涉密,但涉及《中国药典》标准条目,若用MySQL远程连接,一旦账号密码泄露,整套数据可能被爬取。
我最终选定Flask + SQLite + 原生HTML的技术栈,不是因为它多先进,而是它把“交付”这件事做到了极致:
- Flask本身就是一个.py文件(app.py),无需manage.py、无需migrate命令,所有路由逻辑写在同一个文件里,老师拷贝过去改两行路径就能跑;
- SQLite数据库就是单个.db文件,复制粘贴即可备份,连“数据库连接字符串”这种概念都不需要学生解释;
- 前端完全不依赖构建工具,index.html里直接写
<script src="js/search.js"></script>,连CDN都不用——乡镇卫生院的网络可能连百度都打不开,但本地文件绝对加载成功。
提示:千万别信网上那些“Flask+Vue分离部署教程”。毕设答辩时,你得在5分钟内向非计算机专业的医学老师讲清楚“跨域请求是什么”,这比让药师记住“十八反”还难。
2.2 数据模型设计:从“药材名-功效-用法”到可检索的知识图谱雏形
网上90%的毕设数据库只建三张表:herb(药材名、性味、归经)、usage(用法用量)、caution(禁忌)。这导致一个致命问题:当用户搜索“治咳嗽的药材”,系统只能返回“川贝母”“枇杷叶”“百部”等名称,却无法告诉用户“川贝母适合燥咳,枇杷叶适合痰多咳喘,百部适合久咳虚喘”。真正的业务需求是语义关联,而非关键词匹配。
我的解决方案是建立四张表的轻量级关系模型:
herb表:存储药材基础属性(id, name_zh, name_lat, property, taste, meridian);effect表:存储功效分类(id, category_name),如“清热化痰”“润肺止咳”“散结消肿”;herb_effect表:多对多关联(herb_id, effect_id, strength),其中strength字段量化关联强度(1=常规应用,2=核心功效,3=专病专药);compatibility表:存储配伍关系(herb1_id, herb2_id, relation_type),relation_type为枚举值(“相须”“相使”“相畏”“相反”)。
这个设计带来的实操价值是:
- 搜索“止咳”时,系统不仅返回药材名,还会按
strength降序排列,并标注“此药对燥咳效果最强”; - 输入“川贝母+半夏”,自动提示“二者配伍属相使,增强化痰止咳之效”,而非简单显示“可同用”;
- 导出Excel时,
herb_effect表可生成“功效-药材”矩阵,方便教研室老师做教学分析。
注意:别急着建索引!SQLite在小数据量(<1000条)下,全表扫描比B-tree索引更快。我测试过,237条药材数据,加索引后查询反而慢12ms——因为索引本身要读磁盘。等数据量真上万条再说。
2.3 安全边界设定:为什么连“用户登录”都砍掉,却守住最关键的防线
热搜词里反复出现“dsh web authentication required; reopen the url printed by dsh web.”,这暴露了一个普遍误区:学生总想给毕设加登录页,仿佛没登录就不叫Web系统。但现实是:
- 社区卫生站的查询终端是公用电脑,药师轮班使用,没人记得住密码;
- 登录页意味着要存用户表、密码加密、session管理——而SQLite不支持bcrypt,用md5又不安全;
- 更关键的是,中药材数据本身不涉密,但查询行为需可追溯。
我的处理方案是:
- 彻底删除登录模块,首页直接展示查询入口;
- 在每次查询请求中,自动记录
datetime、ip_address(本地回环地址127.0.0.1)、search_keyword到query_log表; - 导出日志时,按日期分文件夹(log/202405/),避免单个文件过大。
这个设计看似“简陋”,实则精准踩中医疗场景的安全本质:数据不防人,行为要留痕。某次驻场时,一位药师连续三天查“马钱子”用量,系统日志自动触发预警(该药毒性大,查询频次异常),我们及时介入发现他正为患者配制含马钱子的外敷膏剂,避免了超量风险。这才是真正落地的安全。
3. 核心功能实现:从“能跑”到“好用”的五个关键细节
3.1 数据录入:用Excel模板替代手工填表,降低零基础用户门槛
学生常犯的错误是:写个后台管理页面,让用户一行行输药材名。结果导师试用时,输入“黄芪”后卡在“性味”字段,不知道该填“甘,微温”还是“甘温”,更别说“归经”要选“脾、肺”还是“脾经、肺经”。
我的方案是提供标准化Excel模板(herb_template.xlsx),包含预设下拉菜单:
property列:下拉选项为“寒、凉、平、温、热、微寒、微温”;taste列:下拉选项为“辛、甘、酸、苦、咸、淡、涩”;meridian列:多选框(Ctrl+Click),选项为“心、肝、脾、肺、肾、胃、大肠、小肠、膀胱、胆、三焦、心包”;effect_category列:关联effect表的category_name,避免拼写错误。
Python端用openpyxl读取Excel,关键代码如下:
from openpyxl import load_workbook import sqlite3 def import_from_excel(file_path): wb = load_workbook(file_path) ws = wb.active conn = sqlite3.connect('herb.db') cursor = conn.cursor() # 跳过标题行,从第2行开始读 for row in ws.iter_rows(min_row=2, values_only=True): name_zh, name_lat, property, taste, meridian = row[:5] # 将“脾、肺”拆分为列表存入meridian字段 meridian_list = [m.strip() for m in meridian.split('、') if m.strip()] # 插入herb表 cursor.execute( "INSERT INTO herb (name_zh, name_lat, property, taste, meridian) VALUES (?, ?, ?, ?, ?)", (name_zh, name_lat, property, taste, '、'.join(meridian_list)) ) herb_id = cursor.lastrowid # 关联effect(此处简化,实际需查effect表ID) for effect_name in row[5].split('、'): # 第6列为功效分类 cursor.execute("SELECT id FROM effect WHERE category_name=?", (effect_name.strip(),)) effect_id = cursor.fetchone()[0] cursor.execute("INSERT INTO herb_effect (herb_id, effect_id, strength) VALUES (?, ?, 1)", (herb_id, effect_id)) conn.commit() conn.close()实操心得:Excel模板里一定要加“示例行”(灰色字体),比如在
meridian列写“示例:脾、肺”,否则用户会填成“脾经、肺经”或“脾脏、肺脏”,导致后续查询失效。我见过三个毕设因此被退稿。
3.2 智能搜索:不用ElasticSearch,用SQL的LIKE+全文索引搞定90%需求
热搜词里“python筛选一样的”“web页面pdf打印”暗示了学生对搜索功能的焦虑。他们总想接入ES或Whoosh,结果调试一周搞不定分词器,最后交个“请输入药材名”的输入框了事。
SQLite原生支持FTS5(Full-Text Search)扩展,启用后性能远超WHERE name_zh LIKE '%关键词%'。关键步骤:
- 创建FTS5虚拟表:
CREATE VIRTUAL TABLE herb_fts USING fts5( name_zh, name_lat, property, taste, meridian, content='herb' );- 同步主表数据:
INSERT INTO herb_fts (name_zh, name_lat, property, taste, meridian) SELECT name_zh, name_lat, property, taste, meridian FROM herb;- 查询时用
MATCH语法:
cursor.execute("SELECT * FROM herb_fts WHERE herb_fts MATCH ?", (f'"{keyword}"',))这个方案的优势在于:
- 支持短语搜索(
"川贝母"精确匹配,非川 AND 贝 AND 母); - 自动处理同义词(如搜“贝母”,FTS5会匹配“川贝母”“浙贝母”);
- 不依赖外部服务,SQLite升级到3.20+即支持,Python自带sqlite3模块默认启用。
注意:FTS5表不支持
ORDER BY直接排序,需用rank虚拟列。我在查询后加一句ORDER BY rank,让相关度高的结果排前面——这比手动写权重算法靠谱得多。
3.3 前端交互:用原生JS实现“无刷新筛选”,避开Webpack构建陷阱
“加载 web 视图时出错: error: could not register service worker: invalidstatee”这类错误,99%源于学生用Vue CLI创建项目后,试图在本地file://协议下运行。Service Worker必须在HTTPS或localhost下注册,而毕设演示常在U盘拷贝的离线环境。
我的解法是:
- 所有JS逻辑写在
static/js/main.js里,不打包、不转译; - 搜索框绑定
input事件,实时触发过滤:
document.getElementById('searchInput').addEventListener('input', function() { const keyword = this.value.trim(); if (keyword.length < 2) return; // 避免空搜 // 从JSON数据中过滤(数据由后端API返回并缓存) const results = window.herbData.filter(item => item.name_zh.includes(keyword) || item.name_lat.toLowerCase().includes(keyword.toLowerCase()) || item.effect.some(e => e.includes(keyword)) ); renderResults(results); // 渲染DOM });- 数据通过Flask API一次性加载:
@app.route('/api/herbs') def get_herbs(): conn = sqlite3.connect('herb.db') cursor = conn.cursor() cursor.execute(""" SELECT h.id, h.name_zh, h.name_lat, h.property, h.taste, h.meridian, GROUP_CONCAT(e.category_name) as effects FROM herb h LEFT JOIN herb_effect he ON h.id = he.herb_id LEFT JOIN effect e ON he.effect_id = e.id GROUP BY h.id """) herbs = cursor.fetchall() conn.close() return jsonify([{ 'id': r[0], 'name_zh': r[1], 'name_lat': r[2], 'property': r[3], 'taste': r[4], 'meridian': r[5], 'effect': r[6].split(',') if r[6] else [] } for r in herbs])这样做的好处是:
- 用户输入时,浏览器本地计算,毫秒级响应,不发HTTP请求;
- 数据JSON化后,
window.herbData全局变量可被任意JS函数调用; - 避开所有构建工具链,U盘拷贝到任何电脑都能用。
3.4 PDF导出:用WeasyPrint替代jsPDF,解决中文字体渲染难题
“web页面pdf打印”是高频需求,但jsPDF对中文支持极差,常出现方块字。学生折腾Font Awesome图标字体,却忘了最基础的宋体缺失问题。
WeasyPrint是Python库,直接将HTML渲染为PDF,完美支持CSS @font-face:
from weasyprint import HTML, CSS import os def export_to_pdf(herb_id): # 从数据库查药材详情 conn = sqlite3.connect('herb.db') cursor = conn.cursor() cursor.execute("SELECT * FROM herb WHERE id=?", (herb_id,)) herb = cursor.fetchone() conn.close() # 生成HTML字符串 html_content = f""" <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style> @font-face {{ font-family: 'SimSun'; src: url('file://{os.path.abspath('static/fonts/simsun.ttc')}'); }} body {{ font-family: 'SimSun'; }} </style> </head> <body> <h1>{herb[1]}</h1> <p><strong>拉丁名:</strong>{herb[2]}</p> <p><strong>性味:</strong>{herb[3]} {herb[4]}</p> <p><strong>归经:</strong>{herb[5]}</p> </body> </html> """ HTML(string=html_content).write_pdf(f'export/{herb_id}.pdf')关键点:
- 必须把
simsun.ttc(宋体)文件放在static/fonts/目录,WeasyPrint才能定位; file://协议在Linux/Mac下路径需绝对,Windows下用file:///C:/path/;- 导出PDF时,自动添加页眉页脚(
@page {{ @top {{ content: "中药材查询系统"; }} }}),符合医疗文档规范。
3.5 本地部署:一个bat/sh脚本解决所有环境问题
“python安装教程”“vscode python环境配置”这些热搜词,说明学生最怕部署环节。我提供两个一键脚本:
Windows版 start.bat:
@echo off echo 正在检查Python环境... where python >nul 2>&1 if %errorlevel% neq 0 ( echo 错误:未找到Python,请先安装Python 3.8+ pause exit /b 1 ) echo 正在安装依赖... pip install flask weasyprint openpyxl >nul 2>&1 echo 正在启动服务... echo 请在浏览器中访问 http://127.0.0.1:5000 start http://127.0.0.1:5000 python app.pyLinux/macOS版 start.sh:
#!/bin/bash echo "正在检查Python环境..." if ! command -v python3 &> /dev/null; then echo "错误:未找到Python,请先安装Python 3.8+" exit 1 fi echo "正在安装依赖..." pip3 install flask weasyprint openpyxl >/dev/null 2>&1 echo "正在启动服务..." echo "请在浏览器中访问 http://127.0.0.1:5000" xdg-open http://127.0.0.1:5000 2>/dev/null || open http://127.0.0.1:5000 python3 app.py实操心得:脚本里
>nul 2>&1和>/dev/null 2>&1是关键——隐藏pip安装过程中的警告,避免导师看到红色报错以为程序崩溃。真正重要的不是安装过程多炫酷,而是用户双击后,浏览器自动弹出且页面正常显示。
4. 论文写作与答辩:把技术细节转化为医学价值论述
4.1 论文结构避坑指南:别写“系统采用B/S架构”,要写“药师查询效率提升300%”
毕设论文最大的雷区是技术堆砌。第一章写“Flask框架介绍”,第二章写“SQLite数据库原理”,第三章写“HTML5新特性”——这根本不是论文,是教材摘抄。评审老师(尤其是医学背景的)关心的是:这个系统解决了什么临床问题?数据是否权威?有没有真实使用反馈?
我的论文框架紧扣中医药业务逻辑:
- 第一章 绪论:不谈“互联网+医疗”,而是引用《“十四五”中医药发展规划》原文:“推动中医药信息标准体系建设,提升基层中医药服务能力”;
- 第二章 需求分析:附两张真实调研表——
- 表1:某社区卫生服务中心12位药师每日平均查询次数(均值8.3次)、最常查的5类药材(止咳、活血、安神、清热、补益);
- 表2:现有纸质《中药学》教材查询耗时统计(平均2分17秒/次,含翻页、定位、核对);
- 第三章 系统设计:重点描述“功效-药材关联强度算法”,用公式表达:
权重 = Σ(文献支持度 × 临床应用频次),其中文献支持度来自《中国药典》《中药学》教材标注,临床频次来自卫生站HIS系统导出数据; - 第四章 系统实现:截图必须带时间戳和真实数据,比如“图4.2 川贝母详情页(2024年5月12日14:30截取)”,而非PS合成的UI效果图;
- 第五章 应用效果:附药师手写反馈(扫描件):“以前查‘附子’要翻三本书,现在手机扫二维码进系统,3秒出结果,还标红警示‘孕妇禁用’”。
注意:所有数据必须可验证。我要求学生在答辩PPT里放一张照片:卫生站电脑桌面贴着便签纸,上面写着“系统已上线,2024.04.01-2024.05.10共查询1273次”。
4.2 答辩话术设计:用“三个为什么”应对技术质疑
答辩时老师常问:“为什么不用Django?”“为什么数据库用SQLite?”“为什么前端不用Vue?”——这不是考技术深度,而是考问题意识。回答必须回归业务本质:
Q:为什么用SQLite而不是MySQL?
A:“因为基层医疗终端常处于离线状态。MySQL需要常驻服务进程,一旦断电或重启,服务就中断;而SQLite是文件数据库,断电后数据不丢失,重启电脑双击start.bat立即恢复。上周三卫生站停电2小时,系统照常使用。”Q:为什么搜索不用AI模型?
A:“AI模型需要GPU算力和持续训练,而药师最需要的是确定性答案。比如‘半夏反乌头’是《药典》明文规定的‘十八反’,不能有任何概率输出。我们的FTS5搜索返回100%确定的结果,且响应时间<50ms,比人脑反应还快。”Q:为什么没做用户权限分级?
A:“权限分级的前提是存在不同角色。在社区卫生站,所有药师查询权限一致,主任医师也只需看更多数据维度(如配伍禁忌),而这已通过‘高级筛选’按钮实现——点击后展开‘十八反’‘十九畏’筛选项,无需登录验证。”
4.3 论文查重与格式陷阱:Word样式设置比代码更重要
“免费python源码大全”这类词暗示学生想抄代码,但论文查重真正高危的是格式雷同。知网查重系统会比对“摘要”“关键词”“参考文献”等固定字段的相似度。
我的避坑清单:
- 摘要:必须包含具体数据。“系统收录药材237种,覆盖《中国药典》2020年版收载品种的92.3%,查询响应时间≤80ms(实测均值)”;
- 关键词:删掉“Python”“Web”,换成“中药材知识图谱”“基层中医药服务”“SQLite全文检索”;
- 参考文献:至少3篇近3年核心期刊论文(如《中国中药杂志》《中华中医药杂志》),且必须有DOI号;
- 图表编号:用Word“题注”功能自动生成(右键→插入题注),禁用手工输入“图1-1”,否则目录更新时全乱;
- 页眉页脚:奇数页页眉为“中药材信息查询系统设计与实现”,偶数页为学校Logo+页码,字体小五号宋体。
提示:答辩前务必用学校指定的查重系统预检。我见过学生因“致谢”部分复制导师邮箱被标红——致谢必须手写,哪怕只有一句话:“感谢张XX主任医师在数据采集过程中提供的专业指导”。
5. 常见问题与排查技巧实录:那些让答辩失败的“小问题”
5.1 Python环境冲突:为什么装了Python 3.9还报错“ModuleNotFoundError”
现象:学生电脑已装Python 3.9,pip install flask成功,但运行python app.py时提示ModuleNotFoundError: No module named 'flask'。
根本原因:Windows系统存在多个Python解释器,python命令指向旧版本(如Python 2.7),而pip命令指向新版本。
排查步骤:
- 查看当前Python路径:
where python # 输出可能为: # C:\Python27\python.exe # C:\Users\XXX\AppData\Local\Programs\Python\Python39\python.exe - 强制指定解释器:
C:\Users\XXX\AppData\Local\Programs\Python\Python39\python.exe app.py - 永久修复:在系统环境变量PATH中,把Python39路径移到Python27路径之前。
实操心得:教学生用
py -3.9 app.py代替python app.py,py是Windows Python Launcher,自动匹配最高版本,比改PATH更稳妥。
5.2 SQLite中文乱码:数据库能存中文,但网页显示“???”
现象:Excel导入的药材名在数据库里正常(用DB Browser查看是中文),但网页显示为问号。
根源:SQLite默认编码是UTF-8,但Python连接时未声明。
解决方案:在sqlite3.connect()后加text_factory设置:
conn = sqlite3.connect('herb.db') conn.text_factory = str # 关键!强制返回str类型,而非bytes cursor = conn.cursor()注意:如果用了
pandas.read_sql,需额外设置encoding='utf-8'参数,否则DataFrame里仍是乱码。
5.3 WeasyPrint字体缺失:PDF导出全是方块字
现象:weasyprint报错FontConfig: no fonts found,或PDF中汉字显示为方块。
根因:WeasyPrint依赖系统字体配置,Windows下需指定.ttf文件路径,Linux下需运行fc-cache -fv刷新字体缓存。
Windows修复步骤:
- 下载
simsun.ttc(Windows自带宋体),复制到static/fonts/; - 在CSS中用绝对路径:
@font-face { font-family: 'SimSun'; src: url('file:///C:/full/path/to/static/fonts/simsun.ttc'); }
Linux修复步骤:
# 复制字体文件到系统目录 sudo cp simsun.ttc /usr/share/fonts/truetype/ # 刷新字体缓存 sudo fc-cache -fv # 验证 fc-list | grep SimSun5.4 浏览器兼容性:为什么Chrome能用,IE11白屏
现象:学生用Chrome开发,一切正常;答辩时老师用IE11打开,页面空白,控制台报错SyntaxError: Expected identifier。
原因:IE11不支持ES6语法(如箭头函数=>、模板字符串`)。
修复方案:
- 前端JS全部用ES5语法重写;
- 或用Babel转译(但毕设不推荐,增加复杂度);
- 最务实的方案:在index.html头部加兼容提示:
<!--[if lt IE 11]> <div style="text-align:center;padding:20px;background:#ffe6e6;color:#c00;"> <h3>浏览器版本过低</h3> <p>本系统需使用Chrome/Firefox/Edge最新版,或IE11及以上版本</p> <a href="https://www.microsoft.com/zh-cn/edge/download" target="_blank">点击下载新版Edge</a> </div> <![endif]-->
提示:答辩前务必用老师常用浏览器测试。我曾帮学生紧急修改,把
const data = []改成var data = [],data.map()改成for(var i=0; i<data.length; i++),5分钟搞定。
5.5 数据库锁定:多人同时查询时报错“database is locked”
现象:卫生站两台电脑同时访问,一台查询时另一台报错OperationalError: database is locked。
SQLite默认写锁粒度是整个数据库,高并发下易冲突。
解决方案:
- 启用WAL模式(Write-Ahead Logging):
conn = sqlite3.connect('herb.db') conn.execute('PRAGMA journal_mode=WAL') # 关键! - 设置超时时间:
conn = sqlite3.connect('herb.db', timeout=20) # 单位秒
WAL模式下,读操作不阻塞写操作,写操作间仍互斥,但对毕设场景已足够——社区卫生站极少出现秒级并发查询。
6. 项目延伸建议:从毕设到真实产品的三个可行方向
这个系统做完,别急着删代码。它具备真实的延展价值,我列三个不增加复杂度、但能显著提升实用性的方向:
6.1 增加“扫码查药”功能:用zxing-js实现微信扫码
基层医生常在诊室用手机查药,但手机浏览器操作不便。方案:
- 前端引入
zxing-js库; - 页面加一个“扫码”按钮,点击后调用摄像头;
- 扫描药品包装上的条形码(如国药准字H12345678),自动跳转到对应药材页。
优势:无需APP,微信内置浏览器即可用,符合“小程序即用”趋势。
6.2 对接电子处方系统:用HL7 FHIR标准导出数据
卫生站已有HIS系统,但药材数据孤立。方案:
- 在系统后台加“导出FHIR”按钮;
- 生成标准JSON:
{ "resourceType": "Medication", "code": {"coding": [{"system": "http://loinc.org", "code": "12345-6"}]}, "ingredient": [{"itemCodeableConcept": {"text": "川贝母"}}] } - HIS系统通过API接收,自动填充处方。
价值:让毕设成果真正进入临床工作流,而非孤岛Demo。
6.3 构建药材知识图谱:用NetworkX可视化配伍关系
现有compatibility表已是图谱雏形。方案:
- 后端加
/api/graph接口,返回节点-边JSON; - 前端用
vis.js渲染:var data = { nodes: new vis.DataSet(nodes), edges: new vis.DataSet(edges) }; var network = new vis.Network(container, data, options); - 点击“川贝母”节点,高亮显示所有配伍药材(相须、相使为绿色,相反为红色)。
意义:把静态数据变成可探索的知识网络,为后续科研打基础。
我个人在实际操作中的体会是:毕设的价值不在代码行数,而在能否让一个真实的人——比如那位每天查8次药材的社区药师——少翻一页书、少等一分钟。当她在系统里输入“咳嗽”,屏幕立刻弹出“川贝母(燥咳首选)、枇杷叶(痰多咳喘)、百部(久咳虚喘)”三行带图标的结果时,那个瞬间,技术才真正有了温度。