import random import string import logging from abc import ABC, abstractmethod from django.conf import settings logger = logging.getLogger(__name__) def generate_sms_code(length=6) -> str: return ''.join(random.choices(string.digits, k=length)) # ── 策略接口 ────────────────────────────────────────────────────────────────── class SmsService(ABC): @abstractmethod def send_code(self, phone: str, scene: str, code: str) -> None: """发送验证码短信。失败时抛出 SmsError。""" class SmsError(Exception): pass def get_sms_service() -> SmsService: provider = getattr(settings, 'SMS_PROVIDER', 'mock') if provider == 'aliyun': from apps.user.utils.sms_aliyun import AliyunSmsService return AliyunSmsService() from apps.user.utils.sms_mock import MockSmsService return MockSmsService()