import logging from django.conf import settings logger = logging.getLogger(__name__) _SCENE_TEMPLATE = { 'register': 'ALIYUN_SMS_TEMPLATE_REGISTER', 'login': 'ALIYUN_SMS_TEMPLATE_LOGIN', 'reset': 'ALIYUN_SMS_TEMPLATE_RESET', } class AliyunSmsService: """阿里云短信实现。SDK 按需 import,避免未安装时影响 mock 模式启动。""" def send_code(self, phone: str, scene: str, code: str) -> None: from apps.user.utils.sms import SmsError try: from alibabacloud_dysmsapi20170525.client import Client from alibabacloud_dysmsapi20170525 import models as sms_models from alibabacloud_tea_openapi import models as open_api_models except ImportError as e: logger.error('Aliyun SMS SDK not installed: %s', e) raise SmsError('SMS_PROVIDER_ERROR') from e config = open_api_models.Config( access_key_id=settings.ALIYUN_SMS_ACCESS_KEY_ID, access_key_secret=settings.ALIYUN_SMS_ACCESS_KEY_SECRET, ) config.endpoint = 'dysmsapi.aliyuncs.com' client = Client(config) template_attr = _SCENE_TEMPLATE.get(scene, '') template_code = getattr(settings, template_attr, '') req = sms_models.SendSmsRequest( phone_numbers=phone, sign_name=settings.ALIYUN_SMS_SIGN_NAME, template_code=template_code, template_param=f'{{"code":"{code}"}}', ) try: resp = client.send_sms(req) if resp.body.code != 'OK': logger.error( 'Aliyun SMS biz error: code=%s msg=%s request_id=%s', resp.body.code, resp.body.message, resp.body.request_id, ) raise SmsError('SMS_BIZ_ERROR') except SmsError: raise except Exception as e: logger.error('Aliyun SMS provider error: %s', e) raise SmsError('SMS_PROVIDER_ERROR') from e