from django.db import models from django.utils.translation import gettext_lazy as _ from django.utils import timezone class Users(models.Model): """核心用户模型 (继承现有结构)""" user_id = models.AutoField(primary_key=True, verbose_name="用户ID") name = models.CharField(max_length=80, verbose_name='姓名') openid = models.CharField(max_length=100, unique=True, verbose_name='OPENID') appid = models.CharField(max_length=100, verbose_name='APPID') # 权限系统 vip = models.PositiveIntegerField(default=1, verbose_name='VIP等级') vip_time = models.DateTimeField(auto_now_add=True, verbose_name='VIP生效时间') # 账户状态 is_delete = models.BooleanField(default=False, verbose_name='删除标记') developer = models.BooleanField(default=False, verbose_name='开发者标记') # 安全信息 t_code = models.CharField(max_length=100, unique=True, verbose_name='交易验证码') ip = models.GenericIPAddressField(verbose_name='注册IP') # 基本信息 avatar = models.CharField(max_length=200, default='/static/img/user.jpg', verbose_name='用户头像') create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间') class Meta: db_table = 'user_profile' verbose_name = '用户档案' verbose_name_plural = "用户档案" ordering = ['-create_time'] def __str__(self): return f"{self.name}(ID:{self.user_id})" class AcademicProfile(models.Model): """学术信息扩展模型 (与用户一对一关联)""" class AcademicRole(models.TextChoices): UNDERGRAD = 'UG', _('本科生') MASTER = 'MS', _('硕士生') PHD = 'PhD', _('博士生') POSTDOC = 'PD', _('博士后') FACULTY = 'FAC', _('教职工') RESEARCHER = 'RES', _('研究员') user = models.OneToOneField( Users, on_delete=models.CASCADE, primary_key=True, related_name='user_academic_profile', verbose_name='关联用户' ) # 学术身份 role = models.CharField( max_length=10, choices=AcademicRole.choices, default=AcademicRole.MASTER, verbose_name='学术身份' ) # 年级信息 enrollment_year = models.PositiveIntegerField( verbose_name='入学年份', help_text='格式:YYYY(如2023)' ) graduation_year = models.PositiveIntegerField( null=True, blank=True, verbose_name='预计毕业年份' ) # 学术单位 department = models.CharField(max_length=100, verbose_name='院系/研究所') major = models.CharField(max_length=100, verbose_name='专业方向') # 研究标签 research_tags = models.CharField( max_length=255, blank=True, verbose_name='研究方向', help_text='用逗号分隔多个方向(如:人工智能,教育技术)' ) skill_tags = models.CharField( max_length=255, blank=True, verbose_name='技能标签', help_text='用逗号分隔多个技能(如:Python,数据分析)' ) class Meta: db_table = 'user_academic_profile' verbose_name = '学术档案' verbose_name_plural = "学术档案" def __str__(self): return f"{self.user.name}的学术档案" class ResearchGroup(models.Model): """教研小组模型""" group_id = models.AutoField(primary_key=True, verbose_name="小组ID") name = models.CharField(max_length=100, unique=True, verbose_name="小组名称") description = models.TextField(blank=True, verbose_name="小组描述") created_by = models.ForeignKey( Users, on_delete=models.SET_NULL, null=True, related_name='created_groups', verbose_name="创建人" ) created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") is_active = models.BooleanField(default=True, verbose_name="是否活跃") class Meta: db_table = 'user_research_group' verbose_name = '教研小组' verbose_name_plural = "教研小组" ordering = ['-created_at'] def __str__(self): return f"{self.name}(ID:{self.group_id})" class GroupMembership(models.Model): """小组成员关联模型""" class MemberRole(models.TextChoices): LEADER = 'LEAD', _('组长') DEPUTY = 'DEP', _('副组长') CORE = 'CORE', _('核心成员') MEMBER = 'MEM', _('普通成员') ADVISOR = 'ADV', _('指导老师') OBSERVER = 'OBS', _('观察员') class MemberStatus(models.TextChoices): ACTIVE = 'ACT', _('活跃') LEAVE = 'LV', _('请假') INACTIVE = 'INAC', _('不活跃') GRADUATED = 'GRAD', _('已毕业') TRANSFERRED = 'TRF', _('已转组') user = models.ForeignKey( Users, on_delete=models.CASCADE, related_name='group_memberships', verbose_name="成员" ) group = models.ForeignKey( ResearchGroup, on_delete=models.CASCADE, related_name='members', verbose_name="所属小组" ) role = models.CharField( max_length=20, choices=MemberRole.choices, default=MemberRole.MEMBER, verbose_name="小组角色" ) status = models.CharField( max_length=10, choices=MemberStatus.choices, default=MemberStatus.ACTIVE, verbose_name="在组状态" ) joined_at = models.DateTimeField(auto_now_add=True, verbose_name="加入时间") left_at = models.DateTimeField(null=True, blank=True, verbose_name="离开时间") custom_permissions = models.JSONField( null=True, blank=True, default=dict, verbose_name="特殊权限", help_text="JSON格式存储额外权限" ) class Meta: db_table = 'user_group_membership' verbose_name = '小组成员' verbose_name_plural = "小组成员" unique_together = ('user', 'group') # 确保同一用户不会重复加入同一小组 ordering = ['-joined_at'] def save(self, *args, **kwargs): """自动更新离开时间""" if self.status in [self.MemberStatus.GRADUATED, self.MemberStatus.TRANSFERRED] and not self.left_at: self.left_at = timezone.now() super().save(*args, **kwargs) def __str__(self): return f"{self.user.name}在{self.group.name}({self.get_role_display()})"