from rest_framework.permissions import AllowAny from adrf.views import APIView from rest_framework import status from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi from chunyu_project.common_schemas import success_response, error_response, unauthorized_response, not_found_response from utils.slider_captcha import ( generate_slider_captcha, verify_slider_captcha, verify_slider_trajectory, SliderCaptchaError ) from utils.response_codes import ( ResponseCode, create_standardized_response, create_standardized_error_response, ) class SliderCaptchaGenerateView(APIView): permission_classes = [AllowAny] @swagger_auto_schema( tags=['验证码'], operation_summary='生成滑块验证码', operation_description='生成新的滑块验证码,返回背景图、滑块图和验证 key', responses={200: success_response, 500: error_response}, ) def get(self, request): try: captcha_data = generate_slider_captcha() return create_standardized_response( data=captcha_data, code=ResponseCode.SUCCESS, status_code=status.HTTP_200_OK ) except Exception as e: return create_standardized_error_response( message=str(e), code=ResponseCode.SERVER_INTERNAL_ERROR, status_code=status.HTTP_500_INTERNAL_SERVER_ERROR ) class SliderCaptchaVerifyView(APIView): permission_classes = [AllowAny] @swagger_auto_schema( tags=['验证码'], operation_summary='验证滑块验证码', operation_description='验证滑块验证码结果,支持滑动轨迹可选', request_body=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'captcha_key': openapi.Schema(type=openapi.TYPE_STRING, description='验证码 key'), 'x_position': openapi.Schema(type=openapi.TYPE_INTEGER, description='滑块 X 坐标'), 'trajectory': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Items(type=openapi.TYPE_NUMBER), description='滑动轨迹数组'), }, ), responses={200: success_response, 400: error_response, 500: error_response}, ) def post(self, request): captcha_key = request.data.get('captcha_key') x_position = request.data.get('x_position') trajectory = request.data.get('trajectory') if not captcha_key or x_position is None: return create_standardized_error_response( message='缺少必要参数', code=ResponseCode.PARAMETER_ERROR, status_code=status.HTTP_400_BAD_REQUEST ) try: x_position = int(x_position) except (ValueError, TypeError): return create_standardized_error_response( message='位置参数无效', code=ResponseCode.PARAMETER_ERROR, status_code=status.HTTP_400_BAD_REQUEST ) try: if trajectory: verified = verify_slider_trajectory(captcha_key, x_position, trajectory) else: verified = verify_slider_captcha(captcha_key, x_position) return create_standardized_response( data={'verified': verified}, code=ResponseCode.SUCCESS, status_code=status.HTTP_200_OK ) except SliderCaptchaError as e: return create_standardized_error_response( message=str(e), code=ResponseCode.CAPTCHA_EXPIRED, status_code=status.HTTP_400_BAD_REQUEST ) except Exception as e: return create_standardized_error_response( message=str(e), code=ResponseCode.SERVER_INTERNAL_ERROR, status_code=status.HTTP_500_INTERNAL_SERVER_ERROR )