hidoc/server/models.py
2025-07-09 16:05:50 +08:00

280 lines
14 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
db = SQLAlchemy()
class Hospital(db.Model):
__tablename__ = 'hospital'
id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='医院ID')
name = db.Column(db.String(100), nullable=False, comment='医院名称')
address = db.Column(db.String(255), nullable=True, comment='医院地址')
deleted = db.Column(db.Boolean, default=False, comment='逻辑删除标志True表示已删除')
created_at = db.Column(db.TIMESTAMP, default=datetime.now, comment='创建时间')
def to_dict(self):
return {
'id': self.id,
'name': self.name,
'address': self.address,
'deleted': self.deleted,
'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None
}
class Doctor(db.Model):
__tablename__ = 'doctor'
id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='医生ID')
phone = db.Column(db.String(20), unique=True, nullable=False, comment='医生电话,唯一且非空')
name = db.Column(db.String(100), nullable=False, comment='医生姓名')
password = db.Column(db.String(100), nullable=False, comment='医生密码')
gender = db.Column(db.Enum('', '', '未知'), nullable=False, comment='医生性别')
created_at = db.Column(db.TIMESTAMP, default=datetime.now, comment='创建时间')
def to_dict(self):
return {
'id': self.id,
'phone': self.phone,
'name': self.name,
'password': self.password,
'gender': self.gender,
'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None
}
class Office(db.Model):
__tablename__ = 'office'
id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='科室ID')
name = db.Column(db.String(100), nullable=False, comment='科室名称')
parent_id = db.Column(db.Integer, db.ForeignKey('office.id', ondelete='CASCADE'), nullable=True, comment='上级科室ID')
hospital_id = db.Column(db.Integer, db.ForeignKey('hospital.id'), nullable=False, comment='所属医院ID')
created_at = db.Column(db.TIMESTAMP, default=datetime.now, comment='创建时间')
# 自引用关系,添加级联删除
parent = db.relationship('Office', remote_side=[id],
backref=db.backref('children', lazy='dynamic', cascade='all, delete-orphan'),
passive_deletes=True)
# 与医院的关系
hospital = db.relationship('Hospital', backref=db.backref('offices', lazy='dynamic'))
def to_dict(self):
return {
'id': self.id,
'name': self.name,
'parent_id': self.parent_id,
'hospital_id': self.hospital_id,
'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None
}
class DoctorOffice(db.Model):
__tablename__ = 'doctor_office'
id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='关联ID')
doc_id = db.Column(db.Integer, db.ForeignKey('doctor.id', ondelete='CASCADE'), nullable=False, comment='医生ID')
off_id = db.Column(db.Integer, db.ForeignKey('office.id', ondelete='CASCADE'), nullable=False, comment='科室ID')
created_at = db.Column(db.TIMESTAMP, default=datetime.now, comment='创建时间')
# 关系
doctor = db.relationship('Doctor', backref=db.backref('offices', lazy='dynamic', cascade='all, delete-orphan'))
office = db.relationship('Office', backref=db.backref('doctors', lazy='dynamic', cascade='all, delete-orphan'))
def to_dict(self):
return {
'id': self.id,
'doc_id': self.doc_id,
'off_id': self.off_id,
'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None
}
class DoctorHospital(db.Model):
__tablename__ = 'doctor_hospital'
id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='关联ID')
doc_id = db.Column(db.Integer, db.ForeignKey('doctor.id', ondelete='CASCADE'), nullable=False, comment='医生ID')
hosp_id = db.Column(db.Integer, db.ForeignKey('hospital.id'), nullable=False, comment='医院ID')
created_at = db.Column(db.TIMESTAMP, default=datetime.now, comment='创建时间')
# 关系
doctor = db.relationship('Doctor', backref=db.backref('hospitals', lazy='dynamic', cascade='all, delete-orphan'))
hospital = db.relationship('Hospital', backref=db.backref('doctors', lazy='dynamic'))
def to_dict(self):
return {
'id': self.id,
'doc_id': self.doc_id,
'hosp_id': self.hosp_id,
'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None
}
class Patient(db.Model):
__tablename__ = 'patient'
id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='病人ID')
name = db.Column(db.String(100), nullable=False, comment='病人姓名')
gender = db.Column(db.Enum('', '', '未知'), nullable=False, comment='病人性别')
birthday = db.Column(db.String(10), nullable=True, comment='出生日期格式YYYY-MM-DD')
created_at = db.Column(db.TIMESTAMP, default=datetime.now, comment='创建时间')
def to_dict(self):
return {
'id': self.id,
'name': self.name,
'gender': self.gender,
'birthday': self.birthday,
'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None
}
class Case(db.Model):
__tablename__ = 'case'
id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='病历ID')
patient_id = db.Column(db.Integer, db.ForeignKey('patient.id', ondelete='CASCADE'), nullable=False, comment='病人ID')
office_id = db.Column(db.Integer, db.ForeignKey('office.id', ondelete='CASCADE'), nullable=False, comment='科室ID')
doctor_id = db.Column(db.Integer, db.ForeignKey('doctor.id', ondelete='CASCADE'), nullable=False, comment='医生ID')
case_date = db.Column(db.Date, nullable=False, comment='就诊日期')
chief_complaint = db.Column(db.Text, nullable=True, comment='主诉')
present_illness_history = db.Column(db.Text, nullable=True, comment='现病史')
past_medical_history = db.Column(db.Text, nullable=True, comment='既往史')
personal_history = db.Column(db.Text, nullable=True, comment='个人史')
family_history = db.Column(db.Text, nullable=True, comment='家族史')
physical_examination = db.Column(db.Text, nullable=True, comment='体格检查')
diagnosis = db.Column(db.Text, nullable=True, comment='诊断结果')
treatment_plan = db.Column(db.Text, nullable=True, comment='治疗方案')
medication_details = db.Column(db.Text, nullable=True, comment='用药详情')
notes = db.Column(db.Text, nullable=True, comment='备注')
created_at = db.Column(db.TIMESTAMP, default=datetime.now, comment='创建时间')
updated_at = db.Column(db.TIMESTAMP, default=datetime.now, onupdate=datetime.now, comment='更新时间')
# 关系
patient = db.relationship('Patient', backref=db.backref('cases', lazy='dynamic', cascade='all, delete-orphan'))
office = db.relationship('Office', backref=db.backref('cases', lazy='dynamic'))
doctor = db.relationship('Doctor', backref=db.backref('cases', lazy='dynamic'))
def to_dict(self):
return {
'id': self.id,
'patient_id': self.patient_id,
'office_id': self.office_id,
'doctor_id': self.doctor_id,
'case_date': self.case_date.strftime('%Y-%m-%d') if self.case_date else None,
'chief_complaint': self.chief_complaint,
'present_illness_history': self.present_illness_history,
'past_medical_history': self.past_medical_history,
'personal_history': self.personal_history,
'family_history': self.family_history,
'physical_examination': self.physical_examination,
'diagnosis': self.diagnosis,
'treatment_plan': self.treatment_plan,
'medication_details': self.medication_details,
'notes': self.notes,
'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None,
'updated_at': self.updated_at.strftime('%Y-%m-%d %H:%M:%S') if self.updated_at else None
}
class Image(db.Model):
__tablename__ = 'image'
id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='影像ID')
name = db.Column(db.String(255), nullable=True, comment='影像名称')
format = db.Column(db.Enum('dicom', 'nii', 'picture'), nullable=False, comment='影像格式')
type = db.Column(db.Enum('X-ray', 'CT', 'MRI', 'PET', 'US', '其他'), nullable=False, comment='影像类型')
dim = db.Column(db.Enum('2D', '3D'), nullable=False, default='2D', comment='影像维度')
patient_id = db.Column(db.Integer, db.ForeignKey('patient.id', ondelete='SET NULL'), nullable=True, comment='病人ID')
creator_id = db.Column(db.Integer, db.ForeignKey('doctor.id', ondelete='CASCADE'), nullable=False, comment='创建者ID (医生)')
office_id = db.Column(db.Integer, db.ForeignKey('office.id', ondelete='SET NULL'), nullable=True, comment='科室ID')
case_id = db.Column(db.Integer, db.ForeignKey('case.id', ondelete='SET NULL'), nullable=True, comment='病历ID')
note = db.Column(db.Text, nullable=True, comment='备注')
oss_key = db.Column(db.String(255), nullable=False, unique=True, comment='OSS对象存储键')
size = db.Column(db.Numeric(10, 2), nullable=False, comment='文件大小(KB)')
parent_image_id = db.Column(db.Integer, db.ForeignKey('image.id', ondelete='CASCADE'), nullable=True, comment='父影像ID (用于3D影像切片)')
slice_direction = db.Column(db.Enum('x', 'y', 'z'), nullable=True, comment='3D影像切片方向')
slice = db.Column(db.Integer, nullable=True, comment='3D影像切片索引')
slice_x = db.Column(db.Integer, nullable=True, comment='3D影像x方向切片数')
slice_y = db.Column(db.Integer, nullable=True, comment='3D影像y方向切片数')
slice_z = db.Column(db.Integer, nullable=True, comment='3D影像z方向切片数')
created_at = db.Column(db.TIMESTAMP, default=datetime.now, comment='创建时间')
# 关系
patient = db.relationship('Patient', backref=db.backref('images', lazy='dynamic'))
creator = db.relationship('Doctor', backref=db.backref('created_images', lazy='dynamic'))
office = db.relationship('Office', backref=db.backref('images', lazy='dynamic'))
case = db.relationship('Case', backref=db.backref('images', lazy='dynamic'))
parent_image = db.relationship('Image', remote_side=[id], backref=db.backref('child_images', lazy='dynamic', cascade='all, delete-orphan'))
def to_dict(self):
return {
'id': self.id,
'name': self.name,
'format': self.format,
'type': self.type,
'dim': self.dim,
'patient_id': self.patient_id,
'creator_id': self.creator_id,
'office_id': self.office_id,
'case_id': self.case_id,
'note': self.note,
'oss_key': self.oss_key,
'size': float(self.size) if self.size is not None else None,
'parent_image_id': self.parent_image_id,
'slice_direction': self.slice_direction,
'slice': self.slice,
'slice_x': self.slice_x,
'slice_y': self.slice_y,
'slice_z': self.slice_z,
'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None
}
class ImageBbox(db.Model):
__tablename__ = 'image_bbox'
id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='边界框标注ID')
image_id = db.Column(db.Integer, db.ForeignKey('image.id', ondelete='CASCADE'), nullable=False, comment='影像ID')
creator_id = db.Column(db.Integer, db.ForeignKey('doctor.id', ondelete='CASCADE'), nullable=False, comment='创建者ID (医生)')
up_left_x = db.Column(db.Integer, nullable=False, comment='左上角X坐标')
up_left_y = db.Column(db.Integer, nullable=False, comment='左上角Y坐标')
bottom_right_x = db.Column(db.Integer, nullable=False, comment='右下角X坐标')
bottom_right_y = db.Column(db.Integer, nullable=False, comment='右下角Y坐标')
note = db.Column(db.Text, nullable=True, comment='备注')
created_at = db.Column(db.TIMESTAMP, default=datetime.now, comment='创建时间')
# 关系
image = db.relationship('Image', backref=db.backref('bboxes', lazy='dynamic', cascade='all, delete-orphan'))
creator = db.relationship('Doctor', backref=db.backref('created_bboxes', lazy='dynamic'))
def to_dict(self):
return {
'id': self.id,
'image_id': self.image_id,
'creator_id': self.creator_id,
'up_left_x': self.up_left_x,
'up_left_y': self.up_left_y,
'bottom_right_x': self.bottom_right_x,
'bottom_right_y': self.bottom_right_y,
'note': self.note,
'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None
}
class ImageMask(db.Model):
__tablename__ = 'image_mask'
id = db.Column(db.Integer, primary_key=True, autoincrement=True, comment='掩码标注ID')
image_id = db.Column(db.Integer, db.ForeignKey('image.id', ondelete='CASCADE'), nullable=False, comment='影像ID')
creator_id = db.Column(db.Integer, db.ForeignKey('doctor.id', ondelete='CASCADE'), nullable=False, comment='创建者ID (医生)')
mask_oss_key = db.Column(db.String(255), nullable=False, unique=True, comment='掩码文件OSS键')
note = db.Column(db.Text, nullable=True, comment='备注')
created_at = db.Column(db.TIMESTAMP, default=datetime.now, comment='创建时间')
# 关系
image = db.relationship('Image', backref=db.backref('masks', lazy='dynamic', cascade='all, delete-orphan'))
creator = db.relationship('Doctor', backref=db.backref('created_masks', lazy='dynamic'))
def to_dict(self):
return {
'id': self.id,
'image_id': self.image_id,
'creator_id': self.creator_id,
'mask_oss_key': self.mask_oss_key,
'note': self.note,
'created_at': self.created_at.strftime('%Y-%m-%d %H:%M:%S') if self.created_at else None
}