init medical training project
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
from django.db import models
|
||||
from apps.common.models import BaseModel
|
||||
from apps.user.models import User
|
||||
|
||||
|
||||
class CaseBase(BaseModel):
|
||||
"""病例主表"""
|
||||
CASE_TYPE_CHOICES = [
|
||||
('traditional', '传统病例'),
|
||||
('script', '剧本病例'),
|
||||
('teaching', '教学互动病例'),
|
||||
('osce', 'OSCE'),
|
||||
]
|
||||
STATUS_CHOICES = [
|
||||
(0, '禁用'),
|
||||
(1, '正常'),
|
||||
]
|
||||
PUBLISH_STATUS_CHOICES = [
|
||||
(0, '草稿'),
|
||||
(1, '已发布'),
|
||||
(2, '已下架'),
|
||||
]
|
||||
|
||||
id = models.BigAutoField(primary_key=True)
|
||||
title = models.CharField('病例标题', max_length=255)
|
||||
case_type = models.CharField('病例类型', max_length=30, choices=CASE_TYPE_CHOICES)
|
||||
difficulty = models.CharField('难度', max_length=20, blank=True)
|
||||
difficulty_score = models.IntegerField('AI难度评分', null=True, blank=True)
|
||||
department = models.ForeignKey(
|
||||
'user.Department', on_delete=models.SET_NULL,
|
||||
null=True, blank=True, verbose_name='所属科室'
|
||||
)
|
||||
chief_complaint = models.TextField('主诉', blank=True)
|
||||
description = models.TextField('病例简介', blank=True)
|
||||
patient_age = models.IntegerField('患者年龄', null=True, blank=True)
|
||||
patient_gender = models.CharField('患者性别', max_length=10, blank=True)
|
||||
tags = models.CharField('标签', max_length=500, blank=True)
|
||||
symptom_tags = models.JSONField('症状标签', default=list, blank=True)
|
||||
disease_tags = models.JSONField('疾病标签', default=list, blank=True)
|
||||
competency_tags = models.JSONField('能力标签', default=list, blank=True)
|
||||
guideline_tags = models.JSONField('指南标签', default=list, blank=True)
|
||||
knowledge_points = models.JSONField('知识点', default=list, blank=True)
|
||||
icd_codes = models.CharField('ICD编码', max_length=500, blank=True)
|
||||
estimated_minutes = models.IntegerField('预计训练时长', null=True, blank=True)
|
||||
osce_enabled = models.BooleanField('是否OSCE', default=False)
|
||||
rag_enabled = models.BooleanField('是否启用知识增强', default=False)
|
||||
ai_prompt_template = models.TextField('AI角色Prompt', blank=True)
|
||||
multimodal_assets = models.JSONField('图片/影像/附件', default=dict, blank=True)
|
||||
vector_status = models.SmallIntegerField('是否向量化', default=0)
|
||||
created_by = models.ForeignKey(
|
||||
User, on_delete=models.SET_NULL,
|
||||
null=True, blank=True, verbose_name='创建人'
|
||||
)
|
||||
publish_status = models.SmallIntegerField('发布状态', choices=PUBLISH_STATUS_CHOICES, default=0)
|
||||
status = models.SmallIntegerField('状态', choices=STATUS_CHOICES, default=1)
|
||||
|
||||
class Meta:
|
||||
db_table = 'case_base'
|
||||
verbose_name = '病例'
|
||||
verbose_name_plural = '病例'
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
|
||||
class TraditionalCase(BaseModel):
|
||||
"""传统病例表"""
|
||||
id = models.BigAutoField(primary_key=True)
|
||||
case = models.OneToOneField(
|
||||
CaseBase, on_delete=models.CASCADE,
|
||||
verbose_name='病例'
|
||||
)
|
||||
standard_diagnosis = models.TextField('标准诊断', blank=True)
|
||||
standard_treatment = models.TextField('标准治疗', blank=True)
|
||||
guideline_reference = models.TextField('指南参考', blank=True)
|
||||
|
||||
class Meta:
|
||||
db_table = 'traditional_case'
|
||||
verbose_name = '传统病例'
|
||||
verbose_name_plural = '传统病例'
|
||||
|
||||
def __str__(self):
|
||||
return f"传统病例: {self.case.title}"
|
||||
|
||||
|
||||
class ScriptCase(BaseModel):
|
||||
"""剧本病例表"""
|
||||
id = models.BigAutoField(primary_key=True)
|
||||
case = models.OneToOneField(
|
||||
CaseBase, on_delete=models.CASCADE,
|
||||
verbose_name='病例'
|
||||
)
|
||||
scenario_setting = models.TextField('场景设定', blank=True)
|
||||
emotional_state = models.CharField('情绪状态', max_length=50, blank=True)
|
||||
cultural_level = models.CharField('文化水平', max_length=50, blank=True)
|
||||
branch_logic = models.TextField('分支逻辑', blank=True)
|
||||
hidden_clues = models.TextField('隐藏线索', blank=True)
|
||||
|
||||
class Meta:
|
||||
db_table = 'script_case'
|
||||
verbose_name = '剧本病例'
|
||||
verbose_name_plural = '剧本病例'
|
||||
|
||||
def __str__(self):
|
||||
return f"剧本病例: {self.case.title}"
|
||||
|
||||
|
||||
class TeachingCase(BaseModel):
|
||||
"""教学互动病例表"""
|
||||
id = models.BigAutoField(primary_key=True)
|
||||
case = models.OneToOneField(
|
||||
CaseBase, on_delete=models.CASCADE,
|
||||
verbose_name='病例'
|
||||
)
|
||||
teaching_goal = models.TextField('教学目标', blank=True)
|
||||
discussion_questions = models.TextField('讨论问题', blank=True)
|
||||
teacher_guide = models.TextField('教师指南', blank=True)
|
||||
scoring_focus = models.TextField('评分重点', blank=True)
|
||||
|
||||
class Meta:
|
||||
db_table = 'teaching_case'
|
||||
verbose_name = '教学互动病例'
|
||||
verbose_name_plural = '教学互动病例'
|
||||
|
||||
def __str__(self):
|
||||
return f"教学病例: {self.case.title}"
|
||||
|
||||
|
||||
class CaseStage(BaseModel):
|
||||
"""病例阶段表"""
|
||||
STAGE_MODE_CHOICES = [
|
||||
('dialogue', '对话'),
|
||||
('osce', 'OSCE'),
|
||||
('choice', '选择'),
|
||||
]
|
||||
|
||||
id = models.BigAutoField(primary_key=True)
|
||||
case = models.ForeignKey(
|
||||
CaseBase, on_delete=models.CASCADE,
|
||||
related_name='stages', verbose_name='病例'
|
||||
)
|
||||
stage_type = models.CharField('阶段类型', max_length=50, blank=True)
|
||||
stage_name = models.CharField('阶段名称', max_length=100)
|
||||
stage_mode = models.CharField('阶段模式', max_length=30, choices=STAGE_MODE_CHOICES, default='dialogue')
|
||||
stage_goal = models.TextField('阶段目标', blank=True)
|
||||
ai_role_prompt = models.TextField('AI阶段Prompt', blank=True)
|
||||
standard_action = models.TextField('标准动作', blank=True)
|
||||
expected_questions = models.TextField('期望问题', blank=True)
|
||||
scoring_points = models.TextField('评分点', blank=True)
|
||||
timeout_seconds = models.IntegerField('超时时间', null=True, blank=True)
|
||||
unlock_condition = models.CharField('解锁条件', max_length=255, blank=True)
|
||||
sort_order = models.IntegerField('排序', default=0)
|
||||
|
||||
class Meta:
|
||||
db_table = 'case_stage'
|
||||
verbose_name = '病例阶段'
|
||||
verbose_name_plural = '病例阶段'
|
||||
ordering = ['sort_order', 'id']
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.case.title} - {self.stage_name}"
|
||||
|
||||
|
||||
class ScoringRule(BaseModel):
|
||||
"""评分规则表"""
|
||||
id = models.BigAutoField(primary_key=True)
|
||||
case = models.ForeignKey(
|
||||
CaseBase, on_delete=models.CASCADE,
|
||||
related_name='scoring_rules', verbose_name='病例'
|
||||
)
|
||||
dimension = models.CharField('评分维度', max_length=50)
|
||||
competency_dimension = models.CharField('能力维度', max_length=50, blank=True)
|
||||
score_weight = models.DecimalField('权重', max_digits=5, decimal_places=2, default=1.00)
|
||||
ai_auto_score = models.BooleanField('AI自动评分', default=False)
|
||||
osce_dimension = models.BooleanField('是否OSCE', default=False)
|
||||
scoring_standard = models.TextField('评分标准', blank=True)
|
||||
rubric_json = models.JSONField('评分Rubric', default=dict, blank=True)
|
||||
|
||||
class Meta:
|
||||
db_table = 'scoring_rule'
|
||||
verbose_name = '评分规则'
|
||||
verbose_name_plural = '评分规则'
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.case.title} - {self.dimension}"
|
||||
Reference in New Issue
Block a user