from django.conf import settings from django.db import models class ContentItem(models.Model): class Ability(models.TextChoices): VISION = "vision", "数学眼光" HUMANITIES = "humanities", "数学人文" DETECTION = "detection", "数学侦探" MODELING = "modeling", "数学建模" CONNECTION = "connection", "数学联结" class Kind(models.TextChoices): VIDEO = "video", "视频" KNOWLEDGE = "knowledge", "知识卡片" PERSON = "person", "数学人物" slug = models.SlugField(unique=True) title = models.CharField(max_length=160) kind = models.CharField(max_length=16, choices=Kind.choices) summary = models.TextField(blank=True) body = models.TextField(blank=True) cover_url = models.URLField(blank=True) media_url = models.URLField(blank=True) topics = models.JSONField(default=list, blank=True) source = models.CharField(max_length=300, blank=True) ability_dimension = models.CharField( max_length=20, choices=Ability.choices, blank=True ) module = models.CharField(max_length=40, blank=True) sub_category = models.CharField(max_length=80, blank=True) discipline = models.CharField(max_length=80, blank=True) discipline_icon = models.CharField(max_length=10, blank=True) author = models.CharField(max_length=120, blank=True) duration_seconds = models.PositiveIntegerField(default=0) view_count = models.PositiveIntegerField(default=0) comment_count = models.PositiveIntegerField(default=0) is_published = models.BooleanField(default=False) published_at = models.DateTimeField(null=True, blank=True) class Meta: ordering = ["-published_at"] def __str__(self): return self.title class ContentInteraction(models.Model): class Action(models.TextChoices): VIEW = "view", "浏览" FAVORITE = "favorite", "收藏" COMPLETE = "complete", "完成" user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) content = models.ForeignKey(ContentItem, on_delete=models.CASCADE, related_name="interactions") action = models.CharField(max_length=16, choices=Action.choices) created_at = models.DateTimeField(auto_now_add=True) class Meta: constraints = [ models.UniqueConstraint( fields=("user", "content", "action"), name="unique_content_interaction" ) ] class VideoProgress(models.Model): user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="video_progress" ) content = models.ForeignKey( ContentItem, on_delete=models.CASCADE, related_name="video_progress" ) position_seconds = models.PositiveIntegerField(default=0) completed = models.BooleanField(default=False) reward_granted = models.BooleanField(default=False) updated_at = models.DateTimeField(auto_now=True) completed_at = models.DateTimeField(null=True, blank=True) class Meta: constraints = [ models.UniqueConstraint( fields=("user", "content"), name="unique_user_video_progress" ) ]