基于SAP.NET Core Web APP(MVC)的医疗记录管理系统完整开发指南
基于SAP.NET Core Web APP (MVC)的医疗记录管理系统完整开发指南
摘要:Web programming ASP .NET Core课程设计要求如下,请给出详细的新建项目步骤,生成完整的项目代码,给出代码设计思路,数据库EF关系图,以及每个数据表的意义,详细的代码注释。开发平台是VS2022,数据存取要用数据库,数据库要有初始化的一些数据。支持医生登录,管理员登录。欢迎页面点击login进行登录,登录后实现下面的任务。最好是该系统支持国际语言切换,网页显示要美观,形成蓝色主题医院。代码注释用英语,最终网页显示的默认语言是英语。项目描述如下:
- 概述
 一家医院希望使用一个网站,以便医生能够更轻松地访问患者的医疗记录。医疗记录包含患者的所有信息:姓氏、名字、地址、社会安全号码、任何过敏情况,以及初级保健医生的详细信息(姓名、名字、地址、专业注册号)。
 过敏情况有编码,并且危险等级从 1 到 10 不等。系统必须记录患者从何时开始过敏以及何时结束。一旦过敏治愈,就不会再次出现。
 如果患者姓名发生变化(例如结婚),必须保留出生姓名(婚前姓氏)和当前姓名(现用名)。
 医疗记录包含对患者进行的所有医疗操作,包括操作名称、摘要、日期和时间,以及任何相关的数字文件。例如,对于 X 光检查,图像文件必须在记录中可用。
 任何治疗患者的医生都必须能够访问该患者的所有信息。每位医生都有:
- 医院特有的唯一标识符
- 姓名、名字、地址- 就业信息:具有唯一标识符、名称和职能(角色)的服务(部门)内的一份工作。医生可能会变更服务部门和/或职能。有些医生可能拥有多个角色,并在多个服务部门工作。对于每个职位,系统必须存储医生的资历(以工作月数计算)。
 医院由多个服务部门组成,每个服务部门都有唯一的标识符和位置。并非所有医生都能访问所有病人的医疗记录——他们只能访问其当前服务部门内病人的记录。
 病人可能会经过多个服务部门,也可能在不同日期多次经过同一个服务部门。既是医生又是病人的人员将被视为普通病人。鉴于此类情况的数量与总病人数量相比非常少,一定程度的数据冗余是可以接受的。
 2 网站
 网站界面将允许医生使用用户名和密码登录,并访问其有权查看的病人的医疗记录。
 1 医生能够为病人添加新的干预措施,但不能修改或删除之前的干预措施。将能够更新有关患者身份的信息。
 由于文件(例如 X 光片)可能很大,系统必须允许不在页面上直接显示文件,而是显示从文件中提取的关键元数据作为占位符。
一、项目创建步骤
1. 创建新项目
1. 打开 Visual Studio 2022
2. 点击 "Create a new project"
3. 选择 "ASP.NET Core Web App (Model-View-Controller)"
4. 项目名称: MedicalRecordSystem
5. Framework: .NET 8.0 (或 .NET 7.0)
6. Authentication type: None (我们将自定义实现)
7. 勾选 "Configure for HTTPS"
8. 点击 "Create"
2. 安装 NuGet 包
# 在 Package Manager Console 中执行
Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Microsoft.EntityFrameworkCore.Tools
Install-Package Microsoft.AspNetCore.Session
Install-Package Microsoft.Extensions.Localization
Install-Package BCrypt.Net-Next
二、完整项目代码
1. 数据模型 (Models)
Models/Doctor.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;namespace MedicalRecordSystem.Models
{/// <summary>/// Represents a doctor in the hospital system/// Stores doctor's personal and employment information/// </summary>public class Doctor{[Key]public int DoctorId { get; set; }/// <summary>/// Hospital-specific unique identifier for the doctor/// </summary>[Required][StringLength(50)]public string HospitalIdentifier { get; set; }[Required][StringLength(100)]public string LastName { get; set; }[Required][StringLength(100)]public string FirstName { get; set; }[Required][StringLength(200)]public string Address { get; set; }/// <summary>/// Username for login authentication/// </summary>[Required][StringLength(50)]public string Username { get; set; }/// <summary>/// Hashed password for security/// </summary>[Required]public string PasswordHash { get; set; }/// <summary>/// Navigation property for doctor's positions in different departments/// </summary>public virtual ICollection<DoctorPosition> Positions { get; set; }/// <summary>/// Navigation property for interventions performed by this doctor/// </summary>public virtual ICollection<MedicalIntervention> Interventions { get; set; }}
}
Models/Patient.cs
using System.ComponentModel.DataAnnotations;namespace MedicalRecordSystem.Models
{/// <summary>/// Represents a patient in the medical system/// Contains personal information and medical history/// </summary>public class Patient{[Key]public int PatientId { get; set; }/// <summary>/// Current last name (may change due to marriage)/// </summary>[Required][StringLength(100)]public string CurrentLastName { get; set; }[Required][StringLength(100)]public string FirstName { get; set; }/// <summary>/// Birth name (maiden name) - preserved when name changes/// </summary>[StringLength(100)]public string BirthName { get; set; }[Required][StringLength(200)]public string Address { get; set; }/// <summary>/// Social Security Number for patient identification/// </summary>[Required][StringLength(20)]public string SocialSecurityNumber { get; set; }/// <summary>/// Primary care physician's full name/// </summary>[Required][StringLength(200)]public string PrimaryCarePhysicianName { get; set; }/// <summary>/// Primary care physician's address/// </summary>[Required][StringLength(200)]public string PrimaryCarePhysicianAddress { get; set; }/// <summary>/// Professional registration number of primary care physician/// </summary>[Required][StringLength(50)]public string PrimaryCarePhysicianRegistrationNumber { get; set; }/// <summary>/// Navigation property for patient's allergies/// </summary>public virtual ICollection<PatientAllergy> Allergies { get; set; }/// <summary>/// Navigation property for patient's medical interventions/// </summary>public virtual ICollection<MedicalIntervention> Interventions { get; set; }/// <summary>/// Navigation property for patient's department admissions/// </summary>public virtual ICollection<PatientDepartmentAdmission> DepartmentAdmissions { get; set; }}
}
Models/Department.cs
using System.ComponentModel.DataAnnotations;namespace MedicalRecordSystem.Models
{/// <summary>/// Represents a hospital department/service/// Each department has unique identifier and location/// </summary>public class Department{[Key]public int DepartmentId { get; set; }/// <summary>/// Unique identifier for the department/// </summary>[Required][StringLength(50)]public string DepartmentCode { get; set; }[Required][StringLength(100)]public string Name { get; set; }/// <summary>/// Physical location of the department in the hospital/// </summary>[Required][StringLength(200)]public string Location { get; set; }/// <summary>/// Navigation property for doctors working in this department/// </summary>public virtual ICollection<DoctorPosition> DoctorPositions { get; set; }/// <summary>/// Navigation property for patient admissions to this department/// </summary>public virtual ICollection<PatientDepartmentAdmission> PatientAdmissions { get; set; }}
}
Models/DoctorPosition.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;namespace MedicalRecordSystem.Models
{/// <summary>/// Represents a doctor's position/role in a specific department/// Tracks employment history and seniority/// A doctor can have multiple positions in different departments/// </summary>public class DoctorPosition{[Key]public int PositionId { get; set; }[Required]public int DoctorId { get; set; }[Required]public int DepartmentId { get; set; }/// <summary>/// Unique identifier for this specific position/// </summary>[Required][StringLength(50)]public string PositionCode { get; set; }/// <summary>/// Role/function of the doctor in this position (e.g., "Cardiologist", "Surgeon")/// </summary>[Required][StringLength(100)]public string Role { get; set; }/// <summary>/// Seniority measured in months working in this position/// </summary>[Required]public int SeniorityMonths { get; set; }/// <summary>/// Start date of this position/// </summary>[Required]public DateTime StartDate { get; set; }/// <summary>/// End date of position (null if currently active)/// </summary>public DateTime? EndDate { get; set; }/// <summary>/// Indicates if this is the doctor's current active position/// </summary>public bool IsActive { get; set; }// Navigation properties[ForeignKey("DoctorId")]public virtual Doctor Doctor { get; set; }[ForeignKey("DepartmentId")]public virtual Department Department { get; set; }}
}
Models/Allergy.cs
using System.ComponentModel.DataAnnotations;namespace MedicalRecordSystem.Models
{/// <summary>/// Master table of allergy types/// Contains coded allergies with danger levels/// </summary>public class Allergy{[Key]public int AllergyId { get; set; }/// <summary>/// Unique code for the allergy type/// </summary>[Required][StringLength(20)]public string AllergyCode { get; set; }[Required][StringLength(100)]public string Name { get; set; }[StringLength(500)]public string Description { get; set; }/// <summary>/// Danger level from 1 (mild) to 10 (severe/life-threatening)/// </summary>[Required][Range(1, 10)]public int DangerLevel { get; set; }/// <summary>/// Navigation property for patients with this allergy/// </summary>public virtual ICollection<PatientAllergy> PatientAllergies { get; set; }}
}
Models/PatientAllergy.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;namespace MedicalRecordSystem.Models
{/// <summary>/// Junction table linking patients to their allergies/// Tracks the timeline of allergic conditions/// Once cured, an allergy will not recur (EndDate is set)/// </summary>public class PatientAllergy{[Key]public int PatientAllergyId { get; set; }[Required]public int PatientId { get; set; }[Required]public int AllergyId { get; set; }/// <summary>/// Date when the allergy was first diagnosed/// </summary>[Required]public DateTime StartDate { get; set; }/// <summary>/// Date when the allergy was cured (null if still active)/// </summary>public DateTime? EndDate { get; set; }[StringLength(500)]public string Notes { get; set; }// Navigation properties[ForeignKey("PatientId")]public virtual Patient Patient { get; set; }[ForeignKey("AllergyId")]public virtual Allergy Allergy { get; set; }}
}
Models/MedicalIntervention.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;namespace MedicalRecordSystem.Models
{/// <summary>/// Represents a medical intervention/procedure performed on a patient/// Includes all medical operations with associated documentation/// Immutable once created (cannot be modified or deleted)/// </summary>public class MedicalIntervention{[Key]public int InterventionId { get; set; }[Required]public int PatientId { get; set; }[Required]public int DoctorId { get; set; }/// <summary>/// Name/type of the medical intervention/// </summary>[Required][StringLength(200)]public string InterventionName { get; set; }/// <summary>/// Summary/description of the intervention performed/// </summary>[Required][StringLength(2000)]public string Summary { get; set; }/// <summary>/// Date and time when the intervention was performed/// </summary>[Required]public DateTime InterventionDateTime { get; set; }/// <summary>/// Original filename of associated document (e.g., X-ray image)/// </summary>[StringLength(255)]public string FileName { get; set; }/// <summary>/// File type/MIME type/// </summary>[StringLength(100)]public string FileType { get; set; }/// <summary>/// File size in bytes/// </summary>public long? FileSize { get; set; }/// <summary>/// Path to stored file (not displayed directly, metadata shown instead)/// </summary>[StringLength(500)]public string FilePath { get; set; }/// <summary>/// Extracted metadata from file for display purposes/// </summary>[StringLength(1000)]public string FileMetadata { get; set; }/// <summary>/// Timestamp when this record was created/// </summary>public DateTime CreatedAt { get; set; }// Navigation properties[ForeignKey("PatientId")]public virtual Patient Patient { get; set; }[ForeignKey("DoctorId")]public virtual Doctor Doctor { get; set; }}
}
Models/PatientDepartmentAdmission.cs
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;namespace MedicalRecordSystem.Models
{/// <summary>/// Tracks patient admissions to different departments/// A patient can be admitted to multiple departments/// A patient can be admitted to the same department multiple times on different dates/// </summary>public class PatientDepartmentAdmission{[Key]public int AdmissionId { get; set; }[Required]public int PatientId { get; set; }[Required]public int DepartmentId { get; set; }/// <summary>/// Date and time of admission to the department/// </summary>[Required]public DateTime AdmissionDate { get; set; }/// <summary>/// Date and time of discharge (null if still admitted)/// </summary>public DateTime? DischargeDate { get; set; }[StringLength(500)]public string AdmissionReason { get; set; }// Navigation properties[ForeignKey("PatientId")]public virtual Patient Patient { get; set; }[ForeignKey("DepartmentId")]public virtual Department Department { get; set; }}
}
Models/Administrator.cs
using System.ComponentModel.DataAnnotations;namespace MedicalRecordSystem.Models
{/// <summary>/// Represents a system administrator/// Has full access to manage all system data/// </summary>public class Administrator{[Key]public int AdminId { get; set; }[Required][StringLength(100)]public string Username { get; set; }[Required]public string PasswordHash { get; set; }[Required][StringLength(100)]public string FullName { get; set; }[Required][EmailAddress][StringLength(100)]public string Email { get; set; }public DateTime CreatedAt { get; set; }}
}
2. 数据库上下文
Data/ApplicationDbContext.cs
using Microsoft.EntityFrameworkCore;
using MedicalRecordSystem.Models;
using BCrypt.Net;namespace MedicalRecordSystem.Data
{/// <summary>/// Database context for the Medical Record System/// Manages all entity sets and database configuration/// </summary>public class ApplicationDbContext : DbContext{public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options): base(options){}// Entity setspublic DbSet<Doctor> Doctors { get; set; }public DbSet<Patient> Patients { get; set; }public DbSet<Department> Departments { get; set; }public DbSet<DoctorPosition> DoctorPositions { get; set; }public DbSet<Allergy> Allergies { get; set; }public DbSet<PatientAllergy> PatientAllergies { get; set; }public DbSet<MedicalIntervention> MedicalInterventions { get; set; }public DbSet<PatientDepartmentAdmission> PatientDepartmentAdmissions { get; set; }public DbSet<Administrator> Administrators { get; set; }protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);// Configure unique constraintsmodelBuilder.Entity<Doctor>().HasIndex(d => d.HospitalIdentifier).IsUnique();modelBuilder.Entity<Doctor>().HasIndex(d => d.Username).IsUnique();modelBuilder.Entity<Patient>().HasIndex(p => p.SocialSecurityNumber).IsUnique();modelBuilder.Entity<Department>().HasIndex(d => d.DepartmentCode).IsUnique();modelBuilder.Entity<Allergy>().HasIndex(a => a.AllergyCode).IsUnique();modelBuilder.Entity<Administrator>().HasIndex(a => a.Username).IsUnique();//