152 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Python
		
	
	
	
from django.db import models
 | 
						|
from apps.utils.models import CommonAModel, BaseModel, CommonADModel
 | 
						|
from apps.system.models import User, Dept, File
 | 
						|
 | 
						|
# Create your models here.
 | 
						|
 | 
						|
 | 
						|
class Train(CommonADModel):
 | 
						|
    T_L_POST = 10
 | 
						|
    T_L_TEAM = 20
 | 
						|
    T_L_DEPT = 30
 | 
						|
    T_L_COMPANY = 40
 | 
						|
 | 
						|
    level = models.PositiveSmallIntegerField(verbose_name="级别", choices=((T_L_POST, "岗位"), (T_L_TEAM, "班组"), (T_L_DEPT, "部门"), (T_L_COMPANY, "公司")))
 | 
						|
    name = models.CharField(max_length=200, verbose_name="名称")
 | 
						|
    place = models.CharField(max_length=200, verbose_name="地点", default="", blank=True)
 | 
						|
    start_time = models.DateTimeField(verbose_name="开始时间")
 | 
						|
    end_time = models.DateTimeField(verbose_name="结束时间")
 | 
						|
    duration = models.PositiveIntegerField(verbose_name="时长", default=0, help_text="单位:s", editable=False)
 | 
						|
    description = models.TextField(verbose_name="内容描述", default="", blank=True)
 | 
						|
    is_public = models.BooleanField("是否公开", default=False)
 | 
						|
    files = models.ManyToManyField(File, verbose_name="附件", blank=True)
 | 
						|
 | 
						|
    class Meta:
 | 
						|
        verbose_name = "线下培训"
 | 
						|
        verbose_name_plural = verbose_name
 | 
						|
 | 
						|
 | 
						|
class Questioncat(CommonAModel):
 | 
						|
    name = models.CharField(max_length=200, verbose_name="名称")
 | 
						|
    parent = models.ForeignKey("self", on_delete=models.SET_NULL, null=True, blank=True, verbose_name="父级", related_name="cate_parent")
 | 
						|
    sort = models.PositiveIntegerField(default=0, verbose_name="排序")
 | 
						|
 | 
						|
    class Meta:
 | 
						|
        verbose_name = "题库分类"
 | 
						|
        verbose_name_plural = verbose_name
 | 
						|
 | 
						|
    def __str__(self):
 | 
						|
        return self.name
 | 
						|
 | 
						|
 | 
						|
class Question(CommonAModel):
 | 
						|
    Q_DAN = 10
 | 
						|
    Q_DUO = 20
 | 
						|
    Q_PAN = 30
 | 
						|
    Q_EASY = 10
 | 
						|
    Q_SIMPLE = 20
 | 
						|
    Q_HARD = 30
 | 
						|
    name = models.TextField("题干")
 | 
						|
    img = models.TextField("题干图片", null=True, blank=True)
 | 
						|
    type = models.PositiveSmallIntegerField("题型", choices=((Q_DAN, "单选"), (Q_DUO, "多选"), (Q_PAN, "判断")))
 | 
						|
    level = models.PositiveSmallIntegerField("难度", default=Q_SIMPLE, choices=((Q_EASY, "简单"), (Q_SIMPLE, "一般"), (Q_HARD, "困难")))
 | 
						|
    questioncat = models.ForeignKey(Questioncat, blank=True, null=True, on_delete=models.SET_NULL, verbose_name="所属题库", related_name="questioncat")
 | 
						|
    options = models.JSONField("选项")
 | 
						|
    right = models.JSONField("正确答案")
 | 
						|
    resolution = models.TextField("解析", null=True, blank=True)
 | 
						|
    enabled = models.BooleanField("是否启用", default=False)
 | 
						|
 | 
						|
    class Meta:
 | 
						|
        verbose_name = "题目"
 | 
						|
        verbose_name_plural = verbose_name
 | 
						|
 | 
						|
    def __str__(self):
 | 
						|
        return self.name
 | 
						|
 | 
						|
 | 
						|
class Paper(CommonAModel):
 | 
						|
    PAPER_FIX = 10  # 固定试卷
 | 
						|
    PAPER_RANDOM = 20  # 自动抽题
 | 
						|
 | 
						|
    name = models.CharField(max_length=200, verbose_name="名称")
 | 
						|
    type = models.PositiveSmallIntegerField("类型", default=10, choices=((PAPER_FIX, "固定试卷"), (PAPER_RANDOM, "随机试卷")))
 | 
						|
    questions = models.ManyToManyField(Question, through="PaperQuestion")
 | 
						|
    limit = models.IntegerField(default=0, verbose_name="限时(分钟)")
 | 
						|
    total_score = models.FloatField(default=0, verbose_name="满分")
 | 
						|
    pass_score = models.FloatField(default=0, verbose_name="通过分数")
 | 
						|
    danxuan_count = models.IntegerField(default=0, verbose_name="单选数量")
 | 
						|
    danxuan_score = models.FloatField(default=2, verbose_name="单选分数")
 | 
						|
    duoxuan_count = models.IntegerField(default=0, verbose_name="多选数量")
 | 
						|
    duoxuan_score = models.FloatField(default=4, verbose_name="多选分数")
 | 
						|
    panduan_count = models.IntegerField(default=0, verbose_name="判断数量")
 | 
						|
    panduan_score = models.FloatField(default=2, verbose_name="判断分数")
 | 
						|
 | 
						|
    class Meta:
 | 
						|
        verbose_name = "押题卷"
 | 
						|
        verbose_name_plural = verbose_name
 | 
						|
 | 
						|
    def __str__(self):
 | 
						|
        return self.name
 | 
						|
 | 
						|
    @property
 | 
						|
    def detail(self):
 | 
						|
        return PaperQuestion.objects.filter(paper=self)
 | 
						|
 | 
						|
 | 
						|
class PaperQuestion(BaseModel):
 | 
						|
    paper = models.ForeignKey(Paper, on_delete=models.CASCADE, verbose_name="试卷")
 | 
						|
    question = models.ForeignKey(Question, on_delete=models.CASCADE, verbose_name="试题")
 | 
						|
    total_score = models.FloatField(default=0, verbose_name="单题满分")
 | 
						|
    sort = models.IntegerField(default=0, verbose_name="排序")
 | 
						|
 | 
						|
 | 
						|
class Exam(CommonADModel):
 | 
						|
    name = models.CharField("名称", max_length=100)
 | 
						|
    open_time = models.DateTimeField("开启时间")
 | 
						|
    close_time = models.DateTimeField("关闭时间", null=True, blank=True)
 | 
						|
    chance = models.IntegerField("考试机会", default=1)  # 0表示不限次数
 | 
						|
    paper = models.ForeignKey(Paper, verbose_name="使用的试卷", on_delete=models.SET_NULL, null=True, blank=True)
 | 
						|
    is_public = models.BooleanField("是否公开", default=False)
 | 
						|
    p_users = models.ManyToManyField(User, verbose_name="指定用户", blank=True)
 | 
						|
    p_depts = models.ManyToManyField(Dept, verbose_name="指定部门", blank=True)
 | 
						|
 | 
						|
    class Meta:
 | 
						|
        verbose_name = "在线考试"
 | 
						|
        verbose_name_plural = verbose_name
 | 
						|
 | 
						|
    def __str__(self):
 | 
						|
        return self.name
 | 
						|
 | 
						|
 | 
						|
class ExamRecord(CommonADModel):
 | 
						|
    """
 | 
						|
    考试记录表
 | 
						|
    """
 | 
						|
 | 
						|
    exam = models.ForeignKey(Exam, on_delete=models.CASCADE, verbose_name="关联考试", related_name="record_exam")
 | 
						|
    score = models.FloatField(default=0, verbose_name="得分")
 | 
						|
    took = models.IntegerField(default=0, verbose_name="耗时(秒)")
 | 
						|
    start_time = models.DateTimeField(verbose_name="开始答题时间")
 | 
						|
    end_time = models.DateTimeField(verbose_name="结束答题时间", null=True, blank=True)
 | 
						|
    questions = models.ManyToManyField(Question, verbose_name="答题记录", through="AnswerDetail")
 | 
						|
    is_pass = models.BooleanField(default=True, verbose_name="是否通过")
 | 
						|
    is_submited = models.BooleanField(default=False, verbose_name="是否提交")
 | 
						|
    is_last = models.BooleanField(default=False, verbose_name="是否最后一次考试记录")
 | 
						|
 | 
						|
    class Meta:
 | 
						|
        verbose_name = "考试记录"
 | 
						|
        verbose_name_plural = verbose_name
 | 
						|
 | 
						|
 | 
						|
class AnswerDetail(BaseModel):
 | 
						|
    examrecord = models.ForeignKey(ExamRecord, on_delete=models.CASCADE, related_name="detail_er")
 | 
						|
    total_score = models.FloatField(default=0, verbose_name="该题满分")
 | 
						|
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
 | 
						|
    user_answer = models.JSONField(null=True, blank=True)
 | 
						|
    score = models.FloatField(default=0, verbose_name="本题得分")
 | 
						|
    is_right = models.BooleanField(default=False, verbose_name="是否正确")
 | 
						|
 | 
						|
    class Meta:
 | 
						|
        verbose_name = "答题记录"
 | 
						|
        verbose_name_plural = verbose_name
 |