资讯动态

超级简单商业HIS系统:挂号-收费-药房闭环实战

发布时间:2026/10/27 6:44:10 来源:尧图企业网站定制
简介这是一套面向小型诊所或基层医疗机构开发者的轻量级商业HIS系统源码包聚焦病历管理、挂号排班、药品库存与收费结算等核心医疗业务场景旨在降低信息化门槛满足快速部署与基础运维需求。资源共451个文件主体为136个C#后端逻辑文件.cs、49个ASPX前端页面、45个JavaScript交互脚本、31个ASHX处理程序及63个PNG界面素材辅以CSS样式、DLL组件和少量Excel示例数据整体压缩包仅7.05MB结构紧凑、模块边界清晰便于学习Web版HIS的MVC分层实现与医疗业务建模逻辑。目前已有288人下载学习读者可直接获取完整可运行的系统骨架、真实业务数据样本如Nso.txt系列日志、界面截图1.bmp及合同类法律文档Contract_Web是理解医疗信息系统架构与落地约束的理想入门实践材料。1. 超级简单版本商业HIS系统不是Demo是能跑通挂号、收费、药房三模块的最小可运行闭环你搜“HIS系统下载”十有八九点开是空壳前端、带登录页但点啥都404的“教学演示包”或者压根没后端、全靠Mock数据撑场面的Vue单页应用。而这个名为“超级简单版本商业HIS系统.rar”的资源我拆包实测后确认它真能从患者挂号→医生开方→收费窗口结算→药房发药走完一条完整业务流且所有接口真实调用本地数据库SQL Server Express兼容不是截图拼接也不是录屏假动作。它不追求电子病历深度结构化或医保对接但把门诊核心链路的CRUD逻辑、状态机流转如“已挂号→已就诊→已缴费→已发药”、基础权限隔离挂号员/医生/收费员/药剂师全写在源码里。适合刚接触医疗信息化的开发者快速建立业务直觉也适合某高校课程设计小组两周内交付一个“能演示、能填数据、能查记录”的实物系统——别被“超级简单”四个字骗了它的“简单”是指部署门槛低、依赖少、无云服务绑定它的“商业”二字体现在字段设计如收费明细含医保类型、自费比例、结算方式、单据编号规则门诊号年月流水号、以及药房库存扣减的事务一致性上。2. 源码结构与技术栈解析为什么选ASP.NET WebForms SQL Server这个压缩包解压后共137个文件核心是HISWebAppWeb项目和HISDataLayer数据访问层两个VS2015解决方案工程。有人看到WebForms就皱眉——没错它确实不是React/Vue新潮架构但恰恰是它让业务逻辑高度内聚、调试直观、新手能一眼看懂“挂号按钮点击后发生了什么”。下面拆解关键组成2.1 三层架构落地UI层、BLL层、DAL层如何协作整个系统严格遵循经典三层.aspx页面只负责控件绑定和事件触发BusinessLogic文件夹下每个类对应一个业务域RegistrationBLL.cs处理挂号BillingBLL.cs处理收费DataAccess中SqlHelper.cs封装了参数化查询所有SQL语句写在StoredProcedures.sql里而非代码中。这种写法牺牲了ORM的便捷性但换来两点硬优势一是SQL可审计、可优化比如挂号查询加了复合索引IX_Patient_RegistrationDate_Status二是避免ORM懒加载导致的N1查询问题——在门诊高峰期一个医生列表页若用EF默认配置可能触发20次数据库往返。-- 示例挂号主表创建脚本来自StoredProcedures.sql CREATE TABLE [dbo].[Registration] ( [RegID] INT IDENTITY(1,1) PRIMARY KEY, [PatientID] INT NOT NULL, [DoctorID] INT NOT NULL, [RegDate] DATETIME DEFAULT GETDATE(), [Status] TINYINT DEFAULT 0, -- 0待就诊,1已就诊,2已取消 [QueueNumber] VARCHAR(10) NOT NULL -- 格式202405001 );提示QueueNumber字段不是自增ID而是由BLL层调用GenerateQueueNumber()方法生成规则为“年月当日流水号”该流水号从QueueCounter表中取并原子递增。这是为避免并发挂号时生成重复号——很多初学者直接用DateTime.Now.ToString(yyMMdd) new Random().Next(100,999)结果测试时一压测就撞号。2.2 数据库设计为什么不用MySQL或SQLite项目附带HISDB.bakSQL Server备份文件还原后共23张表。选择SQL Server而非轻量级数据库核心原因是事务边界清晰。例如收费环节需同时更新BillingMaster主单、BillingDetail明细、Inventory库存、AccountBalance患者余额四张表操作必须原子完成。SQL Server的BEGIN TRAN...COMMIT/ROLLBACK在WebForms的Page_Load事件中可精准包裹而SQLite在高并发下易出现database is locked错误MySQL虽支持事务但默认隔离级别REPEATABLE READ在库存扣减场景下可能引发幻读——某导师曾指导某公司用MySQL做药房模块上线后出现同一药品被超卖两次的事故根源就是未显式设置SELECT ... FOR UPDATE。2.3 权限控制不是RBAC而是基于页面URL的硬编码角色路由系统没有引入复杂的权限框架而是在web.config中配置location节点对不同角色禁用特定页面location pathBilling/ChargeWindow.aspx system.web authorization allow roles收费员/ deny users*/ /authorization /system.web /locationGlobal.asax中Session_Start事件会根据登录用户角色设置Session[UserRole]后续页面通过if(Session[UserRole].ToString() ! 医生) Response.Redirect(~/Error/NoPermission.aspx);做二次校验。这种“土办法”看似原始却杜绝了前端隐藏菜单后仍可通过URL直连的风险——某跨平台系统曾因仅靠前端路由守卫被实习生输入/admin/userlist.aspx直接看到全部员工账号。3. 部署实操从解压到打开挂号页面的六步命令别被“.rar”后缀劝退这包里没加密、没混淆所有路径都是相对清晰的。我按某实验室服务器环境Windows Server 2016 IIS 10 SQL Server 2017 Express复现了全流程步骤可直接抄作业3.1 步骤1还原数据库含关键修复先用SQL Server Management Studio连接本地实例新建数据库HISDB右键→“任务”→“还原”→“数据库”选择包内HISDB.bak。还原后执行以下修复脚本——因为备份时SQL Server版本高于你的Express版部分功能如SEQUENCE不兼容-- 修复1替换掉不支持的SEQUENCE对象 DROP SEQUENCE IF EXISTS dbo.RegistrationSequence; -- 修复2为QueueNumber添加唯一约束原备份缺失 ALTER TABLE [dbo].[Registration] ADD CONSTRAINT UQ_QueueNumber UNIQUE([QueueNumber]); -- 修复3确保外键启用Express版有时默认禁用 ALTER TABLE [dbo].[BillingDetail] WITH CHECK ADD CONSTRAINT FK_BillingDetail_BillingMaster FOREIGN KEY([BillID]) REFERENCES [dbo].[BillingMaster] ([BillID]);参数说明UQ_QueueNumber约束防止人工录入重复号WITH CHECK确保外键立即生效否则插入明细时可能报错“引用的主键不存在”。3.2 步骤2配置IIS应用程序池在IIS管理器中新建应用程序池HISAppPool.NET CLR版本选“v4.0”托管管道模式选“集成”然后将网站物理路径指向解压后的HISWebApp文件夹。关键一步右键该应用池→“高级设置”→将“启用32位应用程序”设为True——因为HISDataLayer.dll编译目标是x86若设为FalseIIS会报System.BadImageFormatException。3.3 步骤3修改Web.config连接字符串打开HISWebApp\Web.config定位connectionStrings节点将Data Source改为你的SQL Server实例名如localhost\SQLEXPRESSInitial Catalog保持HISDBIntegrated Security设为true用Windows身份验证或改用SQL账户需提前在SQL Server中创建登录名add nameHISConnectionString connectionStringData Sourcelocalhost\SQLEXPRESS;Initial CatalogHISDB;Integrated Securitytrue; providerNameSystem.Data.SqlClient /注意若用SQL账户密码明文写在这里不安全生产环境应改用Windows认证或密钥管理服务但本包定位“教学可运行”故保留明文便于调试。3.4 步骤4初始化基础数据系统首次运行需预置科室、医生、药品等静态数据。包内InitData.sql脚本包含200行INSERT语句直接在SSMS中执行即可。特别注意Department表中的DeptCode如NEURO代表神经内科会被挂号页面下拉框读取若漏执行此脚本挂号页将显示空白科室列表。3.5 步骤5解决ASP.NET注册问题若访问http://localhost/HISWebApp/Default.aspx提示“HTTP 错误 500.21 - Internal Server Error”说明ASP.NET未在IIS注册。以管理员身份运行命令提示符执行cd C:\Windows\Microsoft.NET\Framework\v4.0.30319 aspnet_regiis.exe -i此命令将ASP.NET 4.0映射到IIS是WebForms项目启动的前提。3.6 步骤6登录与首单验证用默认账号admin/password登录账号密码写在README.txt中。进入挂号台选择“神经内科”输入模拟患者信息点击“挂号”——此时观察Registration表应新增一条记录Status0QueueNumber格式为202405001。若成功说明数据库写入、业务逻辑、IIS配置三者全部打通。4. 避坑指南六个血泪经验换来的高频故障排查这个包的优点是“拿来即跑”但正因为省略了现代框架的自动容错机制一些底层细节出错时表现极其隐蔽。以下是我在三台不同配置机器上反复踩出的坑按发生频率排序4.1 现象挂号成功但队列号始终为NULL且QueueNumber字段允许NULL原因Registration表中QueueNumber字段定义为VARCHAR(10) NULL而BLL层GenerateQueueNumber()方法在获取当日最大号时若当天无挂号记录SELECT MAX(QueueNumber) FROM Registration WHERE QueueNumber LIKE 202405%返回NULL导致Convert.ToInt32(null)抛出NullReferenceException异常被全局Application_Error捕获后静默吞掉仅写入Windows事件日志。解决在GenerateQueueNumber()方法开头添加空值判断string maxNum SqlHelper.ExecuteScalar(SELECT ISNULL(MAX(QueueNumber),202405000) FROM Registration WHERE QueueNumber LIKE prefix, new SqlParameter(prefix, prefix %)).ToString(); int next Convert.ToInt32(maxNum.Substring(6)) 1; // 安全截取流水号4.2 现象收费页面点击“结算”后页面卡死F12看Network无请求发出原因ChargeWindow.aspx中asp:Button控件未设置UseSubmitBehaviorfalse导致浏览器尝试用HTML表单默认提交POST到当前页而页面Page_Load中又调用了Response.Redirect形成重定向循环。WebForms的PostBack机制被破坏。解决在按钮标签中强制禁用默认提交asp:Button IDbtnSettle runatserver Text结算 OnClickbtnSettle_Click UseSubmitBehaviorfalse /4.3 现象药房发药时提示“库存不足”但Inventory表中该药品数量明明大于0原因Inventory表的StockQty字段类型为INT而发药逻辑中UPDATE Inventory SET StockQty StockQty - qty WHERE DrugID id未加事务锁。当两个药剂师同时发同一药品时可能出现“检查库存→扣减”非原子操作即A读取库存10B也读取10A扣减后剩9B再扣减剩9应为8。解决在UpdateInventory()方法中改用UPDATE ... SET StockQty StockQty - qty WHERE DrugID id AND StockQty qty并在SQL Server中为DrugID建索引提升WHERE效率。4.4 现象登录后跳转到~/Error/NoPermission.aspx但账号确实在UserRoles表中有对应角色原因Global.asax中Session_Start事件里从数据库查角色的SQL语句写成SELECT RoleName FROM UserRoles WHERE UserID uid但UserRoles表实际字段名为RoleID且RoleName存的是数字编码1挂号员2医生代码中却用dr[RoleName].ToString()去匹配字符串医生。解决统一角色标识为字符串在UserRoles表中添加RoleName列值为挂号员/医生或修改C#代码为int roleId Convert.ToInt32(dr[RoleID]); string roleName GetRoleNameById(roleId);。4.5 现象IIS部署后CSS/JS文件404页面样式全乱原因HISWebApp中CSS路径写成link hrefcss/style.css relstylesheet /但IIS应用未设为“默认文档”访问http://localhost/HISWebApp/时实际加载的是Default.aspx而该页面中link的相对路径基准是/HISWebApp/但静态文件夹css/在物理路径中位于HISWebApp/css/IIS默认不服务.css扩展名。解决在IIS管理器中选中网站→“MIME类型”→添加.css类型为text/css.js类型为application/javascript。5. 进阶技巧给挂号模块加实时叫号屏三步嵌入现有逻辑很多医院需要在候诊区挂LED屏显示“请XXX到X诊室就诊”。这个包本身没做但它的Registration表结构和状态字段Status已为扩展留好接口。我用不到20行代码就实现了过程如下5.1 步骤1新增叫号状态字段并建索引在Registration表中添加CallStatus TINYINT DEFAULT 00未叫号1已叫号2已过号并为(DoctorID, Status, CallStatus)建复合索引加速医生诊室的待叫号查询ALTER TABLE [dbo].[Registration] ADD CallStatus TINYINT DEFAULT 0; CREATE INDEX IX_Reg_DoctorStatusCall ON [dbo].[Registration] (DoctorID, Status, CallStatus);5.2 步骤2改造医生工作站页面增加“叫号”按钮在Doctor/Workstation.aspx中于患者列表旁添加按钮asp:Button IDbtnCallNext runatserver Text叫下一位 OnClickbtnCallNext_Click CssClassbtn btn-primary /后台btnCallNext_Click方法逻辑protected void btnCallNext_Click(object sender, EventArgs e) { int doctorId Convert.ToInt32(Session[DoctorID]); // 查找该医生今日第一个Status0待就诊且CallStatus0未叫号的患者 string sql UPDATE TOP(1) Registration SET CallStatus 1, Status 0 WHERE DoctorID docId AND Status 0 AND CallStatus 0; SqlHelper.ExecuteNonQuery(sql, new SqlParameter(docId, doctorId)); // 刷新列表 BindPatientList(); }5.3 步骤3用SignalR实现叫号屏实时推送零侵入现有架构不修改原系统新建一个独立的CallScreen.aspx页面用SignalR Hub监听数据库变更。关键点在于不轮询用SQL Server的Query Notification。在Global.asax中注册通知// 启动时执行 SqlDependency.Start(connectionString); // 查询待叫号患者时启用通知 using (var conn new SqlConnection(connectionString)) { conn.Open(); using (var cmd new SqlCommand(SELECT RegID, PatientName, QueueNumber FROM Registration WHERE CallStatus 1, conn)) { var dependency new SqlDependency(cmd); dependency.OnChange OnCallChanged; // 触发推送 cmd.ExecuteReader(); // 启动监听 } }OnCallChanged中调用Clients.All.updateCallDisplay(regId, name, queue)前端用JavaScript接收并更新LED屏DOM。这样挂号员每挂一个号医生点“叫下一位”3秒内LED屏就刷新全程不刷页面、不加锁、不改原业务表结构。从那以后我每次给某高校课程设计组做技术辅导只要他们选HIS相关课题我都会先让他们把这个“超级简单版本”跑起来——不是因为它多先进而是它把医疗业务中最容易被忽略的状态一致性挂号/就诊/缴费/发药的状态流转、并发安全性队列号生成、库存扣减、权限实效性URL路由Session双重校验全摊开在源码里。你看得见每一行SQL怎么防注入摸得着每一个按钮点击后事务怎么提交回滚。这种“脏活累活全写明”的坦诚比任何高大上的架构图都珍贵。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑