""" User models for authentication and profile management. """ from django.db import models from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin class UserManager(BaseUserManager): """Custom user manager.""" def create_user(self, open_id, password=None, **extra_fields): """Create and save a regular user.""" if not open_id: raise ValueError('The open_id must be set') user = self.model(open_id=open_id, **extra_fields) if password: user.set_password(password) else: user.set_unusable_password() user.save(using=self._db) return user def create_superuser(self, open_id, password=None, **extra_fields): """Create and save a superuser.""" extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) extra_fields.setdefault('role', 'admin') return self.create_user(open_id, password=password, **extra_fields) class User(AbstractBaseUser, PermissionsMixin): """Custom user model matching the original schema.""" class Role(models.TextChoices): USER = 'user', '普通用户' ADMIN = 'admin', '管理员' id = models.AutoField(primary_key=True) open_id = models.CharField('OpenID', max_length=64, unique=True) name = models.CharField('用户名', max_length=255, blank=True, null=True) email = models.EmailField('邮箱', max_length=320, blank=True, null=True) avatar = models.TextField('头像', blank=True, null=True) login_method = models.CharField('登录方式', max_length=64, blank=True, null=True) role = models.CharField( '角色', max_length=10, choices=Role.choices, default=Role.USER ) stripe_customer_id = models.CharField('Stripe客户ID', max_length=255, blank=True, null=True) stripe_account_id = models.CharField('Stripe账户ID', max_length=255, blank=True, null=True) # Django auth fields is_active = models.BooleanField('是否激活', default=True) is_staff = models.BooleanField('是否员工', default=False) created_at = models.DateTimeField('创建时间', auto_now_add=True) updated_at = models.DateTimeField('更新时间', auto_now=True) last_signed_in = models.DateTimeField('最后登录时间', auto_now=True) objects = UserManager() USERNAME_FIELD = 'open_id' REQUIRED_FIELDS = [] class Meta: db_table = 'users' verbose_name = '用户' verbose_name_plural = '用户' indexes = [ models.Index(fields=["role", "is_active"]), models.Index(fields=["created_at"]), ] def __str__(self): return self.name or self.open_id @property def is_admin(self): return self.role == self.Role.ADMIN class FriendRequest(models.Model): """Friend request and relationship status.""" class Status(models.TextChoices): PENDING = "pending", "待处理" ACCEPTED = "accepted", "已通过" REJECTED = "rejected", "已拒绝" CANCELED = "canceled", "已取消" requester = models.ForeignKey( User, related_name="sent_friend_requests", on_delete=models.CASCADE, ) receiver = models.ForeignKey( User, related_name="received_friend_requests", on_delete=models.CASCADE, ) status = models.CharField( "状态", max_length=10, choices=Status.choices, default=Status.PENDING, ) accepted_at = models.DateTimeField("通过时间", blank=True, null=True) created_at = models.DateTimeField("创建时间", auto_now_add=True) updated_at = models.DateTimeField("更新时间", auto_now=True) class Meta: db_table = "friend_requests" verbose_name = "好友请求" verbose_name_plural = "好友请求" unique_together = ("requester", "receiver") constraints = [ models.CheckConstraint( check=~models.Q(requester=models.F("receiver")), name="no_self_friend_request", ) ] indexes = [ models.Index(fields=["receiver", "status"]), models.Index(fields=["requester", "status"]), ] def __str__(self): return f"{self.requester_id}->{self.receiver_id} ({self.status})"