123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- 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()})"
|