diff --git a/offer_backend/apps/accounts/serializers.py b/offer_backend/apps/accounts/serializers.py index deadfca..9112c6b 100644 --- a/offer_backend/apps/accounts/serializers.py +++ b/offer_backend/apps/accounts/serializers.py @@ -5,15 +5,59 @@ from .models import VerificationCode User = get_user_model() -class RegisterSerializer(serializers.ModelSerializer): - password = serializers.CharField(write_only=True, min_length=6) +class RegisterSerializer(serializers.Serializer): + """邮箱验证码注册 serializer""" + username = serializers.CharField(max_length=150) + email = serializers.EmailField() + phone = serializers.CharField(max_length=20) + code = serializers.CharField(max_length=6, min_length=6) - class Meta: - model = User - fields = ['username', 'email', 'phone', 'password'] + def validate_username(self, value): + """验证用户名是否已存在""" + if User.objects.filter(username=value).exists(): + raise serializers.ValidationError('用户名已存在') + return value + + def validate_email(self, value): + """验证邮箱是否已存在""" + if User.objects.filter(email=value).exists(): + raise serializers.ValidationError('邮箱已被注册') + return value + + def validate(self, attrs): + """验证邮箱和验证码""" + email = attrs.get('email') + code = attrs.get('code') + + # 检查验证码 + try: + vc = VerificationCode.objects.filter(email=email).latest('created_at') + except VerificationCode.DoesNotExist: + raise serializers.ValidationError({'code': '请先获取验证码'}) + + # 检查验证码是否有效 + if not vc.is_valid(): + raise serializers.ValidationError({'code': '验证码已过期或已使用'}) + + # 验证码是否正确 + if vc.code != code: + vc.increment_attempts() + raise serializers.ValidationError({'code': '验证码错误'}) + + attrs['vc'] = vc + return attrs def create(self, validated_data): - return User.objects.create_user(**validated_data, role='seeker') + """创建用户并标记验证码为已使用""" + vc = validated_data.pop('vc') + user = User.objects.create_user( + username=validated_data['username'], + email=validated_data['email'], + phone=validated_data['phone'], + role='seeker' + ) + vc.mark_as_verified() + return user class UserSerializer(serializers.ModelSerializer): diff --git a/offer_backend/apps/accounts/views.py b/offer_backend/apps/accounts/views.py index 00e5adb..73cfccd 100644 --- a/offer_backend/apps/accounts/views.py +++ b/offer_backend/apps/accounts/views.py @@ -77,10 +77,32 @@ class CustomTokenObtainPairView(TokenObtainPairView): return token -class RegisterView(generics.CreateAPIView): - serializer_class = RegisterSerializer +class RegisterView(APIView): + """邮箱验证码注册""" permission_classes = [AllowAny] + def post(self, request): + serializer = RegisterSerializer(data=request.data) + serializer.is_valid(raise_exception=True) + + # 创建用户 + user = serializer.save() + + # 生成 JWT token + from rest_framework_simplejwt.tokens import RefreshToken + refresh = RefreshToken.for_user(user) + + return Response({ + 'user': { + 'id': user.id, + 'username': user.username, + 'email': user.email, + 'role': user.role, + }, + 'refresh': str(refresh), + 'access': str(refresh.access_token), + }, status=status.HTTP_201_CREATED) + class MeView(APIView): permission_classes = [IsAuthenticated] diff --git a/offer_frontend/src/views/auth/RegisterView.vue b/offer_frontend/src/views/auth/RegisterView.vue index faf7b19..2b1c3d8 100644 --- a/offer_frontend/src/views/auth/RegisterView.vue +++ b/offer_frontend/src/views/auth/RegisterView.vue @@ -3,42 +3,201 @@

求职者注册

- - - - - 注册 + + + + + + + + + + + + + + + 获取验证码 + + + + + +
+ + + {{ codeCountdown > 0 ? `${codeCountdown}s` : '重新获取' }} + +
+
+ + + + 注册 +
-
- 已有账号?立即登录 + +
+ 已有账号?立即登录
+ +